windbg调试命令


windbg调试命令

 #调试命令窗口

 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

#使用gflags.exe工具(在windbg所在目录下),让某个进程启动时,拉取windbg进行调试

如下截图:当名称为captcomm.exe的进程启动时,拉起windbg调试

#重要说明

(1) windbg命令分为标准命令元命令扩展命令

     标准命令提供最基本的调试功能,不区分大小写。如:bp  g  dt  dv  k等

     元命令提供标准命令没有提供的功能,也内建在调试引擎中,以.开头。如.sympath  .reload等

     扩展命令用于扩展某一方面的调试功能,实现在动态加载的扩展模块中,以!开头。如!analyze等

(2) 进入调试状态时,直接回车可重复执行上一条命令;按上下方向键可以浏览和选择以前输入过的命令

(3) 神奇的Tab键,进行命令补全;ESC清除当前命令输入框中的文本

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

(5) 上图红色框中的“0:000”。0当前调试会话的进程号000调试会话的线程号

(6) 当命令提示符显示*BUSY*时,即使命令输入框可以输入命令,但输入的命令不会立即被执行,要等windbg空闲时才能执行。

     可使用Ctrl + Break来终止一个长时间未完成的命令

(7) 一次可以执行多条命令,命令间用分号;分隔 【:bp main;bp `view.cpp:120`】,一次打2个断点

(8) 为了保证windbg流畅运行,在调试时,尽量不要开启Watch、Locals、Registers、Call Stack、Processes and Threads窗口,直接用command来获取信息

#启动调试

windbg -I  // 将windbg设置成默认调试器

windbg "notepad.exe" arguments  // 使用windbg启动调试notepad.exe

windbg -p 4200  // 将windbg附加到一个正在运行的pid为4200的进程上

windbg -pn "notepad.exe"  // 将windbg附加到一个正在运行的名为notepad.exe的进程上

windbg –z "c:\mydumpfile.dmp" // 调试mydumpfile.dmp文件

.opendump "c:\mydumpfile.dmp"  // 调试mydumpfile.dmp文件

.attach 0n4220  // 4220为十进制pid,使用该命令附加调试时,必须先存在一个调试会话

.detach   // 分离调试

.restart  // 重启并调试

.kill  // 强制结束当前调试

q  // 退出windbg

#获取帮助

?   // 打印出所有标准命令

.help  // 打印出所有元命令

.hh  // 打开windbg的chm帮助文件

.hh bp  // 打开windbg的chm帮助文件bp命令介绍页

command /?  // 打印命令command具体参数用法

#注释符

*  // 注释整行

$$ // 注释(遇到分号结束)

#配置调试环境

:如果被调试的模块(无论移动到本机的何处)是用本机代码编译产生的,都不需要进行符号和源代码的路径设置

.sympath   // 查看当前符号查找路径

.sympath c:\symbols   // 将符号查找路径设为:c:\symbols

.sympath+ c:\symbols  // 将c:\symbols添加到符号查找路径集合中

.symfix // 将符号查找路径设为:SRV*WinDbg安装目录\Sym*http://msdl.microsoft.com/download/symbols

.symfix f:\symbols // 将符号查找路径设为:SRV*f:\symbols*http://msdl.microsoft.com/download/symbols

.symfix+ f:\symbols  // 将SRV*f:\symbols*http://msdl.microsoft.com/download/symbols添加到符号查找路径集合中

.srcpath // 查看当前源文件查找路径

.srcpath f:\src // 将源文件查找路径设为:f:\src

.srcpath+ f:\src  // 将f:\src添加到源文件查找路径集合中

.exepath // 查看可执行文件查找路径

.exepath f:\bin // 将可执行文件查找路径设为:f:\bin

.exepath+ f:\bin  // 将f:\bin添加到可执行文件查找路径集合中

#符号加载与查看

除了使用ld和.reload命令直接加载符号文件,某些使用符号的命令也可以触发调试器来加载符号,如:栈回溯命令(k*)和反汇编命令(u)等。

值得说明的是,windbg缺省使用的是懒惰式符号加载策略,当它收到模块加载事件时,它通常是不会加载符号的,符号状态显示为deferred(延迟加载)。

.symopt // 显示当前所有符号选项

.symopt+ flags // 添加符号选项

.symopt- flags // 删除符号选项

!sym noisy   // 激活详细符号加载(noisy symbol loading)显示

!sym quiet   // 禁止详细符号加载显示

ld * // 为所有模块加载符号

ld kernel32 // 加载kernel32.dll的符号

.reload // 为所有已加载模块载入符号信息

.reload /i // 重新加载不匹配符号的模块【dmp文件没有对应的pdb时使用

.reload /i TGame.exe // 重新加载不匹配符号的TGame.exe

.reload /f /v // f:强制立即模式(不允许延迟载入)  v:详细模式

.reload /f @"c:\windows\System32\verifier.dll" // 为指定模块加载符号信息

.reload /f TGame.exe // 为TGame.exe加载符号信息

