Adding sections in a binary

Hey,

LLVM has logic to parse ELF and PE binaries using llvm::object::createBinary. I tried to search in the codebase to see if there’s a possibility to add/remove sections after parsing a binary and re-write the binary to another location. Basically, like what llvm-objcopy does. Can you point me to the right classes to look into, if this is something that LLVM has?

Many thanks

Joseph

Sounds like the llvm-objcopy source code (llvm/tools/llvm-objcopy) is
probably a good place to start.

For ELF,

* adding a non-SHF_ALLOC section is simple. A non-SHF_ALLOC section is not part of
   the memory image and not used by the program (unless for some rare
   introspection use cases)

* adding a SHF_ALLOC section is difficult. You likely need to fix the
   containing PT_LOAD segment. llvm-objcopy only does the base p_offset fix.
   You need to take care p_vaddr/p_paddr/p_filesz/p_memsz by your self.

   + adding a section smaller than the known lowest address (ET_EXEC with a
     non-zero image base) or larger than the known largest address:
     The PT_LOAD fixes are doable.
   + adding a section within the existing address ranges: this is very difficult
     due to many implicit inter-section references. If you have an advanced
     binary rewriting tool, this is still doable, but definitely brittle.

   File offsets (p_offset,sh_offset) can be reconstructed from addresses.
   llvm-objcopy/ELF/Object.cpp layoutSections has some code.
   A more sophisticated implementation is in the linker: lld/ELF/Writer.cpp assignFileOffsets

Many thanks for the great info. What about removing a section? Is there an implementation for that already in the codebase?

Again, llvm-objcopy is the place to look for this. It has code for removing sections from ELF and other formats too, I believe. Again, speaking about ELF, the complexity depends on what you mean by removing a section though, and in what context - removing a section without SHF_ALLOC, or from an unlinked object is fairly straightforward - you simply remove its section header table entry and update any section indexes for references to sections that appear after it in the table. You can scrub over the section contents with e.g. 0. “Squashing” the ELF to remove the excess space left behind is also possible - best refer to llvm-objcopy’s code again for this. Removing SHF_ALLOC sections is more complex, due to section references and addresses that will need fixing up, and borderline impossible if you are working with a linked image, without completely disassembling and reassembling the memory image.

This answers. Many, many thanks to all involved