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

如何在GDB中根据二进制文件偏移地址设置观察点?

解决无调试信息二进制中基于文件偏移设置GDB观察点的问题

我完全懂你的痛点——逆向没有调试信息的二进制时,把静态文件偏移映射到运行时内存地址,确实是设置观察点的关键障碍,尤其是你试过直接用文件偏移设置却没效果的时候。下面一步步教你怎么搞定:

核心思路

GDB的观察点只能作用于运行时内存地址,而文件偏移是相对于二进制文件本身的位置,两者之间需要通过二进制的段信息来转换。你需要先找到目标偏移所在的段,再计算它对应的内存地址。

步骤1:分析二进制的段信息

首先用工具查看二进制的段布局,推荐用objdump或者readelf:

objdump -h your_binary

或者:

readelf -S your_binary

输出里会列出所有段,找到你的目标偏移0x85c6d所属的段(比如.text、.data或者.rodata)。重点关注两个字段:

  • Offset:该段在二进制文件中的起始偏移
  • VMA:该段加载到内存后的虚拟起始地址

举个例子:假设.text段的Offset是0x1000,VMA是0x400000,而你的目标偏移0x85c6d在这个段里,那么内存地址的计算公式是:

内存地址 = 段VMA + (目标文件偏移 - 段Offset)

代入数值就是:0x400000 + (0x85c6d - 0x1000) = 0x4075c6d

步骤2:处理ASLR(地址空间随机化)

如果系统开启了ASLR(大多数默认开启),二进制的实际加载地址会和VMA不一样。这时候你需要在GDB里启动程序后,获取实际的段起始地址:

  1. 在GDB里启动程序:run(或者start让程序停在入口点)
  2. 查看进程的内存映射:info proc mappings
  3. 在输出里找到目标段(比如.text)的起始地址(第一列的起始值)

接着用同样的公式计算:实际内存地址 = 实际段起始地址 + (目标文件偏移 - 段Offset)

步骤3:设置观察点

拿到正确的内存地址后,用GDB的watch命令监控这个地址的读写:

watch *0x<计算出的内存地址>

比如如果计算出的地址是0x5555555d9c6d,就输入:

watch *0x5555555d9c6d

如果只想监控写操作,可以用watch -w,读操作用watch -r。

为什么之前的方法无效?

  • watch 0x85c6d:GDB会把这个当作一个值,监控的是“某个寄存器或变量等于0x85c6d”的情况,完全不是你要的内存监控,所以无效。
  • watch *0x85c6d:这个命令监控的是内存地址0x85c6d,但二进制加载后的内存地址通常远高于这个值(比如64位程序一般从0x555555554000开始),所以你监控的是一个无关的内存区域,自然看不到预期的变化。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:22:37