一、安装WinDbg

Microsoft商店中下载安装即可,默认安装路径

(C:\Users\用户名\AppData\Local\Microsoft\WindowsApps)

添加名为**_NT_SYMBOL_PATH**的系统变量,值为

SRV\*C:\mysymbol\* http://msdl.microsoft.com/download/symbols

二、启动WinDbg

1.打开可执行文件进行调试(Launch executable

2.将调试器附载到一个正在运行的进程中(Attach to process),右边选择要附载的进程

3.开启即时调试

输入命令Windbg -l就能成功开启即时调试,当程序崩溃时会自动启动Windbg

三、功能展示

1.显示信息

模块显示

使用lm命令显示指定的已加载模块,输出包括模块的状态和路径。

lm [Options] [a Address] [m Pattern | M Pattern]

[Options]:
D 使用调试器标记语言显示输出
o 仅显示加载的模块
l 仅显示其符号信息已加载的模块
v 显示详细信息
e 仅显示有符号问题的模块
c 显示校验和
sm 按模块名称而不是起始地址对显示进行排序

  1. [a Address]

    指定此模块中包含的地址,只显示包含此地址的模块。如果 Address 包含表达式,则必须用括号括起来。

  2. [m pattern]

    指定模块名称必须匹配的模式。模式可以包含各种通配符和说明符。

    字符串通配符语法:

    • 一个星号 (*) 零个或多个字符
    • 问号 (?) 表示任何单个字符
    • 包含 ( [ ] ) 字符列表的括号表示列表中的任何单个字符。 列表中只有一个字符匹配。 在这些括号中,可以使用连字符 (-) 指定范围
    • 数字符号 (#) 表示前面的零个或多个字符
    • 加号 (+) 表示前面的一个或多个字符

  3. [M pattern]

指定image路径必须匹配的模式。模式可以包含各种通配符和说明符。

符号加载与显示

ld命令加载指定模块的符号并更新所有模块信息

ld ModuleName [/f FileName]

ModuleName

指定要加载其符号的模块的名称,可以包含各种通配符和说明符。

加载完成后,通过lm命令来查看已加载的模块和符号信息

查看符号

通过x命令查看符号,语法为x [options] module!symbolsx [Options] *

options

/0 只显示每个符号的地址
/1 只显示每个符号的名称
/2 只显示每个符号数据类型的地址和名称
/t 如果数据类型已知,则显示每个符号的数据类型
/a 按地址对显示按升序排序
/n 按名称对显示顺序进行升序排序
/z 按大小以升序对显示进行排序

module

指定符号必须包含的模式。可以包含各种通配符和说明符。

symbols

指定符号必须包含的模式。可以包含各种通配符和说明符。

2.内存

显示内存

Memory窗口显示内存数据

使用命令**d [Options] [Range]**可以查看不同格式的内存数据,如果省略 Range,则该命令将显示从上一个显示命令的结束位置开始的内存。

da ASCII字符
db 字节值和ASCII字符
dc 双字值(4字节)和 ASCII 字符
dd 双字值(4字节)
dD 双精度浮点数字(8字节)
df 单精度浮点数字(4字节)
dp 指针大小的值
dq 四字值(8字节)
du Unicode字符
dw 字值(2字节)
dW 字值(2字节)和 ASCII 字符
dyb 二进制值和字节值
dyd 二进制值和双字值(4 个字节)
  1. db

  1. da

  1. dd

  1. dw

搜索内存

使用命令s搜索

s -sa Range 搜索Range内的ansi字符串
s -su Range 搜索Range内的unicode字符串
s -a Range text 搜索Range内的指定的ansi字符串
s -a Range text 搜索Range内的指定的unicode字符串

例如,搜索起始地址为00007FFFCE990040,长度为0x100范围内的unicode字符串

搜索起始地址为00007FFFCE990040,长度为0x1000范围内的“m”字符串

编辑内存

使用命令e{options} Address [Values]来编辑内存

options
b 字节值
d 双字值(4字节)
D 双精度浮点数 (8字节)
f 单精度浮点数字 (4字节)
p 指针大小的值
q 四字值 (8字节)
w 字值 (2字节)

如果Values未指定任何值,则将显示当前地址和该地址处的值,并且系统将提示您输入,输入完成后按Enter结束

如同下图

也可以指定Values值编辑

3.断点

软件断点

使用bpbubm命令设置一个或多个软件断点。

  1. bp命令是在某个地址下断点,格式为bp Arrdessbp Myapp!Function,对于后者,Windbg会自动找到Myapp!Function对应的地址并设置断点
  2. bu命令是针对某个符号下断点,格式为bu Myapp!Function
  3. bm命令也是针对符号下断点,但是它支持匹配表达式。

以及一些常用命令:

bl 列出所有断点
bc 清除断点
bd 禁用断点
be 启动被bd命令禁用的断点

硬件断点

ba命令是针对数据下断点的命令,该断点在指定内存被访问时触发

命令格式为ba OptionsSize [Address]

options是访问的方式,如下

options
e(执行) 当处理器从指定地址检索指令时触发。
r(读/写) 当处理器读取或写入指定地址的内存时触发。
w(写入) 当处理器将内存写入指定地址时触发。

Size是监控访问的位置的大小,以字节为单位,值为1、2或4,还可以是 8(64位机)

如果options是e,那么Size必须是1

条件断点

新版条件断点语法:

使用bp的"/w"参数创建条件断点(设置断点),命令语法为:

bp /w "(Condition)" Address

当指定的Condition为true时,断点只会导致调试器中断。"w"是"when"的缩写。条件表达式可以是可用于dx对象模型表达式(命令)表达式,包括了大多数C++样式表达式。

dx命令使用NatVis扩展模型显示C++表达式

dx [-g|-gc #] [-c #] [-n|-v] -r[#] Expression

dx [{-?}|{-h}]

Expression 要显示的 C++ 表达式
-r[#] 以递归方式显示(字段的子类型)高达 # 级别。如果未 # 指定,则递归级别为默认值
-g 显示为可迭代的数据网格对象
-gc# 显示为网格,并将网格单元格大小限制为指定的(#)字符数
-v 显示包含方法和其他非典型对象的详细信息
dx {-?} 显示命令行帮助
dx {-h} 显示调试器中可用的对象的帮助

设置断点:

旧版条件断点语法:

断点命令(bp或者bu)与j命令或者.if命令一起使用,后面跟着一个gc命令

命令格式为

bp Address "j (Condition) 'Commands'; 'gc' "

bp Address ".if (Condition) {Commands} .else {gc}"


j命令,语法如下

j Expression Command1 ; Command2

j Expression 'Command1' ; 'Command2'

Expression 要计算的表达式
Command1 如果表达式的计算结果为非零值(True),则为要执行的命令字符串
Command2 如果表达式的计算结果为零(False),则为要执行的命令字符串

.if命令,语法如下

.if (Condition) { Commands }

.if (Condition) { Commands } .else { Commands }

这个和C语言中的if函数的语法类似

Condition 指定条件。如果此计算结果为零,则视为 false;否则为 true
Commands 指定一个或多个将按条件执行的命令

gc(从条件断点继续)

gc命令以与单步执行、跟踪或自由执行(断点相同的方式从条件断点恢复)

仅适用于j.if的条件断点旧样式样式表达式

因此这个命令格式bp Address "j (Condition) 'Commands'; 'gc' "的意思是:

如果遇到此断点且表达式为false,则使用以前使用的同一执行类型继续执行。例如,如果使用g命令到达此断点,则执行将自由恢复。但如果在单步执行或跟踪时到达此断点,则执行会通过步骤或跟踪恢复。