基础命令
说明 | 命令 | 用法 | 描述 |
---|
帮助 | ?/.help/.hh | ?/.help/.hh | 常规命令/元命令/打开windbg help文档 |
清空屏幕 | .cls | .cls | 清空屏幕 |
查看异常信息 | .excr/.lastevent/.exr -1/!analyze | !analyze -v/!analyze -hang/!analyze -f | 显示当前异常信息/分析线程栈,看是否有线程blocking其他线程/See an exception analysis even when the debugger does not detect an exception. |
寄存器 | r | r | 显示寄存器的值 |
时间 | .time | | 显示system/process/kernel/user time |
调试命令
命令 | 说明 | 实例 |
---|
g | 继续执行 | |
gu | 继续执行到当前函数返回 | |
p | 如遇到函数调用,依次执行完函数调用,单步调试 | |
t | 如遇到函数调用则进入被调函数 | |
wt | 自动吹总函数的执行过程,会将函数的执行过程及函数调用输出 | |
.detach | 分离调试目标 | |
.attach | 附加到进程,参数为16进制的PID | .attach 0Xe45 |
模块信息
命令 | 说明 |
---|
lm | 显示加载的模块信息,exe和dll等 |
lmvm | 显示某一模块的详细信息 lmvm ntdll |
调试符号
命令 | 说明 | 实例 |
---|
ld | 加载模块的调试符号 | ld ntdll / ld * |
.sympath | 设置符号文件路径 | |
.symfix | 设置系统符号存放位置 | |
.reload | 重新为所有模块加载符号文件 | |
线程
命令 | 说明 | 实例 |
---|
~ | 显示所有线程信息 | |
~* [cmdline] | 为所有的线程执行指定的命令 | |
~. [cmdline] | 为当前的线程执行指定的命令 | |
~. [cmdline] | 为当前导致异常的线程执行指定的命令 | |
~ TID s | 切换到序号为TID的线程 | |
~ TID f/u | 冻结/解冻序号为TID的线程 | ~0 f |
!runaway | 显示每个线程运行的时间,方便找到消耗cpu的线程 | |
栈
命令 | 说明 |
---|
k | 显示EBP,返回地址与源信息(已加载私有符号的情况下) |
kb | 在k命令的基础上,每行前显示栈帧的序号显示函数的参数信息 |
kn | 在k命令的基础上,每行前显示栈帧的序号 |
设置断点
bp 设置断点
命令格式: bp[ID号] [Options] [Address [第几次命中断点时中断到调试器]] ["一组命令,用分号隔开"]
Options选项可用的值:
- /1 断点被命中一次后自动删除,即一次命中断点
- /p 只用于内核调试中,/p后跟一个EPROCESS结构的地址,即对指定的进程设置断点
- /t 只用于内核调试中,/t后跟一个ETHREAD结构的地址,即对指定的线程设置断点
- /c 和 /C 指定中断给用户的最大函数调用深度和最小函数调用深度
举例:bp /c5 MSVCR80D!printf 只有当函数调用栈深度浅于5时才中断。
Address表达方式:
- 使用模块名加函数符号:bp LocalVar!FuncC 或带偏移值 bp LocalVar!FuncC+9
- 直接使用内存地址:bp 00401089
- 如果使用完全的调试符号,调试符号中包含源代码行信息,可以用:
- bp`模块名!XXX.cpp:行号` , 其中`为重音符号
- 对于C++的类方法,可以使用类名双冒号(::)或双下划线(__)来连接类名和方法名:bp MyClass::MyMethod 或 bp MyClass__MyMethod 或 bp @@(MyClass::MyMethod)
实例:
(1)bp LocalVar!FuncC+9
其中 LocalVar为模块名称,FuncC为函数名称,9为偏移
(2)bp 00401089 在指定的地址上下断点
(3)bp MSVCR80D!printf + 3 2 "kv; da poi(ebp+8)"
在printf的入口偏移3的地址处下断点(为了让建立栈帧的代码执行完),当第2次命中断点时中断到调试器,并自动执行kv和da poi(ebp+8)命令。
其中,da poi(ebp+8)用来显示printf的第一个参数所指定的字符串
命令 | 说明 | 实例 |
---|
bu | 用于对尚未被加载模块中的代码设置断点命令格式: bu[ID号] [Options] [Address [第几次命中断点时中断到调试器]] [“一组命令,用分号隔开”] | 对于调试动态加载模块的入口函数和初始化代码比较有用,比如对于即插即用设备的驱动程序可以使用如下命令在入口函数处设置断点bu MyDriver!DriverEntry |
bl | 列出当前存在的所有断点 | |
bd | 禁用断点 | 使用‘-’来禁用指定范围的断点或使用‘,’分割多个断点 |
bc | 删除断点 | 使用‘-’来禁用指定范围的断点或使用‘,’分割多个断点 |
be | 启用断点 | 使用‘-’来禁用指定范围的断点或使用‘,’分割多个断点 |