Windows软件调试初探-WinDBG命令入门
Windows软件调试初探-WinDBG命令入门
碎碎念
标准命令有:
- 控制调试目标执行,包括回复运行
g
、跟踪执行t
、单步执行p
、追踪监视wt
。 - 观察和修改通用寄存器
r
,读写MSRrdmsr/wrmsr
,设置寄存器显示掩码rm
。 - 读写I/O端口
ib/iw/id
、ob/ow/od
。 - 观察、编辑和搜索内存数据的
d
系列、e
系列、s
系列。观察栈k
系列。 - 设置和维护断点
bp/ba
,管理断点bl/bc/bd/be
。 - 显示和控制线程
~
,显示进程|
。 - 评估表达式
?
,评估C++表达式??
。 - 汇编与反汇编
a/u
。 - 显示段选择子
dg
。 - 执行命令文件
$
。 - 设置调试事件处理方式
sx
系列,启用/禁止静默模式sq
,设置内核选项so
,设置符号后缀ss
。 - 显示调试器和调试目标版本
version
,显示调试目标所在系统信息vertarget
。 - 检查符号
x
。 - 控制和显示源程序
ls
系列。 - 加载调试符号
ld
,搜索相邻符号ln
,显示模块列表lm
。 - 结束调试会话
q
,结束远程调试qq
,结束调试会话并分离调试目标qd
。 - 标准命令帮助
?
。
元命令以点开始,有:
- 显示和设置调试会话的调试器选项,如符号选项
.symopt
、符号路径.sympath/.symfix
、源程序文件.srcpath/.srcnoise/.srcfix
、扩展命令模块路径.extpath
、匹配扩展命令.extmatch
、可执行文件.exepath
、反汇编选项.asm
、控制表达式评估其.expr
等。 - 控制调试会话或调试目标,如重新开始调试会话
.restart
、放弃用户态调试目标进程.abandon
、创建新进程.create
、附加到存在进程.attach
、打开转储文件.opendump
,分离调试目标.detach
、终止进程.kill
等。 - 管理扩展命令模块,如加载模块
.load
、卸载.unload/.unloadall
、显示已加载模块.chain
等。 - 管理调试器日志文件,如显示信息
.logfile
、打开.logopen
、追加.logappend
、关闭.logclose
。 - 远程调试,如启动服务
.remote
、启动调试引擎服务器.server
、列出可用服务器.servers
、向远程服务器发送文件.send_file
、结束远程进程服务器.endpsrv
、结束引擎服务器.endsrv
。 - 控制调试器,如调试器睡眠
.sleep
、唤醒调试器.wake
、启动另一个调试器来调试当前调试器.dbgdbg
。 - 编写命令程序,如
.if/.else/.elsif/.foreach/.do/.while/.continue/.catch/.break/.continue/.leave/.printf/.block
等。 - 显示或转储调试目标数据,如产生转储文件
.dump
、原始内存数据写文件.writemem
、显示调试会话时间.time
、显示线程时间.ttime
、显示任务列表.tlist
、以不同格式显示数字.formats
。 - 元命令帮助
.help
。
扩展命令结构!扩展模块名.扩展命令名 参数
。加载扩展模块用命令.load 扩展模块
或.loadby 扩展模块 已加载程序模块
,用.chain
列出当前加载的所有扩展模块,用.unload/.unloadall
卸载扩展模块,用!扩展模块.help
显示某扩展模块的扩展命令。
对于用户态目标,命令提示符格式为“系统序号:进程序号:线程序号”,所有序号从0开始。对于双机内核调试的内核态目标或内核转储文件目标,为“系统序号:处理器序号:kd”。对于本地内核态调试,为“系统序号:处理器序号:lkd”。
直接按回车则重复上一条命令,用Ctrl+Alt+V开启详细输出模式。大部分命令不区分大小写,有些命令的选项区分大小写。默认使用十六进制,可用0x/h、0n、0y来指定十六进制、十进制、二进制等。
串行执行多个命令用分号隔开,注释用$$
时到分号结束,用*
时整行都被当作注释。
伪寄存器
伪寄存器PR,解析命令时WinDBG调试引擎自动展开:
伪寄存器 | 描述 |
---|---|
$ea |
上一条指令中有效地址 |
$ea2 |
上一条指令中第二个有效地址 |
$exp |
表达式评估器评估的上一条表达式 |
$ra |
当前函数返回地址,如g @$ra 与gu 效果相同 |
$ip |
指令指针寄存器 |
$eventip |
当前调试事件发生时的指令指针 |
$previp |
上一事件的指令指针 |
$relip |
与当前事件关联的指令指针 |
$scopeip |
当前上下文指令指针 |
$exentry |
当前进程入口地址 |
$retreg |
首要函数返回值寄存器 |
$retreg64 |
同上x64 |
$csp |
帧指针 |
$p |
上一个内存显示d 系列命令所打印的第一个值 |
$proc |
当前进程PROCESS结构地址 |
$thread |
当前进程ETHREAD结构地址 |
$peb |
当前进程PEB地址 |
$teb |
当前线程TEB地址 |
$tpid |
拥有当前线程的PID |
$tid |
当前线程ID |
$bpx |
x号断点地址 |
$frame |
当前栈帧序号 |
$dbgtime |
当前时间 |
$callret |
用.call 命令调用的上一个函数的返回值,或用.fnret 命令设置的返回值 |
$ptrsize |
调试目标所在系统的指针类型宽度 |
$pagesize |
调试目标所在系统的内存页字节数 |
使用方法:
1 | 0:000> ln @$exentry *搜索距离指定地址最近的符号 |
别名
WinDBG自动定义的别名有:
别名 | 含义 |
---|---|
$ntnsym |
NT内核或NTDLL符号名 |
$ntwsym |
64位系统上调试32位目标时NT系统DLL符号名 |
$ntsym |
与当前调试目标的机器模式匹配的NT模块名称 |
$CurrentDumpFile |
转储文件名称 |
$CurrentDumpPath |
转储文件路径 |
$CurrentDumpArchiveFile |
最近加载的CAB文件名称 |
$CurrentDumpArchivePath |
最近加载的CAB文件路径 |
例如:
1 | 0:000> .echo $ntnsym |
上下文
1 | !session |
符号
1 | lm v *详细模块列表 |
未完待续。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 The Blog of Monoceros406!