windbg命令
1 minute read
0x01 windbg知识
http://www.yiiyee.cn/Blog/windbg/
http://www.cppblog.com/weiym/archive/2012/06/07/177958.aspx
1>db esi:查看esi地址中的内容
db 400000:查看0x400000处的内容,db按字节大小查看,dd按DWORD类型查看
dd poi(addr)
poi(addr)相当于[addr],也即addr中存放的值,dd poi(addr)也即相当于dd addr1,其中addr1=[addr]
2>!address edi:显示edi地址处的内存状态,信息
3>lmm mso v:匹配mso模块,并显示详细信息
ln addr:查找附近的符号
x something:查找模块在内存中的地址
eg.x *!:查看所有模块在内存中的地址范围
eg.x sufilter!:查看sufilter所有的代码符号(全局变量,函数)的加载地址
eg.x sufilter!sufilterreadwritemt:查看模块中的函数的地址
eg.x moduleName!*funName*:模糊查找出模块中的有关键字的函数
eg.x moduleName!*className*funcName*:模糊查找出模块中的有关键字的类中的有关键字的函数
4>bp eax:在eax处下断点,支持第几次经过后中断,支持中断后执行命令
bp addr 在addr处设置断点
bl 查看所有有已经设置的断点
bc 清除所有断点
bc * 清除所有断点
bu 对某个符号下断点,eg. bu MyApp!SomeFunction
在代码被修改之后,该断点会随着函数地址改变而自动更新到最新位置,而且bu断点会保存在WinDbg工作空间中,下
次启动WinDbg时该断点会自动设置
bd 禁用断点
be 启用被bd命令禁用的断点
ba e|r|w(执行|读|写) 1|2|4|8(单位字节) addr
eg.对内存0x11111111进行写操作的时候下断点命令为:ba w4 0x11111111
5>g:让被调试的程序继续运行(f5)
gh:把异常标识为已处理并断续执行程序
go:对异常不进行任何处理并继续执行程序
gc:条件断点之后恢复运行
6>kb:显示传递给堆栈回溯中的每个函数的前三个参数
kp:显示传递给堆栈回溯中的每个函数的所有参数
kv:在kb的基础上增加了函数调用约定等信息,所以推荐用kv命令察看堆栈.
7>u .:反汇编当前eip处的8条指令
uf .:反汇编当前eip处的整个函数
ub .:反汇编当前eip之前的8条指令
u eip eip+a:反汇编eip到eip+10(a是16进制对应10进制的10)之间的指令
eg.u eip-30 eip+30
ub mso!Ordinal1273+0x2581:反汇编mso!Ordinal1273+0x2581地址之前的代码
uf test!main:反汇编test!main函数
8>p:单步步入step over
t:单步步过trace into
gu:执行到上一层函数,也即把当前函数帧执行到retn,并执行这个retn
9>? ebp-edi:显示表达式ebp-edi的值
?? expression:显示c++表达式的值
10>.cls:清屏
11>获取进程环境块_PEB:
a>.process 获得_PEB地址设为addr
dt _PEB 0xaddr可得到_PEB结构的数据
b>也可通过dt _PEB @$peb直接获取_PEB结构的数据
12>查看堆的信息:
!heap -h 查看所有堆的地址
dt _HEAP 0xaddr 查看一个堆的信息
dt _LIST_ENTRY 0xaddr 查看addr地址中存放的堆块索引信息,得到的结果为Flink和Blink的值
!heap -h 查看所有的堆的情况,也可通过!heap直接查看
!heap -a addr addr要求是一个堆的起始地址,该命令显示这个堆的信息
!heap -p -a addr 查看一个地址在哪个堆块中,并显示这个堆块的信息
13>sxe ld:ModuleName 在首次加载ModuleName对应的模块时中断
sx{e|d|i|n} [-c "Cmd1"] [-c2 "Cmd2"] [-h] {Exception|Event|*}
http://blog.csdn.net/hgy413/article/details/7598236
14>d*s,显示给定范围内存的内容,它们是把内存区域转储出来,并把内存中每个元素都视为一个符号对其进行解析
dds是四字节视为一个符号
dqs是每8字节视为一个符号
dps是根据当前处理器架构来选择最合适的长度
15>其中windbg中的kb命令相当于od中的查看调用堆栈(alt+k),如下图中的ChildEBP列为当前eip对应的ebp的值,RetAddr为当
前eip所在的函数的函数返回地址,Args to Child为当前函数的参数,最后一列的地址是当前排的上一排中的RetAddr的值
要注意的是,并不是kb下面的所有的ChildEBP对应的一列都是函数调用,只有第一排的ChildEBP,RetAddr,Args to
Child的数据值是当前的函数调用的相关参数,从第二排开始的只是栈中高地址的数据内容从ebp到retn到参数相当于地址从
一般情况下,栈空间中的低地址向高地址的排列,函数调用时,栈中的数据如下:
...
... (new ebp为当前函数帧中的新的ebp,此处的new ebp代表当前函数帧的ebp的位置所在)
new ebp --> old ebp(old ebp为上一函数帧的ebp,此处的old ebp代表new ebp位置中的内容值)
retn (retn为当前函数的返回地址)
arg1 (arg1为当前函数的第一个参数)
arg2 (arg2为当前函数的第二个参数)
...
也即当前ebp中存放的是上一函数帧的ebp,且当前ebp的下一栈单元的内容为当前函数的retn地址
0x02 windbg技巧
1>用windbg附加要调试的程序时,在调试之前用gflag.exe开启了+hpa,但是在调试时,程序崩溃了而windbg没有断下来,这种情况
主要原因是被调试的程序衍生出子进程,而windbg默认情况下是不支持子进程调试的,可以使用如下命令开启子进程调试:
.childdbg 1
2>windbg找不到符号表时可用命令行添加符号表路径,eg:
.sympath+ SRV*c:\symbollocal\*http://symbols.mozilla.org/firefox
.reload
3>windbg设置条件记录断点,eg.
bu 55ea6514 ".if(1){.echo 'replen = ';dd ebx l1;gc}"