I want to write a utility to remove a program header from an ELF binary. For example, when I run readelf -l /my/elf I get a listing of all the program headers: PHDR INTERP … GNU_STACK GNU_RELRO. When I run my utility, I would like to get all the same program headers back in the same order, minus the one I deleted. Is there any easier way to do this than recreated the entire ELF from scratch, skipping the unwanted header?
Share
Sure: program headers form a fixed-record table at an offset given by
ehdr.e_phoff, containing.e_phnumentries of.e_phentsizebytes.To delete one entry, simply copy the rest of entries over it, and decrement
.e_phnum. That’s all there is to it.Beware: deleting some entries will likely cause the dynamic loader to crash.
GNU_STACKis about the only header that can be deleted without too much harm (that I can think of).Update:
Yes, setting
.p_typetoPT_NULLis another (and simpler) approach. But such entries are generally not expected to be present, and you may find some systems wherePT_NULLwill trigger an assertion in the loader (or in some other program).Finally, adding a new
Phdrmight be tricky. Usually there is no space to expand the table (as it is immediately followed by some other data, e.g..text). You can relocate the table to the end of the file, and set.e_phoffand.e_phnumto correspond to the new table, but many programs expect the entirePhdrtable to be loaded and available at runtime, and that is not easy to arrange, as the new location at the end of the file will not be “covered” by anyPT_LOADsegment.