Bob5421
Bob5421

Reputation: 9193

Linux executable memory mapping

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

Answers (1)

Employed Russian
Employed Russian

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

Related Questions