原文鏈接: WinDbg. From A to Z!
文章目錄
- 使用WinDbg
- 臨界區相關命令
- 示例 -- 查看臨界區
- 其他有用的命令
- WinDbg中的偽寄存器
- 自動偽寄存器
- WinDbg中的表達式
- 其他操作
- 默認的表達式計算方式
- WinDbg中的重命名
- 調試器命令語言編程
- 控制流
- 命令程序執行
- WinDbg 遠程調試
- 事件監控
- WinDbg 事件過濾器
- 事件過濾器對話框
- 事件參數
- 全局標志 (Global Flags)
- Flags? GFlags? Global Flags!
- Global Flags
- 應用程序驗證器
- 啟用應用程序驗證器
- 應用驗證器的實體
- 應用驗證器的調試符號
- `!avrf`的常用參數
- 示例 -- 使用 `!avrf`
- 進程轉儲 (Process Dumps)
- Dumps的類型
- 確定Dump文件的類型
- 示例 -- 使用`.dump`命令
使用WinDbg
臨界區相關命令
** !avrf
是Application Verifier 的內容
示例 – 查看臨界區
這里有一個簡單的死鎖例子
暫時跳過
其他有用的命令
命令 | 描述 |
---|---|
dt | 顯示某些數據的信息如,局部變量,函數參數,全局變量,數據類型 |
dt 模塊名!類或命名空間或函數 | 列舉模塊里的類型的定義 |
dt 模塊名!類::函數或變量 地址 | 顯示具體實例的值 |
dt ntdll!_PEB 7efde000 | 顯示7efde000處_PEB實例的信息 |
dv | 顯示局部變量 |
dv /i /t /V | /i 指區分是參數還是變量, /t 顯示類型信息 , /V 顯示詳細信息 |
WinDbg中的偽寄存器
- 用在調試器里面的虛擬寄存器,像變量一樣
- 以
$
符號開頭
-
自動偽寄存器(內置的偽寄存器)
- 調試器本身設置的
- 如: $ra , $peb , $teb
-
自定義偽寄存器
- 有20個預設的自定義寄存器:
$0
~~$19
- 可用于存儲中間數據的整數變量
- 可以額外保存類型信息
- r 命令用來賦值
- ?? 命令用來輸出
- 有20個預設的自定義寄存器:
自動偽寄存器
命令 | 描述 |
---|---|
$ra | 當前的堆棧地址 |
$ip | 指令指針 |
$exentry | 進程入口 |
$retreg | 返回值寄存器 |
$csp | 調用棧地址 |
$peb | PEB |
$teb | TEB |
$tpid | 進程ID |
$tid | 線程ID |
$ptrsize | 指針大小 |
$pagesize | 分頁大小 |
WinDbg中的表達式
-
宏匯編(MASM) 表達式
- 使用
?
來計算 - 每個符號都被視為一個地址
- 可以使用源碼行表達式, 如
myfile.c:43
- 寄存器的
@
符號不是必須要寫的 - 數值默認是16進制的,
0n
是10進制,0t
8進制,0y
2進制
- 使用
-
C++ 表達式
- 使用
??
來計算 - 符號被理解為某個類的對象
- 不能使用源碼行表達式
- 寄存器前必須有
@
符號 - 數值默認是10進制的, 16進制以
0x
開頭
- 使用
其他操作
默認的表達式計算方式
WinDbg中的重命名
例子:
調試器命令語言編程
- 兩大部分
- 調試器命令
- 控制流,如(.if, .for, .while )
- 變量
- 重命名當作局部變量
- 偽寄存器作變量
$$
作為行注釋開頭- 一對大括號是一個作用空間
控制流
- 用來循環和條件分支
命令程序執行
- 方法一: 將所有語句當作單個字符串輸入到命令窗口
- 方法二: 編譯到文件中,使用命令
$$><
來執行文件
WinDbg 遠程調試
事件監控
- 調試器引擎提供了用于監視與響應目標應用程序事件的工具
- 事件分為兩類:
- 異常事件
- 斷點、訪問違規、堆棧溢出、除零等。
- 非異常事件
- Create Process, Create Thread, Load Module, Unload Module.
- 異常事件
- 調試器會話可訪問時,會有一個lastevent
- 命令:
.lastevent
- 命令:
WinDbg 事件過濾器
-
提供了簡單的事件過濾
-
目標應用的事件發生后的響應
-
使用
sx
命令來列舉所有事件 -
中斷或執行狀態:
- 可能會中斷目標
- sxe : first-chance break (原文里這個不太明白) , 啟用 enable
- sxd: second-chance break , 不啟用 disenable
- sxn:事件發生后輸出日志 , note
- sxi:忽略事件, ignore
- 可能會中斷目標
-
處理或繼續狀態:
- 確定在目標中是否應將異常事件視為已處理(gH)或未處理(gN)
事件過濾器對話框
事件參數
- 一些過濾器采用參數來限制它們要處理的事件
- 無參數就是無限制
全局標志 (Global Flags)
Flags? GFlags? Global Flags!
- GFlags通過編輯Windows注冊表來啟用和禁用功能
- GFlags設置系統或映象
- 映象的設置在
HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\ImageFileName\GlobalFlag
- 操作系統讀取這些設置并相應地采用其功能
- GFlags可以從命令行或使用對話框運行
- 可以在WinDbg 中使用
!gflags
命令來操作Global Flags - 用GFlags可以實現:
- 堆檢查
- 堆標記
- Loader snaps
- 調試映象
- 應用驗證
- 等等等等
Global Flags
安裝了Windows SDK的話會在這里找到Global Flags
應用程序驗證器
啟用應用程序驗證器
- 應用驗證
- 是Windows應用程序的運行時驗證工具
- 正在監視應用程序與操作系統的交互
- 概覽與軌跡跟蹤:
- 內核對象
- 寄存器
- 文件
- 異常
- Win32 API
- 使用
!avrf
來得到跟蹤信息
應用驗證器的實體
-
GFlags Application Verifier
- 只有verifier.dll被注入到目標進程中
- verifier.dll隨被Windows預裝
- 提供了少量選項子集
-
Application Verifier
- 從微軟官網免費下載
- 另外安裝vrfcore.dll、vfbasics.dll、vfcompat.dll等進入Windows\System32
- 功能強大
應用驗證器的調試符號
- 應用程序驗證器與PDB一起安裝,具有完整的符號信息
- 在disassembly窗口里標記源碼信息
- 這些是我見過的唯一一個帶有完整符號的微軟模塊信息
- 事實上,WinDbg必須使用這些符號,而不是服務器上的公共符號。否則
!avrf
擴展無法工作
.reload /f @"C:\Windows\System32\verifier.pdb
!avrf
的常用參數
示例 – 使用 !avrf
如果已經安裝了Windows SDK,那么可以在系統中找到Application Verifier
,打開Application Verifier,添加應用,在右邊的Tests框中選擇需要測試的項目。
點擊Save后,重啟應用,完事之后用WinDbg來調試目標應用。
在Modules 里面Reload Application Verifier
這樣就會執行.reload /f @"C:\WINDOWS\SysWOW64\verifier.dll"
先看一下Heap相關的操作日志
查看線程
進程轉儲 (Process Dumps)
- 進程轉儲文件
- 與非侵入性附著非常相似
- 表示給定時間進程的快照
- 大小不同,取決于它包含的內容和信息
- 利用轉儲文件
- 我們可以檢查內存以及進程的其他內部結構
- 我們無法設置斷點或逐步執行程序
- Dump 一個轉儲文件
- 我們總是可以將包含更多信息的轉儲“縮小”為包含更少信息的轉儲
- 像處理實時進程一樣使用.dump命令
Dumps的類型
-
Kernel-mode Dumps
變體:完整內存轉儲、內核內存轉儲、小內存轉儲 -
Full User-mode Dumps
- WinDbg中用
.dump /f
生成 - 包括進程的整個內存空間、程序的可執行映像本身、句柄表
- 過去被廣泛使用的微軟正在慢慢放棄對它的支持
- WinDbg中用
-
Minidumps
.dump /m??
- 現代化dumps格式
- 對轉儲中包含的內容進行細粒度控制(請參閱MSDN:MINIDUMP_TYPE)
- 盡管有它們的名字有迷你的字眼,但最大的迷你轉儲文件實際上包含的信息比完整的用戶模式轉儲更多。如
.dump /mf
或.dump /ma
得到的文件比.dump /f
得到的更大更完整。
確定Dump文件的類型
用WinDbg 加載Dump文件,加載成功后會輸出dump文件的類型