windbg 常用命令详解


目录 (?)

[-]

    1. address eax
    2. vertarget
    3. peb
    4. lmvm
    5. lmf
    6. r
    7. d
    8. e
    9. s
      1.      命令是用来切换目标线程
      2. k     命令用来显示当前线程的堆栈如下
      3. u   命令把指定地址上的代码翻译成汇编输出
      4. x    查找符号的二进制地址如下
      5. dds 打印内存地址上的二进制值
    10. frame
      1. dt  格式化显示资料
      2. bp   设定调试断点
      3. bm   使用模式匹配设置断点
      4. ba     对内存访问设置断点 break on access
      5. bl 列出所有的断点 break list
      6. bc 清除断点 break clear
      7. be 开启断点 break enable
      8. bd禁用断点 break disable
      9. 跟踪指令TTATBTCWTPPAPC
      10. 源代码操作指令lsflsclsllsp
      11. 查询符号
      12. gle 查看LastError值
      13. 指定进制的形式0x0n0ty 分别表示 161082进制
      14. srcpath 设置源代码的路径
      15. dv查看本地变量
      16. teb 显示当前线程的执行块execution block
      17. peb 显示当前进程的执行块execution block
      18. lnAddress 显示当前地址上的对象类型
      19. locks 显示死锁
      20. handle可以获取整个进程或者某一个handle的详细信息
      21. cs列出CriticalSection的详细信息
      22. threadpool能看到完成端口线城池工作线程和timer回调占线程池的情况
      23. time 可以看到进程跑了多长时间
      24. dso 查看当前线程中有哪些对象分析泄露时用到
      25. dump保存进程的dump文件
      26. cls
  1. 设置断点命令bu bp bm ba
  2. 其它命令bl bc bd be bpcmds
  3. 软件断点和硬件断点
  4. 参考资料

 

一、

1、 !address eax

查看对应内存页的属性

 


2、 vertarget

显示当前进程的大致信息


3 !peb

显示process Environment Block

 

 


4、 lmvm

可以查看任意一个dll的详细信息
例如:我们查看cyusb.sys的信息



5.reload /!sym 加载符号文件


6、 lmf

列出当前进程中加载的所有dll文件和对应的路径


7、 r

命令显示和修改寄存器上的值
r命令显示和修改寄存器上的值

0:018> r eax=0 修改了寄存器,把eax的值修改为0x0


8、 d

命令显示esp寄存器指向的内存
如下


用dd命令直接指定054efc14地址


注意第二个d表示DWORD格式,此外还有db(byte),du(Unicode),dc(char)等等。
数据查看指令 d{a|b|c|d|D|f|p|q|u|w|W}
d{b|c|d|D|f|p|q}分别是显示:
byte&ASCII, double-word&ASCII,double-word,double-precision,float,pointer-sized,quad-word数据;
DA用于显示ASCII,DU用于显示UNICODE;
BYB,BYD,显示binary和Byte及binary和DWORD
补充一个DV,用于查看本地变量用的


9、 e

命令可以用来修改内存地址
跟d命令一样,e命令后面也可以跟类型后缀,比如ed命
令表示用DWORD的方式修改。下面的命令把054efc14地址上的值修改为11112222。
0:018>ed 054efc14 11112222
修改后可以用dd命令来查看内存。
0:018>dd 0543fc14 L4 L4参数指定内存区间的长度为4个DWORD,这样输出只有1行,
而不是8行了。


10、s

命令用来搜索内存具体见help文档
11!runaway 可以显示每一个线程的cpu消耗
0:018> !runaway 结果如下:
0:83c 0 days 0:00:00.406
13:bd4 0 days 0:00:00.046
10:ac8 0 days 0:00:00.046
24:4f4 0 days 0:00:00.031
上面输出的第一列是线程的编号和线程ID,后一列对应的是该线程在用户态模式中的
总的繁忙时间。
在该命令加上f参数,还可以看到内核态的繁忙时间,当进程内存占用率比较高的时候
,通过该命令可以方便的找到对应的繁忙线程。

12、 ~     命令是用来切换目标线程

0:018> ~ 可以显示线程的信息
0:018> ~0s   把当前的线程切换到0号线程,也就是主线程,切换后提示符会变为0:000.

13 、~* 命令列出当前进程中的所有线程的详细信息

14、~*kb    命令列出所有线程的堆栈

15、 k     命令用来显示当前线程的堆栈,如下

