windbg常见命令

WinDbg

WinDbg支持以下三种类型的命令:

·        常规命令,用来调试进程

·        点命令,用来控制调试器

·        扩展命令,可以添加叫WinDbg的自定义命令,一般由扩展dll提供这些命令

PDB文件

PDB文件是由链接器产生的程序数据库文件。私有PDB文件包含私有和公有符号,源代码行,类型,本地和全局变量信息。公有PDB文件不包含类型,本地变量和源代码行信息,且只包含共有成员的调试信息。

Dump文件

利用Dump工具,你可以获得进程的快照信息。一个mini-dump包含当前进程的所有线程,线程栈信息和已加载模块信息。一个full-dump包括更多信息,如堆信息。

使用WinDbg调试

1.       启动WinDbg

要用WinDbg(x86)调式32位程序,用WinDbg(x64)调试64位程序。

2.       使用帮助

任何时候都可以使用!help命令来获取帮助,查看命令的使用方法。

3.       设置SymbolFile Path,指定了符号库,我们才能看到详细的类型信息

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

WinDbg会将微软的符号库下载指定的本地目录中,以上设置可以使用以下命令来实现:

.symfixc:\symbols,此命令表示要连接到Microsoft服务器下载调试符号文件,符号文件将被下载到c:\symbols目录中。

还可以使用.sympath命令来显示当前的符号路径设置。

4.       重新加载符号

如果进入调试之后才指定的符号路径,需要使用命令来重新加载符号

.reload

5.       加载调试扩展

调试扩展定义了很多命令来调试.net程序。使用调式非托管代码的命令来调试.net程序是非常困难的。下面的命令加载了用于调试.net程序的sos模块。

a.      对于.Net Runtime 2.0

.loadby sos mscorwks

b.     对于.Net Runtime 4.0

.loadby sos clr

sos是一个dll,定义了很多针对.net assembly的调试命令,sos.dll针对不同的runtime有不同的版本。如果使用.load命令,需要为sos.dll指定完整路径。如果使用.loadby命令,则表示要在mscorwks.dll和clr.dll的同一目录下查找sos。对于.net程序,基本上都会加载mscorwks.dll(2.0)和clr.dll(4.0)。

6.       查看线程

a.      包括托管线程和非托管线程

~

b.     查看托管线程

!threads

c.      显示有关托管线程池的信息,包括队列中工作请求的数目、完成端口线程的数目和计时器的数目。

!ThreadPool

d.     切换线程(中间的数字表示线程号)

~0s

e.     查看线程栈, 仅提供托管代码的堆栈跟踪。

!clrstack [-a] [-l] [-p] [-n]

-p 选项显示托管函数的参数。

-l 选项将显示有关帧中的局部变量的信息。若SOSdebugging extension 未能检索本地名称,因此,本地名称的输出格式<local address>= <value>。

-a (all) 选项是一个表示 -l 和 -p 的组合的快捷方式。

-n 选项禁止显示源文件名和行号。

在基于x64 和IA-64 的平台上,SOS调试扩展不显示过渡帧。

f.       查看线程栈,只能正常显示非托管部分

k

g.      显示线程栈全部信息,包括托管和非托管部分

!dumpstack [-EE] [-n] [top stack [bottom stack]]

-EE 选项使DumpStack 命令仅显示托管函数。使用top 和bottom 参数可限制x86 平台上显示的堆栈帧。

-n 选项禁止显示源文件名和行号。如果调试器已指定选项

显示所有线程栈信息

h.     对一个进程中的所有线程运行 DumpStack 命令

!EEStack [-short] [-EE]

将-EE 选项直接传递给DumpStack 命令。-short 参数将输出限制为以下类型的线程:

·        已获取锁的线程。

·        己停止运行以允许垃圾回收的线程。

·        当前在托管代码中的线程。

i.     显示所有线程的堆栈

~*e !clrstack

j.       显示在当前堆栈的边界内找到的所有托管对象

