windbg 常用除錯命令總結

lostin9772發表於2024-08-13

windbg 是 Microsoft 公司免費偵錯程式除錯集合中的 GUI 的偵錯程式,支援 Source 和 Assembly 兩種模式的除錯。Windbg 不僅可以除錯應用程式,還可以進行 Kernel Debug。結合 Microsoft 的 Symbol Server,可以獲取系統符號檔案,便於應用程式和核心的除錯。Windbg 支援的平臺包括 X86、IA64、AMD64。

那麼在我們使用 windbg 的時候,雖然命令紛繁複雜,但是有一些常用的命令是我們需要掌握的,熟練的運用這些命令能給我們除錯帶來事半功倍的效果,因此我對常用命令進行了一個總結,方便查詢。

至於其他更為複雜命令使用,我們可以透過檢視官方提供的 windbg 命令手冊:
https://learn.microsoft.com/zh-cn/windows-hardware/drivers/debuggercmds/commands

1.流程控制相關命令

g       // Go 讓程式跑起來
p       // 單步步進(F10)
p 2     // 單步步進2次
pa 0x7c801b0b   // 單步布進執行到 7c801b0b 地址處停下
pc      // 單步步進執行到下一個函式呼叫處停下

q       // 結束除錯會話

2.記憶體讀寫相關命令

db      // 按位元組顯示(1位元組)
dw      // 按單字顯示(2位元組)
dd      // 按雙字顯示(4位元組)
dq      // 按四字顯示(8位元組)
da      // 按 ASCll 字元顯示(1位元組)
du      // 按 UNICODE 位元組顯示(2位元組)
df      // 按單精度浮點數顯示(4位元組)
dD      // 按雙精度浮點數顯示(8位元組)

eb      // 按位元組寫入(1位元組)
ew      // 按單字寫入(2位元組)
ed      // 按雙字寫入(4位元組)
eq      // 按四字寫入(8位元組)
ea      // 按 ASCll 字元寫入(1位元組,不會自動在結尾填充 '\0' 字元)
eu      // 按 UNICODE 字元寫入(2位元組,不會自動在結尾填充 '\0' 字元)
ef      // 按單精度浮點數寫入(4位元組)
eD      // 按雙精度浮點數寫入(8位元組)
eza     // 按 ASCll 字元寫入(1位元組,會自動在結尾填充 '\0' 字元)
ezu     // 按 UNICODE 字元寫入(2位元組,會自動在結尾填充 '\0' 字元)

!db     // 將實體地址按位元組顯示(1位元組),其他記憶體操作命令同理

dt _eprocess        // 檢視 EPROCESS 結構體成員
dt _eprocess 0x510  // 從地址 0x510 處按照結構體 EPROCESS 對資料進行解析
dt ntdll!*          // 顯示ntdll裡的所有型別資訊
dt ntdll!_peb*      // *是萬用字元;顯示 ntdll 模組中所有peb打頭的結構體名稱;

r               // 顯示所有暫存器資訊及發生 core 所在的指令
r eax, gdtr     // 顯示eax,gdtr暫存器資訊
r eax=5, edx=6  // 對暫存器eax賦值為5,edx賦值為6

3.記憶體搜尋相關命令

可以指定的查詢模式有:
-b    // 位元組(8位)
-w    // WORD(16位)
-d    // DWORD(32位)
-q    // QWORD(64位)

s -b fffff801`87b58a70 L100 cc c2    // 從地址處往後100個位元組裡查詢位元組序列為 cc c2 的地址
s -b fffff801`87b58a70 L-100 cc c2   // 從地址處往前查詢
s -b fffff801`87b58a70 L100 'k' 'k'  // 查詢位元組序列的 ascall 碼為 k k 的地址

s -d fffff801`87b58a70 L100 'H'      // 按照雙字查詢 ascall 碼為 H 的地址,結果如下:
(fffff801`87b58a70 00000048 00000000 500c0163 00000000 H.......c..P....)

s -a fffff801`87b58a70 L100 "ntdll"  // 查詢 ascall 字串為 "ntdll" 的地址,結果如下:
(fffff801`87b58a70 6e 74 64 6c 6c 5c 6c 64-72 69 6e 69 74 2e 63 00 ntdll\ldrinit.c.)

4.斷點相關命令

bp main        // 在main函式開頭設定一個斷點
bp 0x7c801b00  // 在7c801b00地址處放置一個斷點
bu 0x7c801b00  // 未解析的斷點
ba i4 3f8      //處理器斷點(硬體斷點,訪問該地址資料時斷下,該命令在所有串列埠上新增一個斷點,其中包含從 0x3F8 到 0x3FB 的地址)
bl            // 列出所有斷點
bc *          // 清除所有斷點
be *          // 啟用所有斷點
bd *          // 禁用所有斷點
bc 1 2 5      // 清除1號、2號、5號斷點,其他命令同理

5.反彙編相關命令

u                      // 反彙編當前 eip 暫存器地址的後8條指令
u main.exe+0x10 L20    // 反彙編 main.exe+0x10 地址後20條指令
ub 000c135d L20        // 檢視地址為000c135d指令前的20條指令內容
uf NtOpenProcess       // 反彙編 NtOpenProcess 函式
uf demo::add           // 反彙編demo類的add函式

6.堆疊相關命令

k       // 顯示當前呼叫堆疊
kn      // 帶棧編號顯示當前呼叫堆疊
kb      // 列印出前3個函式引數的當前呼叫堆疊
kb 5    // 只顯示最上的5層呼叫堆疊
kv      // 在kb的基礎上增加了函式呼叫約定、FPO等資訊
kp      // 顯示每一層函式呼叫的完整引數,包括引數型別、名字、取值
kd      // 列印堆疊的地址

.frame         // 顯示當前棧幀
.frame n       // 顯示編號為n的棧幀(n為16進位制數)
.frame /r n    // 顯示編號n的棧幀(n為16進位制數) 並顯示暫存器變數
.frame /c n    // 設定編號n的棧幀為當前棧幀(n為16進位制數)

7.程序相關命令

!process -1 1                    // 檢視當前程序資訊
!process 0n<程序PID> 0(e.g. !process 0n4 0)         // 獲取 PID 為 4 的程序資訊
!process 0 0 <程序名>(e.g. !process 0 0 x64.exe)    // 獲取程序名為 x64 的程序資訊
.process /p /i <程序eprocess>    // 切換到目標程序的上下文

8.模組相關命令

lm            // 列出所有模組對應的符號資訊
ld *          // 為所有模組載入符號
ld kernel32   // 載入 kernel32.dll 的符號

9.符號相關命令

.sympath              // 檢視當前符號查詢路徑
.sympath c:\symbols   // 將符號查詢路徑設為:c:\symbols
.sympath+ c:\symbols  // 將c:\symbols新增到符號查詢路徑集合中

.reload               // 為所有已載入模組載入符號資訊
.reload /f /v         // f:強制立即模式(不允許延遲載入)  v:詳細模式
.reload /f @"c:\windows\System32\verifier.dll"   // 為指定模組載入符號資訊

10.其他常用命令

ed kd_default_mask 0xffffffff    // 設定在 windbg 上輸出除錯資訊

相關文章