0:018> k
跟d命令一样,k后面也可以跟很多后缀,比如kb kp,kn,kv,kl等,这些后缀控制了显示的格式和信息
栈指令k[b|p|P|v]
这四条指令显示的内容类似,但是每个指令都有特色;

KB显示三个参数;

Kp显示所有的参数,但需要Full Symbols或Private PDBSymbols支持。KP与Kp相似,只是KP将参数换行显示了;

Kv用于显示FPO和调用约定;

KD,用于显示Stack的Dump,在跟踪栈时比较有用。
这些指令区分大小。

16 、u   命令把指定地址上的代码翻译成汇编输出

0:018> u 7739d023 
USER32!NtUserWaitMessage:
7739d023 b84a120000 mov eax,0x124a
7739d028 ba0003fe7f mov edx,0x7ffe0300
7739d02d ff12 call dword ptr [edx]
7739d02f c3 ret
如果符号文件加载正确,可以用uf命令直接反汇编整个函数,比如uf USER32! NtUserWaitMessage

17 、x    查找符号的二进制地址如下

0:018> x msvcr!printf
77bd27c2 msvcrt!printf = 
上面的命令找到了printf函数的入口地址在77bd27c2

0:001> x ntdll!GlobalCounter
7c99f72c ntdll!GlobalCounter = 
上面的命令表示ntdll!GlobalCounter这个变量保存的地址是7c99f72c。


注意:符号对应的是变量和变量所在的地址,不是变量的值,上面只是找到GlobalCounter这个变量的值是7c99f72,要找到变量的值,需要用d命令读取内存地址来获取。

X命令还支持通配符,比如x ntdll !*命令列出ntdll模块中的所有的符号,以及对应的二进制地址。

18、 dds 打印内存地址上的二进制值

同时自动搜索二进制值对应的符号。
比如要看看当前**中保存了那些函数地址,就可以检查ebp指向的内存
0:018>dds ebp
0013ed98 0013ee24
0013ed9c 75ecb30f BROWSEUI!BrowserProtectedThreadProc+0x44
0013eda0 00163820
0013eda4 0013ee50
0013eda8 00163820
0013edac 00000000
0013edb0 0013ee10
0013edb4 75ece83a BROWSEUI!__delayLoadHelper2+0x23a
0013edb8 00000005
0013edbc 0013edcc
0013edc0 0013ee50
0013edc4 00163820
0013edc8 00000000
0013edcc 00000024
0013edd0 75f36d2c BROWSEUI!_DELAY_IMPORT_DESCRIPTOR_SHELL32
0013edd4 75f3a184 BROWSEUI!_imp__SHGetInstanceExplorer
0013edd8 75f36e80 BROWSEUI!_sz_SHELL32
0013eddc 00000001
0013ede0 75f3726a BROWSEUI!urlmon_NULL_THUNK_DATA_DLN+0x116
0013ede4 7c8d0000 SHELL32!_imp__RegCloseKey (SHELL32+0x0)
0013ede8 7c925b34 SHELL32!SHGetInstanceExplorer

这里dds命令从ebp指向的内存地址0013ed98开始打印,第一列是内存地址的值,第二列是地址上对应的二进制数据,第三列是二进制对应的符号。上面的命令自动找到了75ecb390f对应的符号是BROWSEUI!BrowserProtectedThreadProc +0x44.

Com interface 和c++ vtable里面的成员函数都是顺序排列的。所以,dds命令可以方便的找到虚函数表中的具体的函数地址,比如用下面的命令可以找到OpaqueDatinfo类型中虚函数的实际函数地址。
首先通过x命令找到OpaqueDataInfo虚函数地址
0:000> x ole32!OpaqueDataInfo::vftable’
7768265c ole32!OpaqueDataInfo::`vftable'' = 
77682680 ole32!OpaqueDataInfo::`vftable'' = 
接下来dds命令可以打印出虚函数表中的函数名字
0:000> dds 7768265c


19 .frame

命令在栈中切换以便检查局部变量。
要查看局部变量的需要如下:
19、1    查看线程的callstack

第一列的号称为Frame num,通过.frame命令就可以切换到对应的函数中检查局部变量,比如我们检查CYUSB+0x916,这个函数的frame num是0,于是,我们如下:
19、2   iframe    切换到指定行号的函数中

