驅(qū)動程序一般調(diào)試手段及方法

字號:

Windows驅(qū)動程序的難于調(diào)試是眾所周知的,調(diào)試步驟繁瑣,而且內(nèi)核環(huán)境下固有的多線程環(huán)境和代碼執(zhí)行的順序不確定性,更增加了調(diào)試的難度,我自己感覺的辦法,就是利用DbgPrint(我自己則最常使用KdPrint)打印出足夠多的信息,以便于我們分析。下面是一些打印出詳細trace的一些手段:
    利用__LINE__ __FILE__以及__FUNCTION__定位代碼位置
    這幾個編譯器指令分別指示當(dāng)前代碼所在的行號、文件名和函數(shù)名;你可以在你的代碼中定義如下的宏:
    #define DBG_TRACER \"%s(%d)-%s\"
    #define DBG_ARGS __FILE__,__LINE__,__FUNCTION__
    然后,你可以像這樣使用這兩個宏:
    KdPrint((DBG_TRACER\"你的字符串消息\\n\",DBG_ARGS));
    2. 利用Osr上的OsrNTStatusToString將你的NTSTATUS狀態(tài)碼值轉(zhuǎn)換成對應(yīng)的字符串值:當(dāng)你要打印一個錯誤狀態(tài)碼時,直接打印出表意的字符可能會為你節(jié)省一些時間;
    3. 打印UNICODE_STRING:本來這是一個比較easy的事情,但是驅(qū)網(wǎng)上不時有人說到微軟給的sfilter例子里面獲取文件全路徑名的函數(shù)無法獲取中文路徑,實際是不是不能獲取,而是KdPrint打印的時候,沒有把中文字符打印出來,轉(zhuǎn)換成ANSI_STRING,然后再打印出來,代碼如下:
    {
     ANSI_STRING AnsiStr;
     NTSTATUS status;
    status = RtlUnicodeStringToAnsiString(
    if (NT_SUCCESS(status))
    {
     KdPrint((AnsiStr.Buffer));
     RtlFreeAnsiString( }
    }
    4. 利用Filemon中的代碼:Filemon本身是很有用的一個工具,當(dāng)然,它的源代碼也是一座金礦,你可以從中學(xué)到很多東西。利用FileMon中的若干代碼,可以將對應(yīng)的IRP轉(zhuǎn)換成對應(yīng)的字符打印出來(FileSpy或者MiniSpy中的PrintIrpCode可以做同樣的事情);也可以將FileInformationClass對應(yīng)的字符打印出來;最后,你可能用到的最多的,就是將FileMon中的打印當(dāng)前進程名的代碼搗鼓出來自己使用,稍加改變,你也可以用它來打印任意一個你獲取了PEPROCESS進程指針的進程名(注意在一個較低的IRQL下使用它);
    5. 文章的最后,給出一些其他的代碼,包括:打印IRP的Flags值、打印FILE_OBJECT的Flags值、打印Volume的DeviceType值以及打印FILE_OBJECT結(jié)構(gòu)中的BOOLEAN值設(shè)置,代碼中也包括了上文提到了從filemon中抽出的部分代碼,都是些體力活,如果你自己不想寫,直接下載就好!