An elf executable contains a section table. This sections are mapped to segments when the program is loaded in memory. I think it is the compiler which decide the segments address in memory ? Do you think it is possible for the operating system to change the segments address when the program is loaded.
I am talking about a single elf executable. This is not a library. In fact, i have a binary. I know a function address in memory and i want to hook this function from an external program. I just want to be sure that this address will never change. I won t recompile or change anything in the target program.
An elf executable contains a section table.
False: it is perfectly valid for section table to be stripped from a fully-linked ET_EXEC or ET_DYN binary.
This sections are mapped to segments when the program is loaded in memory.
False: section to segment mapping happens at static link time, not at runtime.
I think it is the compiler which decide the segments address in memory ?
False: it the static linker that decides this for ET_EXEC. For ET_DYN, static linker and runtime loader cooperate.
Do you think it is possible for the operating system to change the segments address when the program is loaded.
For ET_EXEC, the binary is always loaded at the address at which static linker linked that binary. Loading it anywhere else will make the program crash.
For ET_DYN, also known as PIE binary, loading at random address is both possible and expected.
i have a binary. I know a function address in memory and i want to hook this function from an external program. I just want to be sure that this address will never change.
If the binary is of type ET_EXEC, all segments are always loaded at the linked-at address, so yes.
Update:
In a PIE binary, everything will move together (main, foo, _start, etc.) by the same relocation (the relocation will normally vary from run to run; but GDB disables address space randomization, so one must do (gdb) set disable-randomization off).
To find the relocation in GDB, you can do:
(gdb) p &main
(gdb) start
(gdb) p &main
The first value of &main before the process starts should be the same as output from nm test | grep main. The second value (after process started) should be relocated value (where main landed in memory). The difference between the two is (page-aligned) relocation.
To find this relocation at runtime (from within the program itself), one needs to use dl_iterate_phdr() and use dlpi_addr. Documentation.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With