我很好奇readelf
,objdump
和gdb
這樣的程序如何知道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
感謝您的信息。爲了澄清,readelf --relocs顯示值爲000100000007的信息字段,其中第4位數字按預期增加。假設這是索引,爲什麼readelf -s(顯示.symtab)將UND顯示爲所有函數的索引?在.symtab下,函數位於約45個條目中,而在.dynsym中它們是預期的位置,但仍具有UND索引。 – 2014-10-02 18:09:28
自發布第一條評論以來,我瞭解到'.rela.plt'具有'.dynsym'的sh_link值,我需要使用ELF64_R_SYM()宏來獲取/提取索引編號。這樣做後,兩部分之間的關系是清楚的,但我仍然沒有看到這些數字如何對應'.dynstr'。 '.dynsym'中的索引號列爲UND,排序與字符串表中的條目不匹配。 – 2014-10-02 21:17:18
@OwenM符號是UND,因爲它們在給定的二進制文件中不是_defined_ - 它們是在其他庫(本例中爲libc)中定義的。至於與.dynsym匹配的字符串,字符串表索引是從.dynstr開始的字節偏移量,而不是字符串數量的索引,因此應該匹配。 – 2014-10-02 21:46:56