!dumpstackobjects [-verify] [top stack [bottom stack]] 或 !dso

7.       查看堆中的所有对象信息,包括类型信息,个数,大小等

!dumpheap –stat

a.      指定对象类型,如果需要结果准确,需要使用全名称,类型名称是大小写敏感的

!dumpheap -type FlowThrottle –stat

b.     以上命令输出的第一列是mt(method table)信息,表示类型对象的地址。我们可以使用此信息来明确指定我们感兴趣的对象在堆中的信息。

!dumpheap -mt 000007feee769c00  -stat

注意,如果不指定-stat,那么输出每个对象的信息,使用-stat,将会看到统计信息。

c.      使用如下命令只输出对象地址

!dumpheap -mt 000007feee769c00  -short

d.     -short 选项将输出限制为只是每个对象的地址。这使您方便地以管道方式将输出从该命令转移到另一个调试器命令,以便自动化。

e.     -min 选项忽略小于 size 参数指定的大小(单位为字节)的对象。-max 选项忽略大于size 参数指定的大小(单位为字节)的对象。

8.       显示有关内部公共语言运行时数据结构所使用的进程内存的信息。

EEHeap [-gc][-loader]

-gc 和-loader 选项将此命令的输出限制为垃圾回收器或加载程序数据结构。有关垃圾回收器的信息列出了托管堆中每个段的范围。如果指针落在由-gc 给出的段范围内,则该指针是一个对象指针。

9.       打印对象信息,指定任何有效的对象地址,就能查看该对象的内容

!dumpobj <address>或者 !do<address>

输出的对象信息中有每个属性的地址信息,所以可以继续使用!do命令来打印属性指向的对象信息。

!dumpobj –nofields<address>或者!do <address>

nofields选项指示不要输出对象字段信息,当对象是string类型时,该选项就非常有用。

10.   显示有关指定地址处的值类字段的信息。

DumpVC<MethodTable address> <Address>

MethodTable 参数使DumpVC 命令可以正确解释字段。值类不使用方法表作为它的第一个字段。

11.   输出多个对象信息

.foreach (myobj{!dumpheap -mt 008f4104-short}) {!do ${myobj}}

以上命令指示,对于堆中所有类型为008f4104的对象,依次调用!do命令。

12.   打印数组信息

!dumparray [-start<startIndex>] [-length <length>] [-details] [-nofields] <arrayobject address>或者!da

·        -start 选项指定开始显示元素的起始索引。

·        -length 选项指定要显示的元素数量。

·        -details 选项使用 DumpObj 和 DumpVC 格式显示元素的详细信息。

·        -nofields 选项可阻止显示数组。此选项只有在指定了-detail 选项之后才可用。

下面的命令显示在地址 00ad28d0 处的数组内容。显示从第二个元素开始,连续显示五个元素。

!dumparray -start2 -length 5 -detail 00ad28d0

13.   输出app domain信息

!dumpdomain

枚举在指定的 AppDomain 对象地址内加载的每个Assembly 对象。若在调用DumpDomain 命令时不提供任何参数,则将列出进程中的所有AppDomain 对象。

14.   输出程序集信息

!dumpassembly

15.   打印方法表

!dumpmt [-MD]<MethodTable address>

显示有关指定地址处的方法表的信息。指定-MD 选项将显示与对象一起定义的所有方法的列表。每个托管对象都包含一个方法表指针。

16.   打印EEClass结构,其中可以看到类型静态变量信息

!dumpclass<EEClass address>

显示有关与类型关联的 EEClass 结构的信息。DumpClass命令显示静态字段值,但不显示非静态字段值。使用DumpMT、DumpObj,Name2EE 或Token2EE 命令获取EEClass 结构的地址。

17.   显示异常

a.      使调试器在引发指定异常时停止,但在引发其他异常时继续运行。

!StopOnException [-derived] [-create | -create2]<Exception> <Pseudo-register number>

