第39章 WinDbg

本文最后更新于:2022年5月27日 下午

第39章 WinDbg

WinDbg是Windows平台下用户模式和内核模式调试工具,它是一个轻量级的调试工具,但是功能十分强大。本章将学习有关WinDbg调试工具的知识(参考图39-1 )。

39.1 WinDbg

WinDbg是微软发布的一款免费调试工具,支持用户模式调试与内核模式调试,是一种“全天候”的调试器,但主要还是应用于内核调试。各位可以访问以下网址下载WinDbg调试器。

http://www.microsoft.com/whdc/devtools/debugging/default.mspx

本章讲解的是64位的WinDbg,它与32位版本在用户界面结构、命令组成上基本没有什么差别

39.1.1 WinDbg 的特征

WinDbg默认运行在CUI(Console User Interface,控制台用户界面)环境下,用户主要通过键盘而非鼠标来操作。要适应这种方式需要花费相当长的时间,可一旦熟悉起来就会非常方便。对于习惯了OllyDbg与IDAPro等GUI环境的朋友来说,初次接触WinDbg时会感到非常陌生、非常不方便(它们的差别就像Windows用户第一次接触Linux的终端用户环境时的感觉一样)。WinDbg中也提供大量快捷键,以及额外的窗口(反汇编、内存、寄存器、栈等),所以也可以使用类似OllyDbg形态的方式调试(当然,与OllyDbg、IDA Pro的GUI相比还差很远)。

39.1.2运行 WinDbg

符号

符号(Symbol)指的是调试信息文件(*.pdb)。使用Visual C++编译程序时,除了生成PE文件外,还会一起生成*.pdb(Program Data Base,程序数据库)文件,该文件包含PE文件的各种调试信息(变量/函数名、函数地址、源代码行等)。为了帮助理解,各位可以比较图39-2和图39-3。

虽然是相同的PE文件,但是符号文件的有无决定了反汇编代码的可读性。有符号文件时调试更方便快捷。但是通常只有程序的编写者才有符号文件,且一般不会对外发布。所以我们的调试工作大部分是在没有符号文件的情形下进行的。

安装符号文件

微软公开了Windows OS系统库的符号文件。在WinDbg中设置好符号的位置后,调试应用程序或驱动程序时会相当方便(因为拥有了系统库的调试信息)。在WinDbg菜单栏中依次选择File-Symbol File path菜单,弹岀对话框。像图39-4这样输入符号路径,需要时WinDbg会自动下载与OS相匹配的符号文件。

39.1.3 内核调试

WinDbg的特征之一就是可以进行内核调试(Kernel Debugging )。使用WinDbg进行内核调试时,一般要使用2台PC(调试器调试者),调试前需要通过Null Modem、1394、USB、Direct LAN Cable等将2台PC连接起来。近来,使用虚拟机(Virtual Machine)技术可以在同一台PC上同时运行调试器与被调试者,这被称为本地内核调试(Local Kernel Debugging ),即在运行WinDbg的PC上调试它(从Windows XP起支持该调试功能)。调试器的许多功能在这种调试方式下都受到限制,但是用来查看一些简单的信息还是非常方便的。

调试普通应用程序时,调试器与被调试者都在同一台PC中运行,但内核调试不同。内核调试中,被调试者为系统内核,即OS本身,所以OS系统自身会暂停。因此,调试内核时一般需要使用2台物理PC。以前SofllCE调试器可以完美地支持本地内核调试,受到广泛欢迎,但是由于它已经停止开发,不再有版本更新,所以调试内核时只好使用WinDbg调试器。关于内核调试的内容已经超出了本书的讨论范围,在此不再深入探讨。下面学习使用WinDbg调试器调试64位应用程序及查看PEB/TEB等系统结构体。

下面使用WinDbg的本地内核调试功能简单分析一下系统行为。为了进行本地内核调试,首先要把系统修改为调试模式。在控制台窗口输入bcdedit指令,查看当前系统状态,如图39-5所示。

在最后一行可以看到1个debug项目,其值为No,即“非调试模式”。使用以下命令修改该项的值,转换为调试模式,如图39-6所示

重启系统后进人内核调试模式,此时本地内核调试功能变为可用(再次使用bcdedit指令确认)。运行WinDbg调试器,在菜单栏中依次选择File-Kernel Debug菜单(快捷键Ctrl+K ),弹出Kernel Debugging对话框,如图39-7所示。

选择Local选项卡,然后单击“确定”按钮。一段时间后弹出WinDbg行初始画面,如图39-8所示。

首先岀现的是基于控制台的用户界面(看上去包含各种强大功能)。初始运行画面中显示的是基本的系统信息以及内核基址,该地址为ntoskrnl.exe文件的装载地址。Ntoskml.exe其实是驱动程序文件,指的是Windows内核本身。从技术上说,Windows内核实体是Ntoskml.exe驱动程序文件的内存装载映像。接下来输入简单指令,查看ntoskral!ZwCreateFile() API的实际代码,如图39-9所示。

ZwCreateFile() API的代码相当简单,它将服务编号(52)设置到EAX寄存器,然后跳转到KiServicelnternal()函数(函数的参数在寄存器与栈中)。其实,大部分ZwXXX系列函数都是由这种结构构成的。可以继续跟踪KiServicelnternal()API查看更详细的代码。查看系统内核代码如此方便,但是若想正式调试系统内核,应当釆用PC to PC或虚拟机方式连接。

39.1.4 WinDbg基本指令

下面简单整理WinDbg基本指令,调试64位应用程序或系统内核时会经常使用它们(更详细的说明请参考WinDbg帮助手册),如表39-1所示

指令 说明 应用
u Unassemble u:显示下一条指令
u address:显示地址之后的指令
u L10:显示10行指令
ub:显示上一条指令
t Trace(F11) Step Into
p Pass(F10) Step Over
g Go(Run) g:运行
g address:运行到地址处
d Dump d address:显示地址内容
db address:byte
dd address:dword
dq address:qword
r Register r:显示寄存器
r register:仅显示指定寄存器
bp Break Point bp:设置断点
bl:显示断点列表
bc:BP Clear(删除断点)
lm Loaded Module Im:显示被调试进程中加载的模块
dt Display Type dt struct name:显示结构体成员
dt struct name address:映射地址到结构体并显示
!dh Display PE Header !dh loaded address:PE Viewer

WinDbg支持的指令超过数十种,且各种指令的使用方法灵活多样。希望各位反复练习使用WinDbg调试器,直到能够熟练进行各种调试。


第39章 WinDbg
https://m0ck1ng-b1rd.github.io/1999/03/09/逆向工程核心原理/第39章 WinDbg/
作者
何语灵
发布于
1999年3月9日
许可协议