3

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.

Bob5421
  • 7,757
  • 14
  • 81
  • 175

1 Answers1

4

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.

Employed Russian
  • 199,314
  • 34
  • 295
  • 362
  • Thanks. When you say "For ET_DYN, also known as PIE binary, loading at random address is both possible and expected.": Suppose i compile an elf executable (not a library) that contains main function and a foo function. Does that mean that those functions should be loaded too at random address ? But the entry point can not move between 2 executions ! – Bob5421 Jun 23 '16 at 05:38
  • @Bob5421 If you link an executable with `-pie` flag, that executable will have `ET_DYN` type and will behave like a shared library. See also https://stackoverflow.com/questions/1449987/building-a-so-that-is-also-an-executable – Employed Russian Jun 23 '16 at 06:02
  • Okay so in this case main and foo will be at a random address ? – Bob5421 Jun 23 '16 at 07:17
  • @Bob5421 In a `PIE` binary, both `main` and `foo` will be relocated by the same page-aligned but otherwise random address, yes. – Employed Russian Jun 23 '16 at 12:39
  • okay so how entry point will reach main ? via _start function, which do not move even in PIE mode ? – Bob5421 Jun 23 '16 at 13:04
  • @Bob5421 *Everything* in the `PIE` binary will move, including `_start`. The loader knows where in memory the executable ended up, so it can call `_start` at `${value of _start in symbol table} + ${runtime relocation}` – Employed Russian Jun 23 '16 at 13:22
  • i have tried this: "gcc -fPIC test.c -o test". gcc contains 2 functions: main and function_foo. When i launch gdb, i type disassemble main and disassemble function_foo. I have launch 10 times the test app throw gdb and the address were the same. What can impact the random memory position ? – Bob5421 Jun 23 '16 at 20:04
  • 1
    @Bob5421 To build a `PIE` binary, `-fPIC` is not enough. `readelf -h test` will show `ET_EXEC` for your binary, not `ET_DYN`. Try `gcc -fPIE -pie test.cc -o test`. Also, GDB by default disables address randomization. You need to `set disable-randomization off` to enable randomization when running the binary from inside GDB. – Employed Russian Jun 23 '16 at 20:26
  • You are right: Il i compile with gcc -pie test.cc -o test (no need of -fPIE), i display main address in the program with printf("%x\n",main) and i can see the address changing. The entry point is 0x4c0. So this entry point is ignored by loader ? Or _start function will always be at 0x4c0 ? – Bob5421 Jun 24 '16 at 04:56
  • @Bob5421 The entry point also moves, and is *not* ignored, as I explained 2 comments ago. – Employed Russian Jun 24 '16 at 06:00
  • Thanks. How can i get the runtime relocation offset value ? (with GDB or in C code) – Bob5421 Jun 24 '16 at 07:26
  • Thanks. Is this address randomisation (PIE), the same thing than ASLR. Or is ASLR something different ? – Bob5421 Jun 27 '16 at 05:16
  • @Bob5421 PIE is one of many techniques included in ASLR. Stack and heap placement randomization, shared library placement randomization are some of the others. – Employed Russian Jun 27 '16 at 05:27
  • I have compile an elf simple program with ET_EXEC. Each function is at the same address between several executions. but stack seems to be at a random position, which changes. Is it normal ? – Bob5421 Jun 28 '16 at 21:52
  • @Bob5421 Yes, that's the "stack placement randomization" part of ASLR I mentioned earlier. Location of `sbrk(0)` will also vary (heap placement randomization). – Employed Russian Jun 29 '16 at 05:24
  • I am ok with all of this on Linux. But i have just made a test on mac os x (mach-o executable). It is strange because ending of function address do not change at execution, but MSB bytes of address are changing whatever the gcc options... – Bob5421 Jun 30 '16 at 07:16