如何在GDB中查看si、s等指令执行前后的内存变化?
在GDB中查看单步执行前后的内存变化
一、手动dump+diff的具体实现
如果你想用dump内存后对比的方法,步骤很直接:
- 单步执行前,导出目标内存区域:
dump memory before.bin 0x起始地址 0x结束地址 - 执行单步指令:
si(单步汇编)或s(单步源码) - 单步完成后,导出同一内存区域:
dump memory after.bin 0x起始地址 0x结束地址 - 退出GDB(或在另一个终端)用工具对比:
# 二进制对比,仅显示差异位置 diff before.bin after.bin # 转成十六进制文本后对比,更易读 hexdump -C before.bin > before.txt hexdump -C after.bin > after.txt diff before.txt after.txt
二、更高效的替代方案
1. 内存监视点(Watchpoint)
这是GDB内置的最实用方法,能自动捕获内存修改:
- 监视单个地址的内存变化:
watch *0x12345678 # 监视0x12345678地址的内容 - 监视一段连续内存(比如10个字节):
watch *(char[10])0x12345678 - 设置好后执行
si,如果这段内存被修改,GDB会立即暂停,并输出修改前后的数值,无需手动导出对比。
注意:大范围内存监视会轻微影响调试性能,建议只监视你关心的小区域。
2. 自动化GDB脚本
写个简单脚本把dump+diff的流程自动化,不用重复输入命令:
创建step_mem_diff.gdb文件,内容如下:
# 用法:step-and-check 起始地址 结束地址 define step-and-check if $argc != 2 echo 用法: step-and-check <起始地址> <结束地址>\n return end dump memory /binary before_mem.bin $arg0 $arg1 si dump memory /binary after_mem.bin $arg0 $arg1 shell echo "内存对比结果:" && diff before_mem.bin after_mem.bin || echo "无内存变化" end
在GDB中加载脚本:
source step_mem_diff.gdb
之后直接用命令完成单步+对比:
step-and-check 0x12345678 0x12345688
3. 第三方调试插件
像PEDA、GEF这类常用GDB插件都内置了内存对比功能,比如PEDA的memdiff命令,可以直接对比两个内存区域,或者结合单步指令快速查看变化,省去自己写脚本的麻烦。
内容的提问来源于stack exchange,提问作者XMRHRX
相关产品推荐
相关产品推荐