.chain  // 显示已经加载进来的模块

x *! // 列出所有模块对应的符号信息

lm // 列出所有模块对应的符号信息

lmvm ntdll  // 查看ntdll.dll的详细信息(注意exe、dll等都不要带后缀名)

x ConsoleTest!* // 列出ConsoleTest模块中的所有符号

x ConsoleTest!add* // 列出ConsoleTest模块中的所有add开头的符号

x /t /v ConsoleTest!* // 带数据类型、符号类型和大小信息,列出ConsoleTest模块中的所有符号

x kernel32!*LoadLib* // 列出kernel32模块中所有含LoadLib字样的符号

u  // 反编译当前线程的当前指令后的8条指令

uf CTest::add  // 反汇编CTest类的add函数

uf /c main  // 反汇编main函数,通过/c可以查看main函数中的函数调用(call)都有哪些

ub 000c135d L20  // 查看地址为000c135d指令前的20条指令内容

 

函数调用如果还没开始,即一般函数入口代码
push ebp
mov ebp, esp
还未执行,则[esp+4]表示第一参数值, [esp+8]表示第二参数,以此类推, [esp]表示的是返回地址
如果上面的入口代码已经执行,则一般通过ebp来获取函数参数和局部变量
[ebp+8]表示第一参数, [ebp+0xC]表示第二个参数,以此类推
[ebp+4]表示返回地址 [ebp]表示上一堆栈桢的基地址 [ebp-4]表示函数第一个局部变量

 

#进程与线程

|   // 列出调试进程

|*  // 列出调试进程

|N  // 参看序数为N的调试进程

|Ns // 切换序数为N的进程为当前调试进程

~   // 列出线程

~*  // 所有线程

~* k // 所有线程堆栈信息

~* r // 所有线程寄存器信息

~.  // 查看当前线程

~0s // 查看主线程

~# // 查看导致当前事件或异常的线程

~N  // 查看序数为N的线程

~~[n]  // 查看线程ID为n的线程

~Ns   // 切换序数为N的线程为当前调试线程

~N f  // 冻结序数为N的线程

~N u // 解冻序数为N的线程

~N n  // Suspend序数为N的线程

~N m // Resume序数为N的线程

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

#断点

bl   // 列出所有断点

bc * // 清除所有断点

bc 1 // 清除1号断点

bc 1 2 5  // 清除1号、2号、5号断点

be *  // 启用所有断点

be 1  // 启用1号断点

be 1 2 5 // 启用1号、2号、5号断点

bd *  // 禁用所有断点

bd 1  // 禁用1号断点

bd 1 2 5 // 禁用1号、2号、5号断点

bp 7c801b00  // 在7c801b00地址处放置一个断点

bp `ConsoleTest.cpp:36`  // 在ConsoleTest.cpp的36行处放置一个断点

bp main // 在main函数的起始处放置一个断点

bp CSecondLoader::CSecondLoader  // 在CSecondLoader的构造函数处放置一个断点

bp TestCommon! CTest::add  // 在TestCommon.dll的Test.cpp文件的CTest::add()函数起始处放置一个断点

bp `ConsoleTest.cpp:40` "j (poi(pVar)>5) '''g'" // j为条件表示式:条件断点 pVar指针指向的值>5,执行空语句;,断住  否则继续执行

---------------------------------

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) 返回第一个指针所指向的值

---------------------------------

bp `ConsoleTest.cpp:40` "j @eax = 0xa3 ''; 'g'" // j为条件表示式:条件断点 寄存器eax的值为0xa3时断住

bu  // 保存断点,其用法和bp一样

bm add_*  // 匹配add_开头的函数,并在这些函数起始处都打上断点

ba w4 0483dfe0 // 当对0483dfe0地址写操作时停下

                          // ba [r|w|e] [Size] Addr      [r=read/write, w=write, e=execute], Size=[1|2|4 bytes]

#调试执行控制

g  // Go(F5)

gH // 执行gH命令强制让调试器返回已经处理了这个异常。【Go with Exception Handled

     // 系统收到这个回复后会停止分发异常(因为调试器声称已经处理了异常),恢复调试目标继续执行,

     //  但由于异常条件仍在,所以还会产生异常,于是再次分发,WinDBG再次中断到命令模式。

gN // 【Go with Exception Not Handled

     // 执行gN命令强制让调试器返回没有处理了这个异常,那么系统会进一步分发该异常,

     // 如果没有其他调试器也不处理,最后系统会弹出程序终止对话框。

gu  // 执行到当前函数完成时停下Go Up

Ctrl+Break  // 暂停正在运行的程序

p    // 单步执行(F10)  【Step

p 2 // 2为步进数目

pc   // 执行到下一个函数调用处停下Step to  Next Call

pa 7c801b0b // 执行到7c801b0b地址处停下  【Step to Adress

t     // Step into(F11) 【Trace

tc    // 执行到下一个进入点处停下 【Trace to Next Call