-derived 选项用于捕获指定异常以及从指定异常派生的每个异常。

b.     显示当前活动线程上的最后一个异常

!PrintException [-nested] [-lines] [<Exception objectaddress>] 或 !PE

显示从指定地址处的Exception 类派生的任何对象的字段并设置这些字段的格式。如果不指定地址,PrintException命令将显示在当前线程上引发的最后一个异常。

-nested 选项显示有关嵌套异常对象的详细信息。

-lines 选项显示源信息(如果可用)。

c.      显示发生在所有线程上的最后的异常

~*e !pe

18.   调试GC相关信息

a.      显示有关对指定地址处的对象的引用(或根)的信息。

!GCRoot [-nostacks] <Object address>

GCRoot 命令将检查整个托管堆和句柄表以查找其他对象内的句柄和堆栈上的句柄。然后,在每个堆栈中搜索对象的指针,同时还搜索终结器队列。此命令无法确定堆栈根是有效的还是已丢弃。使用CLRStack 和U 命令可对本地或参数值所属的帧进行反汇编,以便确定堆栈根是否仍在使用中。

-nostacks 选项将搜索限制为垃圾回收器句柄和 Freachable 对象。

b.     显示所有已进行终结注册的对象。

!FinalizeQueue [-detail] | [-allReady] [-short]

-detail 选项显示有关需要清理的任何 SyncBlocks 的额外信息以及有关等待清理的任何RuntimeCallableWrappers (RCW) 的额外信息。这两种数据结构都由终结器线程在运行时进行缓存和清理。

-allReady 选项显示所有准备终止的对象,无论它们已被垃圾回收标记成这样,还是将被下一个垃圾回收标记。在“准备终止”列表中的对象为不再为根的可终止对象。此选项可能耗费大量资源,因为它验证可终止队列中的所有对象是否仍然为根对象。

-short 选项将输出限制为每个对象的地址。如果与-allReady 一起使用,则将枚举具有不再为根的终结器的所有对象。如果单独使用,则将列出终结和“准备终结”队列中的所有对象。

19.  设置断点

!bpmdSystem.Windows.Forms.dllSystem.Windows.Forms.MessageBox.Show

第一个参数是dll文件名,第二个是完整的方法名。

20.  查看所有断点列表

bl

21.   释放当前断点, 让程序继续运行。让程序运行到断点后WinDBG会自动停下来。

g

22.   显示公共语言运行时版本。

!eeversion

23.   清除屏幕信息,该命令还你一个清洁的屏幕

.cls

24.   退出当前调试

q

//断点相关

bp + 地址设置断点

bl  显示已经设定的断点

bu + 地址设置断点,但是这种类型断点再下一次启动时被记录

bc 清除断点

对于断点范围,可以用*匹配,-表示一个范围,表达多个可用,号隔开

程序入口伪寄存器

WinDbg里有个伪寄存器叫$exentry,里面记录了程序的入口点。所以我们只要在命令输入栏里输入

bp $exentry

(bp就是用来下断点的命令,详细用法可以参考WinDbg的帮助文档)

//调试符号

ld kernerl32 //加载kernerl32模块的符号

lm   m k*        //显示已经加载的,以k开头的模块

ln         //显示最近操作过的模块名

dt dbg2     //检测模块

[[[[[[[[[[[[]]]]]]]]]]]]

x kernerl32!k* 显示模块kernerl32中所有以k开头的函数

dv 显示局部变量值

dv /i/t/v 显示局部变量的类型,值相关信息。

x <module>!* / ? 显示指定模块的符号

x argc 查看变量argc的值。

dt argc 查看变量值

dt _PEB 7ffdd00 将内存地址7ffdd00开始的内容以PEB结构的方式显示出来。

dd 12000 L4 查看地址12000 后面的四个字

dds 12000 L100 查看堆栈上地址12000开始,后面的100个dword的内容,如果有调试符号,会将符号显示。此方法来追踪堆栈。(先看ebp,再用此方法)

