Linux objdump输出解析:.plt与.plt.sec段差异及GOT地址定位问题
Linux PLT/GOT结构差异及GOT地址获取方案
1. 为何两台机器的PLT段结构不同,机器1不存在.plt.sec段?
这是因为两台机器使用的GCC/链接器(ld)版本差异导致的。较旧版本的链接器采用单一PLT段设计,所有外部函数的PLT调用条目都集中在.plt段中;而从GCC 8及后续版本开始,链接器引入了拆分式PLT结构:将需要延迟绑定(首次调用才触发地址解析)的外部函数PLT条目放到.plt.sec段,原.plt段仅保留动态链接器自身依赖的少量条目。机器1使用的是旧版链接器,因此没有.plt.sec段。
2. 在机器2中如何获取可用于覆写的GOT地址?
有几种直接可行的方法:
- 静态分析工具:
- 执行
objdump -R <可执行文件名>,查看重定位表中sayHello对应的JUMP_SLOT类型条目,其标注的地址即为GOT表项地址。 - 执行
readelf -r <可执行文件名>,同样定位到sayHello的JUMP_SLOT重定位项,其中的偏移地址就是目标GOT地址。
- 执行
- 反汇编计算:
反汇编.plt.sec段的sayHello条目,x86_64架构下的PLT条目通常是jmpq *0xXXXX(%rip)格式,其中0xXXXX是相对于当前指令的偏移。计算时,取该指令的地址加8(RIP指向当前指令的下一条指令),再加上偏移值,即可得到对应的GOT地址。 - 运行时解析:
通过ptrace读取进程内存,解析ELF文件的.dynamic段,找到DT_PLTGOT项获取GOT表基地址,再结合重定位表中sayHello的偏移量,计算出目标GOT地址。
3. 为何机器1无.plt.got段而机器2存在该段?
.plt.got是链接器的优化特性,用于存放无需延迟绑定的函数PLT条目(比如动态链接器自身的函数,或通过-z now编译选项强制立即绑定的函数),这类函数的地址在程序启动时就已解析完成,不需要延迟绑定的流程。旧版链接器不支持该优化,仅使用单一.plt段处理所有PLT条目;机器2使用的新版链接器引入了该优化,因此存在.plt.got段。
内容的提问来源于stack exchange,提问作者SimpleCoder
相关产品推荐
相关产品推荐

