Windbg工作中用的不多,所以命令老是记不住,每次使用都要重新查命令,挺烦。

趁这次培训的机会好好测试和总结了一下,下次再用就方便多了。

在这里一起共享一下,如果有错误,请指正。

基本知识和常用命令

(1)       Windbg下载地址http://msdn.microsoft.com/en-us/windows/hardware/gg463009.aspx

安装完后执行windbg –I将Windbg设置成默认调试器

(2)       Windbg的命令分为标准命令,原命令和扩展命令,输入问号(?)可以显示所有的标准命令的帮助信息; 元命令以一个点(.)开始,输入.help可以显示所有的原命令的帮助信息;扩展命令以叹号(!)开始。

所有命令的具体用法可以通过F1查看Windbg的帮助文件。

(3)       通过设置符号文件路径,让Windbg自动从微软网站更新系统Dll的符号文件

SRV*d:\symbols* http://msdl.microsoft.com/download/symbols

(4)       用分号(;)作为分隔符,可以在一行输入多条命令

(5)       按上下箭头可以浏览和选择以前输入过的命令

(6)       Ctrl+Break终止一个很长时间没有完成的命令, Ctrl+Break也可以让正在运行的程序暂停

(7)       Windbg默认的数值进制一般是16, 可以通过n命令查看和设置当前进制,所以我们一般在数值里带上进制, 0n(十进制), 0x(十六进制), 0t(8进制), 0y(2进制), 比如0n20表示20, 0x14表示20等

(8)       可以通过问号命令(?)显示表达式值,双问号(??)显示C++表达式值, 通过.cls命令清屏

(9)       如果x表示的一个地址, 则可以通过以下方法获取x所指向的值

hi(x) 高16 bits

low(x) 低16 bits

by(x) 返回第一个byte

wo(x) 返回第一个word

dwo(x) 返回第一个dword

qwo(x) 返回第一个4 word(Quad-word)

poi(x) 返回第一个指针值

(10)   函数调用如果还没开始,即一般函数入口代码

push ebp

mov ebp, esp

还未执行,

则[esp+4]表示第一参数值, [esp+8]表示第二参数,以此类推, [esp]表示的是返回地址

如果上面的入口代码已经执行,则一般通过ebp来获取函数参数和局部变量

[ebp+8]表示第一参数, [ebp+0xC]表示第二个参数, 以此类推,[ebp+4]表示返回地址 [ebp]表示上一堆栈桢的基地址。

[ebp-4]表示函数第一个局部变量

(11)   条件表达式

j<条件表达式>[Command1];[Command2]

例如bp consoletest!add “j(dwo(esp+4)==0n10) ‘kv;.echo \”break\”‘;’g'” 表示条件断点,如果consoletest!add的第一个参数是10, 则打印堆栈,输出”break”, 并暂停,否则继续执行

也可用元命令代替

bp consoletest!add  “.if(dwo(esp+4)==0n10) {kv;.echo \”break\”} .else {g}”

(12)   上下文

上下文(Context)包括会话(Session)上下文, 进程上下文,寄存器上下文,局部变量上下文。

会话上下文和登陆用户帐号有关。进程上下文和当前调试的默认进程有关, 寄存器上下文和当前默认线程有关。

局部变量上下文和当前的堆栈桢有关, 比如可以通过.frame [index] 切换当前堆栈桢,然后通过dv 显示当前堆栈桢函数的局部变量(堆栈桢的index从0开始,可以通过kn命令显示堆栈桢索引)

(13)   保存dump文件

.dump /ma c:\test.dmp 保存full-dump

.dump /m c:\test.dmp 保存mini-dump

(14)   分析Dump

一般先 !analyze –v Windbg会根据上面命令自动分析,

然后 ~* kv 打印所有线程的堆栈

(15)   重新加载符号文件

.reload –f [name], 强制重新加载某个模块的符号文件

比如 .reload –f  test.dll

(16)   察看模块信息

lm显示所有模块信息

lmf 显示所有模块及其路径

lmD 显示所有模块详细信息

!lmi  [module name] 显示某一模块的详细信息

(17)   分析调试符号

X [选项] 模块名!符号名

比如x ntdll!dbg*显示所有ntdll模块中以dbg开头的符号

比如x test!cmyclass::init 显示test模块中cmyclass类中的init函数符号

(18)   搜索符号

ln [address] 搜索离address最近的符号名(list nearest symbols)

(19)   事件处理

可以通过菜单Debug->Event Filter…设置

sx 显示各个事件的代码和目前的处理选项

sx {e|d|i|n} [command]  , e|d|i|n分别对应Enabled, Disabled,Output和Ignore

比如 sxe ld user32.dll 表示在加载user32.dll时设置的中断

