天天看點

Windbg核心調試之二: 常用指令

運用Windbg進行核心調試, 熟練的運用指令行是必不可少的技能. 但是面對衆多繁瑣的指令, 實在是不可能全部的了解和掌握. 而了解Kernel正是需要這些指令的指引, 不斷深入了解其基本的内容. 下面, 将介紹最常用的一些指令, 使初學Kernel調試的朋友們能有一個大緻的了解. 至于如何熟練的運用它們, 還需要實際的操作過程中進行反複的琢磨.

Windbg能夠友善的進行遠端調試和本地程序調試(隻限于User模式), 遠端調試又分User mode和Kernel mode兩種. 個人認為用Windbg進行遠端的User mode調試還不如用Visual Studio來的友善, 畢竟要一些相應的配置才行, 而Visual Studio隻需要遠端機器的IP位址即可.(當然, 如果你在LiveCD或WinPE下進行User mode的調試, 這時候沒有VS, Windbg就是不二之選了). Windbg的優勢就在于遠端的Kernel模式的調試, 這是VS所做不到的.

1. 首先是設定符号路徑(無論在User mode下還是Kernel mode下都需要), 在Windbg的符号路徑對話框中, 輸入以下符号路徑:

      srv*c:\symbols*http://msdl.microsoft.com/download/symbols

這個符号路徑是自動在微軟給定的symbols路徑下進行自動搜尋, 一些常用的符号都可以利用這個連結自動找到. 當然, 如果你的本地已經有相應的符号路徑, 包含本地的也可以.

2. 等Windbg的聯機狀态設定好後, 按下Ctrl+break, 中斷目前的Kernel狀态, 在Windbg的指令行視窗輸入"?", 則會輸出幫助菜單, 在這個Menu中會顯示一些常用的指令:

  (1)斷點指令

     B[C|D|E] [<bps>]

     clear|disable|enable breakpoints

     BL

     list breakpoints

     BP <address>

     set soft breakpoints

     BA <access> <size> <addr>

     break on access

  (2)資料檢視指令

     D[type][<range>]

     dump memory

     DT [-n|y] [[mod!]name] [[-n|y]fields][address] [-l list] [-a[]|c|i|o|r[#]|v]

     dump using type information

     DV [<name>] 

     dump local variables

  (3)資料修改指令

     E[type] <address> [<values>]

     enter memory values

  (4)運作

     G[H|N] [=<address> [<address>...]] 

     go

     P [=<addr>] [<value>]

     step over

  (5)堆棧操作

     K[b|p|P|v]

  (6)顯示加載的子產品清單

     LM

     list modules

  (7)寄存器操作

     R [[<reg> [= <expr>]]]

     view or set registers

  (8)Search指令

     S[<opts>] <range> <values>

     search memory

  (9)跟蹤指令T,TA,TB,TC,WT,P,PA,PC

  (10)退出

      Q

  (11)反彙編

      U[<range>]

其中最常用的就是反彙編操作和顯示子產品操作. LM指令顯示目前加載的子產品. 當你連接配接過程中, Windbg提示相應的module找不到時, 就可以運用這個指令進行檢視. LM的一個擴充指令是"lm t n", 這個指令顯示目前所有加載的驅動資訊(過去的指令是!driver),在調試核心驅動的過程中非常有用,可以找到相應驅動的起始位址。反彙編指令u, 可以在相應的位址中逐漸的解析代碼,這在核心調試中是最常用的一種檢視代碼的方式。

除上面的一些基本指令之外,還有一些非常有用的指令:

  (1)K[KB|KP]

     顯示目前的堆棧,當然也可以用alt+6直接調出視窗顯示

  (2)!process

     顯示目前的程序EXPROCESS狀态,!process 0 0 顯示所有的程序狀态

  (3)!thread

     顯示目前的線程狀态,dt nt!_ethread顯示ETHREAD結構

  (4)!drvobj [path]

     列出目前的驅動程式在驅動對象中的例程,其中path是驅動的裝置路徑,例如: !drvobj \filesystem\fat 2 列出FAT檔案系統驅動的例程

  (5)dt nt!_*

     檢視核心的資料結構

  (6)!stack 0

     顯示線程目前位址

  (7)!ioapic

     檢視I/O的中斷控制器

  (8)!irql

     檢視CPU的IRQL,這在CPU中斷調試中非常有用

  (9)!exqueue

     可以看系統輔助的線程清單

  (10)!reg viewlist

     系統資料庫的存儲顯示,!reg hivelist顯示系統資料庫一個存儲的記憶體使用量

  (11)!vm

     顯示系統的記憶體池資訊

  (12)dt _TOKEN

     顯示内部通路令牌

  (13)!object \device

     顯示裝置對象資訊,用winobj工具也可以看到

以上指令是一些常用的核心調試指令, 還有非常多的指令技巧, 不可能全部一一解釋. 在今後的文章, 還會結合具體的調試過程分析進行逐漸介紹. 核心的調試無非是處理器, 系統裝置, 記憶體, 程序線程, 系統資料庫, 驅動這幾大類的資訊, 每一類都有很多的指令, 需要我們在實際的調試過程中不斷認識和體會它的用法. 當然, 了解這些指令用法的前提是需要我們對作業系統内部構造有一個清晰的認識. 這需要不斷的學習, 對OS有一個全局的把握, 這樣才能更深入的了解它. 而通過Windbg的核心調試, 我們有一種更好的方式直接與Kernel打交道, 這對我們深入了解和認識作業系統有很大的幫助. 下一節我們将通過一個實際的調試driver的例子, 來進一步認識Windbg在核心調試中的作用.