windbg基本知識和常用命令

基本知識和常用命令

(1)    下載、安裝及設置   

   Windbg下載地址http://msdn.microsoft.com/en-us/windows/hardware/gg463009.aspx

通過命令設置:安裝完後執行windbg –IWindbg設置成默認調試器

手動設置註冊表:其設置在註冊表
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AeDebug
(注:64位windows的上的路徑不同,在HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows NT\CurrentVersion\AeDebug\Debugger  )
這裏面有2個主要的值:
Auto
 = 0 的時候,系統會彈出一個對話框,讓你在幾個調試器中選擇(如果你的系統安裝了多個調試器的話)
 = 1 的時候,系統會自動調用默認調試器
Debugger
  默認調試器的路徑。
  比如windows自帶的Dr.Watson : DRWTSN32 -p %ld -e %ld -g
  或者是WinDBG: windbg.exe" -p %ld -e %ld -g


(2)     命令分類  

    Windbg的命令分爲標準命令,元命令和擴展命令,輸入問號(?)可以顯示所有的標準命令的幫助信息元命令以一個點(.)開始,輸入.help可以顯示所有的元命令的幫助信息;擴展命令以歎號(!)開始。

 所有命令的具體用法可以通過F1查看Windbg的幫助文件。

 

(3)     符號文件設置  

    通過設置符號文件路徑,讓Windbg自動從微軟網站更新系統Dll的符號文件

SRV*d:\Winsymbols* http://msdl.microsoft.com/download/symbols

 

(4)       用分號(;)作爲分隔符,可以在一行輸入多條命令

 

(5)       按上下箭頭可以瀏覽和選擇以前輸入過的命令

 

(6)       Ctrl+Break終止一個很長時間沒有完成的命令, Ctrl+Break也可以讓正在運行的程序暫停

 

(7)       Windbg默認的數值進制一般是16 可以通過n命令查看和設置當前進制,所以我們一般在數值裏帶上進制, 0n(十進制) 0x(十六進制) 0t(8進制) 0y(2進制) 比如0n20表示20 0x14表示20

 

(8)       可以通過問號命令(?)顯示錶達式值,雙問號(??)顯示C++表達式值通過.cls命令清屏

 

(9)       如果x表示的一個地址, 則可以通過以下方法獲取x所指向的值

hi(x) 16 bits

low(x) 16 bits

by(x) 返回第一個byte

wo(x) 返回第一個word

dwo(x) 返回第一個dword

qwo(x) 返回第一個4 word(Quad-word)

poi(x) 返回第一個指針值

 

(10)   函數調用如果還沒開始,即一般函數入口代碼

push ebp

mov ebp, esp

還未執行,

 

[esp+4]表示第一參數值, [esp+8]表示第二參數,以此類推, [esp]表示的是返回地址

 

如果上面的入口代碼已經執行,則一般通過ebp來獲取函數參數和局部變量

[ebp+8]表示第一參數, [ebp+0xC]表示第二個參數, 以此類推,[ebp+4]表示返回地址 [ebp]表示上一堆棧楨的基地址。

[ebp-4]表示函數第一個局部變量

 

(11)   條件表達式

j<條件表達式>[Command1];[Command2]

例如bp consoletest!add "j(dwo(esp+4)==0n10) 'kv;.echo \"break\"';'g'" 表示條件斷點,如果consoletest!add的第一個參數是10 則打印堆棧,輸出”break”, 並暫停,否則繼續執行

 

也可用元命令代替

bp consoletest!add  ".if(dwo(esp+4)==0n10) {kv;.echo \"break\"} .else {g}"

 

(12)   上下文

上下文(Context)包括會話(Session)上下文, 進程上下文,寄存器上下文,局部變量上下文。

會話上下文和登陸用戶帳號有關。進程上下文和當前調試的默認進程有關, 寄存器上下文和當前默認線程有關。

局部變量上下文和當前的堆棧楨有關, 比如可以通過.frame [index] 切換當前堆棧楨,然後通過dv 顯示當前堆棧楨函數的局部變量(堆棧楨的index0開始,可以通過kn命令顯示堆棧楨索引)

 

