核心對話
Windows啟動核心調試後,主要做了以下幾個工作
1. 建立串連
2. 調試器讀取目標系統資訊,初始化偵錯引擎(目標機)。
3. 核心偵錯引擎通過狀態變化資訊包通知調試器載入初始模組的偵錯符號(目標機)。
4. 調試器端發送中斷包,將目標系統中斷到調試器,互動調試後又恢複執行的過程。
5. 因斷點命中,目標系統中斷到調試器的過程。
6. 核心中的模組輸出調試字串(DbgPrint)到調試器
《軟體調試》(490-491)總結的表如下:
核心偵錯引擎
核心偵錯引擎相當於再目標系統中進行調試的一個代理,偵錯引擎代表調試器來訪問和控制目標系統。
核心調試的幾個關鍵函數:
KdEnterDbugger
它用於凍結核心,調用後首先會禁止中斷,對於多處理器的系統,它會將當前CPU的IRQL升高到HIGH_LEVEL並凍結所有的其他的CPU。鎖定調試調試通訊連接埠,調用KdSave讓通訊擴充模組儲存通訊狀態,並將全域變數KdEnteredDebugger設定為真。當KdEnterDebugger執行後,整個系統進入一種簡單的單任務狀態,當前的CPU只執行當前的線程,其他CPU處於凍結狀態。
KdExitDebugger 恢複核心運行,主要工作有調用KdRestore讓通訊擴充模組恢複通訊狀態,對鎖定的通訊連接埠解鎖。調用KeThawExecution來恢複系統進入正常的運行狀態,包括恢複中斷,降低當前CPU的IRQL,對多CPU系統,恢複其他CPU。
KdpReportExceptionStateChange CPU報告異常類狀態變化
KdpReportLoadSymbolsStateChange CPU報告符號載入類異常
KdpSendWaitContinue 函數用來發送資訊包,與調試器對話。
KeUpdateSystemTime函數在每次更新系統時間時會檢查全域變數KdDebuggerEnable來判斷核心偵錯引擎是否被啟動,如果為真則調用KdPollBreakIn函數來查看調試器是否發送了終端命令,如果是,則調用DbgBreakPointWithStatus觸發斷點異常,中斷到調試器。
kdpTrap來處理核心態的異常。當核心態中發生異常時,KiDispatchException函數會調用全域變數KiDebugRoutine所指向的函數。當偵錯引擎啟用時,這個變數的值是函數KdpTrap的地址。所以一旦異常發生時,系統就會調用KdpTrap。KdpTrap調用KdpReport向調試器報告異常。
KiSaveProcessorControlState儲存CPU的控制狀態
KiRestoreProcessorControlState恢複CPU狀態
DbgPrint,DbgPrintEx,vDbbgPirntEx列印調試資訊
下面簡單介紹一下本地核心調試:
除了可以進行兩個系統間的核心調試外(包括虛擬機器),還可以在本地進行核心調試,但建議在本地進行核心調試時盡量做一些觀察變數或檢查符號之類的簡單任務。
除了windbg外還有一個小軟體LiveKD可以用於本地核心調試,它可以在保持系統工作的情況下產生一個轉儲檔案,然後利用Windbg進行分析。
WinDbg的本地核心調試主要是通過未公開的核心服務zwSystemDebugControl來提供的,zwSystemDebugControl為WinDBG提供了一種在本地訪問核心調試API的功能。