內核調試-WinDbg操作!

網上搜WinDbg教程,大部分就是一兩個來回來去轉帖,還有就是大部分都不是內核方面調試的。

這裏總結一些windbg的操作方法、小技巧,羅列一些常用的命令以供查詢。

lm(查看當前的符號鏈接情況)

WinDbg 10大調試命令

u: 反編譯機器碼
在檢查crash dump是否正確時,你已經用過了此命令,u命令有三種格式:
1.u <from> 從地址<from>開始反編譯8個機器碼。
2.u <from> <to> 反編譯<from>到<to>之間的所有機器碼。
3.u 不提供任何參數時,從上次u命令停止的位置開始反編譯。
當然,反編譯打段代碼是十分厭煩的,但如果你只想知道在特定地址發生的事情,那這是最便捷的方法。或許u命令最令人感興趣的特性是它可以解析代碼引用到的符號----即使是目標模塊沒有導出的符號。

db,dw和dd:Dump Memory BYTEs、WORDs和DWORDs
如果你當前感興趣的內存數據是二進制的,那麼調試器的16進制轉儲命令將能完成此任務。根據你對源地址(source address)數據類型的判斷,來選擇dd(針對BYTES)、dw(針對WORDS)、dd(針對DWORDS)。
1.db 將指定內存範圍裏的數據顯示爲兩個部分:左邊是16進製表示(每2個8 bit一組),右邊是對應的ASCI碼。
2. dw 僅按照16進制顯示(16 bit一組)
3. dw 僅按照16進制顯示(32 bit一組)
此組命令可以使用與u命令相同的參數。注意,<to>所指示的地址內容,也會被顯示出來。如果沒有任何參數,將顯示接下來的128個字節。

x:檢查符號
x命令非常重要。它可以根據已安裝的符號文件創建一個列表。典型的使用方式如下:
1.x *!* 顯示所有可用符號的模塊。在啓動後,默認只有ntoskrnl.exe的符號是可用的。其他模塊的符號可以使用.reload命令來加載。
2.x <module>!<filter> 顯示模塊<module>的符號文件中的符號名稱,<filter>可以包括通配符?和*。<module>必須屬於x *!*列出的模塊名。例如,x nt!*將列出在內核符號文件ntoskrnl.dbg中找到的所有符號,x win32k!*將列出win32k.dbg提供的符號。如果調試器報告說“Couldn’t resolv‘X….’”,嘗試用.reload再次加載所有的符號文件。
3.x <filter> 顯示所有可用符號的一個子集,該子集不匹配<filter>表達式。本質上,這是x <module>!<filter>的一個變形,在這裏<module>!被省略了。隨符號名一起顯示的,還有與其相關的虛擬地址。對於函數名,與其對應的就是函數的入口地址。對於變量,就是改變量的基地址。該命令值得的注意的地方是,它可以輸出很多內部符號(internal symbols),這些在可執行文件的導出表中都是找不到的.


ln:列出最近的符號
ln是我最喜歡的一個命令。因爲它可以快速且簡單的訪問已安裝的符號文件。算是x命令的理想補充。不過後者適用於列出所有系統符號的地址。Ln命令則用於按照地址或名稱查找符號。
1.ln <address> 顯示<address>指示的地址以及和其前後相鄰的地址的符號信息。
2.ln <symbol> 將符號名解析爲與其對應的虛擬地址。其過程與ln <address>類似。像x命令一樣,調試器知道所有導出的以及一些內部的符號。因此,對於想弄清楚出現在反編譯列表或16進制轉儲中的不明指針的確切含義的人有着非常大的幫助。注意,u、db、dw、dd也會使用符號文件。

!processfield:列出EPROCESS的成員
該命令前的!號,意味着它來自於調試器的擴展模塊―kdextx86.dll。該命令可顯示內核用來代表一個進程的EPROCESS結構(該結構並沒有正式的說明文檔)的成員及其偏移量。
儘管該命令僅列出了成員的偏移量,但你也能很容易的猜出其正確的類型。例如,LockEvent位於0x70處,其下一個成員的偏移量爲0x80。則該成員佔用了16個字節,這與KEVENT結構非常類似。


