# relocmain Swap out an ELF executable's `main` function with another function from its symbol table, without touching its code at all. ## How it works The typical ELF entrypoint isn't `main` directly, but rather `_start`, an assembly stub that first does some runtime initialization before calling `main`. But instead of directly calling the latter function, it is often passed as a parameter to `__libc_start_main` (which in turn calls `main` after doing *more* initialization stuff). 'Relocations' are instructions for an ELF linker or loader on how to patch a binary when moving it around in memory or when resolving functions. Some examples are "this value here is an absolute address, so when you move me around, please keep it updated" (`R__RELATIVE`), or "I'm using this external function, and I'm accessing it through a PLT, so when you resolve the symbol, please put it in the PLT" (`R__JUMP_SLOT`). This programs adds another relocation entry that replaces the code that loads the address `main` (to pass it to `__libc_start_main`) with the address of a different symbol. Due to how relocations work, it is restricted to replacing it with another symbol that is either imported from another library, or exported by the executable itself. Currently, only x86_64 is supported (but it's not too hard to add support for other instruction sets, 32-bit ELF support is a bit harder). The code looks for a `lea rdi, [rel ]` instruction near `_start`, this is often the instruction that loads `main` to pass it to `__libc_start_main` (at least on glibc and musl it is). This then gets overwritten *at runtime by *`ld.so` due to a relocation of type `R_X86_64_PC32` targetting the `pcrel32` operand of that instruction --- all without touching any code of the executable. ## Usage ```sh # build only the tool make manip-exe # usage: ./manip-exe # also show some example stuff make all ``` ## License See [LICENSE](/LICENSE).