天天看點

windbg條件斷點II

    想逆向一個程式,發現很久不用條件斷點居然生疏了,隻能先寫個示例程式溫故一下,程式如下:

int condbp(char* str,int val)
{
  printf("%s-%d\n",str,val);
  return 0;
}

int _tmain(int argc, _TCHAR* argv[])
{
  int idx = 0;
  char* strtab[3]={"abc","edf","hig"};
  while(1)
  {
    do
    {
      condbp(strtab[idx],idx);
      Sleep(200);
      idx++;
    }while(idx%3);
    printf("\n");
    idx=0;
  }
  return 0;
}      

想要達到的目标:循環中,如果condbp的參數1的内容為"edf",則讓windbg停下,列印參數2 idx的值。一步到位似乎有點困難,容我分步實作這個目标。

Step 1 依次獲得參數的值:

0:000:x86> uf 4dbg!main
...

4dbg!main+0x43 [c:\users\eugene\desktop\studio\4dbg\4dbg\4dbg.cpp @ 22]:
   22 00a072b3 8b45f8          mov     eax,dword ptr [ebp-8]
   22 00a072b6 50              push    eax
   22 00a072b7 8b4df8          mov     ecx,dword ptr [ebp-8]
   22 00a072ba 8b548de4        mov     edx,dword ptr [ebp+ecx*4-1Ch]
   22 00a072be 52              push    edx
   22 00a072bf e89de5ffff      call    4dbg!ILT+2140(?condbpYAHPADHZ) (00a05861) ;<-------下斷點的位置,此時參數已經入棧,可以通過esp獲得各個參數值
...
0:000:x86> bp 00a072bf ;00a072bf 是指令call 4dbg!ILT+2140處的位址
0:000:x86> g
Breakpoint 1 hit
4dbg!main+0x4f:
00a072bf e89de5ffff      call    4dbg!ILT+2140(?condbpYAHPADHZ) (00a05861)
0:000:x86> dd esp L4 ;檢視棧變量
010ffbfc  00a51c7c 00000000 00a05a1e 00a05a1e ;esp+0是strtab[idx],esp+4是idx

;dwo取指定位址處雙位元組
0:000:x86> r @$t0=dwo (@esp+4)
0:000:x86> r @$t0
$t0=00000000
;poi取指定指定處指針
0:000:x86> r @$t1=poi(@esp)
0:000:x86> da @$t1
00a51c7c  "abc"      

Step 2 比較參數1的内容是否為"edf",如果是,則讓windbg中斷:

0:000:x86> ad* ;删除先前使用過的别名

;準備條件斷點
0:000:x86> bp 00a072bf "as /ma $ustr poi(@esp); .block{r @$t0=$scmp(@\"$ustr\",@\"edf\");.if(@$t0==0){};.else{gc;}}"
;這條指令将@esp+0處的棧變量(當然是字元串指針),以ASCII字元串的形式指派給ustr變量,指派由as /ma $ustr poi(@esp);完成
;windbg變量可能要在.block中使用,是以,後半句比較判斷語句需要放在.block{}中
;注意,條件斷點的條件由""包括,是以在條件中要表示"",如在字元串中用到""則需要用@\"\",進行轉義!!!
;$scmp是windbg内置的字元串比較函數,比較的結果存放在僞寄存器$t0中
0:000:x86> g
4dbg!main+0x4f:
00a072bf e89de5ffff      call    4dbg!ILT+2140(?condbpYAHPADHZ) (00a05861)
0:000:x86> g
4dbg!main+0x4f:
00a072bf e89de5ffff      call    4dbg!ILT+2140(?condbpYAHPADHZ) (00a05861)
;windbg在call指令處中斷,檢視參數2的内容
0:000:x86> r @$t1=dwo (@esp+4)
0:000:x86> r @$t1
$t1=00000001      

Step 3 基于上一步的比較結果,結合.printf元指令,将參數1的值輸出:

0:001> bp 00a072bf "as /ma $ustr poi(@esp); .block{r @$t0=$scmp(@\"$ustr\",@\"edf\");.if(@$t0==0){r @$t1=dwo (@esp+4);.printf @\"idx equal to %d\",@$t1;gc;};.else{gc;}}"
breakpoint 0 redefined