objdump 显示错误的函数开始和结束地址
objdump showing wrong start and end address for functions
出于测试目的,我修改了由 llvm 链接器生成的 PLT 存根,lld。
之前的存根是:
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 [=11=]x2
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 [=13=]xd5a,%eax
2012de: 68 02 00 00 00 pushq [=13=]x2
2012e3: e9 b8 ff ff ff jmpq 2012a0 <_fini+0x10>
2012e8: 0f 1f 40 00 nopl 0x0(%rax)
PLT 存根的地址被 objdump
解释为 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
从哪里得到它的信息?很可能是我忘记修改链接器中的某些内容。
For testing purposes, I modified the PLT stub that is generated by the llvm linker, lld.
plt
条目的大小和布局由 ABI(见第 79 页)一成不变,无法更改。
Linking and running programs with this modification seems to work just fine.
我怀疑任何非平凡的程序都可以 运行 正确地进行您的修改——动态加载器采用 ABI plt
布局,并且在给定虚假 plt
时应该崩溃并烧毁。
出于测试目的,我修改了由 llvm 链接器生成的 PLT 存根,lld。
之前的存根是:
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 [=11=]x2
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 [=13=]xd5a,%eax
2012de: 68 02 00 00 00 pushq [=13=]x2
2012e3: e9 b8 ff ff ff jmpq 2012a0 <_fini+0x10>
2012e8: 0f 1f 40 00 nopl 0x0(%rax)
PLT 存根的地址被 objdump
解释为 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
从哪里得到它的信息?很可能是我忘记修改链接器中的某些内容。
For testing purposes, I modified the PLT stub that is generated by the llvm linker, lld.
plt
条目的大小和布局由 ABI(见第 79 页)一成不变,无法更改。
Linking and running programs with this modification seems to work just fine.
我怀疑任何非平凡的程序都可以 运行 正确地进行您的修改——动态加载器采用 ABI plt
布局,并且在给定虚假 plt
时应该崩溃并烧毁。