我很好奇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