dd ebp + 4, 返回地址, ebp + 8 第一个参数

[[[[[[[[[]]]]]]]]]

.kill 杀死调试进程

.restart 重新调试

[[[[[]]]]]]]]]]]]]]

k 显示调用堆栈

,kn加序号而已。

kb 显示前三个参数。第一个参数ebp+8;第二个ebp+0x0C;第三个ebp+0x10;dd ebp+0x14是第四个参数

kp 显示函数参数类型,数值

kp f f开关显示相邻栈基之差,从而可以推断出栈的健康状况。

[[[[[[[[[[]]]]]]]]]]

| 显示进程

~显示线程

~0 s 切换到 0号线程

[[[[[[[[[]]]]]]]]]

dv 显示函数参数&局部变量,注意,dv是跟栈帧相关的,对不同的栈帧显示不同的局部变量。

@1, kn 显示所有栈帧

@2, .frame选择想要查看的栈帧

@3, dv /i/v/t显示该栈帧里局部变量信息

@3, dv /i /V /t 显示变量基于栈帧的地址

如果没有私有符号,dv是不能显示变量信息的。

vc 生成的调试符号*.pdb windbg不认识,需要设置为c++/General/DebugInfo= C7 compatible

=====

sympath + c:\nasm 添加符号搜索路径

.sympath 显示符号搜索路径

//显示一定范围内存

!db L 32 : results in 32 bytes being displayed (as hexadecimal bytes),

//查看pe信息

!dh [Options] Address : 查看模块pe信息

!dh -f : display file headers

!dh -s : section headers

!dh -a : all header informations

查看结构体成员

dt nt!_EPROCESS

查看当前的irql

!irql

查看Verifier 检测统计信息

!verifier

查看某个内存地址属于那一个模块

!pool 地址

!lmi Address  : 查看模块的主要信息

!pcr 可以查看当前执行的线程及irql, 等信息

//

Why doesn‘t the WinDBG command !irql always return the correct IRQL for my target?

[Answer by Jake Oshins, jakeo_at_windows_dot_microsoft_dot_com. Workaround provided by James Antognini, antognini_at_mindspring_dot_nospam_dot_com, 27 August 2003]

!irql currently only produces useful results on a crashdump, not a live system. To retrieve the current IRQL on a live system you should instead use the !pcr command.

!processfield:列出EPROCESS的成员

该命令前的!号,意味着它来自于调试器的扩展模块―kdextx86.dll。该命令可显示内核用来代表一个进程的EPROCESS结构(该结构并没有正式的说明文档)的成员及其偏移量。

尽管该命令仅列出了成员的偏移量,但你也能很容易的猜出其正确的类型。例如,LockEvent位于0x70处,其下一个成员的偏移量为0x80。则该成员占用了16个字节,这与KEVENT结构非常类似。

!threadfields:列出ETHREAD成员

这是kdextx86.dll提供的另一个强大的选项。和!processfields类似,它列出未文档化的ETHREAD结构的成员及其偏移量。内核使用它表示一个线程.

//进程信息

!tep

!peb ,显示peb(进程信息)

//显示相关

dt ntdll!*teb* 列出匹配通配符的结构名

dt -v -r ntdll!_TEB

列出结构_TEB的成员信息

//显示变量地址

r $peb 显示模块peb的地址

//查看错误信息

!gle

//设置断点的技巧

可以直接把断点设在: kernel32!BaseProcessStart

1), 先用lm 显示所有已经加载的模块

2), dt our_exe_name!*main*  //在我们的程序模块中搜索包含main的地址(注意:如果未加载symbol是不能显示的!)

3), 如果存在,在our_exe_name!*main 处设置断点

=======

Command     SoftICE OllyDbg

Run         F5     F9

Step Into     F11 F7

Step Over     F10 F8

Set Break Point F8 F2

搜索内存

5、查找字符串

