多彩编程 多彩编程MZPH · CODE BLOG
ARTICLE DETAIL

文章详情

深耕前端与后端开发技术的一线实战笔记与踩坑复盘。

x64dbg 异常断点命令条件控制:SetExceptionBreakpointCommandCondition 命令深度解析

x64dbg 异常断点命令条件控制:SetExceptionBreakpointCommandCondition 命令深度解析 x64dbg 异常断点命令条件控制SetExceptionBreakpointCommandCondition 命令深度解析【免费下载链接】x64dbgAn open-source user mode debugger for Windows. Optimized for reverse engineering and malware analysis.项目地址: https://gitcode.com/gh_mirrors/x6/x64dbgSetExceptionBreakpointCommandCondition是 x64dbg 中用于为**异常断点exception breakpoint**设置命令触发条件的命令。它为异常断点的自动执行命令通过SetExceptionBreakpointCommand设置提供了一层精确的门控只有当指定条件表达式求值为真时命令才会被真正执行从而避免在大量同类型异常中出现时被无关命令反复打扰。读完本文你将掌握该命令的参数语义、与断点条件/日志条件的区别、底层实现链路以及如何配合条件表达式实现精准的异常自动化处理。命令概览为异常断点的命令加上开关在 x64dbg 中一个异常断点由多层行为叠加而成每一层都可以独立配置断点条件break condition控制调试器是否在此中断SetExceptionBreakpointCondition命令command on hit中断发生时自动执行的脚本命令SetExceptionBreakpointCommand命令条件command condition控制命令是否执行本文主角日志与日志条件log / log condition控制日志输出及输出条件SetExceptionBreakpointLog、SetExceptionBreakpointLogCondition快速恢复fast resume、单次生效singleshoot、静默silent等开关。根据 SetExceptionBreakpointCommandCondition.md 的定义该命令的语义是设置异常断点的命令条件。当未指定命令条件时命令将在调试器将要中断时执行否则命令只在条件满足时执行。也就是说SetExceptionBreakpointCommandCondition与SetExceptionBreakpointCommand是成对使用的前者描述何时执行命令后者描述执行什么命令。参数详解命令语法如下SetExceptionBreakpointCommandCondition arg1 [, arg2]arg1异常断点的定位方式arg1用于唯一定位目标异常断点支持三种写法断点名称为该异常断点设置的自定义名称通过SetExceptionBreakpointName设置异常名称如ACCESS_VIOLATION、ILLEGAL_INSTRUCTION、INTEGER_DIVIDE_BY_ZERO等异常代码如0xC0000005访问违例、0x80000003断点异常、0x406D1388MS_VC_EXCEPTION即 MSVC 的_CrtDbgReport异常定义见 exception.h。底层对异常名称与代码的互相换算由异常处理模块负责相关函数ExceptionCodeToName、ExceptionNameToCode声明在 src/dbg/exception.h。arg2命令条件表达式[arg2]为可选参数表示命令条件。它是一个 x64dbg 表达式可以是常量1始终执行、0永不执行寄存器/标志位比较eip fffff80012345678、al 0x41变量引用脚本变量、$result等伪寄存器$breakpointcondition引用断点自身的断点条件即命令条件 断点条件的等价写法。当arg2省略时命令条件保持默认即命令在调试器即将中断时无条件执行当arg2提供时只有表达式求值为真非零命令才会执行。注意该命令不设置任何结果变量见原文档 result 部分因此无法通过$result判断命令是否执行成功。典型使用场景场景一条件性输出寄存器信息假设进程频繁抛出0xC0000005但你只关心 EIP 落在特定模块范围内的那次可这样组合SetExceptionBPX 0xC0000005 SetExceptionBreakpointCommand 0xC0000005, log \AV at {eip} in {modname(eip)}\ SetExceptionBreakpointCommandCondition 0xC0000005, modname(eip) \target.dll\此时每次0xC0000005中断时只有 EIP 位于target.dll内日志命令才会执行。场景二按标志位/数据值过滤例如只对某异常发生时EAX 0的情况执行 dump 命令SetExceptionBreakpointCommandCondition 0xC0000005, eax 0场景三与断点条件解耦断点条件决定是否中断命令条件决定中断后是否执行命令两者可以独立组合。例如断点条件为$breakpointcondition保留原中断逻辑而命令条件为1每次中断都执行命令SetExceptionBreakpointCondition 0xC0000005, $breakpointcondition SetExceptionBreakpointCommandCondition 0xC0000005, 1源码级实现从命令注册到内存写入该命令的完整调用链在仓库源码中清晰可循共分四层。1. 命令注册命令在调试器核心的初始化阶段被注册debug参数为true表示需在调试会话中调用见 src/dbg/x64dbg.cppdbgcmdnew(SetExceptionBreakpointCommandCondition, cbDebugSetBPXExceptionCommandCondition, true); //set breakpoint commandCondition2. 命令回调回调函数实现在 src/dbg/commands/cmd-conditional-breakpoint-control.cpp它直接委托给公共处理函数bool cbDebugSetBPXExceptionCommandCondition(int argc, char* argv[]) { return cbDebugSetBPXCommandConditionCommon(BPEXCEPTION, argc, argv); }cbDebugSetBPXCommandConditionCommon同文件 L57-L60进一步委托给文本通用处理函数cbDebugSetBPXTextCommonL9-L30其行为要点如下参数少于 2 个缺arg1时直接返回falsearg2缺省时使用空字符串对应默认条件语义通过BpGetAny(BPEXCEPTION, argv[1], bp)按名称/异常名/代码定位断点找不到时输出No such breakpoint ...并返回false定位成功后调用BpSetCommandCondition写入失败时输出Cant set command condition on breakpoint ...成功后会调用DebugUpdateBreakpointsViewAsync()异步刷新 GUI 断点视图。3. 底层写入BpSetCommandCondition实现在 src/dbg/breakpoint.cppbool BpSetCommandCondition(duint Address, BP_TYPE Type, const char* Condition) { ASSERT_DEBUGGING(Command function call); EXCLUSIVE_ACQUIRE(LockBreakpoints); // Set breakpoint hit command BREAKPOINT* bpInfo BpInfoFromAddr(Type, Address); if(!bpInfo) return false; bpInfo-commandCondition Condition; return true; }它在线程安全的LockBreakpoints锁保护下将条件字符串写入对应断点对象的commandCondition字段。命令文本与命令条件在数据结构中是两个独立字段见 src/dbg/breakpoint.hstd::string commandText; // script command to execute. std::string commandCondition; // condition to execute the command4. GUI 联动GUI 侧在编辑断点时也会生成并执行该命令断点视图的右键菜单/编辑对话框中异常断点的命令条件编辑框对应命令模板见 src/gui/Src/Gui/BreakpointsView.cppbpcmdcnd SetExceptionBreakpointCommandCondition %1, \%2\;在断点数据库保存时GUI 会依次重放各属性的 setter 命令以重建断点状态其中就包括该命令见 src/gui/Src/Utils/Breakpoints.cpp。持久化与数据库迁移注意事项命令条件会随断点数据库一起保存/加载序列化字段为commandCondition见 src/dbg/breakpoint.cpp 与 L983因此重启调试器后依然生效。源码中保留了一段重要的旧数据库迁移逻辑src/dbg/breakpoint.cpp注释与代码说明在 2023-06-10 之前命令条件的默认值是$breakpointcondition此后默认值改为1。若检测到旧版数据库则尽量保留旧行为将命令条件回填为$breakpointcondition。// On 2023-06-10 the default of the command condition was changed from $breakpointcondition to 1 // If we detect an older database, try to preserve the old behavior. if(migrateCommandCondition !breakpoint.commandText.empty() !breakpoint.commandCondition.empty()) { breakpoint.commandCondition $breakpointcondition; }这提醒使用者如果你是从旧版 x64dbg 数据库升级而来且依赖命令条件默认等于断点条件的旧语义迁移逻辑会为你保留旧行为而新创建的断点默认命令条件为1即无条件执行命令。与同族命令的关系SetExceptionBreakpointCommandCondition属于条件断点控制命令族docs/commands/conditional-breakpoint-control/其姊妹命令覆盖其他断点类型与维度命令作用对象用途SetExceptionBreakpointCommand异常断点设置中断时执行的命令见 SetExceptionBreakpointCommand.mdSetExceptionBreakpointCommandCondition异常断点设置命令的执行条件本文SetExceptionBreakpointCondition异常断点设置断点自身的中断条件SetExceptionBreakpointLogCondition异常断点设置日志输出条件SetBreakpointCommandCondition普通断点普通地址断点的命令条件SetBreakpointCommandCondition.mdSetHardwareBreakpointCommandCondition/SetMemoryBreakpointCommandCondition硬件/内存断点对应断点类型的命令条件从源码结构看所有这些命令共用同一个公共实现cbDebugSetBPXCommandConditionCommon仅传入的BP_TYPE不同cmd-conditional-breakpoint-control.cpp体现了 x64dbg 命令层对断点类型的高度统一抽象。最佳实践小结成对配置先用SetExceptionBreakpointCommand设置命令再用SetExceptionBreakpointCommandCondition设置执行条件二者配合才能实现条件化自动命令条件表达式优先引用确定性信号如模块名modname(eip)、寄存器值、数据内容比较避免用易变地址硬编码明确默认语义差异新版默认命令条件为1总是执行旧数据库迁移后为$breakpointcondition与断点条件一致升级前需确认自己的自动化脚本依赖哪种语义调试排错命令失败会在日志输出No such breakpoint或Cant set command condition on breakpoint据此检查arg1是否定位到了正确的异常断点。结合 x64dbg 的断点数据库持久化、GUI 联动与表达式引擎SetExceptionBreakpointCommandCondition是构建无人工值守异常处理流程的关键一环值得在逆向与恶意样本分析工作流中熟练运用。关于条件表达式的完整语法可进一步参阅 条件断点指南 与 表达式文档。【免费下载链接】x64dbgAn open-source user mode debugger for Windows. Optimized for reverse engineering and malware analysis.项目地址: https://gitcode.com/gh_mirrors/x6/x64dbg创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表