2014-10-02 85 views
1

我很好奇readelfobjdumpgdb這樣的程序如何知道callq旁邊的指令。由於該方案尚未運行,他們如何知道'跌入'.plt有多遠?他們猜測是基於傳遞給它的參數嗎?或者他們真的做了一個模擬運行的程序來找出答案?程序鏈接表和呼叫相對

例如:

400ca4:  e8 e7 fb ff ff   callq 400890 <[email protected]> 
    400ca9:  48 8b 85 28 ff ff ff mov -0xd8(%rbp),%rax 

上面的代碼知道去printf().plt在0x400890:

0000000000400890 <[email protected]>: 
    400890:  ff 25 ba 17 20 00  jmpq *0x2017ba(%rip)  # 602050 <_GLOBAL_OFFSET_TA$ 
    400896:  68 07 00 00 00   pushq $0x7 
    40089b:  e9 70 ff ff ff   jmpq 400810 <_init+0x20> 

這是objdump -d只是輸出,所以我不知道如何計劃知道它想要printf。我能看到的唯一關聯是搬遷指數(pushq $0x7)和部分.dynsym,雖然它是一個價值了,因爲它開始在0:

8: 0000000000000000  0 FUNC GLOBAL DEFAULT UND [email protected]_2.2.5 (2) 

,混淆我是在參考了GOT另一件事.plt條目(#602050)。我從readelf看到它是基於地址範圍的.got.plt的一部分,但是這些程序在程序運行之前如何確定其值?

[23] .got.plt   PROGBITS   0000000000602000 00002000 
     00000000000000b8 0000000000000008 WA  0  0  8 

**編輯**

Symbol table '.dynsym' contains 22 entries: 

     Num: Value   Size Type Bind Vis  Ndx Name 
     0: 0000000000000000  0 NOTYPE LOCAL DEFAULT UND 
     1: 0000000000000000  0 FUNC GLOBAL DEFAULT UND [email protected]_2.2.5 (2) 
     2: 0000000000000000  0 FUNC GLOBAL DEFAULT UND [email protected]_2.2.5 (2) 
     3: 0000000000000000  0 FUNC GLOBAL DEFAULT UND [email protected]_2.2.5 (2) 
     4: 0000000000000000  0 FUNC GLOBAL DEFAULT UND [email protected]_2.2.5 (2) 
     5: 0000000000000000  0 FUNC GLOBAL DEFAULT UND [email protected]_2.2.5 (2) 
     6: 0000000000000000  0 FUNC GLOBAL DEFAULT UND strlen[email protected]_2.2.5 (2) 
     7: 0000000000000000  0 FUNC GLOBAL DEFAULT UND [email protected]_2.4 (3) 
     8: 0000000000000000  0 FUNC GLOBAL DEFAULT UND [email protected]_2.2.5 (2) 
     9: 0000000000000000  0 FUNC GLOBAL DEFAULT UND [email protected]_2.2.5 (2) 
     10: 0000000000000000  0 FUNC GLOBAL DEFAULT UND [email protected]_2.2.5 (2) 
     11: 0000000000000000  0 NOTYPE WEAK DEFAULT UND __gmon_start__ 
     12: 0000000000000000  0 FUNC GLOBAL DEFAULT UND [email protected]_2.2.5 (2) 
     13: 0000000000000000  0 FUNC GLOBAL DEFAULT UND [email protected]_2.2.5 (2) 
     14: 0000000000000000  0 FUNC GLOBAL DEFAULT UND [email protected]_2.2.5 (2) 
     15: 0000000000000000  0 FUNC GLOBAL DEFAULT UND [email protected]_2.2.5 (2) 
     16: 0000000000000000  0 FUNC GLOBAL DEFAULT UND [email protected]_2.2.5 (2) 
     17: 0000000000000000  0 FUNC GLOBAL DEFAULT UND [email protected]_2.2.5 (2) 
     18: 0000000000000000  0 FUNC GLOBAL DEFAULT UND [email protected]_2.2.5 (2) 
     19: 0000000000000000  0 FUNC GLOBAL DEFAULT UND [email protected]_2.2.5 (2) 
     20: 0000000000000000  0 FUNC GLOBAL DEFAULT UND [email protected]_2.2.5 (2) 
     21: 0000000000400a4d 34 FUNC GLOBAL DEFAULT 13 err 

回答

0

一點點的這是怎麼回事關的記憶,但讓我們看看我能不能幫你...

至於你第一個問題,有一連串的東西聯繫在一起。我不能保證這些工具是如何做的,而只是爲了表明這是一種方法。

  1. PLT與.rel(a).plt部分具有1對1的對應關係(PLT [0]除外,這是特殊的)。本節包含PLT條目的重定位。
  2. 每個.rel(a).plt條目具有一個具有符號表索引的信息字段,例如,到.dynsym。
  3. 每個符號表條目在其字符串表(例如.dynstr)中都有一個偏移名稱。此偏移量是從字符串部分的開始處開始的一個字節偏移量。

所以,你可以看到,你可以按照PLT到rel(a).plt,到符號表,在那裏你會找到「printf」。

要回答第二個問題,請查看程序標題(readelf -Wl <program>),您將看到不同部分的虛擬地址。這就是該地址範圍的來源。

+0

感謝您的信息。爲了澄清,readelf --relocs顯示值爲000100000007的信息字段,其中第4位數字按預期增加。假設這是索引,爲什麼readelf -s(顯示.symtab)將UND顯示爲所有函數的索引?在.symtab下,函數位於約45個條目中,而在.dynsym中它們是預期的位置,但仍具有UND索引。 – 2014-10-02 18:09:28

+0

自發布第一條評論以來,我瞭解到'.rela.plt'具有'.dynsym'的sh_link值,我需要使用ELF64_R_SYM()宏來獲取/提取索引編號。這樣做後,兩部分之間的關​​系是清楚的,但我仍然沒有看到這些數字如何對應'.dynstr'。 '.dynsym'中的索引號列爲UND,排序與字符串表中的條目不匹配。 – 2014-10-02 21:17:18

+0

@OwenM符號是UND,因爲它們在給定的二進制文件中不是_defined_ - 它們是在其他庫(本例中爲libc)中定義的。至於與.dynsym匹配的字符串,字符串表索引是從.dynstr開始的字節偏移量,而不是字符串數量的索引,因此應該匹配。 – 2014-10-02 21:46:56