过程链接表和调用相对

时间:2014-10-02 14:42:26

标签: linker offset elf relocation

我很好奇readelfobjdumpgdb这样的程序如何知道callq指令旁边显示的内容。由于该计划还没有运行,他们如何知道.plt“落后”的距离?他们根据传递给它的论据猜测吗?或者他们是否真的对程序进行模拟运行以找出答案?

例如:

  400ca4:       e8 e7 fb ff ff          callq  400890 <printf@plt>
  400ca9:       48 8b 85 28 ff ff ff    mov    -0xd8(%rbp),%rax

以上代码知道要转到printf()的{​​{1}},地址为0x400890:

.plt

这只是0000000000400890 <printf@plt>: 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部分,虽然它是一个值,因为它从0开始:

.dynsym

让我感到困惑的另一件事是在8: 0000000000000000 0 FUNC GLOBAL DEFAULT UND printf@GLIBC_2.2.5 (2) 条目中引用GOT(#602050)。我从.plt看到它是基于地址范围的readelf的一部分,但这些程序在程序运行之前如何确定值?

.got.plt

**编辑**

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

1 个答案:

答案 0 :(得分:0)

其中一小部分内存不足,但让我们看看能不能帮助你...

关于你的第一个问题,有一系列链接在一​​起的东西。我无法保证这些工具是如何做的,只是为了表明有办法。

  1. PLT与.rel(a).plt部分具有一对一的对应关系(除了PLT [0],这是特殊的)。此部分包含PLT条目的重定位。
  2. 每个.rel(a).plt条目具有信息字段,该信息字段具有符号表索引,例如,进入.dynsym。
  3. 每个符号表条目在字符串表中都有一个偏移量(例如.dynstr)作为其名称。此偏移量是从字符串部分的开头开始的字节偏移量。
  4. 正如您所看到的,您可以按照PLT到rel(a).plt,到符号表,到字符串表,在那里找到&#34; printf。&#34;

    要回答第二个问题,请查看程序标题(readelf -Wl <program>),然后您将看到不同部分的虚拟地址。那个地址范围来自哪里。