在步骤1我们运行程序时就记录了提示注册错误的字符串“Wrong Serial, try again!”,现在我们就要在内存找到该字符串的位置。

输入命令

s –a 00400000 L53000 “Wrong”

该命令的意思是以ASCII码形式在内存地址00400000往后53000个字节搜索字符串“Wrong”。

s,就是要调用查找的命令

-a,指定使用ASCII码的形式查找

00400000,指定要开始寻找的内存地址。

L53000,说明要在00400000往后的53000字节搜索。这个数值和00400000都可以从Stud_PE获得。00400000是程序的装入地址,而53000是映像的大小,也就是程序载入内存后占用的内存大小。使用这两个数值,基本上可以搜索到程序使用的整个内存范围。

“Wrong”,就不用多解释了,就是我们要寻找的字符串。不过WinDbg不支持模糊搜索,所以这里输入的字符串必定要完全正确。

内存访问断点

6、下内存访问断点

WinDbg中,ba命令代表Break On Access,即访问时中断。

我们在命令行输入:

ba r 1 0044108c

命令的意思是在内存0044108c的位置下字节的读断点。命令中各元素的含义可以参考帮助文档,这里不啰嗦。

输入bl,查看断点使用情况:

地址运算

? 0x33 + 0x44

运行后将得到计算和

3.查看和修改数据

调试中不可避免的要查看和修改数据

查看内存:

db/dw/dd/dq [Address]       字节/字/双字/四字方式查看数据

da/du [Address]           ASCII字符串/Unicode字符串方式查看指定地址

其它常用的如查看结构

dt nt!_EPROCESS

dt nt!_EPROCESS 89330da0 (把0x89330da0作为对象指针)

修改内存:

eb/ew/ed/eq/ef/ep Address [Values]

字节/字/双字/四字/浮点数/指针/

ea/eu/eza/ezu Address [Values]

ASCII字符串/Unicode字符串/以NULL结尾的ASCII字符串/以NULL结尾的Unicode字符串

搜索内存:

s -[b/w/d/q/a/u] Range Target

搜索字节/字/双字/四字/ASCII字符串/Unicode字符串

2.断点

断点之于调试当然是非常重要的

常用命令:

bp [Address]or[Symbol] 在指定地址下断

可以使用地址或符号,如

bp 80561259(Windbg默认使用16进制)

bp MyDriver!GetKernelPath

bp MyDriver!GetKernelPath+0x12

bp [Address] /p eprocess 仅当当前进程为eprocess时才中断

这个很常用,比如你bp nt!NtTerminateProcess,但是只想在某一进程触发此断点时才断下来,那就加上这个参数吧,因为内核中的代码是各个进程共用的,所以此命令很实用

bp [Address] /t ethread 仅当当前线程为ethread时才中断,用法跟/p参数类似

bu [Address]or[Symbol] 下一个未解析的断点(就是说这个断点需要延迟解析)

这个也很常用,比如我们的驱动名为MyDriver.sys,那么在驱动加载之前下断bu MyDriver!DriverEntry,

然后加载这个驱动时就可以断在驱动入口,并且这个是不需要调试符号支持的

bl 列出所有断点,L=List

bc[id] 清除断点,c=Clear,id是bl查看时的断点编号

bd[id] 禁用断点,d=Disable,id即断点编号

be[id] 启用断点,e=Enable,id为断点编号

时间: 2024-11-09 10:08:24

windbg常见命令的相关文章

ansys 常见命令集合

