objdump显示函数的错误开始和结束地址

时间:2017-12-11 01:34:22

标签: elf objdump lld

出于测试目的,我修改了由llvm链接器lld生成的PLT存根。

之前的存根是:

 0xff, 0x25, 0x00, 0x00, 0x00, 0x00, // jmpq *got(%rip)
 0x68, 0x00, 0x00, 0x00, 0x00,       // pushq <relocation index>
 0xe9, 0x00, 0x00, 0x00, 0x00        // jmpq plt[0]

将程序与此(原始)存根链接并使用objdump进行检查会产生如下结果:

00000000002012d0 <printf@plt>:
  2012d0:   ff 25 62 0d 00 00       jmpq   *0xd62(%rip)        # 202038 <__TMC_END__+0x28>
  2012d6:   68 02 00 00 00          pushq  $0x2
  2012db:   e9 c0 ff ff ff          jmpq   2012a0 <_fini+0x10>

我通过简单地在末尾添加NOP来修改PLT存根:

 0xff, 0x25, 0x00, 0x00, 0x00, 0x00, // jmpq *got(%rip)
 0x68, 0x00, 0x00, 0x00, 0x00,       // pushq <relocation index>
 0xe9, 0x00, 0x00, 0x00, 0x00,       // jmpq plt[0]
 0x0f, 0x1f, 0x40, 0x00              // nop

我确保修改PltEntrySize变量,以便它反映大小的变化。使用此修改链接和运行程序似乎工作正常。

但是,当我尝试用objdump检查链接程序的反汇编时,我看到一些奇怪的东西:

00000000002012d0 <printf@plt>:
  2012d0:   cc                      int3   
  2012d1:   ff                      (bad)  
  2012d2:   ff                      (bad)  
  2012d3:   ff 0f                   decl   (%rdi)
  2012d5:   1f                      (bad)  
  2012d6:   40 00 ff                add    %dil,%dil
  2012d9:   25 5a 0d 00 00          and    $0xd5a,%eax
  2012de:   68 02 00 00 00          pushq  $0x2
  2012e3:   e9 b8 ff ff ff          jmpq   2012a0 <_fini+0x10>
  2012e8:   0f 1f 40 00             nopl   0x0(%rax)

objdump将PLT存根的地址解释为0x2012d0,但真正的printf@plt地址位于0x2012d8!这由readelf -s确认:

Symbol table '.dynsym' contains 7 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
    ...
    6: 00000000002012d8     0 FUNC    GLOBAL DEFAULT  UND printf@GLIBC_2.2.5 (2)

objdump从哪里获取信息?很可能是我忘记修改链接器中的内容。

1 个答案:

答案 0 :(得分:0)

  

出于测试目的,我修改了由llvm链接器lld生成的PLT存根。

plt条目的大小和布局由ABI设置(见第79页),并且无法更改。

  

使用此修改链接和运行程序似乎工作正常。

我怀疑任何非平凡程序都会在您的修改中正确运行 - 动态加载程序采用ABI plt布局,并且在给定伪造plt时应该崩溃并刻录。