WinDbg使用学习
一、安装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 | 按模块名称而不是起始地址对显示进行排序 |
-
[a Address]
指定此模块中包含的地址,只显示包含此地址的模块。如果 Address 包含表达式,则必须用括号括起来。
-
[m pattern]
指定模块名称必须匹配的模式。模式可以包含各种通配符和说明符。
字符串通配符语法:
- 一个星号 (*) 零个或多个字符
- 问号 (?) 表示任何单个字符
- 包含 ( [ ] ) 字符列表的括号表示列表中的任何单个字符。 列表中只有一个字符匹配。 在这些括号中,可以使用连字符 (-) 指定范围
- 数字符号 (#) 表示前面的零个或多个字符
- 加号 (+) 表示前面的一个或多个字符
-
[M pattern]
指定image路径必须匹配的模式。模式可以包含各种通配符和说明符。
符号加载与显示
ld命令加载指定模块的符号并更新所有模块信息
ld ModuleName [/f FileName]
ModuleName
指定要加载其符号的模块的名称,可以包含各种通配符和说明符。
加载完成后,通过lm
命令来查看已加载的模块和符号信息
查看符号
通过x
命令查看符号,语法为x [options] module!symbols
或x [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 个字节) |
- db
- da
- dd
- 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.断点
软件断点
使用bp
、bu
和bm
命令设置一个或多个软件断点。
bp
命令是在某个地址下断点,格式为bp Arrdess
或bp Myapp!Function
,对于后者,Windbg会自动找到Myapp!Function对应的地址并设置断点bu
命令是针对某个符号下断点,格式为bu Myapp!Function
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命令到达此断点,则执行将自由恢复。但如果在单步执行或跟踪时到达此断点,则执行会通过步骤或跟踪恢复。