2013-07-19 22 views
2

我有一個x86-64可執行文件,我試圖用靜態方法分析它。從_start開始,我看到跳轉到0x400648 - PLT之內的地址 - 其中包含指令jmp *0x20065a(%rip)。這個跳轉導致了*0x600ca8,這實際上是0x40064e。這使我們回到PLT並執行pushq $0x2爲什麼ELF64可執行文件中的.dynsym條目未初始化?

這裏是我卡住的地方:我知道pushq $0x2指令存在告訴動態鏈接器解決.dynsym表中的第3個條目。問題是該條目中的st_value字段是0x0。這個值實際上應該是main_start的偏移量,對不對?如果是這樣,st_value字段如何初始化?

回答

1

這個值實際上應該是_start的主偏移量,對不對?

錯誤。你不能從_start跳到main - 後者預計參數爲argcargv[],但是沒有人設置它們。這是libc初始化代碼工作:

  • 初始化的libc本身,創建標準FILE句柄(stdout等),設置環境等,並
  • 呼叫main使用正確的參數,並
  • 如果/當main返回時,用正確的退出代碼安排程序到exit(2)

你們看到的其實是一個PLT呼叫__libc_start_main,這將做到以上的,以及然後呼叫main。你可以用objdump -dr a.out看到這一點,這將類似於此:

00000000004003d0 <_start>: 
    4003d0:  31 ed     xor %ebp,%ebp 
    4003d2:  49 89 d1    mov %rdx,%r9 
    4003d5:  5e      pop %rsi 
    4003d6:  48 89 e2    mov %rsp,%rdx 
    4003d9:  48 83 e4 f0    and $0xfffffffffffffff0,%rsp 
    4003dd:  50      push %rax 
    4003de:  54      push %rsp 
    4003df:  49 c7 c0 50 05 40 00 mov $0x400550,%r8 
    4003e6:  48 c7 c1 c0 04 40 00 mov $0x4004c0,%rcx 
    4003ed:  48 c7 c7 b4 04 40 00 mov $0x4004b4,%rdi 
    4003f4:  e8 c7 ff ff ff   callq 4003c0 <[email protected]> 
    4003f9:  f4      hlt 
    4003fa:  90      nop 
    4003fb:  90      nop 

怎樣的st_value領域得到初始化?

你可以閱讀有關如何動態符號解析的實際細節工作here(搜索「過程鏈接表」;要注意:很少有人真正理解它是如何工作的詳細)。

+0

有什麼方法可以靜態確定'main'的地址是什麼? – RouteMapper

+0

我仍然想知道我的問題的答案。 – RouteMapper

相關問題