windbg條件斷點II
阿新 • • 發佈:2019-01-13
想逆向一個程式,發現很久不用條件斷點居然生疏了,只能先寫個示例程式溫故一下,程式如下:
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
看下效果圖: