1.标准命令
1.控制进程目标:
恢复:g, 跟踪执行:t, 单步:p, 追踪监视: wt
2.操作寄存器:
r, rdmgr, wrmsr, rm
3.读写io端口
ib/iw/id ob/ow/od
4.内存命令
d, e, s
5.栈 k
6.断点:
bp, ba硬件断点, bl列出断点, bc/bd/be 清除,禁止,重启断点
7.显示进程l, 汇编a, 反汇编u
8.显示段选择子 dg
1.设置和保存工作空间
直接通过ui界面操作即可
工作空间保存了下列信息:
调试会话状态: 包括断点,打开的源文件,定义的别名
调试器设置:符号文件路径, 可执行文件路径, 源文件路径
windbg图形界面信息:标题,窗口位置,字体等UI界面设置
2.标准命令: 第一个字符不分大小写,第2个可能分 ? 查看标准命令帮助
控制行为: g 恢复, t跟踪, p 单步, wt 追踪监视
寄存器相关: r 观察修改寄存器, rdmsr, wrmsr读写msr寄存器,rm 设置寄存器显示掩码
读写io: ib/iw/id 和ob/ow/od
内存: d 查看, e 编辑, s 搜索
栈: k
断点:bp 软件断点, ba 硬件断点, bl 列出断点, bc/bd/be 清除,禁止,重启断点
显示控制线程: ~
评估表达式 ?,评估c++ ??
汇编 a, 反汇编 u
显示段选择子 dg
执行命令文件 $
检查符号 x
控制显示源程序 ls系列
加载调试符号 ld , 搜索相邻符号ln, 显示模块列表 lm
结束回话 q, 分离目标 qd
元命令:所有元命令以.开始 .help 查看元命令帮助
显示,设置调试回话和调试器选项: .symopt, 符号路径:.sympath 和.symfix 这些带path和带fix的后面可以接路径作为参数
源程序文件: .srcpath, .srcnoise, .srcfix 拓展命令模块路径:.extpath 匹配拓展命令的.extmatch
用于可执行文件的.exepath. 反汇编: .asm 控制表达式评估其 .expr
控制调试会话: .restart, .abandon, .create, .attach, 打开转储文件 .opendump , 分离调试目标的.detach, .kill
管理拓展命令模块: .load , .unload, .unloadall, 显示已有模块: .chain
管理调试日志文件: 显示 .logfile, .logopen打开, 追加:.logappend , 关闭: .logclose
编写命令程序如: .if .else .elsif .foreach .do .while .continue .catch .break .leave .printf .block
......
拓展命令: .chain查看帮助
![拓展模块名].<拓展命令名>[参数]
如开启hpa !gflag +hpa
上下文:
会话上下文, 进程上下文, 寄存器上下文, 局部(变量)上下文
!session 显示会话, !session -s 会话号 切换到会话号 (内核调试)
!sprocess 列出指定会话进程 (内核调试)
进程上下文:
!process 0 0 列出所有进程
.process 地址
.context 显示页目录基址(物理地址)
寄存器上下文:
当线程没有执行时它的大部分寄存器值存放在内存中,修改寄存器值也是内存中的而不是当前物理寄存器的
.thread ethread地址 设置当前调试线程
r 读取寄存器值
局部(变量)上下文
.frame 查看当前局部上下文
dv 查看当前函数内局部变量
~0 s 切换到0号线程
符号文件和模块
观察模块:
lm
lm v
!lmi 模块名 查看模块信息
检查符号 x
x 模块名!函数名或者变量名(可以加*#通配符)
ln 地址 搜索该地址附加的符号
控制调试目标
1.初始断点: 通过windbg打开一个文件就断下 附加一个进程是通过创建远程线程来触发一个断点
2.继续: gh 已处理异常继续运行 gn未处理该异常继续
3.单步执行:
p 单步越过 t单步步入
pa 地址 单步执行到地址
ta 地址 和pa一样 类似于od f4
图形界面上还有其他执行操作和快捷键
wt监视执行过程
gu执行到返回
设置断点
软件断点
bp 地址 穿越次数
bu 模块!函数名 当这个模块被加载后函数被调用时中断
bm 模块名!函数名 目标可以设置*通配符,来设置多个断点
硬件断点 ba access size options address
access: e|r|w|i e是执行断点,r是读取或者写入断点,w写入断点,i i/o访问断点
size: 数据大小:1,2,4字节
选项: /1 一次性断点 /p 内核调试, 跟一个eprocess地址只有这个进程时中断时中断 /t 指定ethread线程 /c 数字 函数调用到达数字深度时中断
条件断点,以上断点命令都可以设置条件断点
命令 地址 "j (条件) '命令1'; '命令2' " 即当条件为true时断下并执行命令1否则执行命令2 . 一般有一条是g继续运行
地址表达式:(确保地址是一条指令首地址
nt!函数名 或者再+一个数字 表示偏移
如果有调试符号可以包含行信息: bp `a!main.cpp:20` 对a模块的main.cpp文件的第20行下断
针对线程断点: ~0 bp 0x88880000 如果有多个线程都会执行该地址的指令,但只对0号线程断下
控制线程: 当中断时所有线程都是挂起的,当恢复时所有线程都被恢复.
~查看所有线程状态
增加挂起计数:~1 n 对序号为1的线程增加1个挂起计数
减少挂起计数:~1 m 同上,效果相反
冻结线程:~1 f 冻结后该线程不可执行
解冻线程:~1 u
执行线程单步: ~1 t
栈回溯
k 显示
kb 显示栈上前3个参数
kp
kv
dv查看栈变量
分析内存
显示内存区域
d{a|b|c|d|D|f|p|q|u|w|W} option 地址1 地址2
a:ascii吗 b字节和ascii c:dword和ascii,d:dword ,D:double, f:flout, p:指针,q8字节显示, u:unicode,w:word,yb:二进制字节,yd二进制dword
2地址表示地址范围或者一个地址1 外加一个数字,后面的数字表示从地址1开始显示这么多个目标类型的值
显示数据类型
dt 模块名!类型名 可以加通配符
加-b屏蔽递归显示子类型 -rx x表示递归显示x层子类型
sa 地址范围 所搜ascii字符串 su搜索unicode字符串
s-数据类型 地址范围 值1 值2 .... 如 s-d 0x00001111 12a000 11 22 33 ff dd 在0x00001111 后面12a000 的内容搜索11 22 33 ff dd这5个值
甚至s-u 地址范围 "windbg" 在地址范围搜索windbg
修改内存:e[a|u|za|zu] 地址 "修改后的值"
a:ascii字符数组
u:unicode字符数组
za:ascii字符串
zu:unicode字符串
显示内存属性:
!address 地址
内核调试
注意的地方: 内核模块的加载和卸载并不频繁,如果发现内核模块被加载时需要注意这个可能与恶意代码有关
当有驱动被加载时windbg将会提示.
查看加载驱动的驱动对象
!drvobj 驱动文件名 :可以列出它的设备对象
!object \Driver 浏览所有驱动对象
dt nt!_DRIVER_OBJECT 地址
查找驱动对象:
!devobj 设备地址(句柄,由dt nt!_DRIVER_OBJECT 地址获得)
!devhandles 设备地址 查询那个用户进程拥有该句柄
分析ssdt:
查看item,他们的值(地址)相近,如果发现远离的地址,可以怀疑被修改.而这些正常地址在ntoskrnl.exe模块中.所以也可以看是否超出了该模块地址范围
lm m nt 显示该模块地址范围, 然后检查所有驱动模块,看这个被修改的地址大致离哪个更近,然后可以分析那个可以驱动
rootkit挂钩idt:
查看idt: !idt
正常idt 函数有微软签名,反之没有,识别被修改idt
.................