2014-10-02 127 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