Skip to content

标题: 在windbg中获取断点经过次数

创建: 2018-01-25 16:27 更新: 2022-06-08 20:30 链接: https://scz.617.cn/windows/201801251627.txt

bu $iment(KERNELBASE) 0xffffffff

假设初始Passes为n,则在第n次(从1计)经过断点时才中断。缺省n等于1。仅当g经过 断点时,计数器递减1,t/p单步经过断点不会递减计数器。计数器递减至1后,就跟 未指定初始Passes一样,之后每次经过断点都会中断,不会自动删除断点。

计数器不为1时,表示还需经过这么多次(含)才会中断。计数器为1时,啥也不说明, 这将是个每过必断的断点,此时无法获得断点经过次数。

假设初始Passes为n,实际经过断点次数为n+2,在第n+2次经过断点时会中断,但bl 看不出实际经过次数。为了得到断点的经过次数,务必指定一个超大的初始Passes, 比如0xffffffff。

用cdb启动mspaint,设置如上断点,看到GUI,关闭mspaint,bl查看断点:

ntdll!NtTerminateProcess+0x14: 00007ffd`f4cf03c4 c3 ret

bl 0 e 00007ffd`f1c3dc50 fffffff6 (ffffffff) 0:**** KERNELBASE!KernelBaseDllInitialize

初始Passes等于0xffffffff,显示在圆括号内,前面是计数器的当前值0xfffffff6。 直至进程结束,都没有真正断在前述断点,但计数器忠实地反映了实际经过次数:

0xffffffff-0xfffffff6=9

这个调试技巧在特定场景中会用到,比如可反复重现的崩溃调试场景,自行脑补剩余 情节。

完全可以自己统计断点经过次数,比如:

r @$t0=0 bu $iment(KERNELBASE) "r @$t0=@$t0+1;gc" ? @$t0

为什么不这么干呢?不要问我,我想静静。

另有几个用法可以关注一下:

@$bphit

当前命中的断点ID

@$bp

<n>必须替换成断点ID,伪寄存器对应相应的断点地址

bl [Expression] bc [Expression]

必须保持方括号,Expression可以是任意计算结果等于数字的表达式,对应断点
ID

2022-06-08 scz

bp 0x1400650C4 3 ".if(qwo(@rdx)==@$t9){dq @rdx l 1;dqs @$t9 l 4}.else{gc}"

本意是第三次满足约束条件时断下,但达不到预期目的。windbg先检查Passes,非1 时直接过,不会评估约束条件,仅当Passes为1时才评估约束条件。若原始需求是满 足约束条件的前提下第N次(从1计)经过断点时断下,无法利用内置的Passes参数,必 须自行计数。

r $t7=0;r $t8=3;bp 0x1400650C4 ".if(qwo(@rdx)==@$t9){r $t7=@$t7+1;.if(@$t7==@$t8){dq @rdx l 1;dqs @$t9 l 4}.else{gc}}.else{gc}"