I have an ELF file that I would like to decompile into C
code, and make simple changes to the resulting C
code and rebuild it into an ELF.
This will give you (almost) an assembly code translation:
objdump --disassemble <elf file>
I say almost because the output contains some annotations like binary file position markers and can't serve directly as input to an assembler, but it's close.
You write a simulator for the processor, then you run the elf instructions through your simulated processor. It's generally not too much of a task because even CISC processors have relatively small, contained instruction sets that perform simple operations.
When you've got that working, look at more efficient solutions, like outputting C code to match instructions.