【问题标题】:WinDbg - count breakpoint hits when certain values are on the stackWinDbg - 当某些值在堆栈上时计数断点命中
【发布时间】:2014-09-30 16:05:01
【问题描述】:

我不是在谈论调用堆栈。

我想计算当 ESP 持有的地址有某个值时,某个函数被调用了多少次。在您告诉我检查返回地址之前,我对此不感兴趣 - 在这种情况下,返回地址位于 ESP+4,[ESP] 持有一个在函数返回之前弹出的值。细节不重要。

我可以使用以下语法计算函数调用:

bp MyFunction "r @$t0 = @$t0 + 1; r @$t0; gc"

我可以通过添加在 [ESP] 处显示双字

dd $csp L1

到上面的命令。

问题是有很多调用,我只对某些调用感兴趣,并且在每个断点之后手动跟踪它们既烦人又耗时。

我仍然习惯使用 WinDbg 的语法。我的 .if 语句中的条件应该如何?

我尝试了一些疯狂的事情,比如

.if( (dd $csp L1) == 2 )

但这显然是错误的。

我还考虑在 [ESP] 的值移动到局部变量(类似于 bp MyFunction+eip_after_assignment)之后在函数中的某处设置断点,但这有点太晚了。我想我可以解决这个问题,但如果我能在一开始就检查 [ESP],事情就会变得更简单。

【问题讨论】:

  • 你能试试.if(poi($csp) == 2)吗?
  • @Thomas W. 这就是我要找的。谢谢。现在它仍然会在所有呼叫中中断,但只计算我感兴趣的呼叫。我想有一种方法可以在不满足条件时完全不中断?
  • 你的意思是像.if (Condition) { Commands } .else { g; }?抱歉,我目前无法尝试所有这些。
  • 这仍然中断,但进入 else 路径并发出 continue 命令。 .if(condition) { break } 之类的东西。当有很多呼叫时,系统会由于大量中断而冻结几秒钟。现在不是真正的问题,只是好奇。我会玩弄一下 EIP,看看我会在哪里结束。
  • @ThomasW。 else 分支应使用gc 而不是g,以便使用之前使用的相同执行类型继续执行。

标签: windbg


【解决方案1】:

0:000> lsa .

     2: int dummy=0;
     3: void useless(int in) {
     4:     dummy=in;
     5: }
>    6: void main(void) {
     7:     for(int i=0;i<0xffffffff;i++)
     8:         useless(i);        
     9: }

0:000> uf countfunc!useless

countfunc!useless [c:\countfunc.cpp @ 3]:
    3 00401000 55              push    ebp
    3 00401001 8bec            mov     ebp,esp
    4 00401003 8b4508          mov     eax,dword ptr [ebp+8]
    4 00401006 a320bb4000      mov     dword ptr [countfunc!dummy (0040bb20)],eax
    5 0040100b 5d              pop     ebp
    5 0040100c c3              ret

0:000> bl 0:000> bp 0040100b ".if ( poi(@$csp+8) != 1337 ) {gc}" 0:000> .bpcmds

bp0 0x0040100b  ".if ( poi(@$csp+8) != 1337 ) {gc}";

0:000> 克

> eax=00001337 ebx=7ffdf000 ecx=00001337 edx=0040c340 esi=00000000
> edi=0098f6ee eip=0040100b esp=0013ff68 ebp=0013ff68 iopl=0         nv
> up ei pl nz ac po cy cs=001b  ss=0023  ds=0023  es=0023  fs=003b 
> gs=0000             efl=00000213 countfunc!useless+0xb: 0040100b 5d   
> pop     ebp

0:000> ??在
int 0n4919
0:000> dv
在 = 0n4919
0:000> ? 0n4919/1
求值表达式:4919 = 00001337

对相同代码进行更复杂的条件中断

0:000> r $t0 = 0; bp 0040100b ".if ( poi(@$csp+8) != @$t0*1337 ) {gc} .else { .echotime ;? poi(@$csp+8) ; r$t0 = @$t0+1 ;gc }"
0:000> .bpcmds
bp0 0x0040100b  ".if ( poi(@$csp+8) != @$t0*1337 ) {gc} .else { .echotime ;? poi(@$csp+8) ; r$t0 = @$t0+1 ;gc }";
0:000> .echotime
Debugger (not debuggee) time: Tue Sep 30 12:12:15.890 2014 
0:000> g
Debugger (not debuggee) time: Tue Sep 30 12:12:24.062 2014 
Evaluate expression: 0 = 00000000
Debugger (not debuggee) time: Tue Sep 30 12:12:32.578 2014 
Evaluate expression: 4919 = 00001337
Debugger (not debuggee) time: Tue Sep 30 12:12:41.093 2014 
Evaluate expression: 9838 = 0000266e
Debugger (not debuggee) time: Tue Sep 30 12:12:49.609 2014 
Evaluate expression: 14757 = 000039a5
Debugger (not debuggee) time: Tue Sep 30 12:12:58.156 2014 
Evaluate expression: 19676 = 00004cdc
Debugger (not debuggee) time: Tue Sep 30 12:13:06.687 2014 
Evaluate expression: 24595 = 00006013
Debugger (not debuggee) time: Tue Sep 30 12:13:15.218 2014 
Evaluate expression: 29514 = 0000734a
Debugger (not debuggee) time: Tue Sep 30 12:13:23.765 2014 
Evaluate expression: 34433 = 00008681
Debugger (not debuggee) time: Tue Sep 30 12:13:32.828 2014 
Evaluate expression: 39352 = 000099b8
Debugger (not debuggee) time: Tue Sep 30 12:13:40.906 2014 
Evaluate expression: 44271 = 0000acef

如果这样继续下去,这个简单的代码可能需要 86 天才能完成,在 windbg 中处理 4919 个函数调用似乎需要大约 8.5 秒

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-27
    • 2013-02-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-06
    相关资源
    最近更新 更多