50 lines
1.9 KiB
Markdown
50 lines
1.9 KiB
Markdown
# 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_<arch>_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_<arch>_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 <pcrel32>]` 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 <input> <output> <symbol>
|
|
|
|
# also show some example stuff
|
|
make all
|
|
```
|
|
|
|
## License
|
|
|
|
See [LICENSE](/LICENSE).
|
|
|