9. Build (& Load) Process Usually you just type “gcc foo.c” and it invokes the four sub-processes for you. (text) (text) (text) (ELF) (ELF) (ELF) C code Preprocessed C code Assembly code Executable code Relocatable code Preprocessor Compiler Process Image Assembler Linker Loader DL
15. Relocatable code % objdump -d hello.o // disassemble text section [...] 0000000000000000 <main>: 0: 55 push %rbp 1: 48 89 e5 mov %rsp,%rbp 4: bf 00 00 00 00 mov $0x0,%edi 9: e8 00 00 00 00 callq e <main+0xe> e: b8 00 00 00 00 mov $0x0,%eax 13: 5d pop %rbp 14: c3 retq This must be a call to “puts”. But ...
16.
17.
18. Relocation section % readelf -r hello.o # output edited for better readability Relocation section '.rela.text' at offset 0x598 contains 2 entries: Offset Info Type Sym. Val. Sym. Name + Addend 00000005 00050000000a R_X86_64_32 00000000 .rodata + 0 0000000a 000a 00000002 R_X86_64_PC32 00000000 puts - 4 […] The symbol has index 0x0a (= “puts”) Show relocation section Replace value at 0x0a addend Value = [value of symbol] + [addend] - [offset]
30. Executable code has “.rela.plt” section Relocation section '.rela.plt' at offset 0x360 contains 2 entries: Offset Info Type Sym. Val. Sym. Name + Addend 00600870 […] R_X86_64_JUMP_SLO 00000000 puts + 0 00600878 […] R_X86_64_JUMP_SLO 00000000 __libc_start_main + 0 Stack Top ... 0x600860 0
31.
32.
33. Changes in GOT Address Value in Executable Value in Process 0x600858 0x6006c0 0x6006c0 0x600860 0x0 0x302cc20288 0x600868 0x0 0x302ca13850 <_dl_runtime_resolve> 0x600870 0x4003be <_puts@plt+6> 0x4003be <_puts@plt+6> 0x600878 0x4003ce <__libc_start_main@plt+6> 0x302ce212b0 <__libc_start_main> Ignore this change for now
42. GOT after calling “puts” (gdb) ni 0x00000000004004cd in main () (gdb) ni Hello, World! 0x00000000004004d2 in main () (gdb) x/a 0x600870 0x600870: 0x302ce692e0 <puts> Step over to next instruction “ puts” is called Now the GOT entry contains the actual address of “puts” !