x64dbg 内存断点命令 SetMemoryBPX/membp/bpm 完整实战指南:基于 GUARD_PAGE 的内存访问监视 逆向工程调试器开发工具应用安全【免费下载链接】x64dbgAn open-source user mode debugger for Windows. Optimized for reverse engineering and malware analysis.项目地址https://gitcode.com/gh_mirrors/x6/x64dbg点击查看免费下载内存断点Memory Breakpoint是逆向工程中监视数据读写与代码执行的关键手段与普通断点INT3和硬件断点DRx 寄存器不同它通过 Windows 的 GUARD_PAGE 页保护机制可以在不改写指令、不消耗硬件断点寄存器的情况下监视一整个内存区域的所有访问行为。本指南以 x64dbg 的SetMemoryBPX/membp/bpm命令为主线完整讲解其语法、参数语义、默认值与底层实现原理并顺带覆盖内存断点的启用、禁用、删除与范围设置等配套命令帮助你直接在调试会话中高效使用这一能力。命令速览三个等价别名SetMemoryBPX命令在 x64dbg 的命令系统中注册了三个完全等价的别名输入任何一个效果相同全名别名 1别名 2SetMemoryBPXmembpbpm命令注册点位于 src/dbg/x64dbg.cppdbgcmdnew(SetMemoryBPX,membp,bpm, cbDebugSetMemoryBpx, true); //SetMemoryBPX该命令的核心行为一句话概括在指定地址所在的内存区域memory region上设置一个 GUARD_PAGE 内存断点监视对该区域的内存访问。区域范围不是由用户手工指定而是由 x64dbg 根据地址自动推导出的整个内存块。参数详解地址、恢复标志与断点类型SetMemoryBPX的完整语法为SetMemoryBPX arg1 [arg2] [arg3]arg1要监视的内存区域内的地址必填arg1可以是该内存区域内任意一个地址包括区域中间地址x64dbg 会自动定位其所属的整个内存区域并对其整体设置断点。地址支持 x64dbg 的完整表达式语法寄存器、符号、算术表达式等例如eax、401000、[rsp8]等。源码中通过valfromstring统一解析duint addr; if(!valfromstring(argv[1], addr)) // 支持表达式求值 return false;随后调用MemFindBaseAddr(addr, size, true)反查该地址所属内存区域的内存基址与大小见 src/dbg/commands/cmd-breakpoint-control.cpp。arg2命中后是否恢复断点可选arg2为1或0表示断点命中后是否恢复restore即继续监视该内存断点1命中后恢复断点断点保持有效可反复触发0命中后不恢复等价于一次性/单发断点 singleshoot断点触发一次后自动失效。参数省略时默认值为0即默认是单发行为。这一默认行为在源码中有明确体现bool restore false; // 默认不恢复 bool singleshoot false; if(!restore) singleshoot true; // 默认即为单发singleshootarg3断点类型可选arg3指定监视的内存访问类型支持四个取值默认值为a取值含义对应 TitanEngine 内部枚举a读 写 执行默认UE_MEMORYr读UE_MEMORY_READw写UE_MEMORY_WRITEx执行UE_MEMORY_EXECUTE源码中的类型映射逻辑位于cbDebugSetMemoryBpx见 src/dbg/commands/cmd-breakpoint-control.cpp无效类型会提示 Invalid type (argument ignored) 并被忽略。参数省略的智能推断规则这是本命令最灵活也最需要注意的一点当arg2的值不是1或0时它会被自动当作arg3断点类型处理。官方文档对此的表述是bpm eax,r与bpm eax,0,r完全等价。源码中的解析逻辑印证了这一规则见 cmd-breakpoint-control.cppif(argc 2) { if(*argv[2] 1) restore true; else if(*argv[2] 0) restore false; else strcpy_s(arg3, argv[2]); // 非 1/0 则视为类型参数 }因此三种参数形态都是合法的bpm eax、bpm eax,r、bpm eax,1,w。实战示例以下示例覆盖最常见的用法场景// 监视 eax 寄存器指向的整个内存区域的读写执行 bpm eax // 只监视该区域的读访问省略 restore等价于 bpm 401000,0,r bpm 401000,r // 监视写访问且命中后恢复可反复触发 bpm 401000,1,w // 监视执行命中一次后自动失效单发 bpm 401000,0,x // 使用符号地址 bpm kernel32.VirtualAlloc,x // 使用表达式 bpm [rsp8],w命令成功执行后日志窗口会输出类似Memory breakpoint at 0000000140001000[00001000] set!的提示%p[%p]分别打印区域基址与大小并自动刷新 GUI 视图。若目标区域已经存在内存断点命令会提示 Memory breakpoint already set!若断点存在但处于禁用状态则会自动将其重新启用详见下文重复设置保护。底层实现原理从命令到 GUARD_PAGE要理解这条命令需要看它背后的完整调用链。第一步命令分发命令SetMemoryBPX/membp/bpm统一由回调函数cbDebugSetMemoryBpx处理注册见 src/dbg/x64dbg.cpp。第二步解析与建点解析完地址、恢复标志与类型后x64dbg 依次完成三件事见 cmd-breakpoint-control.cppMemFindBaseAddr(addr, size, true)—— 反查地址所属内存区域得到base与size从而把断点作用域扩展为整个内存块BpNew(base, true, singleshoot, 0, BPMEMORY, type, 0, size)—— 在 x64dbg 内部断点数据库中登记一个类型为BPMEMORY的断点SetMemoryBPXEx(base, size, type, restore, cbMemoryBreakpoint)—— 调用 TitanEngine 底层 API真正通过VirtualProtect等手段为目标内存页设置PAGE_GUARD保护标志GUARD_PAGE并注册命中回调。第三步命中回调当被监视区域发生对应类型的访问时CPU 会抛出 guard page 异常调试器捕获后通过回调cbMemoryBreakpoint进入断点处理流程见 src/dbg/debugger.cppvoid cbMemoryBreakpoint(const void* ExceptionAddress) { lastExceptionInfo GetDebugData()-u.Exception; cbGenericBreakpoint(BPMEMORY, ExceptionAddress); }cbGenericBreakpoint会统一处理断点条件判断、命中计数、日志输出以及 singleshoot 断点的自动清除等逻辑。这也意味着为内存断点设置的命令、条件、日志等联动行为走的是与普通断点同一套通用处理框架。restore 与 singleshoot 的关系源码中restore与singleshoot是互斥的restore1时断点命中后继续保留监视restore0时断点标记为单发命中后自动失效。这一状态会同时写入内部断点记录和 TitanEngine 的UE_SINGLESHOOT标志位中见 src/dbg/breakpoint.cpp。内存断点的配套管理命令内存断点的完整生命周期管理还需要以下配套命令均可在 docs/commands/breakpoint-control 索引中找到删除DeleteMemoryBPX/membpc/bpmc按断点名称或基地址删除指定内存断点省略参数时删除全部内存断点见 DeleteMemoryBPX 文档。源码实现中删除时若断点未记录 size会先通过MemFindBaseAddr反查区域大小再依次调用BpDelete与RemoveMemoryBPX完成登记数据与页保护的双重清理见 cmd-breakpoint-control.cpp。// 按地址删除 membpc 401000 // 删除全部内存断点 membpc启用EnableMemoryBreakpoint/membpe/bpme启用之前被禁用的内存断点省略参数时启用全部。内部先调用SetMemoryBPXEx重新挂上页保护再通过BpEnable更新状态见 cmd-breakpoint-control.cpp。membpe 401000 // 启用指定断点 membpe // 启用全部内存断点禁用DisableMemoryBreakpoint/membpd/bpmd禁用挂起内存断点页保护被移除但断点记录保留省略参数时禁用全部。内部调用RemoveMemoryBPX移除保护、BpEnable(false)标记禁用见 cmd-breakpoint-control.cpp。bpmd 401000查看bplist所有内存断点可通过 bplist 命令统一列出方便核对地址、类型与启用状态。按范围设置SetMemoryRangeBPX/memrangebp/bpmrangeSetMemoryBPX自动推导整个内存区域若希望精确控制监视范围可使用其姊妹命令SetMemoryRangeBPX详见 SetMemoryRangeBPX 文档语法为SetMemoryRangeBPX start size [type]参数说明start内存范围起始地址size内存范围大小type同SetMemoryBPX的arg3a/r/w/x默认a追加ss后缀表示单发断点该命令额外支持ss后缀实现单发语义例如bpmrange 401000 1000 wss表示监视0x401000起0x1000字节的写访问命中一次后自动失效。若省略ss也可事后通过 SetMemoryBreakpointSingleshoot 命令将断点切换为单发。两条命令的差异对照如下维度SetMemoryBPXSetMemoryRangeBPX范围来源自动取地址所在整个内存区域手工指定 start size单发开关通过arg20默认通过 type 追加ss后缀命中后恢复通过arg21不追加ss即可源码实现上两条命令共用同一套建点与页保护流程cbDebugSetMemoryRangeBpx解析 start/size/type 后同样调用BpNew与SetMemoryBPXEx见 cmd-breakpoint-control.cpp。注意事项与常见问题断点作用域是整个内存区域SetMemoryBPX不区分页内偏移传入区域中任意地址都会监视整个内存块。若只想监视一小段字节请改用SetMemoryRangeBPX。默认是单发行为省略arg2时断点命中一次即失效singleshoottrue。需要反复触发的场景务必显式传1例如bpm 401000,1,w。参数位置易混淆bpm addr,1,w与bpm addr,w都合法但bpm addr,w,1中多余的1会被忽略类型参数只取首字符。牢记非 1/0 的第二个参数会被当作类型这一规则即可。不设置结果变量与SetBPX等命令类似SetMemoryBPX、SetMemoryRangeBPX、DeleteMemoryBPX、EnableMemoryBreakpoint、DisableMemoryBreakpoint均不写任何脚本结果变量脚本中请通过bplist或断点查询 API 验证结果。与硬件断点的取舍硬件断点仅 4 个且依赖寄存器普通断点会改写指令字节内存断点以页保护实现不消耗硬件资源适合监视大块数据区但需要注意其异常处理路径带来的开销在性能敏感的大循环场景应谨慎使用。联动条件与日志内存断点同样支持条件、日志、命令等扩展配置相关命令参见 docs/commands/conditional-breakpoint-control 目录下的SetMemoryBreakpointCondition、SetMemoryBreakpointLog、SetMemoryBreakpointCommand等文档。仓库中 src/tests/membp 目录保存了内存断点相关的测试工程与用例可作为理解该功能预期行为的补充参考资料。赞分享逆向工程调试器开发工具应用安全【免费下载链接】x64dbgAn open-source user mode debugger for Windows. Optimized for reverse engineering and malware analysis.项目地址https://gitcode.com/gh_mirrors/x6/x64dbg点击查看免费下载相关推荐x64dbg 内存范围断点 SetMemoryRangeBPXbpmrange完全指南GUARD_PAGE 精确范围监控与实战x64dbg 内存范围断点 SetMemoryRangeBPXbpmrange完全指南GUARD_PAGE 精确范围监控与实战 导读 SetMemoryR逆向工程调试器开发工具应用安全x64dbg 内存断点命令条件SetMemoryBreakpointCommandCondition完全指南x64dbg 内存断点命令条件SetMemoryBreakpointCommandCondition完全指南 本文基于 x64dbg 官方命令参考文档深入逆向工程调试器开发工具应用安全x64dbg 内存断点命中计数查询命令 GetMemoryBreakpointHitCount 完整指南x64dbg 内存断点命中计数查询命令 GetMemoryBreakpointHitCount 完整指南 导读 GetMemoryBreakpointHitCo逆向工程调试器开发工具应用安全创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考