條件斷點(condition breakpoint)的是指在上面3種基本斷點停下來後,執行一些自定義的判斷。
在基本斷點命令後加上自定義除錯命令,可以讓偵錯程式在斷點觸發停下來後,執行偵錯程式命令。每個命令之間用分號分割。
語法格式如:
0:000>bpaddress"j (condition) 'optionalcommands'; 'gc' "
0:000>bpaddress".if (condition) .else "
這兩條是等價的.
當然.if
.else
更好理解.
0:000>bp `mysource.cpp:143` "j (poi(myvar)>0n20) ''; 'gc' "
0:000>bp `mysource.cpp:143` ".if (poi(myvar)>0n20) {} .else "
若myvar大於20則不stop,
否則stop下來進行除錯.
myvar
符號表示符號所在的記憶體位址,而不是符號的數值,相當於c語言中的&操作符的作用。windbg命令poi的作用是取這個位址上的值,相當於c語言中的*操作符.因此這裡取得myvar的值.
偽暫存器,幫助儲存除錯的中間資訊
考慮這樣的情況,如果要記錄某乙個函式被執行了多少次,應該怎麼做?簡單的做法就是修改**,在對應的函式入口做記錄。可是,如果要記錄的函式是系統api呢?
設定暫存器條件斷點
當eax內的值為0xa3時斷點sop. 沒問題,hah.
0:000>bp mydriver!myfunction "j @eax = 0xa3 '';'gc'"
0:000>bp mydriver!myfunction ".if @eax = 0xa3 {} .else "
但以下就不一定了,當eax中人值為0xc0004321時,
不一定會斷下來.
為什麼呢?
原因是核心態時,masm會對eax中的值進行符號擴充套件.
那麼0xc0004321 會變成0xffffffffc0004321
這樣當然斷不下來啦。
0:000>bp mydriver!myfunction "j @eax = 0xc0004321 '';'gc'"
0:000>bp mydriver!myfunction ".if @eax = 0xc0004321 {} .else "
如何處理呢?看看下面就知道了.
0:000>bp mydriver!myfunction "j (@eax & 0x0`ffffffff) = 0x0`c0004321 '';'gc'"
0:000>bp mydriver!myfunction ".if (@eax & 0x0`ffffffff) = 0x0`c0004321 {} .else "
爽吧,高位清0!
下面的命令可以統計virtualallocex被執行了多少次:
bp /1 /c @$csp @$ra;g
bp kernel32!virtualallocex "r $t0=@$t0+1;.printf
\"function executes: %d times \",@$t0;.echo;g"
這裡用到的$t0就是windbg提供的偽暫存器。可以用來儲存中間資訊。這裡用它來儲存函式執行的次數。r命令可以用來檢視,修改暫存器(cpu暫存器和windbg的偽暫存器都有效)的值。隨便挑乙個繁忙的程序,用這個命令設定斷點後觀察:
0:009> bp kernel32!virtualallocex "r $t0=@$t0+1;.printf
\"function executes: %d times \",@$t0;.echo;g"
0:009> g
function executes: 1 times
function executes: 2 times
function executes: 3 times
function executes: 4 times
哈哈,這確實是乙個好方法.
windbg設定條件斷點
一直以為windbg的bp斷點只是簡單的在某個位址上下斷點,後來才發現bp斷點功能很強大 除了可以設定條件斷點還是windbg指令碼的基礎.使用方法很簡單 bp address if condition else 具體例子形如 bp 4dbg.cpp 18 if hfile 0 else 這裡是對原...
windbg字串比較條件斷點
當暫存器指向字串為與某個字串相同時,斷下程式。問題關鍵 需要把暫存器指向的字串取出來比較,而別名可以做到這一點。測試原始碼 void main 斷點 1 e 0040141f e hello test2 test2.cpp 30 0001 0001 0 test2 main 0x3f 指令碼e sc...
通過WinDbg條件斷點收集Log
前段時間花了幾天一直在用windbg除錯乙個比較棘手的bug。這個bug是c team那邊發現的,他們的testcase跑大概10分鐘左右會出乙個在clr內部的assert。比較難除錯的主要原因在於assert表明乙個全域性的資料結構出現了問題,本來不應該用完的陣列卻已經用完了 因為按照設計,這個陣...