• Like
Runtime Symbol Resolution
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

Runtime Symbol Resolution

  • 3,472 views
Published

This presentation material is about runtime symbol resolution on Linux x86-64. We will not discuss Windows/Mac implementation.

This presentation material is about runtime symbol resolution on Linux x86-64. We will not discuss Windows/Mac implementation.

  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
No Downloads

Views

Total Views
3,472
On SlideShare
0
From Embeds
0
Number of Embeds
2

Actions

Shares
Downloads
41
Comments
0
Likes
1

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. Runtime Symbol Resolution
  • 2. Outline
    • Overview of Dynamic Library
    • 3. Relocatable code / Relocation section
    • 4. Executable code / PLT & GOT
    • 5. Runtime process analysis with GDB
    • 6. Summary
  • 7. Overview
    • This is about runtime symbol resolution on Linux x86-64
      • Windows/Mac have different mechanisms
    • Assume source code is written in C
    • 8. “Linker” means “static linker” (not dynamic) in this material
  • 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
  • 10. What's Dynamic Library?
    • Dynamic library is linked at runtime
      • While static library is linked at “compile-time”
    • Shared by more than one application
      • Often called “Shared library”
    Process 1 Process 2 Dynamic Lib Static Lib Static Lib Process 1 Process 2 Memory (or storage) image
  • 11. How is DL different?
    • Address of symbols (functions, variables) are only known at run-time
      • Linker cannot tell where the DL will be loaded
      • 12. Executables cannot contain exact addresses
    • Loader must play a role so that the code can call functions (or refer to variables) defined in DLs
  • 13. Sample Code: Hello, World! #include <stdio.h> int main() { puts(&quot;Hello, World!&quot;); return 0; } hello.c
  • 14. Build
    • Preprocess & Compile & Assemble
      • “gcc -c hello.c” generates a relocatable file “hello.o”
    • Preprocess & Compile & Assemble & Link
      • “gcc hello.c” generates an executable file “a.out”
    % ls a.out hello.c hello.o
  • 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. “e8” or “callq”
    • Instruction “e8” is “Call … displacement relative to next instruction...”
      • See “Intel Software Developer's Manual”
    • “e8 00 00 00 00” means “call next instruction”, which doesn't make sense
    • 17. “00 00 00 00” must be replaced with “puts”
      • “hello.o” must contain relocation info
  • 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]
  • 19. Summary: Relocatable code
    • Code (or “.text” section) has zero as an address
    • 20. Relocation table (or “.rela” section) tells what to replace the zero with
    • 21. The later process must utilize the relocation info to actually link “puts” to the code
  • 22. Executable code % objdump -d a.out // disassemble text section [...] 00000000004004c4 <main>: 4004c4: 55 push %rbp 4004c5: 48 89 e5 mov %rsp,%rbp 4004c8: bf e0 05 40 00 mov $0x4005e0,%edi 4004cd: e8 e6 fe ff ff callq 4003b8 <puts@plt> 4004d2: b8 00 00 00 00 mov $0x0,%eax 4004d7: 5d pop %rbp 4004d8: c3 retq Calling “puts@plt”, not “puts”
  • 23. Executable code: PLT % objdump -d a.out [...] 00000000004003a8 <puts@plt-0x10>: 4003a8: pushq 0x2004b2(%rip) # 600860 4003ae: jmpq *0x2004b4(%rip) # 600868 4003b4: nopl 0x0(%rax) 00000000004003b8 < [email_address] >: 4003b8: jmpq *0x2004b2(%rip) # 600870 4003be: pushq $0x0 4003c3: jmpq 4003a8 <_init+0x18> _GLOBAL_OFFSET_TABLE_+0x8 _GLOBAL_OFFSET_TABLE_+0x10 _GLOBAL_OFFSET_TABLE_+0x18 Machine code is omitted as it's getting cryptic...
  • 24. Executable code: GOT Symbol Address Value _GLOBAL_OFFSET_TABLE_ + 0x0 0x600858 0x006006c0 _GLOBAL_OFFSET_TABLE_ + 0x8 0x600860 0x00000000 _GLOBAL_OFFSET_TABLE_ + 0x10 0x600868 0x00000000 _GLOBAL_OFFSET_TABLE_ + 0x18 0x600870 0x004003be _GLOBAL_OFFSET_TABLE_ + 0x20 0x600878 0x004003ce
    • GOT contents can be shown with objdump
      • “objdump -s --start-address=0x600858 --stop-address=0x600880 a.out”
  • 25. Summary: Executable code
    • When “puts@plt” is called …
      • Jump to an address stored in GOT
        • The address points to the next instruction
      • Push 0 to stack
      • 26. Jump to “puts@plt – 0x10”
      • 27. Push an address of a GOT entry to stack
      • 28. Jump to the address stored in GOT
        • The address is set to 0
    • What's going on???
    ??? Jumping to address 0 will crash the process What's this 0? What's this address used for?
  • 29. A bit more analysis...
    • Just before jumping to address 0, stack should look like...
    • 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. Process Image
    • GOT in the executable code looks weird. Gdb can show us the real GOT at runtime
    % gdb a.out [...] Reading symbols from /foo/a.out...[...] (gdb) start Temporary breakpoint 1 at 0x4004c8 Starting program: /foo/a.out Temporary breakpoint 1, 0x00000000004004c8 in main ()
  • 32. Process Image: GOT
    • Remember GOT is stored at 0x600858
    (gdb) x/a 0x600858 0x600858: 0x6006c0 <_DYNAMIC> (gdb) x/a 0x600860 0x600860: 0x302cc20288 (gdb) x/a 0x600868 0x600868: 0x302ca13850 <_dl_runtime_resolve> (gdb) x/a 0x600870 0x600870: 0x4003be <puts@plt+6> (gdb) x/a 0x600878 0x600878: 0x302ce212b0 <__libc_start_main>
  • 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
  • 34. Revisiting “puts@plt”
    • When “puts@plt” is called …
      • Jump to an address stored in GOT
        • The address points to the next instruction
      • Push 0 to stack
      • 35. Jump to “puts@plt – 0x10”
      • 36. Push an address of a GOT entry to stack
        • The address stores value 0x302cc20288
      • Jump to “_dl_runtime_resolve”
        • The name suggests “runtime symbol resolution”
    ??? What's this 0? What's this address used for?
  • 37. _dl_runtime_resolve
    • Don't have time to dive into the function :-)
    • 38. Takes 2 arguments
      • A pointer to a structure containing DL info
        • 0x302cc20288 in this case
      • An index of relocation entry in “.rela.plt”
        • 0 for “puts”; 1 for “__libc_start_main”
    • Replaces a value in GOT
    • 39. Jmp to the function
      • “puts” in this case
  • 40. Revisiting “puts@plt” (3 rd time)
    • When “puts@plt” is called …
      • Jump to an address stored in GOT
        • The address points to the next instruction
      • Push 0 to stack
        • 2 nd argument to “_dl_runtime_resolve”
      • Jump to “puts@plt – 0x10”
      • 41. Push an address of a GOT entry to stack
        • 1 st argument to “_dl_runtime_resolve”
      • Jump to “_dl_runtime_resolve”
        • GOT entry is replaced with the address of “puts”
    ???
  • 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” !
  • 43. Lazy link
    • What happens if the code has another call to “puts”
      • “puts@plt” is called
      • 44. Jump to an address stored in GOT
        • Which is now an exact address of “puts”
        • 45. No need to jump to “_dl_runtime_resolve”
    • The complicated code in “.plt” section is for lazy link
      • Every function call is resolved on the first call
  • 46. Revisiting “puts@plt” (4 th time)
    • When “puts@plt” is called …
      • Jump to an address stored in GOT
        • The address initially points to the next instruction and is later replaced with “puts” address
      • Push 0 to stack
      • 47. Jump to “puts@plt – 0x10”
      • 48. Push an address of a GOT entry to stack
      • 49. Jump to “_dl_runtime_resolve”
        • Which uses 0 and the GOT entry address
  • 50. Summary
    • How dynamic link is implemented
      • “.rela” section in ELF
      • 51. Indirect call via Procedure Linkage Table
      • 52. Lazy linking by using Global Offset Table
        • Help to speed up application launch
      • “_dl_runtime_resolve” does the linking
        • Defined in glibc. Might be interesting to look into it.
  • 53. References
    • AMD64 Application Binary Interface
      • http://www.x86-64.org/documentation/abi.pdf
    • Intel386 Architecture Processor Supplement
      • http://www.sco.com/developers/devspecs/abi386-4.pdf
    • Intel Software Developer Manual
      • http://www.intel.com/content/www/us/en/processors/architectures-software-developer-manuals.html
    • Linkers and Loaders
      • http://www.iecc.com/linker/