如何获取全局偏移表(GOT)中目标函数的绝对虚拟地址
运行时计算方案(无需读取ELF文件)
x86_64架构下PLT条目结构是固定的,每个用户函数的PLT条目首指令为间接跳转到对应GOT条目,指令格式为jmp QWORD PTR [GOT地址偏移],你可以直接从已知的PLT地址计算得到对应的GOT地址:
- 从PLT地址偏移2字节的位置读取4字节的立即数偏移值
- 用公式直接计算GOT地址:
GOT_entry_addr = PLT_addr + 6 + 读取到的4字节偏移值
拿到GOT条目的虚拟地址后,直接读取该地址处的内容就是你要的函数绝对虚拟地址:
- 若该函数还未被首次调用,读取到的值为对应PLT条目的第二条指令地址,用于触发动态链接解析
- 若该函数已经完成过调用,读取到的值就是函数在内存中的绝对虚拟地址
静态解析ELF方案(需要读取ELF标准公开段)
如果无法直接操作运行时内存,可以解析对应的ELF文件(主程序或动态库均可)获取GOT地址,不需要读取ELF的私有表段,仅依赖标准公开段即可:
- 读取ELF的
.dynsym动态符号表,定位到_ZN4test13overwriteFuncEiml符号对应的条目,记录该符号的索引值 - 读取ELF的
.rela.plt重定位表,找到和上述符号索引绑定的重定位条目,该条目r_offset字段的值就是对应GOT条目的虚拟地址 - 如果是运行中的进程,直接读取该虚拟地址的值即可得到函数绝对地址;如果是静态解析,需要将
r_offset加上对应ELF文件的运行时加载基地址,才能得到内存中实际的GOT条目地址
内容的提问来源于stack exchange,提问作者Qiyang Li
相关产品推荐
相关产品推荐