19、3   然后调用 x  显示当前frame的局部变量,比如这个函数中有两个局部变量pcls和rawptr
0:018> x
0012fced pcls = 0x0039ba80
0012fcd8 rawptr = 0x0039ba80

20、 dt  格式化显示资料

Dt   命令格式化显示变量的资料和结构
0:000> dt pcls
Local var @ 0x12fce4 Type MyCls*
0x0039ba80 
+0x000 str : 0x00416648 'abcd'
+0x004 inobj : inner
上面的命令打印出pcls的类型是MyCls指针,指向的地址是0x0039ba80,其中的两个class成员的偏移分别在+0和+4,对应的值在第2列显示。加上-b -r参数可以显示inner class和数组的信息:
0:000> dt pcls -b -r
Local var @ 0x12fce4 Type MyCls*
0x0039ba80 
+0x000 str : 0x00416648 'abcd'
+0x004 inobj : innner
+0x000 arr : 'abcd'
[00] 97 ''a''
[01] 98 ''b''
[02] 99 ''c''
[03] 100 ''d''
[04] 0 ''''
[05] 0 ''''
[06] 0 ''''
[07] 0 ''''
[08] 0 ''''
[09] 0 ''''
对于任意的地址,也可以手动指定符号类型来格式化显示。比如把0x0039ba80地址上的数据用MyCls类型来显示:
0:000> dt 0x0039ba80 MyCls
+0x000 str : 0x00416648 'abcd'
+0x004 inobj : innner

21、  bp   设定调试断点

(1)比如可以这样写:0:018>bp notepad!WinMain 在notepade的winmain函数处下断点。
断点的位置可以用符号来表示,如上,也可以直接用地址以及windbg的Pseudo_Register(虚拟寄存器)。

比如,我们用$exentry表示进程的入口,那么可以用bp @$exentry在进程的入口设置断点。