sxr 恢复成默认设置

(20)   单步调试

g 继续运行(go), 热键F5

t 单步越过(step over), 热键F10

p 单步进入(step into), 热键 F11

(21)   设置断点(break point)

bp [address] [“command”] 设置软件断点。

比如 bp kernel32!CreateProcessW表示在调用这个CreateProcess时设置断点。

比如bp kernel32!CreateFileW “du poi(esp+4); g” 表示在调用CreateFile时打印出文件路径(第一个参数),然后继续执行

针对某线程设置断点,只要在命令前加~线程号:

比如 ~0 bp 0x441242, 表示0号线程执行到地址0x441242时中断

ba [access size] [command]设置硬断点。

其中,access指定访问方式(e执行指令, r读取数据,w写入数据)

size 表示监视数据的大小(1, 2, 4)

比如ba r4 0x414422, 表示在地址0x414422写入4字节数据是触发断点

(22)   管理断点

bl 列出所有当前断点的状态

bc 清除断点, bc * 清除所有断点, bc 0 清除0号断点

bd 禁用某个断点(disable)

be 打开某个断点(enable)

(23)   察看堆栈

kn [frame count]察看当前堆栈及其索引, frame count指定要显示多少桢

kb显示堆栈桢地址,返回地址,参数,函数名等

kv在kb的基础上增加了函数调用约定等信息, 所以推荐用kv命令察看堆栈.

.frame [frame index] 将当前堆栈切换到某个堆栈桢, 比如.frame 1 切换到第1桢

dv 命令察看当前堆栈桢的局部变量

(24)   察看和修改寄存器

r显示所有寄存器的值

r  eax=0x100 将eax寄存器的改成0x100

(25)   显示内存区域(dump memory)

d{a|b|d|D|f|q|u|w} [range]

其中a表示ASCII码,b表示byte, d表示DWORD, D表示double, f表示float, q表示8字节, u表示Unicode String, w表示word

Range 表示地址范围,可以用2种表示:一是起始地址加终止地址, 二是起始地址加L长度(不是字节长度,是单位长度)。

比如 dw 77e0d827 L10 表示显示77e0d827开始的10个word

比如 dd 77e0d820 77e0d844, 表示显示 77e0d820 和77e0d844之间的所有dword

比如 du 77e0d820, 表示77e0d820开始的以0结尾的字符串

dps [range] 显示某一地址范围内的符号(display word and symobols)

(26)   显示数据类型(dump symbolic type information)

dt [模块名!]类型名

dt testApp!g_appInstance 表示显示testApp里全局变量g_appInstance的内存布局

dt 0x0458e850 test!CMyApp 表示将地址0x0458e850以test!CMyApp类地址解析,并打印内存布局, 所以只有私有符号才有这个功能

如果当前堆栈桢是在某个类函数内,可以通过dt this 打印当前类的内促布局。

(27)   搜索内存(search memory)

s –[type] range pattern

其中type, b表示byte, w表示word, d 表示dword, a表示ASCII string,u表示unicde string

Range 表示地址范围,可以用2种表示:一是起始地址加终止地址, 二是起始地址加L长度(不是字节长度,是单位长度)。如果搜索空间长度超过256M,用L?length。

Pattern指定要搜索的内容.

比如 s -u 522e0000 527d1000 “web”表示在522e0000 和527d1000之间搜索Unicode 字符串”web”

比如s -w 522e0000 L0x100  0x1212 0x2212 0x1234 表示在起始地址522e0000之后的0x100个单位内搜索0x1212 0x2212 0x1234系列的起始地址

(28)   修改内存 (edit memory)

e{a|u|za|zu} address “String”

其总za和zu表示以0结尾的Ascii和Unicode字符串, a和u则表示没有0结尾

比如 ezu 0x445634 “abc” 表示在0x445634地址写如unicode 字符串abc

比如ea 0x445634 “abc” 表示在0x445634地址写入Ascii字符串abc, 不包含结束符0

e{a|b|d|D|f|q|u|w} address [values]

其中a表示ASCII码,b表示byte, d表示DWORD, D表示double, f表示float, q表示8字节, u表示Unicode String, w表示word

比如eb  0x123432 0x41 0x41 0x41 表示在地址0x123432 写入3个0x41

(29)   观察内存属性

!address [address]

比如!address 0x414453, 显示地址0x414453所在区域的内存属性

!heap -h 显示所有的内存堆(heap)

(30)   反汇编某一地址

u address, 比如u 0x410040表示反汇编地址0x410040的代码

uf  反汇编某个函数, 比如uf test!main

ub 反汇编某地址之前的代码,比如ub 0x 0x410040 L20

(31)   进程线程控制

~*命令显示当前所有线程的详细信息

