首先說說應用層的調試吧.當我們在調試windows可執行程序的時候,通過將PE文件頭中的ImageBase和AddressOfEntryPoint相加,從而得出第一條指令的地址.針對這個地址下斷之後目標程序就中斷在了了入口處.但是這個方法在驅動調試的時候卻有心無力.這是因爲可執行程序都是首先被加載到各自的私有地址空間,他們不會有地址衝突.然而驅動程序運行在內核裏面,所有的驅動程序共享一個地址空間.所以需要重新設定基地址.
1.利用bu命令下延遲斷點.
之前提到過,bu可以針對符號下斷點.這裏是用bu下延遲斷點的意義在於即使目標驅動沒有被加載,windbg也允許我們針對符號設置斷點.當新加載驅動程序後,windbg就會檢查驅動程序中是否包含了設置了延遲斷點的函數.如果找到了,就把斷點替換爲地址形式,然後再設置斷點.筆者的測試驅動程序爲TestDriver.sys.
- 0: kd> .sympath
- Symbol search path is: E:\Symbol\windbg Symbols;E:\Code\Vc_code\Ring3Ring0\Driver\objchk_wxp_x86\i386
- Expanded Symbol search path is: e:\symbol\windbg symbols;e:\code\vc_code\ring3ring0\driver\objchk_wxp_x86\i386
- 0: kd> .srcpath
- Source search path is: E:\Code\Vc_code\Ring3Ring0\Driver
在VMware客戶機裏,安裝驅動後,敲下 net start TestDevice之後,系統理所應當的被斷下來了.
- Breakpoint 0 hit
- TestDriver!DriverEntry:
- f8c4ee10 8bff mov edi,edi
假如我們調試的驅動並不是以DriverEntry作爲入口函數,bu針對符號下斷也就沒有了意義.但是我們可以使用模塊加偏移的方式下斷.假設TestDriver的入口函數的偏移爲0xFB4.直接bu TestDriver+0xFB4即可.
現在來看看我們的程序,中斷在了DriverEntry之中.我們能不能在進入DriverEntry之前下斷.首先我們dv和esp看一下當前的棧
- 1: kd> dv
- pDriverObject = 0x81f346e8
- pRegistryPath = 0x81865000 "\REGISTRY\MACHINE\SYSTEM\ControlSet001\Services\TestDevice"
- status = 0n8
- 1: kd> r esp
- esp=f8af9c88
- 1: kd> dd f8af9c88 L8
- f8af9c88 80582377 81f346e8 81865000 00000000
- f8af9c98 b2926cf4 00000000 00000018 00000000
dv命令只顯示了參數,還是用esp靠譜一點,至少給出了我們返回地址0x80582377.接下來該ln命令登場了
- 1: kd> ln 80582377
- (80581d0a) nt!IopLoadDriver+0x66d | (80582442) nt!IopLoadUnloadDriver
返回地址位於nt!IopLoadDriver+0x66d處,直接反彙編一下吧,看看再哪裏調用了DriverEntry
- 0: kd> bu TestDriver!DriverEntry
- 0: kd> bl
- 0 eu 0001 (0001) (TestDriver!DriverEntry)
- <pre name="code" class="plain">1: kd> u nt!IopLoadDriver+0x660
- nt!IopLoadDriver+0x660:
- 8058236a 8b7d80 mov edi,dword ptr [ebp-80h]
- 8058236d ffb570ffffff push dword ptr [ebp-90h]
- 80582373 57 push edi
- 80582374 ff572c call dword ptr [edi+2Ch]
- 80582377 3bc3 cmp eax,ebx
- 80582379 8b8d68ffffff mov ecx,dword ptr [ebp-98h]
- 8058237f 8945ac mov dword ptr [ebp-54h],eax
- 80582382 8901 mov dword ptr [ecx],eax</pre><br>
- <pre></pre>
- <pre></pre>
- <pre></pre>
- <pre></pre>
0x80582377處是nt!IopLoadDriver+0x66d.前面的call指令佔了3個字節.所以我們下斷在nt!IopLoadDriver+0x66a就能在進入DriverEntry之前中斷下來.
3.使用事件異常
先來看看系統中提供了哪些事件異常吧.直接sx下
- 1: kd> sx
- ct - Create thread - ignore
- et - Exit thread - ignore
- cpr - Create process - ignore
- epr - Exit process - ignore
- <strong>ld - Load module - output</strong>
- ud - Unload module - ignore
- ser - System error - ignore
- ibp - Initial breakpoint - break
- iml - Initial module load - ignore
- out - Debuggee output - output
- 1: kd> sxe ld
- 1: kd> sx
- ct - Create thread - ignore
- et - Exit thread - ignore
- cpr - Create process - ignore
- epr - Exit process - ignore
- ld - Load module - break
- ud - Unload module - ignore
- ser - System error - ignore
- ibp - Initial breakpoint - break
- iml - Initial module load - ignore
- out - Debuggee output - output
加載我們的驅動吧,在load module的時候系統中斷
然後我們找到模塊基址,並在入口處下斷即可.
- 1: kd> lm n
- start end module name
- [...]
- f8b9c000 f8b9d100 WMILIB WMILIB.SYS
- f8b9e000 f8b9f580 intelide intelide.sys
- f8ba0000 f8ba1700 dmload dmload.sys
- f8ba4000 f8ba5280 vmmouse vmmouse.sys
- f8bb0000 f8bb1100 swenum swenum.sys
- f8bb6000 f8bb7280 USBD USBD.SYS
- f8bba000 f8bbbf00 Fs_Rec Fs_Rec.SYS
- f8bbe000 f8bbf080 Beep Beep.SYS
- f8bc2000 f8bc3080 mnmdd mnmdd.SYS
- f8bc6000 f8bc7080 RDPCDD RDPCDD.sys
- f8bf8000 f8bf9a80 ParVdm ParVdm.SYS
- f8bfc000 f8bfde00 vmmemctl vmmemctl.sys
- <strong>f8c4e000 f8c4f300 TestDriver TestDriver.sys</strong>
- [...]
- 1: kd> !dh -a f8c4e000
- File Type: EXECUTABLE IMAGE
- FILE HEADER VALUES
- 14C machine (i386)
- 6 number of sections
- 5077C38E time date stamp Fri Oct 12 15:15:26 2012
- 0 file pointer to symbol table
- 0 number of symbols
- E0 size of optional header
- 102 characteristics
- Executable
- 32 bit word machine
- OPTIONAL HEADER VALUES
- 10B magic #
- 9.00 linker version
- C00 size of code
- 280 size of initialized data
- 0 size of uninitialized data
- <strong> FB4 address of entry point</strong>
- 480 base of code
- ----- new -----
- [...]
然後bp TestDriver+0xFB4即可讓系統中斷在我們驅動程序的入口處.