拓冰建站拓冰建站
首页 / 资讯中心 / 正文

x64dbg 断点控制命令全解析:软件/硬件/内存/DLL/异常五类断点的用法与源码实现

x64dbg 断点控制命令全解析软件/硬件/内存/DLL/异常五类断点的用法与源码实现【免费下载链接】x64dbgAn open-source user mode debugger for Windows. Optimized for reverse engineering and malware analysis.项目地址: https://gitcode.com/gh_mirrors/x6/x64dbgx64dbg 的命令行断点控制系统覆盖软件断点INT3/UD2、硬件断点调试寄存器、内存断点Guard Page、DLL 加载断点与异常断点五大门类并提供bpgoto、bplist、SetBPXOptions等辅助命令。本文以 breakpoint-control 文档目录 为骨架逐条讲解 25 个命令的参数、默认值、别名与典型用法并结合 cmd-breakpoint-control.cpp 与 breakpoint.h 的源码说明其底层原理帮助你完全掌握 x64dbg 的脚本化断点操作能力。断点控制命令总览与命令注册机制x64dbg 的断点控制命令统一在调试引擎启动时注册注册入口位于 x64dbg.cpp每个命令通过dbgcmdnew(命令名,别名1,别名2, 回调函数, 是否可在运行时执行)注册例如dbgcmdnew(SetBPX,bp,bpx, cbDebugSetBPX, true); //软件断点 dbgcmdnew(SetHardwareBreakpoint,bph,bphws, cbDebugSetHardwareBreakpoint, true); dbgcmdnew(SetMemoryBPX,membp,bpm, cbDebugSetMemoryBpx, true); dbgcmdnew(LibrarianSetBreakpoint,bpdll, cbDebugBpDll, true); dbgcmdnew(SetExceptionBPX, cbDebugSetExceptionBPX, true); dbgcmdnew(bplist, cbDebugBplist, true); dbgcmdnew(SetBPXOptions,bptype, cbDebugSetBPXOptions, false);全部命令按断点类型可分为五组加上三个辅助命令类别命令含别名底层机制软件断点SetBPX/bp/bpx、DeleteBPX/bpc/bc、EnableBPX/bpe/be、DisableBPX/bpd/bd改写指令字节为 INT3/UD2硬件断点SetHardwareBreakpoint/bph/bphws、DeleteHardwareBreakpoint/bphc/bphwc、EnableHardwareBreakpoint/bphe/bphwe、DisableHardwareBreakpoint/bphd/bphwdx86 调试寄存器 DR0-DR3内存断点SetMemoryBPX/membp/bpm、SetMemoryRangeBPX/memrangebp/bpmrange、DeleteMemoryBPX/membpc/bpmc、EnableMemoryBreakpoint/membpe/bpme、DisableMemoryBreakpoint/membpd/bpmdGuard Page 内存保护页DLL 断点LibrarianSetBreakpoint/bpdll、LibrarianRemoveBreakpoint/bcdll、LibrarianEnableBreakpoint/bpedll、LibrarianDisableBreakpoint/bpddllLdrLoadDll 回调拦截异常断点SetExceptionBPX、DeleteExceptionBPX、EnableExceptionBPX、DisableExceptionBPX调试事件筛选辅助命令bpgoto、bplist、SetBPXOptions/bptype断点跳转、列表与默认类型在引擎内部所有断点统一由 breakpoint.h 中的BREAKPOINT结构体描述其type字段对应BP_TYPE枚举enum BP_TYPE { BPNORMAL 0, //软件断点 BPHARDWARE 1, //硬件断点 BPMEMORY 2, //内存断点 BPDLL 3, //DLL 断点 BPEXCEPTION 4 //异常断点 };结构体中的enabled启用状态、singleshoot命中一次即删除、oldbytes软件断点被改写前的原始字节、titantype传给 TitanEngine 的底层类型标志等字段正是下文各命令所操作的核心状态。而 breakpoint.cpp 提供的BpNew、BpGet、BpDelete、BpEnable、BpEnumAll等 API 则是所有断点命令共用的数据层接口。软件断点SetBPX 与 bpc/bpe/bpdSetBPXbp / bpx设置软件断点SetBPX用于在指定地址写入 INT3short/long或 UD2 指令并可选地为断点命名是最常用的下断命令。它的参数设计非常灵活arg1断点地址可以是表达式或API 名称如kernel32.CreateFileW这是对系统 API 下断的关键能力[arg2]断点名称含空格时需用引号包裹。该名称可被EnableBPX、DisableBPX、DeleteBPX当作别名使用但主要用途是为命中断点提供一行可读信息。当 arg2 恰好等于一个合法的断点类型arg3 的取值时它会被当作类型解析arg2 被忽略[arg3]断点类型可随机序组合以下关键字sssingle shot命中一次后自动删除long长 INT3机器码CD03ud2UD2 指令机器码0F0Bshort短 INT3机器码CC默认。类型参数支持ss与其它类型组合成一个字符串。例如文档给出的经典示例SetBPX 00401000,entrypoint,ssud2即在00401000处设置一个名为 entrypoint、命中一次即删除的 UD2 单次断点。当不指定类型、或只指定ss时使用默认类型默认类型为shortCC可通过SetBPXOptions命令修改。从源码看cbDebugSetBPX 的实现流程为先用valfromstring解析地址 → 判断 arg2 是否为合法类型scmp(argname, ss/long/ud2)→ 用strstr从类型字符串中提取ss置UE_SINGLESHOOT与long/ud2/short分别映射为UE_BREAKPOINT_TYPE_LONG_INT3/UE_BREAKPOINT_TYPE_UD2/UE_BREAKPOINT_TYPE_INT3→ 读取并保存原字节 → 调用BpNew登记断点 → 调用 TitanEngine 的SetBPX真正改写内存。若地址上已有同名/同址断点命令会提示 Breakpoint already set!若断点存在但处于禁用态则会自动转为bpe启用。DeleteBPXbpc / bc删除软件断点DeleteBPX [arg1]删除用SetBPX设置的断点arg1可以是断点名称或地址不指定 arg1 时删除全部软件断点。其实现cbDebugDeleteBPX先尝试按名称查找BpGet(0, BPNORMAL, name, found)失败再按地址解析删除前会检查断点是否启用若启用则调用DeleteBPX还原被改写的内存字节。EnableBPXbpe / be与 DisableBPXbpd / bdEnableBPX [arg1]与DisableBPX [arg1]用于启用/禁用软件断点参数语义与删除命令一致传名称或地址操作单个断点不传参数则操作全部All breakpoints enabled/disabled。启用时通过SetBPX重新写回断点字节禁用时通过DeleteBPX移除断点字节但保留断点记录。需要注意的是禁用/启用的语义与删除不同——被禁用的断点仍保留名称、条件等元信息可在断点窗口看到灰色状态。硬件断点bph 系列与调试寄存器SetHardwareBreakpointbph / bphws硬件断点使用 CPU 的调试寄存器DR0-DR3不修改内存中的任何字节因此对自校验代码、压缩壳等场景特别有效。参数如下arg1断点地址[arg2]断点类型rread/write读写均触发、wwrite仅写入触发、xexecute仅执行触发默认x[arg3]监视大小1、2、4或88 仅 x64 可用默认1。地址必须按该大小对齐否则报错 Address not aligned。例如监视 4 字节数据的写入bph 00401000,w,4源码 cbDebugSetHardwareBreakpoint 展示了几个关键约束类型通过switch(*argv[2])解析为UE_HARDWARE_READWRITE/UE_HARDWARE_WRITE/UE_HARDWARE_EXECUTE大小在_WIN64下才允许8UE_HARDWARE_SIZE_8设断前调用GetUnusedHardwareBreakPointRegister寻找空闲调试寄存器若已用满 4 个会提示You can only set 4 hardware breakpoints——这是 x86 架构 DR0-DR3 的物理上限通过TITANSETDRX/TITANSETTYPE/TITANSETSIZE组装titantype再交给 TitanEngine 的SetHardwareBreakPoint写入调试寄存器。DeleteHardwareBreakpointbphc / bphwc、EnableHardwareBreakpointbphe / bphwe、DisableHardwareBreakpointbphd / bphwd这三个命令与软件断点对应命令用法一致arg1为名称或地址不传则操作全部。一个值得注意的差异是EnableHardwareBreakpoint不带参数时的语义——文档明确为 as many as possible hardware breakpoints will be enabled即尽可能多地启用受空闲调试寄存器数量限制而删除/禁用不带参数时是全部操作。内存断点bpm 系列与 Guard PageSetMemoryBPXmembp / bpmSetMemoryBPX通过设置 Guard Page 保护属性对指定地址所在的内存区域整体从区域基址开始进行监视arg1区域内的任意地址命令会自动定位到该内存区域的基址[arg2]1/0表示命中后是否恢复继续保留该断点。当该值既不是1也不是0时它会被当作 arg3 处理即bpm eax,r等价于bpm eax,0,r[arg3]监视类型a读写执行、r读、w写、x执行默认a。源码 cbDebugSetMemoryBpx 的实现要点是调用MemFindBaseAddr(addr, size, true)自动求出区域基址与大小然后通过BpNew(base, ..., BPMEMORY, type, 0, size)登记断点最后调用SetMemoryBPXEx真正设置 Guard Page。从代码看未指定 arg2 时restore默认为 0即命中后不自动恢复single-shot 语义指定1则断点会一直保留直到手动删除。监视类型解析为UE_MEMORYa/UE_MEMORY_READr/UE_MEMORY_WRITEw/UE_MEMORY_EXECUTEx。SetMemoryRangeBPXmemrangebp / bpmrange与bpm的整块区域不同bpmrange允许精确指定范围start范围起始地址size范围大小[type]监视类型a/r/w/x默认a在类型后追加ss表示 single-shot只命中一次等价于使用 SetMemoryBreakpointSingleshoot 命令设置单次语义。例如memrangebp 00401000,100,rss表示对00401000起始的 0x100 字节做只读监视命中一次即失效。实现 cbDebugSetMemoryRangeBpx 通过strstr(argv[3], ss)识别单次标志并直接以start/size调用BpNew与SetMemoryBPXEx无需再计算区域基址。DeleteMemoryBPXmembpc / bpmc、EnableMemoryBreakpointmembpe / bpme、DisableMemoryBreakpointmembpd / bpmd与前述类别一致arg1为名称或基地址不带参数则全部删除/启用/禁用。实现上启用通过SetMemoryBPXEx重新设置 Guard Page见 cbEnableAllMemoryBreakpoints禁用通过RemoveMemoryBPX移除保护属性。DLL 断点bpdll 系列DLL 断点用于在指定模块加载/卸载时自动中断对跟踪插件加载顺序、监控模块注入非常实用。LibrarianSetBreakpointbpdllarg1要监视的 DLL 名称不区分大小写[arg2]触发时机a表示加载与卸载都中断l仅加载u仅卸载默认a[arg3]只要出现该参数即为 single-shot命中一次后断点自动移除不指定则持续生效。例如bpdll user32.dll bpdll myplugin.dll,l,ss第一个命令在user32.dll加载/卸载时都中断第二个命令在myplugin.dll加载时中断一次即失效。从实现 cbDebugBpDll 看命令会先剥离路径strrchr(argv[1], \\)并转小写再映射a/l/u为UE_ON_LIB_ALL/UE_ON_LIB_LOAD/UE_ON_LIB_UNLOAD依次调用BpNewDll登记和dbgsetdllbreakpoint挂接底层回调。LibrarianRemoveBreakpointbcdll、LibrarianEnableBreakpointbpedll、LibrarianDisableBreakpointbpddll三个命令均以 DLL 名称为参数不带参数则作用于全部 DLL 断点bpedll/bpddll的文档原文如此虽然描述文字沿用了 SetBreakpoint 的说法但语义为启用/禁用 DLL 断点。注意 DLL 断点的查找方式与其它类型不同——它按module匹配而非地址见BpGetAny(BPDLL, argv[1], bp)。异常断点SetExceptionBPX 系列SetExceptionBPX异常断点把指定异常变成断点事件只要该异常断点处于激活状态所有相同 chance首次/二次机会与代码的异常都会被捕获为断点事件不再走默认的异常处理策略。arg1异常名称或代码如ACCESS_VIOLATION、80000003INT3 断点异常代码等[arg2]捕获时机chancefirst或1仅首次机会异常默认second或2仅二次机会异常all或3所有异常。从实现 cbDebugSetExceptionBPX 看地址解析支持valfromstring数值与ExceptionNameToCode名称两条路径chance 被映射为ex_firstchance/ex_secondchance/ex_all并存入BpNew(ExceptionCode, true, false, 0, BPEXCEPTION, extype, )。注意异常断点的地址字段实际存放的是异常代码这是它与其它断点类型最本质的区别。DeleteExceptionBPX / EnableExceptionBPX / DisableExceptionBPX三者参数语义一致arg1为名称、异常名或代码不带参数则删除/启用/禁用全部异常断点。删除与查找时同样支持名称与ExceptionNameToCode两种匹配方式cbDebugDeleteExceptionBPX。辅助命令bpgoto、bplist、SetBPXOptionsbpgoto命中断点后跳转bpgoto arg1,arg2把断点配置成到达 arg1 时将程序流导向 arg2。文档明确给出了它的等价展开——以下四条命令SetBreakpointCondition arg1, 0 SetBreakpointCommand arg1, CIParg2 SetBreakpointCommandCondition arg1, 1 SetBreakpointFastResume arg1, 0即条件恒为假不真正停止、命中后执行CIParg2改写指令指针、命令条件恒真、不快速恢复保证命令被执行。源码 cbDebugSetBPGoto 正是通过cmddirectexec依次执行这四条命令实现的。这本质上是一种断点即补丁技巧常用于跳过反调试代码或某段耗时逻辑。bplist列出全部断点bplist无参数输出所有断点的状态、类型、地址与可选名称。每行格式为STATE:TYPE:ADDRESS[:NAME]STATE0表示禁用1表示启用。注意文档说明只有 single-shot 与普通断点可以被禁用言下之意部分类型状态固定TYPEBP普通软件断点SetBPX设置、SSsingle-shot 断点、HW硬件断点、GPGuard Page即内存断点ADDRESS断点地址x32/x64 调试器分别以 32/64 位宽度输出NAME断点名称若有。从 cbBreakpointList 的实现看实际输出还额外支持DLL与EX两种类型对应 DLL 断点与异常断点且 DLL 断点的行格式为STATE:TYPE:模块名:名称异常断点的地址列输出的是异常代码。因此bplist也是脚本里枚举断点、做自动化断点管理的基础工具。SetBPXOptionsbptype设置默认断点类型SetBPXOptions arg1修改SetBPX的默认类型可选值shortCC短 INT3默认longCD03长 INT3ud20F0BUD2。文档强调该默认类型同时影响普通断点与 single-shot 断点。实现 cbDebugSetBPXOptions 会把选择持久化到配置文件BridgeSettingSetUint(Engine, BreakpointType, setting_type)0short、1long、2ud2下次启动依然生效。UD2 断点对反调试检测如检测 CC 断点字节的完整性校验有天然对抗优势是逆向常用技巧。实战组合使用与脚本化建议将上述命令串联即可完成复杂的调试自动化例如bpx kernel32.CreateFileW,CreateFile //对 API 下带名断点 bph 00401234,w,4 //监视 4 字节写操作 bpm eax,r //对 eax 所在内存区域做读监视 bpdll plugin.dll,l,ss //插件加载时中断一次 SetExceptionBPX ACCESS_VIOLATION,first //捕获首违例异常 bplist //查看全部断点状态 bpgoto 00401337,00401400 //命中 00401337 时跳转 bptype ud2 //把默认软件断点类型改为 UD2所有这些命令均可在命令栏、脚本文件配合 script 命令以及条件断点的命令回调中使用断点命中后的条件、日志、命令执行等进阶能力则属于 conditional-breakpoint-control 章节的范畴例如上文提到的 SetMemoryBreakpointSingleshoot。掌握本节的 25 个命令与 BREAKPOINT 结构 的字段语义即可对 x64dbg 的断点体系形成完整认知写出精确、可复用的调试脚本。小结x64dbg 的断点控制命令在设计上高度一致——每个断点类别都配套设置/删除/启用/禁用四个命令且都支持不传参数即操作全部的批量语义这降低了记忆成本而每种断点的底层机制字节改写、调试寄存器、Guard Page、加载回调、异常筛选又各有特性与限制例如硬件断点上限 4 个、内存断点作用于整个区域、异常断点按代码而非地址登记等。结合 cmd-breakpoint-control.cpp 的源码逐条对照可以更准确地预判每条命令在边界情况下的行为让断点成为逆向与恶意软件分析中最可靠的控制手段。【免费下载链接】x64dbgAn open-source user mode debugger for Windows. Optimized for reverse engineering and malware analysis.项目地址: https://gitcode.com/gh_mirrors/x6/x64dbg创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门