~[Index]   n增加索引为Index的线程的挂起计数

~[Index]  m减少索引为Index的线程的挂起计数

比如通过~2 n 增加2号线程的挂起计数后, 执行g命令(继续运行), 这时2号线程会依然暂停运行。

~[Index]  f 冻结某一线程的执行

~[Index] u 解冻某一线程的执行

~[Index]  g只运行线程号为index的线程

~[Index] s 切换当前线程

比如 ~2 kv; ~2 r 可以打印2号线程的当前堆栈和寄存器

~* kv可以打印所有线程堆栈。

!runaway 显示所有线程的CPU消耗

|. 显示当前调试进程

|* 显示当前调试中的所有进程

|[nIndex] s 切换当前调试进程

!peb 显示进程信息块(process environment block)

!teb 显示线程信息块(thread environment block)

(32)   线程死锁

!locks 显示死锁

!handle 列出当前进程所handle

!handle [index] f, 显示某个handle的详细信息

(33)   自动调试子进程

.childdbg 0

Disable child process debugging

.childdbg 1

Attach child process automatically

(34)   脚本支持

$$>< filename 加载脚本文件,并将脚本里的换行符自动换成;(分号)

$t0~$t19为伪寄存器,可用来存储临时值, 使用伪寄存器时前面尽量加@符号以加快搜索

.printf 可以输出格式化信息

as Name EquivalentLine 别名,类似define宏 , 比如 r $t0=poi(esp+4); as $filename $t0

ad Name 删除别名, ad*删除所有别名

al 列出所有别名

.block {…}重新开始替换里面的所有别名

${alias}强制要求替换里面的别名, ${/v:alias}不要替换里面的别名

运用别名的脚本样例:

bp Kernel32!CreateFileW ”

r $t0=poi(esp+4)

as /mu ${/v:$fileName} @$t0

.block

{

.if( $sicmp(\”${$fileName}\”, \”C:\\11.txt\”)==0)

{

.echo OK

.printf \”done:%mu\”, @$t0

}

.else

{

.echo error

}

}

ad ${/v:$fileName}

gc

FAQ

(1)       如何在某个窗口收到某个消息时设置断点? 比如在我想在某窗口收到系统最小化消息时设置断点,该怎么操作?

其实就是监视窗口处理函数MsgProc(hWnd, WM_SYSCOMMAND, SC_MINIMIZE, 0)消息:首先通过Spy察看窗口句柄, 比如为0x350d72; 通过Spy也可以看到窗口消息处理函数的地址,比如00E814DE; 察看WM_SYSCOMMAND的值(0x0112); 察看SC_MINIMIZE的值0xF020,因此我们可以写入如下条件断点:

bp 0xE814DE

“j((dwo(esp+4)==0x350d72)&(dwo(esp+8)==0x0112)&(dwo(esp+0xc)==0xF020)) ‘kv’;’g’”

上面的命令表示在调用窗口函数时如果符合我们的条件,则打印堆栈(kv)并暂停,

否则继续执行(g).

(2)       堆栈桢的含义

堆栈生成原理:

堆栈从高地址向低地址生长,

__stcall和__cdecl调用约定都是从函数参数的右到左压栈.

因此调用某一函数比如int add(int a, int b) { return a + b;}

我们调用 add(1, 2)函数时,

从堆栈高地址到低地址依次入栈, 依次是参数2入栈, 参数1入栈,返回地址(ret address)入栈,然后跑到add函数执行入口代码push ebp   ,  mov ebp, esp , 即上一函数桢的基址(ebp)入栈, 然后将当前的堆栈指针值赋给ebp(保存当前的堆栈指针给ebp, 这样可以用新的ebp操作当前函数的局部变量,该函数内部再调用某个函数时也能通过新ebp知道上一函数的基栈地址, 所有函数调用都以此类推)。

所以从堆栈低地址到高地址依次表示ebp(上一函数的堆栈桢基址), ret address, parameter 1, parameter 2…

(3)       如何用Windbg写高级脚本

参考http://blogs.msdn.com/b/debuggingtoolbox/archive/tags/windbg+scripts/default.aspx

(4) 如何将64位Dump转成32位

.load wow64exts 回车

!sw 回车

附:Windbg 用法详解

Posted by crinai @ 15:31:39

