windbg基本命令
生活随笔
收集整理的這篇文章主要介紹了
windbg基本命令
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
一、
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
0: kd> !idt ? ? ? ? ? ? ? ? ? ? ? ? ? //查看中斷向量表內容 ?
0: kd> dt nt!_KINTERRUPT 89c03bb0 ? ? //查看對應中斷向量的詳細內容 ?
0: kd> !ioapic ? ? ? ? ? ? ? ? ? ? ? ?//顯示I/O APIC(即連接至設備的中斷控制部件) ?
0: kd> !pic ? ? ? ? ? ? ? ? ? ? ? ? ? // ??
0: kd> !apic ? ? ? ? ? ? ? ? ? ? ? ? ?//有關PIC的配置情況 ?
kd> !idt運行后顯示為
[plain] view plain copy
0: kd> !idt ?
??
Dumping IDT: ?
??
37: 806e7864 hal!PicSpuriousService37 ?
3d: 806e8e2c hal!HalpApcInterrupt ?
41: 806e8c88 hal!HalpDispatchInterrupt ?
50: 806e793c hal!HalpApicRebootService ?
63: 89ac57e4 USBPORT!USBPORT_InterruptService (KINTERRUPT 89ac57a8) ?
? ? ? ? ? ? ?USBPORT!USBPORT_InterruptService (KINTERRUPT 8982abb0) ?
73: 89d6767c atapi!IdePortInterrupt (KINTERRUPT 89d67640) ?
? ? ? ? ? ? ?atapi!IdePortInterrupt (KINTERRUPT 89dc4bb0) ?
83: 89c1471c VIDEOPRT!pVideoPortInterrupt (KINTERRUPT 89c146e0) ?
? ? ? ? ? ? ?HDAudBus!AzController::Isr (KINTERRUPT 89c16ac8) ?
? ? ? ? ? ? ?NDIS!ndisMIsr (KINTERRUPT 89847bb0) ?
94: 8976fbec USBPORT!USBPORT_InterruptService (KINTERRUPT 8976fbb0) ?
a4: 89770bec USBPORT!USBPORT_InterruptService (KINTERRUPT 89770bb0) ?
b1: 89d859e4 ACPI!ACPIInterruptServiceRoutine (KINTERRUPT 89d859a8) ?
b4: 89c03bec USBPORT!USBPORT_InterruptService (KINTERRUPT 89c03bb0) ?
c1: 806e7ac0 hal!HalpBroadcastCallService ?
d1: 806e6e54 hal!HalpClockInterrupt ?
e1: 806e8048 hal!HalpIpiHandler ?
e3: 806e7dac hal!HalpLocalApicErrorService ?
fd: 806e85a8 hal!HalpProfileInterrupt ?
fe: 806e8748 hal!HalpPerfInterrupt ?
//前部分是使用的中斷類型號。例如83號中斷是有三個硬件復用。 ?
?
2.0: kd> dt nt!_KINTERRUPT 89c03bb0,運行后顯示為
[plain] view plain copy
0: kd> dt nt!_KINTERRUPT 89c03bb0 ?
? ?+0x000 Type ? ? ? ? ? ? : 0n22 ?
? ?+0x002 Size ? ? ? ? ? ? : 0n484 ?
? ?+0x004 InterruptListEntry : _LIST_ENTRY [ 0x89c03bb4 - 0x89c03bb4 ] ?
? ?+0x00c ServiceRoutine ? : 0xb9159e54 ? ? unsigned char ?USBPORT!USBPORT_InterruptService+0 ?
? ?+0x010 ServiceContext ? : 0x89c38028 Void ?
? ?+0x014 SpinLock ? ? ? ? : 0 ?
? ?+0x018 TickCount ? ? ? ?: 0xffffffff ?
? ?+0x01c ActualLock ? ? ? : 0x89c03e14 ?-> 0 ?
? ?+0x020 DispatchAddress ?: 0x805466d0 ? ? void ?nt!KiInterruptDispatch+0 ?
? ?+0x024 Vector ? ? ? ? ? : 0x1b4 ?
? ?+0x028 Irql ? ? ? ? ? ? : 0xa '' ?
? ?+0x029 SynchronizeIrql ?: 0xa '' ?
? ?+0x02a FloatingSave ? ? : 0 '' ?
? ?+0x02b Connected ? ? ? ?: 0x1 '' ?
? ?+0x02c Number ? ? ? ? ? : 0 '' ?
? ?+0x02d ShareVector ? ? ?: 0x1 '' ?
? ?+0x030 Mode ? ? ? ? ? ? : 0 ( LevelSensitive ) ?
? ?+0x034 ServiceCount ? ? : 0 ?
? ?+0x038 DispatchCount ? ?: 0xffffffff ?
? ?+0x03c DispatchCode ? ? : [106] 0x56535554 ?
?
3.0: kd> !ioapic,運行后顯示
[plain] view plain copy
0: kd> !ioapic ?
IoApic @ FEC00000 ?ID:8 (20) ?Arb:170020 ?
Inti00.: 52000000`000100ff ?Vec:FF ?FixedDel ?Ph:52000000 ? ? ?edg high ? ? ?m ?
Inti01.: 00c00000`000100ff ?Vec:FF ?FixedDel ?Ph:00C00000 ? ? ?edg high ? ? ?m ?
Inti02.: 00000000`000100ff ?Vec:FF ?FixedDel ?Ph:00000000 ? ? ?edg high ? ? ?m ?
Inti03.: 00000000`000100ff ?Vec:FF ?FixedDel ?Ph:00000000 ? ? ?edg high ? ? ?m ?
Inti04.: 00000000`000100ff ?Vec:FF ?FixedDel ?Ph:00000000 ? ? ?edg high ? ? ?m ?
Inti05.: 52c00000`000100ff ?Vec:FF ?FixedDel ?Ph:52C00000 ? ? ?edg high ? ? ?m ?
Inti06.: 00c00000`000100ff ?Vec:FF ?FixedDel ?Ph:00C00000 ? ? ?edg high ? ? ?m ?
Inti07.: 02000000`000100ff ?Vec:FF ?FixedDel ?Ph:02000000 ? ? ?edg high ? ? ?m ?
Inti08.: 01000000`000008d1 ?Vec:D1 ?FixedDel ?Lg:01000000 ? ? ?edg high ? ? ? ??
Inti09.: 03000000`0000d9b1 ?Vec:B1 ?LowestDl ?Lg:03000000-Pend lvl high rirr ? ?
Inti0A.: 00c00000`000100ff ?Vec:FF ?FixedDel ?Ph:00C00000 ? ? ?edg high ? ? ?m ?
Inti0B.: 00000000`000100ff ?Vec:FF ?FixedDel ?Ph:00000000 ? ? ?edg high ? ? ?m ?
Inti0C.: 42000000`000100ff ?Vec:FF ?FixedDel ?Ph:42000000 ? ? ?edg high ? ? ?m ?
Inti0D.: 00000000`000100ff ?Vec:FF ?FixedDel ?Ph:00000000 ? ? ?edg high ? ? ?m ?
Inti0E.: 00000000`000100ff ?Vec:FF ?FixedDel ?Ph:00000000 ? ? ?edg high ? ? ?m ?
Inti0F.: 00000000`000100ff ?Vec:FF ?FixedDel ?Ph:00000000 ? ? ?edg high ? ? ?m ?
Inti10.: 03000000`0000f983 ?Vec:83 ?LowestDl ?Lg:03000000-Pend lvl low ?rirr ? ?
Inti11.: 00000000`000100ff ?Vec:FF ?FixedDel ?Ph:00000000 ? ? ?edg high ? ? ?m ?
Inti12.: 03000000`0000a994 ?Vec:94 ?LowestDl ?Lg:03000000 ? ? ?lvl low ? ? ? ? ?
Inti13.: 00c00000`000100ff ?Vec:FF ?FixedDel ?Ph:00C00000 ? ? ?edg high ? ? ?m ?
Inti14.: 03000000`0000a973 ?Vec:73 ?LowestDl ?Lg:03000000 ? ? ?lvl low ? ? ? ? ?
Inti15.: 03000000`0000a963 ?Vec:63 ?LowestDl ?Lg:03000000 ? ? ?lvl low ? ? ? ? ?
Inti16.: 03000000`0000a9a4 ?Vec:A4 ?LowestDl ?Lg:03000000 ? ? ?lvl low ? ? ? ? ?
Inti17.: 03000000`0000f9b4 ?Vec:B4 ?LowestDl ?Lg:03000000-Pend lvl low ?rirr ? ?
?
4.0: kd> !pic ,運行后顯示
[plain] view plain copy
0: kd> !pic ?
----- IRQ Number ----- 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ?
Physically in service: ?. ?. ?. ?. ?. ?. ?. ?. ?. ?. ?. ?. ?. ?. ?. ?. ?
Physically masked: ? ? ?Y ?Y ?Y ?Y ?Y ?Y ?Y ?Y ?Y ?Y ?Y ?Y ?Y ?Y ?Y ?Y ?
Physically requested: ? Y ?. ?. ?Y ?. ?Y ?. ?. ?Y ?Y ?Y ?Y ?. ?. ?. ?. ?
?
5.0: kd> !apic,運行后顯示
[plain] view plain copy
0: kd> !apic ?
Apic @ fffe0000 ?ID:0 (50014) ?LogDesc:01000000 ?DestFmt:ffffffff ?TPR FF ?
TimeCnt: 0fdad680clk ?SpurVec:1f ?FaultVec:e3 ?error:40 ?
Ipi Cmd: 02000000`000008e1 ?Vec:E1 ?FixedDel ?Lg:02000000 ? ? ?edg high ? ? ? ??
Timer..: 00000000`000300fd ?Vec:FD ?FixedDel ? ?Dest=Self ? ? ?edg high ? ? ?m ?
Linti0.: 00000000`0001001f ?Vec:1F ?FixedDel ? ?Dest=Self ? ? ?edg high ? ? ?m ?
Linti1.: 00000000`000084ff ?Vec:FF ?NMI ? ? ? ? Dest=Self ? ? ?lvl high ? ? ? ??
TMR: 63, 73, 83, 94, A4, B1, B4 ?
IRR: 41, B1, D1 ?
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中的代碼;而硬件則沒有這個限制。
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
0: kd> !idt ? ? ? ? ? ? ? ? ? ? ? ? ? //查看中斷向量表內容 ?
0: kd> dt nt!_KINTERRUPT 89c03bb0 ? ? //查看對應中斷向量的詳細內容 ?
0: kd> !ioapic ? ? ? ? ? ? ? ? ? ? ? ?//顯示I/O APIC(即連接至設備的中斷控制部件) ?
0: kd> !pic ? ? ? ? ? ? ? ? ? ? ? ? ? // ??
0: kd> !apic ? ? ? ? ? ? ? ? ? ? ? ? ?//有關PIC的配置情況 ?
kd> !idt運行后顯示為
[plain] view plain copy
0: kd> !idt ?
??
Dumping IDT: ?
??
37: 806e7864 hal!PicSpuriousService37 ?
3d: 806e8e2c hal!HalpApcInterrupt ?
41: 806e8c88 hal!HalpDispatchInterrupt ?
50: 806e793c hal!HalpApicRebootService ?
63: 89ac57e4 USBPORT!USBPORT_InterruptService (KINTERRUPT 89ac57a8) ?
? ? ? ? ? ? ?USBPORT!USBPORT_InterruptService (KINTERRUPT 8982abb0) ?
73: 89d6767c atapi!IdePortInterrupt (KINTERRUPT 89d67640) ?
? ? ? ? ? ? ?atapi!IdePortInterrupt (KINTERRUPT 89dc4bb0) ?
83: 89c1471c VIDEOPRT!pVideoPortInterrupt (KINTERRUPT 89c146e0) ?
? ? ? ? ? ? ?HDAudBus!AzController::Isr (KINTERRUPT 89c16ac8) ?
? ? ? ? ? ? ?NDIS!ndisMIsr (KINTERRUPT 89847bb0) ?
94: 8976fbec USBPORT!USBPORT_InterruptService (KINTERRUPT 8976fbb0) ?
a4: 89770bec USBPORT!USBPORT_InterruptService (KINTERRUPT 89770bb0) ?
b1: 89d859e4 ACPI!ACPIInterruptServiceRoutine (KINTERRUPT 89d859a8) ?
b4: 89c03bec USBPORT!USBPORT_InterruptService (KINTERRUPT 89c03bb0) ?
c1: 806e7ac0 hal!HalpBroadcastCallService ?
d1: 806e6e54 hal!HalpClockInterrupt ?
e1: 806e8048 hal!HalpIpiHandler ?
e3: 806e7dac hal!HalpLocalApicErrorService ?
fd: 806e85a8 hal!HalpProfileInterrupt ?
fe: 806e8748 hal!HalpPerfInterrupt ?
//前部分是使用的中斷類型號。例如83號中斷是有三個硬件復用。 ?
?
2.0: kd> dt nt!_KINTERRUPT 89c03bb0,運行后顯示為
[plain] view plain copy
0: kd> dt nt!_KINTERRUPT 89c03bb0 ?
? ?+0x000 Type ? ? ? ? ? ? : 0n22 ?
? ?+0x002 Size ? ? ? ? ? ? : 0n484 ?
? ?+0x004 InterruptListEntry : _LIST_ENTRY [ 0x89c03bb4 - 0x89c03bb4 ] ?
? ?+0x00c ServiceRoutine ? : 0xb9159e54 ? ? unsigned char ?USBPORT!USBPORT_InterruptService+0 ?
? ?+0x010 ServiceContext ? : 0x89c38028 Void ?
? ?+0x014 SpinLock ? ? ? ? : 0 ?
? ?+0x018 TickCount ? ? ? ?: 0xffffffff ?
? ?+0x01c ActualLock ? ? ? : 0x89c03e14 ?-> 0 ?
? ?+0x020 DispatchAddress ?: 0x805466d0 ? ? void ?nt!KiInterruptDispatch+0 ?
? ?+0x024 Vector ? ? ? ? ? : 0x1b4 ?
? ?+0x028 Irql ? ? ? ? ? ? : 0xa '' ?
? ?+0x029 SynchronizeIrql ?: 0xa '' ?
? ?+0x02a FloatingSave ? ? : 0 '' ?
? ?+0x02b Connected ? ? ? ?: 0x1 '' ?
? ?+0x02c Number ? ? ? ? ? : 0 '' ?
? ?+0x02d ShareVector ? ? ?: 0x1 '' ?
? ?+0x030 Mode ? ? ? ? ? ? : 0 ( LevelSensitive ) ?
? ?+0x034 ServiceCount ? ? : 0 ?
? ?+0x038 DispatchCount ? ?: 0xffffffff ?
? ?+0x03c DispatchCode ? ? : [106] 0x56535554 ?
?
3.0: kd> !ioapic,運行后顯示
[plain] view plain copy
0: kd> !ioapic ?
IoApic @ FEC00000 ?ID:8 (20) ?Arb:170020 ?
Inti00.: 52000000`000100ff ?Vec:FF ?FixedDel ?Ph:52000000 ? ? ?edg high ? ? ?m ?
Inti01.: 00c00000`000100ff ?Vec:FF ?FixedDel ?Ph:00C00000 ? ? ?edg high ? ? ?m ?
Inti02.: 00000000`000100ff ?Vec:FF ?FixedDel ?Ph:00000000 ? ? ?edg high ? ? ?m ?
Inti03.: 00000000`000100ff ?Vec:FF ?FixedDel ?Ph:00000000 ? ? ?edg high ? ? ?m ?
Inti04.: 00000000`000100ff ?Vec:FF ?FixedDel ?Ph:00000000 ? ? ?edg high ? ? ?m ?
Inti05.: 52c00000`000100ff ?Vec:FF ?FixedDel ?Ph:52C00000 ? ? ?edg high ? ? ?m ?
Inti06.: 00c00000`000100ff ?Vec:FF ?FixedDel ?Ph:00C00000 ? ? ?edg high ? ? ?m ?
Inti07.: 02000000`000100ff ?Vec:FF ?FixedDel ?Ph:02000000 ? ? ?edg high ? ? ?m ?
Inti08.: 01000000`000008d1 ?Vec:D1 ?FixedDel ?Lg:01000000 ? ? ?edg high ? ? ? ??
Inti09.: 03000000`0000d9b1 ?Vec:B1 ?LowestDl ?Lg:03000000-Pend lvl high rirr ? ?
Inti0A.: 00c00000`000100ff ?Vec:FF ?FixedDel ?Ph:00C00000 ? ? ?edg high ? ? ?m ?
Inti0B.: 00000000`000100ff ?Vec:FF ?FixedDel ?Ph:00000000 ? ? ?edg high ? ? ?m ?
Inti0C.: 42000000`000100ff ?Vec:FF ?FixedDel ?Ph:42000000 ? ? ?edg high ? ? ?m ?
Inti0D.: 00000000`000100ff ?Vec:FF ?FixedDel ?Ph:00000000 ? ? ?edg high ? ? ?m ?
Inti0E.: 00000000`000100ff ?Vec:FF ?FixedDel ?Ph:00000000 ? ? ?edg high ? ? ?m ?
Inti0F.: 00000000`000100ff ?Vec:FF ?FixedDel ?Ph:00000000 ? ? ?edg high ? ? ?m ?
Inti10.: 03000000`0000f983 ?Vec:83 ?LowestDl ?Lg:03000000-Pend lvl low ?rirr ? ?
Inti11.: 00000000`000100ff ?Vec:FF ?FixedDel ?Ph:00000000 ? ? ?edg high ? ? ?m ?
Inti12.: 03000000`0000a994 ?Vec:94 ?LowestDl ?Lg:03000000 ? ? ?lvl low ? ? ? ? ?
Inti13.: 00c00000`000100ff ?Vec:FF ?FixedDel ?Ph:00C00000 ? ? ?edg high ? ? ?m ?
Inti14.: 03000000`0000a973 ?Vec:73 ?LowestDl ?Lg:03000000 ? ? ?lvl low ? ? ? ? ?
Inti15.: 03000000`0000a963 ?Vec:63 ?LowestDl ?Lg:03000000 ? ? ?lvl low ? ? ? ? ?
Inti16.: 03000000`0000a9a4 ?Vec:A4 ?LowestDl ?Lg:03000000 ? ? ?lvl low ? ? ? ? ?
Inti17.: 03000000`0000f9b4 ?Vec:B4 ?LowestDl ?Lg:03000000-Pend lvl low ?rirr ? ?
?
4.0: kd> !pic ,運行后顯示
[plain] view plain copy
0: kd> !pic ?
----- IRQ Number ----- 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ?
Physically in service: ?. ?. ?. ?. ?. ?. ?. ?. ?. ?. ?. ?. ?. ?. ?. ?. ?
Physically masked: ? ? ?Y ?Y ?Y ?Y ?Y ?Y ?Y ?Y ?Y ?Y ?Y ?Y ?Y ?Y ?Y ?Y ?
Physically requested: ? Y ?. ?. ?Y ?. ?Y ?. ?. ?Y ?Y ?Y ?Y ?. ?. ?. ?. ?
?
5.0: kd> !apic,運行后顯示
[plain] view plain copy
0: kd> !apic ?
Apic @ fffe0000 ?ID:0 (50014) ?LogDesc:01000000 ?DestFmt:ffffffff ?TPR FF ?
TimeCnt: 0fdad680clk ?SpurVec:1f ?FaultVec:e3 ?error:40 ?
Ipi Cmd: 02000000`000008e1 ?Vec:E1 ?FixedDel ?Lg:02000000 ? ? ?edg high ? ? ? ??
Timer..: 00000000`000300fd ?Vec:FD ?FixedDel ? ?Dest=Self ? ? ?edg high ? ? ?m ?
Linti0.: 00000000`0001001f ?Vec:1F ?FixedDel ? ?Dest=Self ? ? ?edg high ? ? ?m ?
Linti1.: 00000000`000084ff ?Vec:FF ?NMI ? ? ? ? Dest=Self ? ? ?lvl high ? ? ? ??
TMR: 63, 73, 83, 94, A4, B1, B4 ?
IRR: 41, B1, D1 ?
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中的代碼;而硬件則沒有這個限制。
總結
以上是生活随笔為你收集整理的windbg基本命令的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 设计模式C++实现(16)——状态模式
- 下一篇: windbg基本简单步骤