Inject a .preinit_array section in an ELF file with libelf

Viewed 270

I have the following simple hello-world program compiled with gcc in a standard elf binary:

#include <stdio.h>

void hello() {
  printf("Preinit hello!\n");
}

int main() {
    printf("Hello World\n");
    return 0;
}

How can I create a new elf file using libelf (or any other suggested C library for such operations) in order to add a .preinit_array section that calls hello()?

My end goal is to "simulate" what a compiler would do with the following:

__attribute__((section(".preinit_array"))) typeof(hello) *hello_p = hello;

I read libelf by example but I found it completely cryptic and outdated with 32-bit examples only.

I also found this related SO question. objcopy is doing pretty much what I would like to do but obviously I don't want to call objcopy from my C program. Additionally, I tried to copy objcopy's source code from here with little success as the code is quite complicated and interconnected.

1 Answers

My end goal is to "simulate" what a compiler would do with the following

That end-goal (by itself) makes no sense to me: why not just do exactly that: add the .preinit_array, rebuild the program, profit.

Your real end-goal is probably something else (see also XY Problem).

The simple answer to your question is: you can't (or at least, the task is very non-trivial, and you are likely to find some other solution to your real problem well before you succeed with this approach).

The reason: the ELF file format has lots of cross-references (where parts of the file record where other parts of the file are), and the information needed to correctly update all such cross-references is discarded during the linking process.

That is, most UNIX linkers consider the a.out or foo.so the final product of the link, and no subsequent updates are feasible.

This isn't entirely true: some parts may be updated post-link, e.g. chrpath and patchelf can do such limited editing. But the general case is really difficult.

Related