Reputation: 9193
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.
Upvotes: 4
Views: 2439
Reputation: 213935
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.
Upvotes: 4