【舊文章搬運】除錯沒有符號的驅動時如何斷在入口點處
原文發表於百度空間,2009-04-17
==========================================================================
關於除錯沒有符號的驅動時如何斷在入口點處這個問題,先說一個我聽來的很挫的方法:用C32ASM修改DriverEntry處為0xCC,就是int 3,修正校驗和後加載,執行到DriverEntry時產生int 3異常自然就會中斷在偵錯程式了,這時再把原來的指令改回去繼續跑就行了.改來改去的,確實比較挫~~.
那麼怎麼做比較好一點呢?
我們都知道有符號時直接bu drivername!DriverEntry就可以了,載入時就會停在入口點.但是沒有符號時,偵錯程式不知道DriverEntry到底指向哪個位置,但是誰知道呢?誰呼叫誰知道啊~~沒錯,就是IopLoadDriver()啦~~(關於該函式的具體實現,請自行參考WRK).
下面我就直接在IopLoadDriver函式中找呼叫DriverEntry的地方.
找啊找啊,終於找到了,在我的Xp sp2上如下:
lkd> nt!IopLoadDriver+0x65a: 805a9787 83e103 and ecx,3 805a978a f3a4 rep movs byte ptr es:[edi],byte ptr [esi] 805a978c 8b7d80 mov edi,dword ptr [ebp-80h] 805a978f ffb570ffffff push dword ptr [ebp-90h] //指向RegistryPath 805a9795 57 push edi //edi指向DriverObject 805a9796 ff572c call dword ptr [edi+2Ch] //edi+2C,指向DriverObject->DriverInit,即入口點DriverEntry 805a9799 3bc3 cmp eax,ebx 805a979b 8b8d68ffffff mov ecx,dword ptr [ebp-98h]
順便貼個DRIVER_OBJECT的結構,這樣兩個放一起看起來比較容易理解
lkd> dt _DRIVER_OBJECT 8a884e30 nt!_DRIVER_OBJECT +0x000 Type : 4 +0x002 Size : 168 +0x004 DeviceObject : 0x898ef450 _DEVICE_OBJECT +0x008 Flags : 0x92 +0x00c DriverStart : 0xf7b52000 +0x010 DriverSize : 0x8c480 +0x014 DriverSection : 0x8a960ae8 +0x018 DriverExtension : 0x8a884ed8 _DRIVER_EXTENSION +0x01c DriverName : _UNICODE_STRING "\FileSystem\Ntfs" +0x024 HardwareDatabase : 0x80696810 _UNICODE_STRING "\REGISTRY\MACHINE\HARDWARE\DESCRIPTION\SYSTEM" +0x028 FastIoDispatch : 0xf7b71820 _FAST_IO_DISPATCH +0x02c DriverInit : 0xf7bd7204 long +fffffffff7bd7204 //這就是入口點了,程式碼中的edi+2C處 +0x030 DriverStartIo : (null) +0x034 DriverUnload : (null) +0x038 MajorFunction : [28] 0xf7b77e37 long +fffffffff7b77e37
這個call特徵很明顯的.就是:
push reg
call dword ptr [reg+2Ch]
不同的核心版本這裡使用的暫存器可能是不一樣的,找到後把這個偏移記下來
只要我們把斷點下在這個call之前,比如我直接下bp nt!IopLoadDriver+0x65a
然後單步幾下到805a9796,這個call dword ptr [reg+2Ch]單步進去,就是DriverEntry了,很簡單!
如果你跟我一樣使用WinXP Sp2,那麼直接下斷點bp nt!IopLoadDriver+0x65a就可以了
Vista系統下直接下斷點 bp nt!IopLoadDriver+0x801
我提供的偏移可能不適用於你的系統,請自行查詢適合你自己的偏移量,只需查詢一次,以後就可以隨便用了.
此法在Win2000/WinXP/Win2003/WinVista上均適用,對SoftIce,Syser當然也是可以用的.
不過SoftIce好像有專用的命令,而Syser有沒有符號都可以自動斷在入口點處,所以使用Windbg但仍不會這個方法的可以記錄一下.