Windbg实用手册的更多相关文章

  1. WinDbg 命令三部曲:(一)WinDbg 命令手册

    本文为 Dennis Gao 原创技术文章,发表于博客园博客,未经作者本人允许禁止任何形式的转载. 系列博文 <WinDbg 命令三部曲:(一)WinDbg 命令手册> <WinDb ...

  2. 实用手册:130+ 提高开发效率的 vim 常用命令

    Vim 是从 vi 发展出来的一个文本编辑器.代码补完.编译及错误跳转等方便编程的功能特别丰富,在程序员中被广泛使用.和 Emacs 并列成为类 Unix 系统用户最喜欢的编辑器.这里收录了130+程 ...

  3. WinDbg 命令手册

    WinDbg 命令三部曲:(一)WinDbg 命令手册   本文为 Dennis Gao 原创技术文章,发表于博客园博客,未经作者本人允许禁止任何形式的转载. 系列博文 <WinDbg 命令三部 ...

  4. 【转载】Exchange 2010配置与安装实用手册

    Exchange 2010配置与安装实用手册 在Exchange 2010配置的时候主要分三大部分,这分别是网络配置.准备存储以及相关的安装策略和过程.同时还需要注意和其他的Windows软件相协调. ...

  5. Oracle 数据库基本操作——实用手册、表操作、事务操作、序列

    目录: 0. 参考链接与参考手册1. oracle 实用(常用操作)指令2. 数据库基本操作语法 a) 表操作 1)创建表 2)更新表 3)删除表 4)查询 b) 事务操作 c) 序列操作 1)创建序 ...

  6. linux sort 命令实用手册

    Linux 中的sort 命令是一个很实用的工具,用于对文本内容以行为单位进行ASCII 码排序,默认按照升序进行排序(当然也可以按照降序). sort 命令的格式如下: sort `参数` `文件名 ...

  7. linux awk 命令实用手册

    0,简介 Linux awk 是一个实用的文本处理工具,它不仅是一款工具软件,也是一门编程语言.awk 的名称来源于其三位作者的姓氏缩写,其作者分别是Alfred Aho,Peter Weinberg ...

  8. NMAP实用手册

    nmap在网络和渗透中使用相当频繁,相关教程也层出不穷.在此,我只整理出最实用的,言简意赅,方便自己,方便他人. 一.nmap介绍 NMAP,也就是Network Mapper,最早是Linux下的网 ...

  9. MSDN上关于WinDbg的手册

    参考:http://msdn.microsoft.com/en-us/library/windows/hardware/ff540507(v=vs.85).aspx 这是最靠谱的参考了,比.hh要直观 ...

随机推荐

  1. AutoCad 二次开发 Jig操作之墙块的拖动

    测试结果: 主要思路:选择一段多段线,使用封装的jig类进行实时拖动,其原理就是在拖动的时候,确定被拖动的边,我是选择离输入第一个点最近的边作为拖动边,有了这条边,就能确定需要实时更改的点了,然后当鼠 ...

  2. win7技巧

    win7技巧 快捷键 一.Windows键 + 空格键“Space” [作用]:透明化所有窗口,快速查看桌面(并不切换) [快捷键]:win+空格 [小结]:当你打开了很多程序窗口的时候,这招非常有用 ...

  3. C++中重载、重写(覆盖)和隐藏的区别

    转载自:https://blog.csdn.net/zx3517288/article/details/48976097 基本概念: 重载:是指同一可访问区内被声明的几个具有不同参数列(参数的类型,个 ...

  4. Django常用字段及参数、事务、数据库查询优化

    常用字段 注意: Django中没有设置对应char类型的字段,但可以支持自己定义. 自定义对应于数据库的char类型字段: from django.db.models import Field cl ...

  5. 11 个最佳的 Python 编译器和解释器

    原作:Archie Mistry 翻译:豌豆花下猫@Python猫 原文:https://morioh.com/p/765b19f066a4 Python 是一门对初学者友好的编程语言,是一种多用途的 ...

  6. electron-vue 设置cookie

    //设置登录cookie setCookie(name,value){ var Days=30; var exp=new Date(); var date=Math.round(exp.getTime ...

  7. cf 450b 矩阵快速幂(数论取模 一大坑点啊)

    Jzzhu has invented a kind of sequences, they meet the following property: You are given x and y, ple ...

  8. Mysql连接出现时区问题

    错误提示: The server time zone value '¥x¥_¼Ð·Ç®É¶¡' is unrecognized or represents more than one time zon ...

  9. 测试必备之Java知识(四)—— 线程相关

    线程相关 Java多线程实现方式 继承Thread,实现Runnable接口,实现Callable接口(能抛异常且有返回值,不常用) 为什么有了继承Thread方式还要有Runnable接口方式 实现 ...

  10. 今天我的jupyter notebook打不开了,报错原因'No module named 'zmq.eventloop'

    今天我的jupyter notebook打不开了,就是那种一打开出现黑色界面就退出的那种,惊恐爬上了我的面颊. 找了一个小时,试了好几种办法(包括别人说的什么把属性里面后面的%%的去掉)终究无果 打开 ...