Windbg.exe是Windows的一個調試工具,它支持兩種調試模式,即“實時調試模式(Living)”和“事后調試模式(Postmortem)”。
- 實時模式:被調試的程序正在運行當中,調試器可以實時分析、修改被調試目標的狀態,如寄存器、內存、變量,調試exe可執行程序或雙擊雙機實時調試都屬於這種模式;
- 事后模式:被調試的程序已經執行結束,現在只是事后對它保留的快照進行分析,快照就是轉儲文件(Dump文件)。
Windbg的一個非常強大的功能是支持源碼級的調試,就像VS自帶的調試器一樣。
雖然Windbg提供了用戶界面,但Windbg還是要以輸入命令行的方式來操作。這些命令行通過Command窗口執行。
每個調試命令都各有使用范圍,有些命令只能用於內核調試,有些命令只能用於用戶調試,有些命令只能用於實時調試。這些不必記住,一旦在某個環境下,使用了不被支持的命令,都會顯示“No export XXX found”的字樣。
一、基本命令
Windbg中的調試命令分為三種:
- 基本命令;
- 元命令;
- 擴展命令;
基本命令和元命令是調試器自帶的,元命令總是以"."開頭,而擴展命令是外部加入的,總是以感嘆號"!"開頭。各種調試命令成千上萬,我們要向辦法把他們都列舉出來,並取得使用方法。
1、基本命令
基本命令最少了,大概40個左右。列舉所有的基本命令,使用"?"。
?
2、元命令
元命令有一百多個,使用下面命令列舉所有元命令。
.help [/D]
如使用“/D”參數,命令列表將以DML格式顯示。DML是一種類似於HTML的標識語言,下面會講到。下圖以DML格式顯示所以有字母a開頭的元命令:
0:009> .help /D a* A B C D E F G H I J K L M N O P Q R S T U V W X Y Z All
. commands matching a*:
.abandon - abandon the current process
.allow_exec_cmds [0|1] - control execution commands
.allow_image_mapping [0|1] - control on-demand image file mapping
.apply_dbp [<options>] - add current data breakpoint state to a
register context
.asm [<options>] - set disassembly options
.asm- [<options>] - clear disassembly options
.attach <proc> - attach to <proc> at next execution
Use ".hh <command>" or open debugger.chm in the debuggers directory to get
detailed documentation on a command.
3、擴展命令
顧名思義是可以“擴展”的。擴展命令從動態連接庫中暴露出來,一般以DLL文件名來代表一類擴展命令集。
首先我們要搜索出系統中有多少個這樣的DLL文件,使用下面命令:
.chain [/D]
此命令能夠給出一個擴展命令集的鏈表。如:
0:009> .chain
Extension DLL search Path:
C:\Program Files\Debugging Tools for Windows (x86)\WINXP;C:\Program Files\Debugging Tools for Windows (x86)\winext;C:\Program Files\Debugging Tools for Windows (x86)\winext\arcade;C:\Program Files\Debugging Tools for Windows (x86)\pri;C:\Program Files\Debugging Tools for Windows (x86);C:\Program Files\Debugging Tools for Windows (x86)\winext\arcade;%JAVA_HOME%/bin;c:\oracle\product\10.2.0\client_1\bin;C:\Program Files\Intel\iCLS Client\;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Program Files\Intel\Intel(R) Management Engine Components\DAL;C:\Program Files\Intel\Intel(R) Management Engine Components\IPT;C:\Program Files\Intel\OpenCL SDK\2.0\bin\x86;C:\Program Files\TortoiseSVN\bin;C:\Program Files\VisualSVN\bin;C:\Program Files\Microsoft SQL Server\100\Tools\Binn\;C:\Program Files\Microsoft SQL Server\100\DTS\Binn\;C:\Program Files\Microsoft ASP.NET\ASP.NET Web Pages\v1.0\;C:\strawberry\c\bin;C:\strawberry\perl\bin;C:\Program Files\Microsoft SQL Server\100\Tools\Binn\VSShell\Common7\IDE\;C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\PrivateAssemblies\;C:\Program Files\Microsoft Windows Performance Toolkit\;C:\Program Files\Windows Kits\8.1\Windows Performance Toolkit\;C:\Program Files\Microsoft SQL Server\110\Tools\Binn\
Extension DLL chain:
C:\Program Files\Debugging Tools for Windows (x86)\clr20\sos.dll: image 2.0.50727.5420, API 1.0.0, built Wed Sep 29 12:03:13 2010
[path: C:\Program Files\Debugging Tools for Windows (x86)\clr20\sos.dll]
dbghelp: image 6.12.0002.633, API 6.1.6, built Tue Feb 02 04:08:26 2010
[path: C:\Program Files\Debugging Tools for Windows (x86)\dbghelp.dll]
ext: image 6.12.0002.633, API 1.0.0, built Tue Feb 02 04:08:31 2010
[path: C:\Program Files\Debugging Tools for Windows (x86)\winext\ext.dll]
exts: image 6.12.0002.633, API 1.0.0, built Tue Feb 02 04:08:24 2010
[path: C:\Program Files\Debugging Tools for Windows (x86)\WINXP\exts.dll]
uext: image 6.12.0002.633, API 1.0.0, built Tue Feb 02 04:08:23 2010
[path: C:\Program Files\Debugging Tools for Windows (x86)\winext\uext.dll]
ntsdexts: image 6.1.7650.0, API 1.0.0, built Tue Feb 02 04:08:08 2010
[path: C:\Program Files\Debugging Tools for Windows (x86)\WINXP\ntsdexts.dll]
絕大部分擴展模塊通過使用如下命令就能夠列出擴展庫中所包含的的所有命令
!模塊名.help
如:
0:009> !ext.help
diskspace <DriveLetter>[:] - Displays free disk space for specified volume
address [address] - Displays the address space layout
[-UsageType] - Displays the address space regions of the given type
analyze [-v] - Analyzes current exception or bugcheck
cpuid [processor] - Displays CPU version info for all CPUs
elog_str <message> - Logs simple message to host event log
cppexr <exraddress> - Displays a C++ EXCEPTION_RECORD
error [errorcode] - Displays Win32 & NTSTATUS error string
exchain - Displays exception chain for current thread
for_each_frame <cmd> - Executes command for each frame in current
thread
for_each_local <cmd> $$<n> - Executes command for each local variable in
current frame, substituting fixed-name alias
$u<n> for each occurrence of $$<n>
gle [-all] - Displays last error & status for current thread
imggp <imagebase> - Displays GP directory entry for 64-bit image
imgreloc <imagebase> - Relocates modules for an image
list [-? | parameters] - Displays lists
obja <address> - Displays OBJECT_ATTRIBUTES[32|64]
owner [symbol!module] - Detects owner for current exception or
bugcheck from triage.ini
rtlavl <address> - Displays RTL_AVL_TABLE
std_map <address> - Displays a std::map<>
str <address> - Displays ANSI_STRING or OEM_STRING
ustr <address> - Displays UNICODE_STRING
此外,擴展命令模塊是可“擴展”的。如果自己編寫了一個擴展調試模塊,則可通過.load/.unload命令動態加載/卸載。
二、DML語言
DML(Debugger Markup Language調試器標記語言)像HTML一樣,可從一處鏈接到另一處。不同處在於,DML的鏈接內容需要用戶點擊后才會動態生成。通常用來以精簡方式顯示大量信息和擴展功能。
DML鏈接像HTML的<a>標簽一樣,引導用戶查看調試信息,使得調試工具的使用相比純指令格式而言,更為友好。DML如同是對原指令的一層輕微的包裝一樣,讓生硬的指令更加溫和了。
.prefer_dml 1 //開啟DML .prefer_dml 0 //關閉DML
一旦開啟DML后,像k等支持DML的調試命令,將默認以DML格式顯示輸出內容。
DML還能以一種很特殊的方式為函數畫流程圖。它主要的原理是使用反匯編,類似於uf,但在邏輯分支處,它會停止反匯編並顯示分支讓用戶選擇。另外,它能顯示匯編代碼對應的行號,這一點真的非常好。如果稍加精進,他就能畫出非常漂亮的流程圖了。他的一個特點是反匯編的順序是從后往前推。只要細想一想,就會覺得很有道理。如果正推的話,分支太多;而反推則分支順序在用戶的參與下(即用戶進行分支選擇),是固定了的。
三、基本信息
下面開始了解一下調試器軟件本身相關的命令,比如:查看軟件版本、啟動參數,以及最基本的軟件設置命令。
- version 查看版本命令
下面以w3wp.exe為例,看看輸出什么信息
0:028> version Windows 7 Version 7601 (Service Pack 1) MP (4 procs) Free x86 compatible Product: WinNt, suite: SingleUserTS kernel32.dll version: 6.1.7601.17932 (win7sp1_gdr.120820-0419) Machine Name: Debug session time: Wed May 14 17:22:47.691 2014 (UTC + 8:00) System Uptime: 0 days 8:44:39.675 Process Uptime: 0 days 0:00:33.999 Kernel time: 0 days 0:00:00.561 User time: 0 days 0:00:03.276 Live user mode: <Local> Microsoft (R) Windows Debugger Version 6.12.0002.633 X86 Copyright (c) Microsoft Corporation. All rights reserved.
除了Windbg版本信息,上面的輸出中還包括目標系統信息。如果純粹是為了查看目標系統的版本信息,可使用下面的vertarget命令。
- vertarget 只查看目標系統版本信息
以w3wp.exe為例。
0:028> vertarget
Windows 7 Version 7601 (Service Pack 1) MP (4 procs) Free x86 compatible
Product: WinNt, suite: SingleUserTS
kernel32.dll version: 6.1.7601.17932 (win7sp1_gdr.120820-0419)
Machine Name:
Debug session time: Wed May 14 17:26:03.402 2014 (UTC + 8:00)
System Uptime: 0 days 8:47:55.386
Process Uptime: 0 days 0:03:49.711
Kernel time: 0 days 0:00:00.561
User time: 0 days 0:00:03.276
如果Windbg中同時打開多個調試對象,“||”命令將列出對象列表。
- ||
||0:0:000> ||
. 0 Full memory user mini dump: C:\Users\ChenZhuo\Desktop\chrome.DMP
1 Full memory user mini dump: C:\Users\ChenZhuo\Desktop\notepad.DMP
顯示所有windbg中打開的調試對象。
調試器需要在多個調試目標之間進行切換的話,使用“s”參數。如要切換到0號目標可使用下面的命令:
- || 0 s
如果要查看目標系統時間,可使用如下命令。
- .time
0:000> .time
Debug session time: Thu May 15 08:53:59.000 2014 (UTC + 8:00)
System Uptime: 0 days 0:19:20.909
Process Uptime: 0 days 0:08:04.000
Kernel time: 0 days 0:00:01.000
User time: 0 days 0:00:12.000
包括目標系統當前時間,以及系統正常運行持續時間;用戶模式下還會顯示當前進程的持續時間。
四、基本設置
1、清屏命令
- .cls
當命令窗口太多不需要的內容時,可以執行此命令全部清除。
2、設置進制命令
- n[8|10|16]
軟件默認是16進制,但有時候我們也需要把默認進制改成八進制或十進制。下面給出在8進制下求16的值的示例
0:000> n 8
base is 8
0:000> ? 16
Evaluate expression: 14 = 0000000e
3、處理器模式指令
- .effmach []
命令.effmach表示Effective Machine Type,即有效的機器類型。
0:000> .effmach x86
Effective machine: x86 compatible (x86)
示例中將當前的處理器模式設置為X86模式。
五、格式化顯示
將一個整數以各種格式顯示,包括16進制、10進制、8進制、二進制、字符串、日期、浮點數。使用如下命令:
- .formats 整數
下面以0xa為例:
0:000> .formats 0xa
Evaluate expression:
Hex: 0000000a
Decimal: 10
Octal: 00000000012
Binary: 00000000 00000000 00000000 00001010
Chars: ....
Time: Thu Jan 01 08:00:10 1970
Float: low 1.4013e-044 high 0
Double: 4.94066e-323
六、開始調試
1、掛載進程
- .attach PID
讓調試器負載到一個已運行的進程中去,使用該命令。如果某軟件在運行過程中崩潰,打開Windbg后如何調試呢?第一步就是把Windbg附載到發生崩潰的IE進程上。
或者通過Windbg的啟動參數進行掛載:
- Windbg –p PID
上面兩種方式都需要用PID指定進程ID,如果覺得指定PID不方便,也可以通過進程名進行掛載。
- Windbg -pn 進程名
掛載記事本可以示例如下:
- windbg -pn notepad.exe
上面的命令是把調試器掛載到已經存在的進程上,另外調試器可以創建新進程並對它進行調試,這二者使用了不同的侵入方法。使用下面的命令:
- .create 程序啟動命令行
或者Windbg啟動參數
- Windbg 程序啟動命令行
如果要創建並調試一個記事本子進程,可以使用.create notepad或者windbg notepad命令。也可以打開Windbg后,在File菜單中選擇"Open Executable..."啟動Notepad子進程,但這個選項只能被執行一次(之后會變灰,不能再點擊)。
而使用命令可將調試器連續附載到多個進程,也就是說,能夠同時調試多個進程。
多個進程的切換,就是通過前面的 "| 0 s" 命令切換。注意,多個用戶進程調試目標都處於同一個調試會話中,使用"||"命令會看到,它們屬於同一個"live user mode"調試會話。
下面看dump文件調試,使用命令:
- .opendump 文件名
此命令打開一個dump文件,並建立一個dump調試會話。在調試過程中,遇到無法解決的問題,希望獲得其他人的幫助,則把當前調試環境保存到Dump文件中發送給其他人就可以了。使用此方式可以打開多個dump文件。
0:000> .opendump C:\Users\ChenZhuo\Desktop\notepad.DMP Loading Dump File [C:\Users\ChenZhuo\Desktop\notepad.DMP] User Mini Dump File with Full Memory: Only application data is available Opened 'C:\Users\ChenZhuo\Desktop\notepad.DMP'
- .dump 文件名
dump文件一般以.dmp為后綴,系統生成的dump文件都默認以.dmp為后綴的,但使用.dump命令時,使用者可以設置任意后綴,甚至無后綴。下例中,首先為當前進程生成一個dump文件保存到a.txt中,然后將之打開並分析。
2、解掛進程
上文講到進程掛載命令,當需要解除掛載時,可使用解掛命令,如下:
- .detach
此命令結束當前調試會話,Windbg解除和被調試進程之間的調試關系(不管是通過掛載,還是通過創建方式建立的調試關系),解掛后,被調試進程能夠獨立運行;如果當前的調試會話是一個Dump文件,此命令直接結束對dump文件的調試,即結束調試會話。
如果需要徹底結束調試,下面的命令更有用:
- q|qq|qd
q是Quit的縮寫。結束當前調試會話,並返回到最簡單的工作空間,甚至把命令行界面也關閉掉。q和qq兩個命令將關閉被調試的進程,qd不會關閉調試進程,而是進行解掛操作。
雙機調試的時候,如果目標機動都動不了,此時通過主機讓目標機強制宕機或重啟,不失為一個好主意。
- .crash
- .reboot
crash命令能引發一個系統藍屏,並生成dump文件;而.reboot使系統重啟,不產生dump文件。
一、二、三、四篇都來自於:http://www.yiiyee.cn/Blog/windbg/