ta 7c801b12  // 执行到7c801b12地址处停下 【Trace to Adress

# 查看变量

===  0n(十进制)  0x(十六进制)  0t(8进制)  0y(2进制)    可以使用n [8|10|16]命令来修改数值进制表示方式(输入n可查看当前进制,默认为16进制)===

dt nRet  // 查看局部变量nRet的类型与值(函数参数变量请用dv命令)

dt myApp!g_app // 表示显示myApp进程里全局变量g_app的内存布局(注:vc6编写的工程看不了)

dt WindbgTest!CTest // 查看模块WindbgTest的CTest的内存布局(注:vc6编写的工程看不了)

dt WindbgTest!CTest 0x0041f8d4  // 将0x0041f8d4地址处内容按照模块WindbgTest的CTest的内存布局来解析(注:vc6编写的工程看不了)

dt this // 查看this指针的类型及成员变量(注:vc6编写的工程看不了)

?? this->m_nPen  // 查看成员变量的值(注:vc6编写的工程看不了)

?? this // 查看this指针中的成员变量(注:vc6编写的工程看不了)

? nCount // 显示局部变量nCount的地址(前面4198608为10进制表示地址,004010d0为16进制表示地址) 形如:Evaluate expression: 4198608 = 004010d0

? HeapTest!CTest::Add  // 显示HeapTest模块中CTest类中的Add函数地址

dv   // 显示当前函数内所有局部变量,函数参数的值

dv n*  // 显示当前函数内n开头的所有局部变量,函数参数的值

dv nCount // 查看局部变量nCount的值

dv a // 查看函数参数变量a的值

dv /t /i /V /a|/n|/z

/***************************************** 

更加详细地显示当前函数内所有局部变量,函数参数信息
i = type (local, global, parameter)
t = data type
V = memory address or register location
-----------------------
a = sort by Addr, n = sort by name, z = sort by size

*****************************************/

x  // 用法和dv命令一致,显示当前函数内所有局部变量,函数参数的地址与值

#调用堆栈

k  // 显示当前调用堆栈

kn // 带栈编号显示当前调用堆栈

kb  // 打印出前3个函数参数的当前调用堆栈

 

02a9ffec 00000000 01e511f9 0174c570 00000000 kernel32!BaseThreadStart+0x37
----------------------------------------------
kernel32!BaseThreadStart+0x37 这个是函数地址。
01e511f9 0174c570 00000000 这是前三个参数。
02a9ffec 00000000是 ebp 和 返回地址。

 

kb 5 // 只显示最上的5层调用堆栈

kv   // 在kb的基础上增加了函数调用约定等信息

.frame // 显示当前栈帧

.frame n // 设置编号n的栈帧为当前栈帧

.frame /r n // 设置编号n的栈帧为当前栈帧 并显示寄存器变量

!uniqstack // 显示所有线程的调用堆栈

#寄存器

r // 显示所有寄存器信息及发生core所在的指令

r eax, edx // 显示eax,edx寄存器信息

r eax=5, edx=6  // 对寄存器eax赋值为5,edx赋值为6

#内存

da /c 5 7c801e02  // 从7c801e02内存处开始,显示5个ascii字符

/*****************************************

d[a| u| b| w| W| d| c| q| f| D] [/c 列数] [地址]

a = ascii chars
u = Unicode chars
b = byte + ascii
w = word (2b)
W = word (2b) + ascii
d = dword (4b)
c = dword (4b) + ascii
q = qword (8b)
f = floating point (single precision - 4b)
D = floating point (double precision - 8b)

*****************************************/

dyb /c 3 7c801e02  // 从7c801e02内存处开始,显示3个byte及二进制

/*****************************************

dy[b | d] ..   // b = binary+byte     d = binary+dword

*****************************************/

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

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

ea 0x445634 "abc"  // 表示在0x445634地址写入Ascii字符串abc, 不包含结束符0

eza 0x445634 "abc"  // 表示在0x445634地址写入Ascii字符串abc, 包含结束符0

eu 0x445634 "abc"  // 表示在0x445634地址写入Unicode字符串abc, 不包含结束符0

ezu 0x445634 "abc"  // 表示在0x445634地址写入Unicode字符串abc, 包含结束符0

ed nCounter 80  // 将变量nCounter的值修改为80(注:80为10进制还是16进制,还是其他,取决于当前进制)

#dump输出

 .dump /ma "d:\mydmpfile.dmp" // 将当前调试进程输出Dump文件

#其他元命令

.tlist  // 显示所有进程

.cls  // 清除屏幕

#其他扩展命令

!analyze -v  // 详细显示当前异常信息

!peb // 格式化输出PEB信息(process's environment block)

!gle  // 打印当前线程最近的错误信息LastError

!gle -all  // 打印所有线程的最近的错误信息

!error  897// 显示错误码为897的详细描述信息

#帮助

中文在线帮助:http://www.dbgtech.net/windbghelp/index.html

windbg cmd: http://www.slideshare.net/kewuc/windbg-cmds 【下载

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值