1. 概述
用户成功安装微软Windows调试工具集后,能够在安装目录下发现四个调试器程序,分别是:cdb.exe、ntsd.exe、kd.exe和Windbg.exe。其中cdb.exe和ntsd.exe只能调试用户程序,Kd.exe主要用于内核调试,有时候也用于用户态调试,上述三者的一个共同特点是,都只有控制台界面,以命令行形式工作。
Windbg.exe在用户态、内核态下都能够发挥调试功能,尤其重要的是,它不再是命令行格式而是采用了可视化的用户界面。所以绝大部分情况下,我们在谈及Windows调试工具的时候,都直接指向Windbg,而不大谈及前三者。
Windbg在用户态和内核态下,都支持两种调试模式,即“实时调试模式(Living)”和“事后调试模式(Postmortem)”。所谓实时模式,是被调试的目标对象(Target)当前正在运行当中,调试器可以实时分析、修改被调试目标的状态,如寄存器、内存、变量,调试exe可执行程序或双击实时调试都属于这种模式;所谓事后模式,是被调试的目标对象(Target)已经结束了,现在只是事后对它保留的快照进行分析,这个快照称为转储文件(Dump文件)。
Windbg另一个重大优点,还在于它支持源码级的调试,就像VC自带的调试器一样。
虽然提供了用户界面,但Windbg归根结底还是需要用户一个个地输入命令来指挥其行动。这就是他的Command窗口。
每个调试命令都各有使用范围,有些命令只能用于内核调试,有些命令只能用于用户调试,有些命令只能用于活动调试。但用户也不必记得这许多,一旦在某个环境下,使用了不被支持的命令,都会显示“No export XXX found”的字样。就拿!process命令来说吧,它显示进程信息,但只能用于内核调试中,如果在用户调试中使用,就是下面的情景:
0:001> !process
No export process found
1.1 寻求帮助
我们首先来看如何在使用过程中获取有用的帮助。Windbg中的调试命令,分为三种:基本命令,元命令和扩展命令。基本命令和元命令是调试器自带的,元命令总是以“.”开头,而扩展命令是外部加入的,总是以感叹号“!”开头。各种调试命令成千上万,我们首先要想办法把它们都列举出来,并取得使用方法。
基本命令最少了,大概40个左右。列举所有的基本命令,使用如下命令:
- ?
元命令有一百多个,使用下面命令列举所有元命令:
- .help [/D]
如使用“/D”参数,命令列表将以DML格式显示。DML是一种类似于HTML的标识语言,下面会讲到。下图以DML格式显示所以有字母a开头的元命令:
最后讲扩展命令。所谓扩展命令,顾名思义是可以“扩展”的。扩展命令从动态连接库中暴露出来,一般以DLL文件名来代表一类扩展命令集,首先我们要搜索出系统中有多少个这样的DLL文件,使用下面命令:
- .chain [/D]
此命令能够给出一个扩展命令集的链表。和.help命令一样,也可以使用/D参数以DML格式显示。如下所示:
0:001> .chain
Extension DLL search Path:
C:\Program Files (x86)\Windows Kits\8.0\Debuggers\x64\WINXP;
Extension DLL chain:
dbghelp: image 6.2.9200.20512, API 6.2.6, built Fri Sep 07 13:45:49 2012
[path: C:\Program Files (x86)\Windows Kits\8.0\Debuggers\x64\dbghelp.dll]
ext: image 6.2.9200.16384, API 1.0.0, built Thu Jul 26 10:11:33 2012
[path: C:\Program Files (x86)\Windows Kits\8.0\Debuggers\x64\winext\ext.dll]
exts: image 6.2.9200.16384, API 1.0.0, built Thu Jul 26 10:15:20 2012
[path: C:\Program Files (x86)\Windows Kits\8.0\Debuggers\x64\WINXP\exts.dll]
uext: image 6.2.9200.16384, API 1.0.0, built Thu Jul 26 10:15:09 2012
[path: C:\Program Files (x86)\Windows Kits\8.0\Debuggers\x64\winext\uext.dll]
ntsdexts: image 6.2.9200.16384, API 1.0.0, built Thu Jul 26 10:16:01 2012
[path: C:\Program Files (x86)\Windows Kits\8.0\Debuggers\x64\WINXP\ntsdexts.dll]
最上面两行显示了扩展模块的搜索路径。接下来共列出了六个Windbg自带的扩展模块:wdfkd、dbghellp、ext、exts、uext和ntsdexts。可以查看到这些扩展模块的版本信息、镜像文件路径。如何列出某个扩展库中所包含的扩展命令列表呢?绝大部分扩展模块可使用如下命令:
- !模块名.help
此外,扩展命令模块是可“扩展”的。如果读者从第三方处获取,或自己编写了一个扩展调试模块,则可通过.load/.unload命令动态加载/卸载。
http://www.yiiyee.cn/Blog/windbg/ 很详细得介绍了windgb的基本设置和使用WinDbg配置和使用基础
WinDbg是微软发布的一款相当优秀的源码级(source-level)调试工具,可以用于Kernel模式调试和用户模式调试,还可以调试Dump文件。
1. WinDbg介绍:
Debugging Tools and Symbols: Getting Started
http://www.microsoft.com/whdc/devtools/debugging/debugstart.mspx
A word for WinDbg
http://mtaulty.com/communityserver/blogs/mike_taultys_blog/archive/2004/08/03/4656.aspx
2. WinDbg下载:
Install Debugging Tools for Windows 32-bit Version
http://www.microsoft.com/whdc/devtools/debugging/installx86.mspx
Install Debugging Tools for Windows 64-bit Versions
http://www.microsoft.com/whdc/devtools/debugging/install64bit.mspx
3. 配置WinDbg:
运行WinDbg->菜单->File->Symbol File Path->按照下面的方法设置_NT_SYMBOL_PATH变量:
在弹出的框中输入“C:\MyCodesSymbols; SRV*C:\MyLocalSymbols*http://msdl.microsoft.com/download/symbols”(按照这样设置,WinDbg将先从本地文件夹C:\MyCodesSymbols中查找Symbol,如果找不到,则自动从MS的Symbol Server上下载Symbols)。另一种做法是从这个Symbol下载地址中http://www.microsoft.com/whdc/devtools/debugging/symbolpkg.mspx,下载相应操作系统所需要的完整的Symbol安装包,并进行安装,例如我将其安装在D:\WINDOWS\Symbols,在该框中输入“D:\WINDOWS\Symbols”。(这里要注意下载的Symbols的版本一定要正确,在我的Win2003+Sp1上,我曾经以为安装Win2003+Sp2的Symbols可能会牛×点,但结果证明我错了,用WinDbg打开可执行文件时,提示“PDB symbol for mscorwks.dll not loaded;Defaulted to export symbols for ntdll.dll”的错误,我有重新装上Win2003+Sp1的Symbols, 现在一切运行正常^_^)
4. 使用WinDbg:
WinDbg提供了图形界面和命令行两种运行方式。这里介绍使用图形界面的WinDbg来调试应用程序:
File->OpenExecutable->可以选择一个可执行文件进行调试;
File->Attache to a Process->可以选择一个运行中的进程,并对其进行调试;
至此,我们就可以在上图中用红色方框标记的文本框中输入各个功能指令了(有关指令的帮助文档,可以参考:Help->Contents->Debugging Tools for Windows->Debuggers->Debugger Reference,该目录下列集了所有指令机器功能说明!)。
下面是windgb 和gdb的命令对应表
命令 windbg gdb
附加 attach attach
脱离附加 detach detach
运行 g/F5 run/r
继续 g/F5 continue/c
步过 p/F10 n/ni
步进 F11 s/si
执行到返回 gu finish
下断点 bp ba break/br
查看断点 bl info break
禁止断点 bd disable breakpoint
开启断点 be enable breakpoint
删除断点 bc delete breakpoints
查看寄存器 r info register/i r
修改寄存器 r set
查看内存 db dw dd x
修改内存 eb ew ed set {type}address
查看调用栈 k kb kb kPL bt
查看全部线程 ~* info threads
线程切换 ~ threadid s thread threadid
查看进程 | * info inferior
进程切换 | pid s inferior
查看符号 x module!symbol info symbol
反汇编 u uf x /i disassemble
寄存器表示 eax.... $eax ...
打印变量 dv, dt print/p
条件断点举例,设置断点当esp+4指向的四字节内存值为31时停下:
windbg: bp address if(poi(@esp+4)=0x1f)
gdb: break *address if {int}($esp+4) == 0x1f