You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

自制调试器中如何解析ELF相对地址?

DWARF解析地址转进程实际内存地址的正确方法

问题根源

你错误地将DWARF解析出的地址当作.text节的文件偏移,与加载基址相加导致地址无效——DWARF给出的是ELF文件的虚拟地址(VA),并非磁盘文件里的节偏移。

关键概念区分

  • 虚拟地址(VA):链接器为程序段分配的地址,PIE(位置无关可执行文件)下是相对加载基址的偏移(RVA),非PIE下就是进程运行时的实际地址。
  • 文件偏移:节在可执行文件磁盘镜像中的位置偏移,和内存地址没有直接加法对应关系。

正确解析步骤

  1. 确认可执行文件类型
    执行readelf -h <你的可执行文件>,查看Type字段:

    • EXEC:非PIE文件,DWARF中的VA就是进程运行时的实际地址,直接使用即可。
    • DYN:PIE文件,需要结合加载基址计算实际地址。
  2. 获取.text节的虚拟起始地址
    执行readelf -S <你的可执行文件>,找到.text节的Addr字段(比如示例中可能是0x1000)。

  3. 获取进程加载基址
    查看/proc/<pid>/maps,找到对应可执行文件的r-xp权限段的起始地址(比如0x62313f55e000),注意要选路径匹配你调试的可执行文件的条目,别选共享库的。

  4. 计算实际内存地址
    公式:实际地址 = 加载基址 + (DWARF解析出的VA - .text节虚拟起始地址)
    示例:若DWARF地址是0x1140,.text虚拟起始是0x1000,加载基址是0x62313f55e000,则实际地址为0x62313f55e000 + (0x1140 - 0x1000) = 0x62313f55e140

  5. 验证地址有效性
    用ptrace(PEEKDATA, pid, 实际地址, 0)读取,应该能得到正确的指令字节(比如0x55,对应push rbp)。

额外提示

  • PIE文件每次启动的加载基址会被ASLR随机化,必须在进程启动后动态从/proc/<pid>/maps获取,不能硬编码。
  • 检查/proc/<pid>/maps的条目时,确保路径是你的可执行文件路径,避免误取共享库的基址。

内容的提问来源于stack exchange,提问作者franzageek

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 04:14:53