(13)   保存dump文件

.dump /ma c:\test.dmp 保存full-dump

.dump /ma /o c:\test.dmp 保存full-dump如果存在test.dmp,將其覆蓋掉

.dump /m c:\test.dmp 保存mini-dump

 

(14)   分析Dump

一般先 !analyze –v Windbg會根據上面命令自動分析,然後 ~* kv 打印所有線程的堆棧

用~命令可以顯示線程信息和在不同的線程之間切換,例如:~0s就是切換到0號線程

用k命令可以顯示當前線程的call stack,k後面也可以跟很多後綴,比如kb kp,kn,kv等,這些後綴控制了顯示的格式和信息,可以結合~和k命令來顯示

所有線程的call stack,kb顯示3個參數,kp顯示所有參數,Kv用於顯示FPO和調用約定,kn顯示棧幀數量

vertarget顯示當前進程的大致信息

 

(15)   重新加載符號文件

.reload –f [name], 強制重新加載某個模塊的符號文件

比如 .reload –f  test.dll

 

(16)   察看模塊信息

lm顯示所有模塊信息

lmf 顯示所有模塊及其路徑
lmD 顯示所有模塊詳細信息

!lmi  [module name] 顯示某一模塊的詳細信息

 

(17)   分析調試符號

X [選項模塊名!符號名

       比如x ntdll!dbg*顯示所有ntdll模塊中以dbg開頭的符號

            比如x test!cmyclass::init 顯示test模塊中cmyclass類中的init函數符號

 

(18)   搜索符號

ln [address] 搜索離address最近的符號名(list nearest symbols

 

(19)   事件處理

可以通過菜單Debug->Event Filter…設置

sx 顯示各個事件的代碼和目前的處理選項

sx {e|d|i|n} [command]  , e|d|i|n分別對應Enabled, Disabled,OutputIgnore

比如 sxe ld user32.dll 表示在加載user32.dll時設置的中斷

sxr 恢復成默認設置

 

(20)   單步調試

    g 繼續運行(go) 熱鍵F5

    t 單步越過(step over), 熱鍵F10

    p 單步進入(step into), 熱鍵 F11

 

(21)   設置斷點(break point)

bp [address] [“command”] 設置軟件斷點。

比如 bp kernel32!CreateProcessW表示在調用這個CreateProcess時設置斷點。

比如bp kernel32!CreateFileW "du poi(esp+4); g" 表示在調用CreateFile時打印出文件路徑(第一個參數),然後繼續執行

 

針對某線程設置斷點,只要在命令前加~線程號:

比如 ~0 bp 0x441242, 表示0號線程執行到地址0x441242時中斷

 

ba [access size] [command]設置硬斷點。

其中,access指定訪問方式(e執行指令, r讀取數據,w寫入數據)

size 表示監視數據的大小(1, 2, 4)

比如ba r4 0x414422, 表示在地址0x414422寫入4字節數據是觸發斷點

 

(22)   管理斷點

bl 列出所有當前斷點的狀態

bc 清除斷點, bc * 清除所有斷點, bc 0 清除0號斷點

bd 禁用某個斷點(disable)

be 打開某個斷點(enable)

 

(23)   察看堆棧

kn [frame count]察看當前堆棧及其索引, frame count指定要顯示多少楨

kb顯示堆棧楨地址,返回地址,參數,函數名等

kvkb的基礎上增加了函數調用約定等信息, 所以推薦用kv命令察看堆棧.

 

.frame [frame index] 將當前堆棧切換到某個堆棧楨比如.frame 1 切換到第1

dv 命令察看當前堆棧楨的局部變量

 

(24)   察看和修改寄存器

r顯示所有寄存器的值

r  eax=0x100 eax寄存器的改成0x100

 

(25)   顯示內存區域(dump memory)

d{a|b|d|D|f|q|u|w} [range]

其中a表示ASCII碼,b表示byte, d表示DWORD, D表示double, f表示float, q表示8字節, u表示Unicode String w表示word

Range 表示地址範圍,可以用2種表示:一是起始地址加終止地址二是起始地址加L長度(不是字節長度,是單位長度)

比如 dw 77e0d827 L10 表示顯示77e0d827開始的10word

比如 dd 77e0d820 77e0d844, 表示顯示 77e0d820 77e0d844之間的所有dword

比如 du 77e0d820, 表示77e0d820開始的以0結尾的字符串

 

dps [range] 顯示某一地址範圍內的符號(display word and symobols)

 

(26)   顯示數據類型(dump symbolic type information)

dt [模塊名!]類型名

dt testApp!g_appInstance 表示顯示testApp裏全局變量g_appInstance的內存佈局

dt 0x0458e850 test!CMyApp 表示將地址0x0458e850test!CMyApp類地址解析,並打印內存佈局, 所以只有私有符號纔有這個功能

如果當前堆棧楨是在某個類函數內,可以通過dt this 打印當前類的內促佈局。

 

(27)   搜索內存(search memory)

s –[type] range pattern

其中type, b表示byte w表示word, d 表示dword, a表示ASCII stringu表示unicde string

Range 表示地址範圍,可以用2種表示:一是起始地址加終止地址二是起始地址加L長度(不是字節長度,是單位長度)。如果搜索空間長度超過256M,L?length

Pattern指定要搜索的內容.

比如 s -u 522e0000 527d1000 "web"表示在522e0000 527d1000之間搜索Unicode 字符串”web”

比如s -w 522e0000 L0x100  0x1212 0x2212 0x1234 表示在起始地址522e0000之後的0x100個單位內搜索0x1212 0x2212 0x1234系列的起始地址

 

(28)   修改內存 (edit memory)

e{a|u|za|zu} address “String”

            其總zazu表示以0結尾的AsciiUnicode字符串, au則表示沒有0結尾

比如 ezu 0x445634 “abc” 表示在0x445634地址寫如unicode 字符串abc

            比如ea 0x445634 “abc” 表示在0x445634地址寫入Ascii字符串abc, 不包含結束符0

 

e{a|b|d|D|f|q|u|w} address [values]

其中a表示ASCII碼,b表示byte, d表示DWORD, D表示double, f表示float, q表示8字節, u表示Unicode String w表示word

比如eb  0x123432 0x41 0x41 0x41 表示在地址0x123432 寫入30x41

 

(29)   觀察內存屬性

!address [address]

比如!address 0x414453, 顯示地址0x414453所在區域的內存屬性


!heap -h 顯示所有的內存堆(heap)

(30)   反彙編某一地址

u address, 比如u 0x410040表示反彙編地址0x410040的代碼

uf  反彙編某個函數, 比如uf test!main
ub 反彙編某地址之前的代碼,比如ub 0x 
0x410040 L20

 

(31)   進程線程控制

~*命令顯示當前所有線程的詳細信息

~[Index]   n增加索引爲Index的線程的掛起計數

~[Index]  m減少索引爲Index的線程的掛起計數

比如通過~2 n 增加2號線程的掛起計數後, 執行g命令(繼續運行) 這時2號線程會依然暫停運行。

 

~[Index]  f 凍結某一線程的執行

~[Index] u 解凍某一線程的執行

~[Index]  g只運行線程號爲index的線程

~[Index] s 切換當前線程

 

比如 ~2 kv; ~2 r 可以打印2號線程的當前堆棧和寄存器

~* kv可以打印所有線程堆棧。

 

!runaway 顯示所有線程的CPU消耗

 

|. 顯示當前調試進程

|* 顯示當前調試中的所有進程

|[nIndex] s 切換當前調試進程

 

!peb 顯示進程信息塊(process environment block)

!teb 顯示線程信息塊(thread environment block)


(32)   線程死鎖

!locks 顯示死鎖

!handle 列出當前進程所handle

!handle [index] f, 顯示某個handle的詳細信息

!cs是針對criticalsection死鎖的命令


(33)   將64位dump轉換成32位

      .load wow64exts 回車 
      !sw 回車

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