(2)如果notepade的winmain的入口地址为01006420,那么断点也可以这么写:
Bp 01006420
bp mysource.cpp:143` 'j (poi(MyVar)”0x20) ''''; ''g'' '
意思就是:当myvar的值等于0x20时,g命令继续执行;
(3)下面一个设置条件断点
0:001> bp exceptioninject!foo3 “k; .echo ‘breaks’ ; g”
在exceptioninject!foo3上设置断点后,每次断下来后,先用k显示callstack,然后用.echo命令输出简单的字符串‘breaks’,最后g命令继续执行。
(4)下面看一个更复杂的设置条件断点的例子:
ba w4 execptioninject!i ”j(poi(exceptioninject!i)<0n40) ‘.printf//”exceptioninject!i value is :%d//”,poi(exceptioninject!i); g’ ; ‘.echo stop!’ ”
首先ba w4 exceptioninject!i 表示在修改exceptioninject!i这个全局变量的时候,停下来;
j(judge)命令的作用就是对后面的表达式作条件判断如果为true,执行第一个单引号里面的命令,否则执行第2个单引号里面的命令,
条件表达式是(poi(exceptioninject!i)<0n40),在windbg中excepioninject!i符号表示符号所在的内存地址,而不是符号的数值,相当于c语言的&操作符的作用,poi命令就是取这个地址上的值,相当于c语言的*操作符。

所以这个条件判断的意思就是判断exceptioninject!i的值,是否小于十进制的40。如果为真,就执行第一个单引号,‘.printf//”exceptioninject!i value is :%d//”,poi(exceptioninject!i); g’,如果为假,就执行第二个单引号‘.echo stop!’
第一个单引号里有三个命令,.printf .echo 和g。这里的printf和c语言的printf函数语法一样,不过由于这个printf命令本身是在ba命令的双引号里面,所以需要用//来转义print中的引号。第一个引号的作用是:打印出当前exceptioninject!i的值,.echo命令换行 g命令继续执行
第二个引号的作用就是显示stop,由于后面没有g命令,所以windbg会停下。

22、  bm   使用模式匹配设置断点

这个功能需要符号表的支持,bm可以通过模式一次设置多个断点,比如
bm mydriver!FastIO* 可以将所有与FastIO*模式匹配的函数下设置断点,比如FastIoRead ,FastIoWriter等函数都会被设置上断点。需要注意的是,bm命令需要full or export symbols支持。

23、 ba     对内存访问设置断点 break on access

就是对于内存访问设置断点,对于在多核处理或者多核处理器调试的时候很有用,对于调试多线程也很有用,比如说,我们可以对一个全局变量设置断点,
ba mydriver!gMonitoreedDevices , 如果你认为这个变量的值被莫名的修改了,相信通过ba设置的断点,你可以很快找到是谁修改的。

也可以这样
ba w4 0x4000000 'kb;g' 当0x4000000地址有写操作时,进入断点 。w表示类型为写 4表示长度为4个字节

24 、bl 列出所有的断点 break list

 

25、 bc 清除断点 break clear

 bc [断点号]

26、 be 开启断点 break enable

 

27、 bd禁用断点 break disable

 

以上提到的断点指令通过和j指令很容易形成条件断点,比如
bp USER32!GetMessageW 'r $t1=poi(esp+4);r $t2=poi(@$t1+4); j(@$t2 = 0x102 ) ''du @$t1+8 L2;gc'';''gc'''
这个条件断点,截取WM_CHAR消息,并将字符(包括中文)显示出来。
条件断点的最简形式:bp Address 'j (Condition) ''OptionalCommands''; ''gc'' '
Address是指令的地址,Condition是一个条件表达式,如果@eax=1,''OptionalCommands''是在断点被击中并且表达式成立时要执行的指令;gc指定是从一个条件断点返回,是不可少的一部分。

28、跟踪指令T,TA,TB,TC,WT,P,PA,PC

T   指令单步执行,在源码调试状态下,可指源码的一行,根据不同的选项也可以为一行ASM指令
TA   单步跟踪到指定地址,如果没有参数将运行到断点处

TB  执行到分支指令,分支指令包括calls,   returns,   jumps,    counted loops,    and while loops;
TC  执行到Call指令;
WT  Trace and Watch Data,一条强大指令,对执行流程做Profile,执行一下看看结果吧;
P,PA,PC    相信不用多做解释,大家也都明白了;

29、源代码操作指令.,lsf,lsc,ls,l,lsp

.指令打一个源文件,可以打开一个全路径的文件,也可以通过函数地址来打开并定位到源文件中函数的位置,如. –a myapp!main,. j://mydriver//mydriver.c
lsf指定一个源文件为当前源文件,使用lsc可显示当前指定的源文件ls可显示源文件的代码。Lsf可以使用全路径,如果源路径已经设置,也可以直接指定源文件名称。如lsf mydriver.c,lsf j://mydriver//mydriver.c
lsc显示当前源文件
ls显示当前源文件的代码,如ls 200显示第200行
l 用于设置源文件选项
lsp 设置源文件行在调试时显示范围比如,
显示当前行的前50,后50,lsp 100
但通常使用Windbg时,可以直接用Ctrl+O来打开并查看源文件

30 、查询符号

kd> x nt!KeServiceDescriptorTable* 
8046e100 nt!KeServiceDescriptorTableShadow = 
8046e0c0 nt!KeServiceDescriptorTable = 
kd> ln 8046e100 
(8046e100) nt!KeServiceDescriptorTableShadow | (8046e140) nt!MmSectionExtendResource
Exact matches: 
nt!KeServiceDescriptorTableShadow =

31、!gle 查看LastError值

 

32、指定进制的形式0x/0n/0t/y 分别表示 16/10/8/2进制

? 0x12345678+0n10 
Evaluate expression: 305419906 = 12345682 
33、!sym noice/quiet symbol prompts开关

34、srcpath 设置源代码的路径

 

35、dv查看本地变量

 

36、!teb 显示当前线程的执行块(execution block)
37、!peb 显示当前进程的执行块(execution block)
38、ln[Address] 显示当前地址上的对象类型

 

39、!locks 显示死锁

 

40、!handle可以获取整个进程或者某一个handle的详细信息

首先运行以下!handle,可以看到当前进程的每个一个handle的类型,以及统计信息
0:002>!handle
Handle 4
Type key
Handle c
Type keyEvent
…….
然后找到一个key,查看详细信息
0:001>!handle 4 f
就会列出这个handle的详细信息。
41!htrace命令检查操作句柄的历史记录
!htrace命令可以打印出指定的handle的最近几次调用堆栈
0:001>!htrace 384

42、!cs列出CriticalSection的详细信息

 

43、!threadpool能看到完成端口,线城池工作线程和timer回调占线程池的情况
44、time 可以看到进程跑了多长时间

 

45、 !dso 查看当前线程中有哪些对象,分析泄露时用到
46、dump保存进程的dump文件

Dump文件是进程的内存镜像,

可当在调试器中打开dump文件时,使用上面的命令检查,看到的结果跟用调试检查进程看到的一样
.dump /ma c://testdump.dmp
这个命令把当前进程的镜像保存为c://testdump.dmp,其中/ms参数表示dump的文件应该包含进程的完整信息。
在windbg中,通过file—open---open Crash dump菜单打开dump文件进行分析。打开文件后,运行调试命令看到的信息和状态就是dump文件保存时进程的状态。通过dump文件能够方便的保存发生问题时进程的状态,方便事后分析。

 

47、
[plain]  view plain copy
  1. 0: kd> !idt                           //查看中断向量表内容  
  2. 0: kd> dt nt!_KINTERRUPT 89c03bb0     //查看对应中断向量的详细内容  
  3. 0: kd> !ioapic                        //显示I/O APIC(即连接至设备的中断控制部件)  
  4. 0: kd> !pic                           //   
  5. 0: kd> !apic                          //有关PIC的配置情况  


kd> !idt运行后显示为

[plain]  view plain copy
  1. 0: kd> !idt  
  2.   
  3. Dumping IDT:  
  4.   
  5. 37: 806e7864 hal!PicSpuriousService37  
  6. 3d: 806e8e2c hal!HalpApcInterrupt  
  7. 41: 806e8c88 hal!HalpDispatchInterrupt  
  8. 50: 806e793c hal!HalpApicRebootService  
  9. 63: 89ac57e4 USBPORT!USBPORT_InterruptService (KINTERRUPT 89ac57a8)  
  10.              USBPORT!USBPORT_InterruptService (KINTERRUPT 8982abb0)  
  11. 73: 89d6767c atapi!IdePortInterrupt (KINTERRUPT 89d67640)  
  12.              atapi!IdePortInterrupt (KINTERRUPT 89dc4bb0)  
  13. 83: 89c1471c VIDEOPRT!pVideoPortInterrupt (KINTERRUPT 89c146e0)  
  14.              HDAudBus!AzController::Isr (KINTERRUPT 89c16ac8)  
  15.              NDIS!ndisMIsr (KINTERRUPT 89847bb0)  
  16. 94: 8976fbec USBPORT!USBPORT_InterruptService (KINTERRUPT 8976fbb0)  
  17. a4: 89770bec USBPORT!USBPORT_InterruptService (KINTERRUPT 89770bb0)  
  18. b1: 89d859e4 ACPI!ACPIInterruptServiceRoutine (KINTERRUPT 89d859a8)  
  19. b4: 89c03bec USBPORT!USBPORT_InterruptService (KINTERRUPT 89c03bb0)  
  20. c1: 806e7ac0 hal!HalpBroadcastCallService  
  21. d1: 806e6e54 hal!HalpClockInterrupt  
  22. e1: 806e8048 hal!HalpIpiHandler  
  23. e3: 806e7dac hal!HalpLocalApicErrorService  
  24. fd: 806e85a8 hal!HalpProfileInterrupt  
  25. fe: 806e8748 hal!HalpPerfInterrupt  
  26. //前部分是使用的中断类型号。例如83号中断是有三个硬件复用。  


 

2.0: kd> dt nt!_KINTERRUPT 89c03bb0,运行后显示为

[plain]  view plain copy
  1. 0: kd> dt nt!_KINTERRUPT 89c03bb0  
  2.    +0x000 Type             : 0n22  
  3.    +0x002 Size             : 0n484  
  4.    +0x004 InterruptListEntry : _LIST_ENTRY [ 0x89c03bb4 - 0x89c03bb4 ]  
  5.    +0x00c ServiceRoutine   : 0xb9159e54     unsigned char  USBPORT!USBPORT_InterruptService+0  
  6.    +0x010 ServiceContext   : 0x89c38028 Void  
  7.    +0x014 SpinLock         : 0  
  8.    +0x018 TickCount        : 0xffffffff  
  9.    +0x01c ActualLock       : 0x89c03e14  -> 0  
  10.    +0x020 DispatchAddress  : 0x805466d0     void  nt!KiInterruptDispatch+0  
  11.    +0x024 Vector           : 0x1b4  
  12.    +0x028 Irql             : 0xa ''  
  13.    +0x029 SynchronizeIrql  : 0xa ''  
  14.    +0x02a FloatingSave     : 0 ''  
  15.    +0x02b Connected        : 0x1 ''  
  16.    +0x02c Number           : 0 ''  
  17.    +0x02d ShareVector      : 0x1 ''  
  18.    +0x030 Mode             : 0 ( LevelSensitive )  
  19.    +0x034 ServiceCount     : 0  
  20.    +0x038 DispatchCount    : 0xffffffff  
  21.    +0x03c DispatchCode     : [106] 0x56535554  


 

3.0: kd> !ioapic,运行后显示

[plain]  view plain copy
  1. 0: kd> !ioapic  
  2. IoApic @ FEC00000  ID:8 (20)  Arb:170020  
  3. Inti00.: 52000000`000100ff  Vec:FF  FixedDel  Ph:52000000      edg high      m  
  4. Inti01.: 00c00000`000100ff  Vec:FF  FixedDel  Ph:00C00000      edg high      m  
  5. Inti02.: 00000000`000100ff  Vec:FF  FixedDel  Ph:00000000      edg high      m  
  6. Inti03.: 00000000`000100ff  Vec:FF  FixedDel  Ph:00000000      edg high      m  
  7. Inti04.: 00000000`000100ff  Vec:FF  FixedDel  Ph:00000000      edg high      m  
  8. Inti05.: 52c00000`000100ff  Vec:FF  FixedDel  Ph:52C00000      edg high      m  
  9. Inti06.: 00c00000`000100ff  Vec:FF  FixedDel  Ph:00C00000      edg high      m  
  10. Inti07.: 02000000`000100ff  Vec:FF  FixedDel  Ph:02000000      edg high      m  
  11. Inti08.: 01000000`000008d1  Vec:D1  FixedDel  Lg:01000000      edg high         
  12. Inti09.: 03000000`0000d9b1  Vec:B1  LowestDl  Lg:03000000-Pend lvl high rirr    
  13. Inti0A.: 00c00000`000100ff  Vec:FF  FixedDel  Ph:00C00000      edg high      m  
  14. Inti0B.: 00000000`000100ff  Vec:FF  FixedDel  Ph:00000000      edg high      m  
  15. Inti0C.: 42000000`000100ff  Vec:FF  FixedDel  Ph:42000000      edg high      m  
  16. Inti0D.: 00000000`000100ff  Vec:FF  FixedDel  Ph:00000000      edg high      m  
  17. Inti0E.: 00000000`000100ff  Vec:FF  FixedDel  Ph:00000000      edg high      m  
  18. Inti0F.: 00000000`000100ff  Vec:FF  FixedDel  Ph:00000000      edg high      m  
  19. Inti10.: 03000000`0000f983  Vec:83  LowestDl  Lg:03000000-Pend lvl low  rirr    
  20. Inti11.: 00000000`000100ff  Vec:FF  FixedDel  Ph:00000000      edg high      m  
  21. Inti12.: 03000000`0000a994  Vec:94  LowestDl  Lg:03000000      lvl low          
  22. Inti13.: 00c00000`000100ff  Vec:FF  FixedDel  Ph:00C00000      edg high      m  
  23. Inti14.: 03000000`0000a973  Vec:73  LowestDl  Lg:03000000      lvl low          
  24. Inti15.: 03000000`0000a963  Vec:63  LowestDl  Lg:03000000      lvl low          
  25. Inti16.: 03000000`0000a9a4  Vec:A4  LowestDl  Lg:03000000      lvl low          
  26. Inti17.: 03000000`0000f9b4  Vec:B4  LowestDl  Lg:03000000-Pend lvl low  rirr    


 

4.0: kd> !pic ,运行后显示

[plain]  view plain copy
  1. 0: kd> !pic  
  2. ----- IRQ Number ----- 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F  
  3. Physically in service:  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  
  4. Physically masked:      Y  Y  Y  Y  Y  Y  Y  Y  Y  Y  Y  Y  Y  Y  Y  Y  
  5. Physically requested:   Y  .  .  Y  .  Y  .  .  Y  Y  Y  Y  .  .  .  .  


 

5.0: kd> !apic,运行后显示

[plain]  view plain copy
  1. 0: kd> !apic  
  2. Apic @ fffe0000  ID:0 (50014)  LogDesc:01000000  DestFmt:ffffffff  TPR FF  
  3. TimeCnt: 0fdad680clk  SpurVec:1f  FaultVec:e3  error:40  
  4. Ipi Cmd: 02000000`000008e1  Vec:E1  FixedDel  Lg:02000000      edg high         
  5. Timer..: 00000000`000300fd  Vec:FD  FixedDel    Dest=Self      edg high      m  
  6. Linti0.: 00000000`0001001f  Vec:1F  FixedDel    Dest=Self      edg high      m  
  7. Linti1.: 00000000`000084ff  Vec:FF  NMI         Dest=Self      lvl high         
  8. TMR: 63, 73, 83, 94, A4, B1, B4  
  9. IRR: 41, B1, D1  
  10. ISR: D1  

 48、.cls

 .cls用于清屏

注意:得在windbg处于命令行模式时才可用(即按了Ctro+Break)

 或者直接使用工具栏:

 

二、

 

Windbg断点命令

1. 设置断点命令bu bp bm ba

1) bu bp bm设置软件断点

a). bp设置地址关联的断点

b). bu设置符号关联的断点

c). bm支持设置含通配符的断点,可以一次创建一个或多个bu或bp (bm /d)断点

bp和bu的主要区别

a) bp所设断点和地址关联,如果模块把该地址的指令移到其它地方,断点不会随之移动,而是依然关联在在原来的地址上; 而bu所设断点是和符号关联,如果符号的地址改变了,断点依然保持和原来的符号关联。

b) 如果bp所设断点的地址在加载的模块中被找到,后来软件模块被卸载,断点会被自动移除;而bu所设断点则会一直存在。

c) bp设置的断点不会被保存windbg的workspace中,bu设置的断点会则会被保存下来。

 

2)ba设置硬件断点(数据断点)

硬件断点是指当一个内存地址被访问(读、写、执行)或IO端口被访问时触发的断点。

 

2. 其它命令bl bc bd be .bpcmds

bl 列举所有断点和它们的状态

bc 删除对应断点

bd 禁用对应断点

be 启用对应断点

.bmcmds 列举所有断点以及创建它们的命令

 

3. 软件断点和硬件断点

1) 软件断点 - 调试工具控制的断点。当调试器在某个地址设置一个断点,它会首先把该地址的内容保存,零时插入一条中断指令(如int3 (0xCC)),当程序执行到该地址是cpu进入调试状态,当调试结束,程序重新载入该地址原先的指令重新执行下去。

 

2) 硬件断点 - 又称为数据断点,是处理器控制的断点,可以用来监控某个内存地址的访问(读、写、执行)和IO地址的访问(读、写)。处理器中有相应的调试寄存器,用来记录数据断点的地址,当该地址(内存地址或IO端口地址)被访问时,断点将被触发,cpu进入调试状态。

 

3) 软件断点和硬件断点的区别

a)理论上我们可以设置无穷多个软件断点,但设置软件断点会使程序变慢,尤其在内核态影响比较大,调试器大多会对断点数量加以限制。例如Windbg在内核态最多支持32个软件断点,在用户态则支持任意多个;硬件断点数量取决于处理器,例如X86支持四个断点(80386有八个调试寄存器-DR0~DR3用于断点,DR4~DR5保留,DR6~DR7用于控制)。

b)软件断点需要修改相应代码,所以它不能调试时flash和rom中的代码;而硬件则没有这个限制。

 

3. 参考资料

1. http://www.lslnet.com/linux/dosc1/59/linux-389058.htm

2. http://blog.csdn.net/wingeek/article/details/4025475

3. http://embexperts.com/viewthread.php?tid=69

4. http://msdn.microsoft.com/en-us/library/ff538903%28v=VS.85%29.aspx

5. http://msdn.microsoft.com/en-us/library/ff538165%28v=VS.85%29.aspx

6. http://msdn.microsoft.com/en-us/library/ff553451%28v=VS.85%29.aspx

 

 

1. 使用!process 0 0 获取用户空间的所有的进程的信息

如果有多个相同进程名,!process 0 0 SampleExe.exe

kd> !process 0 0
**** NT ACTIVE PROCESS DUMP ****
PROCESS fe5039e0  SessionId: 0  Cid: 0008    Peb: 00000000  ParentCid: 0000
    DirBase: 00030000  ObjectTable: fe529b68  TableSize:  50.
    Image: System

2.使用.process /i 指定进程地址

因为要对用户态代码下断点,这里不用/p,而使用/i

If you want to use the kernel debugger to set breakpoints in user space, use the/i option to switch the target to the correct process context.

3. g继续,再次发生int 3中断后,进程Context就已切换,使用!process查看确认。

4. reload符号文件。

5. bu, bp下用户态断点。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值