APDL换行与续行- APDL规定每行72个字符 如果要写表达式A=C1+C2 (C1与C2都为表达式 可以用 B=C1 A=B+C2 将一行拆成两行来做但是如果不是表达式,而是输入一个命令参数过多的话,可以用续行命令RMORE,格式如下: RMORE, R7, R8, R9, R10, R11, R12 这个命令每次也只能输入6个参数,如果多于6个,可以重复使用RMORE就可以输入13-18,19-24等等.另外,于上面续行相应的是换行,一行命令太短可以使用多个命令共一行 $",没有双引号.这

Linux常见命令详解

1.Linux语法格式 命令 -参数 命令:是告诉干什么 命令后面有空格 -是固定 参数是告诉怎么干. 如果不需要参数,也不要-. 如果选项是个完整的单词,必须是--. 例如:杀鸡 杀是命令 怎么杀是参数. 如果有多个参数,可以分开写,也可以连起来写,同类项组合. 保留-,合并字母. 2.帮助命令 ls --help man(manual) ls(更多的是以手册形式来展现) whatis ls 当我们使用命令记不住的时候,只有记住开头,我们可以通过TAB键补全. 当我们只记住命令中间了部分的时候

备起来!Linux安全运维常见命令小贴士

备起来!Linux安全运维常见命令小贴士 常用命令 1. 查找关键词并统计行数 cat 2015_7_25_test_access.log | grep "sqlmap" | wc -l 2. 删除含有匹配字符的行 sed -i '/Indy Library/d' 2015_7_25_test_access.log 3. 查找所有日志中的关键词 find ./ -name "*.log" |xargs grep "sqlmap" |wc -l 4

Linux常见命令 ls cd type whatis date man cal hwclock

Linux常见命令:[可选项],<必须项>,-可重复多次 ,| 多选一  ,{}分组 ls(list) -l:long 长格式,一个文件或目录显示一行  文件类型:   -:普通文件   d:目录文件   b:块设备文件(block)   c:字符设备文件(character)   l:符号链接文件(symbolic link file)   p:命令管道文件(pipe)   s:套接字文件(socket)     文件权限(9位,每三位一组,每组rwx):  文件硬链接次数  文件属主(ow

一个linux常见命令的列表

这是一个linux常见命令的列表. 那些有• 标记的条目,你可以直接拷贝到终端上而不需要任何修改,因此你最好开一个终端边读边剪切&拷贝. 所有的命令已在Fedora和Ubuntu下做了测试 命令 描述 • apropos whatis 显示和word相关的命令. 参见线程安全 • man -t man | ps2pdf - > man.pdf 生成一个PDF格式的帮助文件   which command 显示命令的完整路径名   time command 计算命令运行的时间 • time c

Memcached 常见命令 telnet 使用方法介绍

Memcached 常见命令: telnet 使用方法介绍: (1)建立telnet连接,命令"telnet 127.0.0.1 11211".win7下会提示"telnet不是内部或外部命令",解决方法是"控制面板"-->"程序和功能"-->"打开或关闭windows功能"-->勾选"telnet客户端". (2)添加数据--命令"add name 0 60

【Linux命令】--(9)其余常见命令

其余常见命令+++++++++++++++++++++++++++++++lndiffdatecal grep wcpswatchatcrontab+++++++++++++++++++++++++++++++先把计划放着,待老夫国庆把它学完!

linux常见命令的列表

http://www.pixelbeat.org/cmdline_zh_CN.html 命令 描述 ? apropos whatis 显示和word相关的命令. 参见线程安全 ? man -t man | ps2pdf - > man.pdf 生成一个PDF格式的帮助文件   which command 显示命令的完整路径名   time command 计算命令运行的时间 ? time cat 开始计时. Ctrl-d停止.参见sw ? nice info 运行一个低优先级命令(这里是info

【Oracle】曾经的Oracle学习笔记(1-3) 数据库常见用语,常见命令,创建测试表

一.数据库的登录 二.数据库常用语 三.测试表的创建,测试数据初始化 四.常见命令介绍 五.测试 user:jeffreysn:jeffrey user:systemsn:jeffrey 浏览器中输入:http://127.0.0.1:8080/apex管理员登陆user:syssn:jeffrey 打开服务列表:win+r打开运行框,输入services.mscOracleServiceXE服务一定要是打开的,要不然oracle根本登录不了.OracleXETNSLintener服务是在我们使