!threadfields:列出ETHREAD成員
這是kdextx86.dll提供的另一個強大的選項。和!processfields類似,它列出未文檔化的ETHREAD結構的成員及其偏移量。內核使用它表示一個線程.


!drivers:列出已加載的Drivers
kdextx86.dll真是太棒了。!drivers列出了當前運行的內核和文件系統模塊的詳細信息。如果檢查crash dump,該命令會列出系統崩潰那一刻的系統狀態。示例1-3是我機器上輸出的摘要。注意,在輸出的最後一行,導致Windows 2000崩潰的Driver的地址爲0xBECC2000,這顯然是w2k_kill.sys引發藍屏後顯示的地址。
注:
在新的i386kd.exe(ver: 6.3.0017.0)中,!driver命令已不被支持。取而代之的是lm命令。該命令的一般用法是:lm t n

!sel:檢查Selector的值
!sel實現於kdextx86.dll。它用來顯示16個連續的memory selector(按地址升序排列)。你可以反覆的使用此命令直到出現“Selector is invalid”。在第4章將討論Memory Selector,到時我會提供一個示列代碼來演示如何在你的程序中crack selectors。
注:
在新的調試器中,該命令已不被支持,取而代之的是:dg命令。其一般性用法爲:dg.注意末尾的.符號。dg命令最多可列出256個Selector。調試器的Online Help中有詳細說明


kd> x nt!KeServiceDescriptorTable*
8046e100 nt!KeServiceDescriptorTableShadow = <no type information>
8046e0c0 nt!KeServiceDescriptorTable = <no type information>

kd> ln 8046e100
(8046e100) nt!KeServiceDescriptorTableShadow | (8046e140) nt!MmSectionExtendResource
Exact matches:
nt!KeServiceDescriptorTableShadow = <no type information>

2. 下載系統文件的符號

symchk c:\winnt\system32\ntoskrnl.exe /s srv*c:\symbols*http://msdl.microsoft.com/download/symbols

SYMCHK: FAILED files = 0
SYMCHK: PASSED + IGNORED files = 1

3. 查看 event 對象的信號狀態

!object \BaseNamedObjects
dt -b nt!_KEVENT xxxxxxxx

4. 查看 LastError 值

!gle

5. 指定進制形式,0x/0n/0t/0y 分別表示 16/10/8/2 進制

? 0x12345678+0n10
Evaluate expression: 305419906 = 12345682

6. 過濾命令窗口輸出信息

.prompt_allow -reg +dis -ea -src -sym

7. .formats 命令

以多種格式顯示錶達式的值
0:000> .formats @eax
Evaluate expression:
Hex: 00181eb4
Decimal: 1580724
Octal: 00006017264
Binary: 00000000 00011000 00011110 10110100
Chars: ....
Time: Mon Jan 19 15:05:24 1970
Float: low 2.21507e-039 high 0
Double: 7.80981e-318

8. 異常處理相關

有 sx, sxd, sxe, sxi, sxn, sxr 幾條命令可用來設置異常和事件的處理方式。比如:
0:000> sxe ld
可以在加載 dll 時中斷下來。

9. 內核調試時切換進程

lkd> !process 0 0
lkd> .process xxxxxxxx

10. 可在桌面上建立一個 WinDbg.exe 的快捷方式,然後在該快捷方式的屬性力設置如下命令行

C:\WinDBG\windbg.exe -c ".prompt_allow +dis -reg -ea -src -sym; .enable_unicode 1; .enable_long_status 1; .logopen /t c:\dbglog\dbglog.txt"

11. 本機內核調試

通過File/Kernel Debug… 菜單可以打開內核調試選擇窗口,選擇最後一個 Local 選項頁,確定後可以以內核方式調試本地機器。這時所有會掛起系統的命令都用不了了,但可以讀寫系統內存。另外,有一個方便的用途是用來查看系統結構,比如:dt nt!_EPROCESS。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章