windbg入门实例

首先先了解一下使用率最高的命令:
查看调用栈:k[b|p|v]
kb显示三个参数;
kp或kP显示所有参数;
kv显示FPO与调用约定;
查看数据:d{a|b|c|d|D|f|p|q|u|v|w|W}
da: ASCII, du: unicode
dv: 局部变量
dc: DWORD&ASCII
dd: DWORD
dp: 按指针大小值,取决于是x86还是x64
详细参考https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/d--da--db--dc--dd--dd--df--dp--dq--du--dw--dw--dyb--dyd--display-memor
设置断点:b
可以针对某个符号下断点:
bu MyApp!SomeFunction
使用bm的话还支持匹配表达式:
bm user32!CreateWindow*
还有数据断点(指定内存被访问时触发):
ba w4 0x0483def(w为写操作,4指监控访问位置字节数)
设置断点还有很多高级用法,具体可参考https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/bp--bu--bm--set-breakpoint-
修改内存地址:e
类似于d命令,后面也可以加类型后缀
查看所有模块信息:lmf,查看某个模块的详细信息:lmvm,切换栈帧:.frame,反汇编指定地址:u
不必多说
在内存中搜索符号:dds, dps
这个东西还是有点有用的,特别是调试某些栈出了问题导致的崩溃问题时。
https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/dds--dps--dqs--display-words-and-symbols-
现在就看个简单例子吧,前天同事扔了个minidump给我,让我看看还能不能抢救一下,用vs看不到啥有用的信息,就下图:


虽然vs一般够用但是这种时候就显示出无奈了,打开WinDBG设置好符号路径,将dmp打开,看一下能不能看到更详细的调用栈:

可以看出这个栈就比VS靠谱多了,不过还是有一些乱七八糟的东西,什么Sogoupy都来了,并不像是真正的崩溃原因。不过可以看到有UnhandledExceptionHandler这个函数,这个函数熟悉win32开发的应该都了解,可以帮助在程序发生异常时捕获到,然后做一些事情,比如说写个dump之类的。这个函数的参数是一个EXCEPTION_POINTERS的结构体,里面保存了一些系统所捕获到的异常相关的信息,比如异常代码,寄存器的值等等,所以可以考虑一下看下这个东西还能不能读得到:
点一下蓝色的02,跳转到UnhandledExceptionHandler所在的栈帧:

可以看到windbg自动帮我们把栈帧内的局部变量都显示出来了,再看一下这个结构体里面有啥东西,还能不能读到:

可以看到里面的值基本上还是正常的,并不像是有受过什么破坏的样子。
这个时候来学习一下另外一个知识点,关于C++编译器一般情况下对寄存器的使用:
EBP:指向当前栈帧的栈基址
ESP:指向整个栈的栈基址
EIP:指向CPU将执行的下一句代码的地址
ECX:很有可能会指向this指针,不过由于编译器优化,并不一定准确
可以看到栈里还保存着另外一套寄存器的信息,又知道ESP指向整个栈,所以尝试一下能不能在esp的地址中找到一些符号,就用之前介绍的dps命令:

这才是真正的问题出现时的调用栈,与同事确认了应该确实是真正的崩溃原因,收工~

你可能感兴趣的:(windbg入门实例)