天天看點

win7 x64部署和序列槽調試虛拟驅動toaster

    WDK7600自帶的toaster驅動是個很好的學習驅動的案例,從總線驅動到App層,Class-install/Co-install都有涉及。本文主要涉及驅動部署和調試。

1.先說說調試的準備工作。一般調試驅動都是在虛拟機中進行的,這裡也不例外,用windbg+vmware輕按兩下聯調。通常開發階段,Wdm驅動以inf形式安裝并加載,加載後依次執行DriverEntry,AddDevice并響應IRP_MJ_PNP&IRP_MN_START事件。安裝的同時,pnp管理器會複制檔案及改寫系統資料庫,待下次重新開機,驅動在系統重新開機階段會加載運作驅動。是以,在DriverEntry時加入斷點尤為重要,要不然将錯過這些函數的調試時機。在x86時代,加入口斷點無非是代碼中插入 asm int 3.但是,這麼美好的時代已經過去了,x64驅動不支援嵌入彙編。取而代之,必須通過編寫一個asm檔案,在源碼中以調用外部函數的形式,共5步來實作。

1.1第一步實作int 3的彙編代碼形如:

.code
asm_int3 proc
  int 3
  ret
asm_int3 endp 
end      

1.2将這段代碼儲存為softbp.asm。然後用wdk自帶的ml64編譯,注意僅編譯生成obj檔案:

ml64 /c softbp.asm      

1.3接着是在C檔案中調用這個函數,如在wdm/bus/busenum.c的DriverEntry處加入斷點

extern void asm_int3(); //<-------------外部函數聲明

NTSTATUS
DriverEntry (
    __in  PDRIVER_OBJECT  DriverObject,
    __in  PUNICODE_STRING RegistryPath
    )
/*++
Routine Description:

    Initialize the driver dispatch table.

Arguments:

    DriverObject - pointer to the driver object

    RegistryPath - pointer to a unicode string representing the path,
                   to driver-specific key in the registry.

Return Value:

  NT Status Code

--*/
{

    asm_int3(); //<--------------外部函數調用
    Bus_KdPrint_Def (BUS_DBG_SS_TRACE, ("Driver Entry \n"));

    //
    // Save the RegistryPath for WMI.      

1.4修改sources檔案,添加對softbp.obj的連結:

原本sources檔案中TARGETLIBS的值為

TARGETLIBS=  $(DDK_LIB_PATH)\wdmsec.lib \
             $(DDK_LIB_PATH)\ntstrsafe.lib      

修改為:

TARGETLIBS=  $(DDK_LIB_PATH)\wdmsec.lib \
             $(DDK_LIB_PATH)\ntstrsafe.lib \
             softbp.obj      

1.5運作build -ceZ編譯連結整個toaster工程。

2.得到驅動檔案後就是部署階段。win7 x64的部署也是夠磨人的:bcdedit增加啟動項(再次懷念xp的好,修改boot.ini就夠了),禁用驅動簽名,最後安裝驅動。以下的步驟都在虛拟機中進行

2.1增加啟動項:

2.1.1 以administrator權限下進入cmd,運作bcdedit指令設定端口COM1為調試端口, baudrate為115200(我已将虛拟機的列印機移除,列印機可恥的占用着COM1,并将序列槽的名字改為COM1)

bcdedit /dbgsettings serial baudrate:115200 debugport:1      

2.1.2 複制一個開機選項, 以進入OS的debug模式

bcdedit /copy {current} /d DebugEnty      

2.1.3 接着增加一個新的選項到引導菜單

bcdedit /displayorder {current} {6426f429-17fc-11e6-bf64-ad656b9740aa}      

{6426f429-17fc-11e6-bf64-ad656b9740aa}是2.1.2運作結束後生成的id值

2.1.4 激活前面生成的debug項

bcdedit /debug {6426f429-17fc-11e6-bf64-ad656b9740aa} on      

最後上一張效果圖,然後重新開機機器準備調試:

win7 x64部署和序列槽調試虛拟驅動toaster
win7 x64部署和序列槽調試虛拟驅動toaster

3.windbg連結。

開始序列槽連接配接前,要設定調試符号和windbg啟動參數,我直接寫了個腳本setenv.bat完成這兩步,以後輕按兩下運作即可:

;set _NT_SYMBOL_PATH=SRV*C:\sym;用于設定調試符号的路徑
set _NT_SYMBOL_PATH=SRV*C:\sym;
;我的winbdg裝在下列位置,後面的參數是序列槽調試參數
"D:\WinDDK\7600.16385.1\Debuggers\windbg.exe" -b -k com:pipe,port=\\.\pipe\com_1,baud=115200,pipe      

系統重新開機後輕按兩下setenv.bat,在虛拟機中選擇DebugEntry 按F8進入進階啟動項,然後選擇Disable Driver Signature Enforcement

win7 x64部署和序列槽調試虛拟驅動toaster

(注,在等待虛拟機啟動期間,經常出現windbg閃退,這時再輕按兩下setenv.bat即可。)

4.部署toaster

進入win7後,在控制台中沒有硬體向導的一席之地!需要通過在開始菜單-運作中輸入hdwwiz.exe來打開。真是何其不易。ms出于安全目的,希望我們通過driver store安裝受信得驅動,倒給開發驅動的找了一堆破事。安裝toaster的步驟不再叙述,參照wdk中xp下安裝方式在hdwwiz.exe中設定即可。

安裝的末尾,也就是進入DriverEntry,由于我們在代碼中設定了int3斷點,是以windbg會獲得執行權。這時可以追加并驗證toaster的調試符号,因為此時驅動已經加載到記憶體中,是以設定斷點不會報類似code not set之類的錯誤,而且符号也能正确加載。

追加toaster調試符号
kd> .sympath+ C:\toaster\wdm\bus\objchk_win7_amd64\amd64
Symbol search path is: SRV*C:\sym;C:\toaster\wdm\bus\objchk_win7_amd64\amd64
檢驗符号是否加載
kd> lm m busenum*
start             end                 module name
fffff880`0392e000 fffff880`0393e000   busenum    (private pdb symbols)  c:\toaster\wdm\bus\objchk_win7_amd64\amd64\BusEnum.pdb
驗證符号是否和sys版本一緻
kd> !itoldyouso busenum c:\toaster\wdm\bus\objchk_win7_amd64\amd64\busenum.sys

busenum.sys
    Timestamp: 57333596
  SizeOfImage: 10000
          pdb: c:\toaster\wdm\bus\objchk_win7_amd64\amd64\BusEnum.pdb
      pdb sig: A8748D1B-8C93-4855-BBC7-4D773CADC3B0
          age: 1

Loaded pdb is c:\toaster\wdm\bus\objchk_win7_amd64\amd64\BusEnum.pdb

BusEnum.pdb
      pdb sig: A8748D1B-8C93-4855-BBC7-4D773CADC3B0
          age: 1

MATCH: BusEnum.pdb and busenum.sys
驗證目前執行的位置是不是在busenum中
kd> ln $ip
(fffff880`039301a0)   busenum!asm_int3   |  (fffff880`039301c0)   busenum!__security_check_cookie
Exact matches:      

待一切驗證完畢,就可以在AddDevice 等函數入口下斷點。等下次系統在啟動階段時,會在這些斷點處停下。

如果想多次進入DriverEntry/AddDevice函數,可以在裝置管理器中找到toaster裝置,然後右鍵disable/enable裝置,就能多次進入這些函數