版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
KernelDebuggingTutorial ?2005MicrosoftCorporation WinDBG內(nèi)核調(diào)試指南使用WinDbg內(nèi)核調(diào)試WINDOWS調(diào)試工具很強(qiáng)大,但是學(xué)習(xí)使用它們并不容易。特別對(duì)于驅(qū)動(dòng)開(kāi)發(fā)者使用的WinDbg和KD這兩個(gè)內(nèi)核調(diào)試器(CDB和NTSD是用戶態(tài)調(diào)試器)。本教程的目標(biāo)是給予一個(gè)已經(jīng)有其他調(diào)試工具使用經(jīng)驗(yàn)的開(kāi)發(fā)者足夠信息,使其能通過(guò)參考WINDOWS調(diào)試工具的幫助文件進(jìn)行內(nèi)核調(diào)試。本文將假定開(kāi)發(fā)者熟悉一般WINDOWS操作系統(tǒng)和進(jìn)程的建立過(guò)程。本文的重點(diǎn)是集成內(nèi)核模式和用戶態(tài)模式的圖形化調(diào)試器WinDbg。KD在腳本和自動(dòng)化調(diào)試中更有用,并且在資深程序員中擁有一定地位,但是本教程將集中討論WinDbg,只會(huì)偶爾提到KD。本文討論的是WindowsNT4.0,Windows2000或以后的版本,而且目標(biāo)電腦的處理器基于X86架構(gòu)。對(duì)于64位平臺(tái),將不會(huì)特別提及??傊?,本教程由簡(jiǎn)單介紹調(diào)試器的安裝開(kāi)始,大體分成2部分,基礎(chǔ)知識(shí)和選擇技術(shù)。基礎(chǔ)知識(shí)包括基本調(diào)試命令和常用調(diào)試命令。選擇技術(shù)是其他命令和在很多情況下都有用的調(diào)查方法。后者并不是調(diào)查象deadlocks,memorycorruption或者resourceleaks的唯一方法。第一次閱讀本教程,你可能會(huì)跳過(guò)選擇技術(shù)。你可以停止閱讀本教程而轉(zhuǎn)向微軟調(diào)試器討論組,也可以通過(guò)調(diào)試器的反饋e-mai解決更多的問(wèn)題。安裝程序取得新版!取得新版的調(diào)試器,并且有規(guī)律的更新它。這里并沒(méi)有夸大新版的價(jià)值,因?yàn)檎{(diào)試器會(huì)經(jīng)常改進(jìn)和修復(fù)錯(cuò)誤。你將能在下面網(wǎng)址下載:/whdc/devtools/debugging/default.mspx.主機(jī)與目標(biāo)之間的連接調(diào)試器有使用null-modemcable或者1394cable連接兩臺(tái)電腦的安裝方案。本教程不分析單操作系統(tǒng)的本地調(diào)試(即在調(diào)試器運(yùn)行的電腦上進(jìn)行分析)。3臺(tái)電腦(目標(biāo)電腦,調(diào)試服務(wù)器,調(diào)試客戶端)的調(diào)試將會(huì)被簡(jiǎn)要的討論。在主機(jī)調(diào)試軟件(WinDbg或者KD)和目標(biāo)操作系統(tǒng)之間,是一個(gè)協(xié)同處理的調(diào)試過(guò)程。每一部分都必須做些什么。更明確地,WinDbg不是作為一個(gè)“管理操作系統(tǒng)”,象客戶和一個(gè)真正操作系統(tǒng)那樣運(yùn)行目標(biāo)。WinDbg是一個(gè)調(diào)試軟件,象目標(biāo)操作系統(tǒng)的合作伙伴那樣知道它在調(diào)試過(guò)程中的角色。在這種關(guān)系中,WinDbg從目標(biāo)接收信息,并且向目標(biāo)發(fā)送信息。這是一種有效的通信機(jī)制。serialprotocol是調(diào)試器與目標(biāo)系統(tǒng)之間可靠的通信機(jī)制。你能通過(guò)null-modemcable使用COM端口連接主機(jī)和目標(biāo)機(jī)器。另一個(gè)可供選擇的通信機(jī)制是1394。在調(diào)試工具的幫助文件中的“ConfiguringSoftwareontheTargetComputer.”主題有關(guān)于它們的描述。你的第一次session假設(shè)你的主機(jī)使用WIN2K或以上的版本。主機(jī)的操作系統(tǒng)可以不同于目標(biāo)電腦的操作系統(tǒng)。主機(jī)可以在你平常進(jìn)行開(kāi)發(fā),維護(hù)或者故障診斷的地方。它應(yīng)該與網(wǎng)絡(luò)連接,如果你希望訪問(wèn)symbol和source服務(wù)器(請(qǐng)看symbols和source)。從命令提示窗口中,改變當(dāng)前的目錄到WINDOWS調(diào)試工具的安裝目錄。這是windbg.exe和kd.exe所在的位置。輸入windbg,按下Enter。你將會(huì)看到:分屏在這里,你能重排你的窗口。下面的例子包括可移動(dòng)的窗口。打開(kāi)組合窗口并移到屏幕上方,單擊“Command”標(biāo)題欄并拖動(dòng)它的窗口離開(kāi)主框架。然后收縮主框架,你可以使用鍵擊代替直接使用菜單或者按鈕。
然后使用FileKernelDebug以得到一個(gè)協(xié)議窗口,選擇1394和channel1。到這里,你的桌面會(huì)象下圖一樣:在KernelDebugging窗口中,點(diǎn)OK。激活連接現(xiàn)在你已經(jīng)準(zhǔn)備好在主機(jī)和目標(biāo)之間建立連接。在目標(biāo)機(jī)器以其中一個(gè)調(diào)試入口啟動(dòng)WINDOWS。立即回到主機(jī)系統(tǒng),用鼠標(biāo)激活WinDbg的命令窗口,按下CTRL+BREAK。不久之后,你會(huì)看到:現(xiàn)在不必?fù)?dān)心關(guān)于symbols的信息。你已經(jīng)將WinDbg連接到WIN2003。你現(xiàn)在很忙!你需要明白一件細(xì)小卻至關(guān)重要的事:在命令窗口的底部顯示“kd>”提示符。這代表WinDbg已經(jīng)準(zhǔn)別好接受命令。如果沒(méi)有提示符顯示,這時(shí)WinDbg將不能處理命令,盡管你輸入的任何命令都將會(huì)被保存在緩沖區(qū)域并盡可能快的運(yùn)行。你必須等待“kd>”出現(xiàn),以確定WinDbg已經(jīng)作好響應(yīng)的準(zhǔn)備。因?yàn)橛袝r(shí)它正在忙于做某些你看不見(jiàn)的事(例如從目標(biāo)取得信息,該信息可能很龐大)。缺少“kd>”是WinDbg處于繁忙狀態(tài)的唯一線索。另一個(gè)可能是WinDbg試圖解析symbol并且時(shí)間超過(guò)了你的預(yù)期。不幸地,WinDbg偶爾會(huì)等待一個(gè)永遠(yuǎn)不會(huì)響應(yīng)的目標(biāo)連接(可能boot.ini配置得不好,或者選擇了錯(cuò)誤的選項(xiàng))。在等待足夠時(shí)間之后,你必須決定采取激烈的措施例如按下CTRL+BREAK,或者停止WinDbg重新開(kāi)始。查找symbols和source現(xiàn)在你很可能渴望開(kāi)始調(diào)試,但仍然有一些東西你必須去做,因?yàn)樗鼈儗?huì)很好的改善你的調(diào)試體驗(yàn)。首先確認(rèn)WinDbg能找到你感興趣模塊的symbols。Symbols指出一個(gè)二進(jìn)制命令與聲明之間的聯(lián)系和什么變量正在被轉(zhuǎn)移。換句話說(shuō),就是Symbols表。如果你在建立模塊的地方,那么你將擁有有效的symbols和source文件。但是如果你需要單步調(diào)試其他很早以前建立代碼呢?或者,在那種情況下,如果你的代碼不在它被建立的地方呢?明確的設(shè)置symbols所在的地方,使用.sympath命令。在命令窗口中中斷(CTRL-BREAK)然后輸入:.sympathSRV*<DownstreamStore>*/download/symbols以便告訴WinDbg在Microsoft公開(kāi)的symbols服務(wù)器上查找symbols。讓W(xué)inDbg使用該服務(wù)以及在本地保存一份已下載的symbols。例如,在D:\DebugSymbols,你應(yīng)該這么做:.sympathSRV*d:\DebugSymbols*/download/symbols你偶爾會(huì)在symbols服務(wù)器上獲取symbols時(shí)遇到一些故障。在這個(gè)情況下,使用!symnoisy命令以獲得關(guān)于WinDbg嘗試獲取symbols的更多信息。然后使用!lmi查看WinDbg知道多少關(guān)于ntoskrnl的信息。然后嘗試取得ntoskrnl的symbols,使用.reload/f。因而:kd>!symnoisynoisymode-symbolpromptsonkd>!lmintLoadedModuleInfo:[nt]Module:ntoskrnlBaseAddress:80a02000ImageName:ntoskrnl.exeMachineType:332(I386)TimeStamp:3e80048bMonMar2423:26:032003Size:4d8000CheckSum:3f6f03Characteristics:10eDebugDataDirs:TypeSizeVAPointerCODEVIEW25,ee00,e600RSDS-GUID:(0xec9b7590,0xd1bb,0x47a6,0xa6,0xd5,0x38,0x35,0x38,0xc2,0xb3,0x1a)Age:1,Pdb:ntoskrnl.pdbImageType:MEMORY-Imagereadsuccessfullyfromloadedmemory.SymbolType:EXPORT-PDBnotfoundLoadReport:exportsymbols在WINDOWS調(diào)試工具幫助文件中,有關(guān)于這里使用的命令及其語(yǔ)法的描述。輸出symbols通常很大。WINDOWS調(diào)試工具包括一個(gè)symbol服務(wù)器,以便連接到Microsoft的網(wǎng)絡(luò)服務(wù)器保存這些公開(kāi)的symbol。添加這些到你的symbol路徑,然后加載它們:kd>.sympathSRV*d:\DebugSymbols*/download/symbolsSymbolsearchpathis:SRV*d:\DebugSymbols*/download/symbolskd>.reload/fntSYMSRV:\\symbols\symbols\ntoskrnl.pdb\EC9B7590D1BB47A6A6D5383538C2B31A1\file.ptrSYMSRV:ntoskrnl.pdbfrom\\symbols\symbols:9620480bytescopiedDBGHELP:nt-publicsymbolsd:\DebugSymbols\ntoskrnl.pdb\EC9B7590D1BB47A6A6D5383538C2B31A1\ntoskrnl.pdbkd>!lmintLoadedModuleInfo:[nt]Module:ntoskrnlBaseAddress:80a02000ImageName:ntoskrnl.exeMachineType:332(I386)TimeStamp:3e80048bMonMar2423:26:032003Size:4d8000CheckSum:3f6f03Characteristics:10eDebugDataDirs:TypeSizeVAPointerCODEVIEW25,ee00,e600RSDS-GUID:(0xec9b7590,0xd1bb,0x47a6,0xa6,0xd5,0x38,0x35,0x38,0xc2,0xb3,0x1a)Age:1,Pdb:ntoskrnl.pdbImageType:MEMORY-Imagereadsuccessfullyfromloadedmemory.SymbolType:PDB-Symbolsloadedsuccessfullyfromsymbolserver.d:\DebugSymbols\ntoskrnl.pdb\EC9B7590D1BB47A6A6D5383538C2B31A1\ntoskrnl.pdbCompiler:C-frontend[13.10bld2179]-backend[13.10bld2190]LoadReport:publicsymbolsd:\DebugSymbols\ntoskrnl.pdb\EC9B7590D1BB47A6A6D5383538C2B31A1\ntoskrnl.pdbsymbols只會(huì)給你一些信息,而不會(huì)提供源代碼。在簡(jiǎn)單的情況下,在它們被建立的時(shí)候,source文件便在同一個(gè)地方(該位置包括2進(jìn)制文件和symbol文件)。但是在大多數(shù)情況下,你不能在那里找到它們(它們可能被移走了),你必須指定在哪里能找到它們。這時(shí),你需要一個(gè)源路徑,例如,.srcpathe:\Win2003SP1它的意思是:想要source文件,請(qǐng)查看e:\Win2003SP1目錄。另一個(gè)解決方案是命名一個(gè)source服務(wù)器,如果你有:.srcpath\\MySrcServer如果你曾經(jīng)在獲取source文件時(shí)遇到麻煩,使用.srcnoisy1以取得更多關(guān)于調(diào)試器查找它們的信息。Workspaces目前你還不能開(kāi)始調(diào)試,除非你已經(jīng)準(zhǔn)備好打很多字。很多設(shè)置都被保存在workspace中。所以你應(yīng)該使用FileSave保存在workspace里面,例如,你將它保存為kernel1394Win2003。在這之后,你希望以這個(gè)workspace的設(shè)置啟動(dòng)WinDbg:windbg-Wkernel1394Win2003-k1394:channel=1–W指定一個(gè)workspace,而–k給出通信方式(祥見(jiàn)WINDOWS調(diào)試工具幫助文件中的“WinDbgCommand-LineOptions”)。注意:在WinDbg或者KD中,你應(yīng)該小心區(qū)分命令行可選項(xiàng)的大小寫。為了讓事情變得簡(jiǎn)單,你可以在桌面建立快捷方式,以使用特定的workspace啟動(dòng)WinDbg,例如,使用1394連接:上述文件中的內(nèi)容:cd/d"d:\ProgramFiles\DebuggingToolsforWindows"startwindbg.exe-ySRV*d:\DebugSymbols*/download/symbols-Wkernel1394Win2003第一行將切換到WINDOWS調(diào)試工具的安裝目錄下面,確認(rèn)調(diào)試器模塊能在那里被找到。第二行啟動(dòng)WinDbg,指定symbo路徑(-y)和workspace(-W)。一個(gè)示例驅(qū)動(dòng)使用示例驅(qū)動(dòng)IoCtl練習(xí),這將會(huì)幫助你熟悉WinDbg。你能在WINDDK和它的后續(xù)產(chǎn)品,WDK中找到。安裝它,你便能在src\general\Ioctl子目錄下找到該驅(qū)動(dòng)。IoCtl的優(yōu)點(diǎn)在于它是示例,而且是一個(gè)“l(fā)egacy”驅(qū)動(dòng),由服務(wù)管理器(SCM)加載,而不是即插即用的一部分(這里并不關(guān)心PnP的輸入和輸出)。你應(yīng)該建立用戶態(tài)程序(ioctlapp.exe),并在前者被加載之后建立內(nèi)核態(tài)驅(qū)動(dòng)程序(sioctl.sys)。這里有些重要的事需要明白。在優(yōu)化代碼方面,建立程序的處理十分靈巧,優(yōu)化會(huì)導(dǎo)致代碼移動(dòng)(當(dāng)然,原邏輯會(huì)被保留),并且將一些變量單獨(dú)保存在寄存器中。為了確保更簡(jiǎn)單的調(diào)試體驗(yàn),你應(yīng)該在建立窗口或者源代碼文件中使用這些編譯指令建立一個(gè)調(diào)試版本:MSC_OPTIMIZATION=/Od(這是“Ohd”而不是“zerod.”)有時(shí)上述的情況會(huì)引起內(nèi)部函數(shù)的一些問(wèn)題,例如memcmp。如果你碰上這個(gè)問(wèn)題,嘗試:MSC_OPTIMIZATION=/Odi請(qǐng)明白阻止優(yōu)化對(duì)于生成正式版產(chǎn)品來(lái)說(shuō),并不是一個(gè)好選擇。使用上述的指令,你將不能建立或者測(cè)試正式版。盡管如此,這對(duì)于測(cè)試未經(jīng)優(yōu)化的版本來(lái)說(shuō),是不錯(cuò)的練習(xí)。一旦你熟悉代碼,排除簡(jiǎn)單的錯(cuò)誤,正式產(chǎn)品便能得到提升。如果你需要處理已優(yōu)化的代碼,你將會(huì)在“處理優(yōu)化代碼”找到相關(guān)幫助。開(kāi)始調(diào)試示例驅(qū)動(dòng)在IoCtl的DriverEntry設(shè)置斷點(diǎn)。在啟動(dòng)驅(qū)動(dòng)之前,中斷在WinDbg的命令窗口,輸入:busioctl!DriverEntrybu(“BreakpointUnresolved”)命令將會(huì)延遲斷點(diǎn)的設(shè)置時(shí)間,直到該模塊被加載;也就是說(shuō)WinDbg會(huì)探測(cè)“DriverEntry”。如果沒(méi)有什么需要做,按下F5(你也可以輸入g,“Go”)接下來(lái),復(fù)制ioctlapp.exe和sioctl.sys到目標(biāo)系統(tǒng),例如C:\Temp\IOCTL,以管理員權(quán)限登陸系統(tǒng),在命令窗口中,切換到C:\Temp\IOCTL目錄下。(你不需要在WinDbg中將此路徑設(shè)置為symbol路徑和source路徑。)在同樣的命令窗口,輸入ioctlapp按下Enter,在WinDbg中,你會(huì)看到:如圖,程序停在斷點(diǎn)之后,!lmi命令顯示W(wǎng)inDbg從DDK中取得symbols。時(shí)間信息象你期望的一樣,本地symbol文件也符合你的要求。依賴于你的排列方案,它并不明顯,當(dāng)前窗口能被其他窗口隱藏,但是你能在某個(gè)地方使用源代碼窗口(按鍵順序‘a(chǎn)lt-Keypad*’―不用按單引號(hào)―將會(huì)把窗口置前):斷點(diǎn)被設(shè)置,即運(yùn)行停止的地方會(huì)以粉紅色標(biāo)記(WINDOWS調(diào)試工具幫助文件把它稱為紫色)。當(dāng)運(yùn)行進(jìn)IoCreateDevice(運(yùn)行控制描述如何熟練運(yùn)用):這里你能看到原始斷點(diǎn)(高亮為紅色,現(xiàn)在控制將停止在這里),你能看到當(dāng)前聲明被標(biāo)記為深藍(lán)色。基礎(chǔ)在調(diào)試session中,這是一個(gè)“測(cè)試驅(qū)動(dòng)”。這是一些基本的調(diào)試操作。命令,擴(kuò)展,等等。命令來(lái)自幾個(gè)系列:簡(jiǎn)單的(未修飾的),一些從句號(hào)(“.”)開(kāi)始,一些從驚嘆號(hào)(“!”)開(kāi)始。WINDOWS調(diào)試工具幫助文件將它們分別描述為commands,meta-commandsandextensioncommands。以現(xiàn)在的效果來(lái)看,這些系列非常接近。斷點(diǎn)在運(yùn)行中產(chǎn)生中斷,是調(diào)試器的功能之一。這是一些實(shí)現(xiàn)方法。在操作系統(tǒng)啟動(dòng)時(shí)中斷為了在操作系統(tǒng)啟動(dòng)時(shí)盡早中斷,請(qǐng)確認(rèn)WinDbg已經(jīng)連接,重新按CTRL-ALT-K直到你看到:在下次啟動(dòng)時(shí),在ntoskrnl加載之后的一小段時(shí)間,這時(shí)所有驅(qū)動(dòng)還沒(méi)有被加載,操作系統(tǒng)將會(huì)掛起,而WinDbg將會(huì)取得控制權(quán)。在系統(tǒng)引導(dǎo)時(shí)間,你可能會(huì)希望為驅(qū)動(dòng)程序定義斷點(diǎn),這就是時(shí)機(jī)。普通斷點(diǎn)簡(jiǎn)單的設(shè)置斷點(diǎn)的方法就是通過(guò)bp(“Breakpoint”)命令。例如:bpMyDriver!xyzbpf89adeaa第一行,這個(gè)斷點(diǎn)設(shè)在模塊中的一個(gè)名字(<module>!<name>);第二行,它被設(shè)置在一個(gè)給出的地址。當(dāng)運(yùn)行到其中一個(gè)斷點(diǎn)時(shí),操作系統(tǒng)就會(huì)掛起,并且把控制權(quán)交給WinDbg。(你可以在“尋找名字”看看如何為第二個(gè)命令取得地址。)注意:第一個(gè)命令的語(yǔ)法假定操作系統(tǒng)已經(jīng)加載該模塊,以及在symbol文件或者外部名定義有足夠可用信息關(guān)于識(shí)別xyz。如果不能在模塊中找到xyz,調(diào)試器會(huì)這么告訴你這些。延遲斷點(diǎn)說(shuō)到驅(qū)動(dòng)程序沒(méi)有被加載,你初的哪個(gè)斷點(diǎn),使用bu(見(jiàn)上述開(kāi)始調(diào)試示例驅(qū)動(dòng))設(shè)置的是一個(gè)“可延遲的”斷點(diǎn)。Bu命令的參數(shù)是一個(gè)模塊及它里面的名字,例如:busioctl!SioctlDeviceControlSioctlDeviceControl是一個(gè)入口點(diǎn),或者其他在模塊sioctl.sys中的名字。這個(gè)形式假定當(dāng)模塊被加載,足夠有用的信息識(shí)別SioctlDeviceControl以便斷點(diǎn)能夠設(shè)置。(如果模塊已經(jīng)加載名字被找到,那么斷點(diǎn)將會(huì)立即被設(shè)置)。如果操作系統(tǒng)找不到SioctlDeviceControl,調(diào)試器會(huì)提示,另外將不會(huì)在SioctlDeviceControl處掛起。延遲斷點(diǎn)的一個(gè)有用的特性便是它對(duì)modules!names操作。相比之下,一般斷點(diǎn)對(duì)地址或者立即將modules!names解釋為地址。延遲斷點(diǎn)的另一個(gè)特性便是在引導(dǎo)的過(guò)程中會(huì)被記住(這不會(huì)影響明確地址的斷點(diǎn))。然而,延遲斷點(diǎn)的另外一個(gè)特性使得即使關(guān)聯(lián)模塊被卸載,它仍然會(huì)被保留。相同情況下,一般斷點(diǎn)將會(huì)被移除。另外一個(gè)設(shè)置一般斷點(diǎn)的方法是通過(guò)source窗口。返回sioctl.sys。當(dāng)你中斷于DriverEntry,,你能向下滾動(dòng)窗口到你希望停止地方,將光標(biāo)移動(dòng)到該行代碼,按下F9:紅色的那一行便是通過(guò)F9設(shè)置的斷點(diǎn)。你可以使用bl(“BreakpointList”)查看所有已設(shè)置的斷點(diǎn):kd>ble[d:\winddk\3790\src\general\ioctl\sys\sioctl.c@123]0001(0001)SIoctl!DriverEntrye[d:\winddk\3790\src\general\ioctl\sys\sioctl.c@338]0001(0001)Sioctl!SioctlDeviceControl+0x103注意兩件事:每個(gè)斷點(diǎn)都有一個(gè)號(hào)碼并且顯示出斷點(diǎn)狀態(tài),“e”是“enabled”,而“d”是“disabled”。假設(shè)你希望臨時(shí)停止使用某個(gè)斷點(diǎn)。bd(“DisableBreakpoint”)將會(huì)完成它。你只需指定斷點(diǎn)號(hào)碼:kd>bd1kd>ble[d:\winddk\3790\src\general\ioctl\sys\sioctl.c@123]0001(0001)SIoctl!DriverEntryd[d:\winddk\3790\src\general\ioctl\sys\sioctl.c@338]0001(0001)SIoctl!SioctlDeviceControl+0x103相似的方法,永久移除斷點(diǎn)號(hào)碼,使用bc1(“ClearBreakpoint”)?,F(xiàn)在該斷點(diǎn)將會(huì)從斷點(diǎn)列表中消除。然而,有時(shí)在操作系統(tǒng)或者驅(qū)動(dòng)程序中,斷點(diǎn)會(huì)被設(shè)置在一些頻繁被激活的地方,你可能希望將它應(yīng)用在一些環(huán)境或者條件操作,以便斷點(diǎn)只在該情況下生效。這是基本格式:bpSIoctl!SioctlDeviceControl+0x103"j(@@(Irp)=0xffb5c4f8)'';'g'"它的意思是:只有Irp=地址0xFFB5C4F8時(shí)才中斷;如果條件不符合,繼續(xù)運(yùn)行。更深入的探討上述命令,并不是斷點(diǎn)本身的狀態(tài)。更準(zhǔn)確的說(shuō),斷點(diǎn)有一個(gè)操作項(xiàng)目(在雙引號(hào)標(biāo)記中);在該項(xiàng)目中,j(“ExecuteIF/ELSE”)命令是一個(gè)條件操作。J的函數(shù)運(yùn)行于TRUE|FALSE項(xiàng)目(在單引號(hào)標(biāo)記中)。如上述一樣,TRUE項(xiàng)目(第一)為空,以便當(dāng)斷點(diǎn)激活和符合TRUE的條件出現(xiàn)時(shí),WinDbg除了掛起程序之外不會(huì)做其他的事。如果符合FALSE的條件出現(xiàn),由于使用了g命令,程序講會(huì)繼續(xù)運(yùn)行。一個(gè)或者其他操作會(huì)被完成,這依賴于實(shí)際情況。思考這個(gè)比上述更詳細(xì)的命令:bpSIoctl!SioctlDeviceControl+0x103"j(@@(Irp)=0xffb5c4f8)'.echoFoundtheinterestingIRP';'.echoSkippinganIRPofnointerest;g'"這里TRUE項(xiàng)目給出信息并停止。FALSE項(xiàng)目給出信息并繼續(xù)(這個(gè)信息很有用,WinDbg計(jì)算出條件為FALSE,并且默默地繼續(xù))。有時(shí)要注意:下面斷點(diǎn),EAX被檢測(cè)(你能在寄存器中找到關(guān)于它們的處理方法),不會(huì)象你想的那樣工作:bpSIoctl!SioctlDeviceControl+0x103"j(@eax=0xffb5c4f8)'.echoHere!';'.echoSkipping;g'"原因是可能會(huì)將寄存器的值擴(kuò)充到64位再計(jì)算,例如,擴(kuò)充到0xFFFFFFFF`FFB5C4F8,這將不會(huì)與0x00000000`FFB5C4F8匹配。這導(dǎo)致只有32位的高位為1和一些其他條件(例如,一個(gè)32位寄存器)才適用。在WINDOWS調(diào)試工具幫助文件中的“SignExtension”有更詳盡的資料(也可以看看“SettingaConditionalBreakpoint”)。斷點(diǎn)可能包含一些條件式,附帶或不附帶條件操作。其中一個(gè)條件是激發(fā)“one-shot”:斷點(diǎn)只激活一次(激活之后便清除)。假如你只對(duì)第一次激活感興趣,對(duì)于那些使用頻繁的代碼,這很便利。bp/1SIoctl!SioctlDeviceControl+0x103另外一個(gè)有用的條件式測(cè)試一個(gè)進(jìn)程或者線程:bp/p0x81234000SIoctl!SioctlDeviceControl+0x103bp/t0xff234000SIoctl!SioctlDeviceControl+0x103它們分別代表,僅當(dāng)進(jìn)程塊(EPROCESS)在0x81234000,才在指定的地方停止,以及僅當(dāng)線程塊(ETHREAD)在0xFF234000時(shí)才在指定地方停止。該條件式能被組合為:bp/1/C4/p0x81234000SIoctl!SioctlDeviceControl+0x103這代表,當(dāng)callstack深度大于4(這里的大寫C很重要,因?yàn)椤癱”代表“少于”)和進(jìn)程塊在0x81234000時(shí)中斷。?另外一種不同類型的斷點(diǎn),需要指定訪問(wèn)方式。例如:baw40xffb5c4f8+0x18+0x4正如你所看到的,這個(gè)地址來(lái)自IRP,它的偏移0x18+0x4處即它的IoStatus.Information成員。所以當(dāng)某程序企圖更新IRP中IoStatus.Information的這4個(gè)字節(jié)時(shí),斷點(diǎn)會(huì)被激活。這種斷點(diǎn)被稱為數(shù)據(jù)斷點(diǎn)(因?yàn)樗鼈冇蓴?shù)據(jù)訪問(wèn)觸發(fā))或者處理器斷點(diǎn)(因?yàn)樗鼈冇商幚砥鲌?zhí)行,而不是調(diào)試器自己)。表達(dá)式:MASM與C++在驅(qū)動(dòng)程序之中使用變量提供參數(shù),如進(jìn)程地址。你或許同意那是很容易的一件事。然而,你需要理解一些調(diào)試器的表達(dá)式。調(diào)試器有兩種評(píng)價(jià)表達(dá)式的方法,參考“MASM”(MicrosoftMacroAssembler)和“C++”。引用WINDOWS調(diào)試工具幫助文件中的“MASMExpressionsvs.C++Expressions”:在MASM的表達(dá)式中,任何符號(hào)的數(shù)值都在內(nèi)存地址中。在C++表達(dá)式中,變量中的數(shù)值是它的真實(shí)數(shù)值,而不是它的地址。閱讀再閱讀這部分,這將會(huì)節(jié)省你更多的時(shí)間。一條表達(dá)式將會(huì)使用MASM,或者C++,或者它們的混合形式計(jì)算。簡(jiǎn)要說(shuō)明:默認(rèn)表達(dá)式類型是MASM.你能使用.expr改變默認(rèn)類型(詳見(jiàn)WINDOWS調(diào)試工具幫助文件)。某些命令總是使用C++的方式求值。一個(gè)特殊的表達(dá)式(或表達(dá)式的一部分)的賦值能通過(guò)前綴“@@”改成與一般表達(dá)式相反的方向。這個(gè)摘要相當(dāng)棘手,你應(yīng)該參考WINDOWS調(diào)試工具幫助文件中的“EvaluatingExpressions”?,F(xiàn)在,這里有一些例子,給你一些關(guān)于賦值是如何工作的概念。你之前已經(jīng)停止在Sioctl!SioctlDeviceControl+0x103,所以使用dv查看一個(gè)已知變量(查看dv命令以獲得更多信息):kd>dvIrpIrp=0xff70fbc0該響應(yīng)的意思是,Irp變量包含0xFF70FBC0。更多地,dv解釋C++語(yǔ)法中的參數(shù)。該響應(yīng)基于變量?jī)?nèi)容,而不是地址。你可以確認(rèn)它:kd>??Irpstruct_IRP*0xff70fbc0??總是以C++為基礎(chǔ)(詳見(jiàn)??命令)。假如使用MASM類型的賦值,嘗試?(詳見(jiàn)?命令):kd>?IrpEvaluateexpression:-141181880=f795bc48這表示變量Irp位于0XF795BC48。你可以通過(guò)使用dd(詳見(jiàn)dd命令)顯示內(nèi)存數(shù)據(jù),確認(rèn)該變量真的包含數(shù)據(jù)0xFF70FBC0。kd>ddf795bc48l1f795bc48ff70fbc0以及內(nèi)存指向這里:kd>dd0xff70fbc0ff70fbc0009400060000000000000070ff660c30ff70fbd0ff70fbd0ff70fbd00000000000000000ff70fbe001010001040000000006fdc000000000ff70fbf000000000000000000000000004008f20ff70fc0000000000000000000000000000000000ff70fc10ff73f4d8000000000000000000000000ff70fc20ff70fc30ffb05b900000000000000000ff70fc300005000e000000640000003c9c402408查看象IRP這樣的變量,正如dt顯示(詳見(jiàn)dt命令),Type和Size成員有一個(gè)似是而非的數(shù)據(jù):kd>dtIrpLocalvar@0xf795bc48Type_IRP*0xff70fbc0+0x000Type:6+0x002Size:0x94+0x004MdlAddress:(null)+0x008Flags:0x70+0x00cAssociatedIrp:__unnamed+0x010ThreadListEntry:_LIST_ENTRY[0xff70fbd0-0xff70fbd0]+0x018IoStatus:_IO_STATUS_BLOCK+0x020RequestorMode:1''+0x021PendingReturned:0''+0x022StackCount:1''+0x023CurrentLocation:1''+0x024Cancel:0''+0x025CancelIrql:0''+0x026ApcEnvironment:0''+0x027AllocationFlags:0x4''+0x028UserIosb:0x0006fdc0+0x02cUserEvent:(null)+0x030Overlay:__unnamed+0x038CancelRoutine:(null)+0x03cUserBuffer:0x04008f20+0x040Tail:__unnamed有時(shí),你會(huì)希望使用C++賦值代替MASM表達(dá)式?!癅@”前綴會(huì)完成它。擴(kuò)展命令總是使用象MASM表達(dá)式一樣的參數(shù),當(dāng)你使用擴(kuò)展命令!irp(詳見(jiàn)IRPs),你能看到@@的效果。kd>!irp@@(Irp)Irpisactivewith1stacks1iscurrent(=0xff70fc30)NoMdlSystembuffer=ff660c30Threadff73f4d8:Irpstacktrace.cmdflgclDeviceFileCompletion-Context>[e,0]5082361348ffb05b9000000000-00000000 \Driver\SIoctl Args:000000640000003c9c40240800000000重復(fù)這個(gè)操作,不在上述的Irp變量中帶@@前綴,!irp將會(huì)使用變量的地址,而不是變量的值。為了使這更加具體,如果變量位于0xF795BC48,它包含的數(shù)據(jù)是0xFF70FBC0,使用!irpIrp代替@@(Irp)將會(huì)請(qǐng)求WinDbg格式化位于0xF795BC48的IRPstack。你需要進(jìn)一步了解的是:@@前綴相當(dāng)通用,正如它的正式意思,使用不同于當(dāng)前表達(dá)式中正在使用的賦值方法。如果大部分表達(dá)式是MASM,@@代表C++,如果它是C++,@@代表MASM。后一點(diǎn)建議:如果表達(dá)式不如你期望那樣工作,考慮你是否在請(qǐng)求調(diào)試器理解MASM或者C++語(yǔ)法。顯示和設(shè)置內(nèi)存,變量,寄存器等等有一些方法可以顯示和改變它們。?在當(dāng)前例程中顯示一個(gè)變量(當(dāng)前的“scope”),使用dv(“DisplayVariables”)。例如,如果停止在Sioctl!SioctlDeviceControl+0x103:kd>dvDeviceObject=0x82361348Irp=0xff70fbc0outBufLength=0x64buffer=0x00000000""irpSp=0xff70fc30data=0xf886b0c0"ThisStringisfromDeviceDriver!!!"ntStatus=0mdl=0x00000000inBufLength=0x3cdatalen=0x26outBuf=0x00000030""inBuf=0xff660c30"ThisStringisfromUserApplication;usingMETHOD_BUFFERED"這是一個(gè)參數(shù)變量列表以及一些在斷點(diǎn)位置已知的變量?!耙阎笔且粋€(gè)重要的限定詞。例如如果一個(gè)變量?jī)?yōu)化成一個(gè)寄存器,它將不會(huì)被顯示,盡管可以反匯編它(View=>Disassembly打開(kāi)反匯編窗口)并且檢查寄存器。如果只關(guān)心一個(gè)變量,你可以:kd>dvoutBufLengthoutBufLength=0x64?另外一個(gè)有用的命令是dt(“DisplayType”)。例如,繼續(xù)使用在Sioctl!SioctlDeviceControl+0x103的斷點(diǎn):kd>dtIrpLocalvar@0xf795bc48Type_IRP*0xff70fbc0+0x000Type:6+0x002Size:0x94+0x004MdlAddress:(null)+0x008Flags:0x70+0x00cAssociatedIrp:__unnamed+0x010ThreadListEntry:_LIST_ENTRY[0xff70fbd0-0xff70fbd0]+0x018IoStatus:_IO_STATUS_BLOCK+0x020RequestorMode:1''+0x021PendingReturned:0''+0x022StackCount:1''+0x023CurrentLocation:1''+0x024Cancel:0''+0x025CancelIrql:0''+0x026ApcEnvironment:0''+0x027AllocationFlags:0x4''+0x028UserIosb:0x0006fdc0+0x02cUserEvent:(null)+0x030Overlay:__unnamed+0x038CancelRoutine:(null)+0x03cUserBuffer:0x04008f20+0x040Tail:__unnamed上面的數(shù)據(jù)說(shuō)明了變量Irp在0xF795BC48,它的值是0xFF70FBC0;因?yàn)閐t知道IRP變量的指針(“Type_IRP*”),0xFF70FBC0區(qū)域被格式化為IRP。展開(kāi)一級(jí)結(jié)構(gòu):kd>dt-r1IrpLocalvar@0xf795bc48Type_IRP*0xff70fbc0+0x000Type:6+0x002Size:0x94+0x004MdlAddress:(null)+0x008Flags:0x70+0x00cAssociatedIrp:__unnamed+0x000MasterIrp:0xff660c30+0x000IrpCount:-10089424+0x000SystemBuffer:0xff660c30+0x010ThreadListEntry:_LIST_ENTRY[0xff70fbd0-0xff70fbd0]+0x000Flink:0xff70fbd0[0xff70fbd0-0xff70fbd0]+0x004Blink:0xff70fbd0[0xff70fbd0-0xff70fbd0]+0x018IoStatus:_IO_STATUS_BLOCK+0x000Status:0+0x000Pointer:(null)+0x004Information:0+0x020RequestorMode:1''+0x021PendingReturned:0''+0x022StackCount:1''+0x023CurrentLocation:1''+0x024Cancel:0''+0x025CancelIrql:0''+0x026ApcEnvironment:0''+0x027AllocationFlags:0x4''+0x028UserIosb:0x0006fdc0+0x000Status:67142040+0x000Pointer:0x04008198+0x004Information:0x2a+0x02cUserEvent:(null)+0x030Overlay:__unnamed+0x000AsynchronousParameters:__unnamed+0x000AllocationSize:_LARGE_INTEGER0x0+0x038CancelRoutine:(null)+0x03cUserBuffer:0x04008f20+0x040Tail:__unnamed+0x000Overlay:__unnamed+0x000Apc:_KAPC+0x000CompletionKey:(null)你可以顯示一些結(jié)構(gòu),甚至在它們不在范圍之內(nèi)的時(shí)候(被詢問(wèn)的內(nèi)存不能以其他一些目的再生)kd>dtnt!_IRP0xff70fbc0+0x000Type:6+0x002Size:0x94+0x004MdlAddress:(null)+0x008Flags:0x70+0x00cAssociatedIrp:__unnamed+0x010ThreadListEntry:_LIST_ENTRY[0xff70fbd0-0xff70fbd0]+0x018IoStatus:_IO_STATUS_BLOCK+0x020RequestorMode:1''+0x021PendingReturned:0''+0x022StackCount:1''+0x023CurrentLocation:1''+0x024Cancel:0''+0x025CancelIrql:0''+0x026ApcEnvironment:0''+0x027AllocationFlags:0x4''+0x028UserIosb:0x0006fdc0+0x02cUserEvent:(null)+0x030Overlay:__unnamed+0x038CancelRoutine:(null)+0x03cUserBuffer:0x04008f20+0x040Tail:__unnamed上面的命令,按照你知道的來(lái)說(shuō),就是IRP在0xFF70FBC0,而事實(shí)上,這是在ntoskrnl映射出的IRP結(jié)構(gòu)。如果你對(duì)眾多成員的區(qū)域中的一塊感興趣呢?取得成員的大小,例如:kd>dtnt!_IRPSize0xff70fbc0unsignedshort0x94更直接的方法是使用??(“EvaluateC++Expression”)命令:kd>??Irp->Sizeunsignedshort0x94那是??,了解它的參數(shù)指向適當(dāng)結(jié)構(gòu)中的一個(gè)成員。顯示內(nèi)存,而不使用上述的格式,一些可用的命令,如dd,dw和db(“DisplayMemory”):kd>dd0xff70fbc0l0x10ff70fbc0009400060000000000000070ff660c30ff70fbd0ff70fbd0ff70fbd00000000000000000ff70fbe001010001040000000006fdc000000000ff70fbf000000000000000000000000004008f20kd>dw0xff70fbc0l0x20ff70fbc00006009400000000007000000c30ff66ff70fbd0fbd0ff70fbd0ff700000000000000000ff70fbe00001010100000400fdc0000600000000ff70fbf00000000000000000000000008f200400kd>db0xff70fbc0l0x40ff70fbc00600940000000000-70000000300c66ffp...0.f.ff70fbd0d0fb70ffd0fb70ff-0000000000000000..p...pff70fbe00100010100000004-c0fd060000000000ff70fbf00000000000000000-00000000208f0004...(注意:3個(gè)命令各自的第二個(gè)參數(shù)是一個(gè)長(zhǎng)度,由l(字母“l(fā)”)后面的數(shù)值給出,例如0x10。)第一個(gè)顯示16個(gè)雙字(每個(gè)4字節(jié),或者共64個(gè)字節(jié))。第二個(gè)顯示同樣的字。第三個(gè)顯示同樣的字節(jié)。?怎么改變變量?繼續(xù)在Sioctl!SioctlDeviceControl+0x103,你會(huì)看到下面格式。kd>outBufLength=00^Syntaxerrorin'outBufLength=00'不工作?但是??完成了這個(gè)工作:kd>??outBufLength=0unsignedlong0現(xiàn)在回到IRP,你在上述使用的dt:kd>dtIrpLocalvar@0xf795bc48Type_IRP*0xff70fbc0+0x000Type:6+0x002Size:0x94+0x004MdlAddress:(null)+0x008Flags:0x70+0x00cAssociatedIrp:__unnamed+0x010ThreadListEntry:_LIST_ENTRY[0xff70fbd0-0xff70fbd0]+0x018IoStatus:_IO_STATUS_BLOCK+0x020RequestorMode:1''+0x021PendingReturned:0''+0x022StackCount:1''+0x023CurrentLocation:1''+0x024Cancel:0''+0x025CancelIrql:0''+0x026ApcEnvironment:0''+0x027AllocationFlags:0x4''+0x028UserIosb:0x0006fdc0+0x02cUserEvent:(null)+0x030Overlay:__unnamed+0x038CancelRoutine:(null)+0x03cUserBuffer:0x04008f20+0x040Tail:__unnamed改變第一個(gè)字(2個(gè)字節(jié)),通過(guò)ew(“EnterValues”):kd>ew0xff70fbc03kd>dtIrpLocalvar@0xf795bc48Type_IRP*0xff70fbc0+0x000Type:3+0x002Size:0x94+0x004MdlAddress:(null)+0x008Flags:0x70+0x00cAssociatedIrp:__unnamed+0x010ThreadListEntry:_LIST_ENTRY[0xff70fbd0-0xff70fbd0]+0x018IoStatus:_IO_STATUS_BLOCK+0x020RequestorMode:1''+0x021PendingReturned:0''+0x022StackCount:1''+0x023CurrentLocation:1''+0x024Cancel:0''+0x025CancelIrql:0''+0x026ApcEnvironment:0''+0x027AllocationFlags:0x4''+0x028UserIosb:0x0006fdc0+0x02cUserEvent:(null)+0x030Overlay:__unnamed+0x038CancelRoutine:(null)+0x03cUserBuffer:0x04008f20+0x040Tail:__unnamed當(dāng)然,下面可能比ew更加自然:kd>??irp->type=3Typedoesnothavegivenmembererrorat'type=3'kd>??irp->Type=3short3kd>dtirpioctlapp!IrpLocalvar@0xf795bc48Type_IRP*0xff70fbc0+0x000Type:3+0x002Size:0x94+0x004MdlAddress:(null)+0x008Flags:0x70+0x00cAssociatedIrp:__unnamed+0x010ThreadListEntry:_LIST_ENTRY[0xff70fbd0-0xff70fbd0]+0x018IoStatus:_IO_STATUS_BLOCK+0x020RequestorMode:1''+0x021PendingReturned:0''+0x022StackCount:1''+0x023CurrentLocation:1''+0x024Cancel:0''+0x025CancelIrql:0''+0x026ApcEnvironment:0''+0x027AllocationFlags:0x4''+0x028UserIosb:0x0006fdc0+0x02cUserEvent:(null)+0x030Overlay:__unnamed+0x038CancelRoutine:(null)+0x03cUserBuffer:0x04008f20+0x040Tail:__unnamed以上需要注意的兩件事。首先,結(jié)構(gòu)中成員的大小寫是有意義的,正如WinDbg的提示那樣,在Irp中沒(méi)有這樣的成員。第二,dtirp是二義的,但是WinDbg顯示了該實(shí)例,它的想法好象被修正了,其中一個(gè)在ioctlapp.exe而另外一個(gè)則在sioctl.sys。因?yàn)榇笮懯怯幸饬x的,你應(yīng)該在任何時(shí)候都使用它。關(guān)于ew的更多信息,有其他“EnterValues”命令:eb用于字節(jié),ed用于雙字,eq用于四倍字長(zhǎng)(8字節(jié))等等。參考WINDOWS調(diào)試工具幫助文件中的“EnterValues”。本地窗口能更容易的顯示內(nèi)嵌到結(jié)構(gòu)中的結(jié)構(gòu)指針:你可以在本地窗口中改寫它們的值。寄存器(也包括段寄存器和標(biāo)記寄存器)可以被顯示和改變。例如:kd>reax=81478f68ebx=00000000ecx=814243a8edx=0000003cesi=81778ea0edi=81478f68eip=f8803553esp=f7813bb4ebp=f7813c3ciopl=0nvupeingnzacpenccs=0008ss=0010ds=0023es=0023fs=0030gs=0000efl=00000292或者只是:kd>reaxeax=81478f68有時(shí)你會(huì)希望改變寄存器。例如,EAX經(jīng)常被用于從例程退出時(shí)傳遞返回參數(shù)。因此,在例程退出之前:reax=0xc0000001現(xiàn)在顯示狀態(tài)數(shù)據(jù)為STATUS_UNSUCCESSFUL.這里是其他的一些例子:reip=poi(@esp)resp=@esp+0xc他們分別表示,設(shè)置Eip(命令指針)為堆棧偏移為0x0指向的值,和Esp(堆棧指針)+0xC,有效的釋放堆棧。WINDOWS調(diào)試工具幫助文件中的“RegisterSyntax”,解釋了poi命令和為什么寄存器一些地方需要加上“@”前綴。你可能會(huì)問(wèn)上述寄存器設(shè)置命令怎么用??紤]一下,當(dāng)一個(gè)“壞”驅(qū)動(dòng)的DriverEntry將會(huì)引起故障檢查(“藍(lán)屏”)—或許由于違規(guī)訪問(wèn)。你可以通過(guò)在ntoskrn加載時(shí)設(shè)置一個(gè)延遲斷點(diǎn)處理這些問(wèn)題。下面命令必須在同一行中:busioctl!DriverEntry"reip=poi(@esp);reax=0xc0000001;resp=@esp+0xc;.echosioctl!DriverEntryentered;g"它的意思是:在sioctl.sys的DriverEntry,1)這樣設(shè)置命令指針(Eip)2)這樣設(shè)置返回代碼(Eax)3)這樣設(shè)置堆棧指針(Esp)4)宣布已經(jīng)進(jìn)入DriverEntry5)繼續(xù)運(yùn)行。(當(dāng)然,這技術(shù)僅僅移除DriverEntry引起崩潰的可能性,例如違規(guī)訪問(wèn)。如果操作系統(tǒng)期待驅(qū)動(dòng)程序供應(yīng)函數(shù),該函數(shù)將不可用,和可能是其他問(wèn)題導(dǎo)致停機(jī)。)在這里,你會(huì)想知道是否能用寄存器設(shè)置一個(gè)變量。例如,返回到IoCtl的dispatchroutine:kd>reax=00000000ebx=00000000ecx=81a88f18edx=81a88ef4esi=ff9e18a8edi=ff981e7eeip=f87a40feesp=f88fac78ebp=f88fac90iopl=0nvupeiplzrnaponccs=0008ss=0010ds=0023es=0023fs=0030gs=0000efl=00000246kd>??ntStatus=@ecxlong-2119659752kd>dd&ntStatusl1f88fac7881a88f18在這個(gè)情況中,應(yīng)該使用@ecx格式,以保證WinDbg知道你在引用一個(gè)寄存器。寄存器的數(shù)量比默認(rèn)顯示的要多。要查看所有寄存器,使用rM命令(“M”必須是大寫;實(shí)際上是r命令帶M參數(shù),這里在命令和參數(shù)之間不允許空格):kd>rM0xffeax=00000001ebx=0050e2a3ecx=80571780edx=000003f8esi=000000c0edi=d87a75a8eip=804df1c0esp=8056f564ebp=8056f574iopl=0nvupeiplnznapenccs=0008ss=0010ds=0023es=0023fs=0030gs=0000efl=00000202fpcw=0000:rn24fpsw=0000:top=0cc=0000fptw=0000fopcode=6745fpip=2301:a0020000fpdp=dcfe:efcdab89st0=5.143591243081972142170e-4932st1=0.001025530551233493990e-4933st2=0.000000002357022271740e-4932st3=2.471625214254630491460e-4906st4=3.370207406893238285120e-4932st5=-7.461339669368745455450e+4855st6=6.698191557136036873700e-4932st7=-2.455410815115332972380e-4906mm0=c3d2e1f010325476mm1=0000ffdff1200000mm2=000000018168d902mm3=f33cffdff1200000mm4=804efc868056f170mm5=7430804efb880000mm6=ff02740200000000mm7=f1a48056f1020000xmm0=09.11671e-0413.10647e+035-1.154e-034xmm1=-7.98492e-039-2.83455e+038-2.91106e+0385.85182e-042xmm2=1.77965e-043-1.17906e-010-4.44585e-038-7.98511e-039xmm3=-7.98511e-03900-7.98504e-039xmm4=-7.98503e-0391.20545e-040-1.47202e-037-1.47202e-037xmm5=-2.05476e+018-452.247-1.42468e-037-8.60834e+033xmm6=2.8026e-044-1.47202e-037-452.2470xmm7=8.40779e-045-7.98503e-0390-7.98511e-039cr0=8001003bcr2=d93db000cr3=00039000dr0=00000000dr1=00000000dr2=00000000dr3=00000000dr6=ffff0ff0dr7=00000400cr4=000006d9如果你不想使用命令作改變,你可以打開(kāi)內(nèi)存窗口(ViewMemory),變量窗口(ViewLocals)或者寄存器窗口(ViewRegisters),并且改寫你想要數(shù)值。例如,如上圖,你可以改寫16進(jìn)制的數(shù)值。運(yùn)行控制在前面的部分(詳見(jiàn)IoCreateDevice)你曾經(jīng)想程序從一點(diǎn)運(yùn)行到下一點(diǎn),而不需要告訴它怎么做。這里有一些方法可以控制運(yùn)行。下面所有的項(xiàng)目,除第一項(xiàng),都假設(shè)程序處于掛起狀態(tài)。中斷(CTRL-BREAK)—該快捷鍵總是中斷系統(tǒng),只要系統(tǒng)正在運(yùn)行并與WinDbg處于通信狀態(tài)(在KD快捷鍵是CTRL-C)。步過(guò)(F10)—每按一次運(yùn)行一條語(yǔ)句(如果C或者C++和WinDbg處于“sourcemode”,可通過(guò)DebugSourceMode切換),或者一條指,并且規(guī)定如果遇到一個(gè)函數(shù)調(diào)用,將會(huì)運(yùn)行過(guò)該函數(shù),而不會(huì)進(jìn)入它。步進(jìn)(F11)—就象步過(guò)那樣,除了運(yùn)行到一個(gè)函數(shù)調(diào)用時(shí),會(huì)進(jìn)入該調(diào)用例程。步出(SHIFT-F11)—這會(huì)使程序運(yùn)行直到完成當(dāng)前例程(在callstack中的當(dāng)前地址)。如果你對(duì)該例程已經(jīng)了解得足夠多,這個(gè)快捷鍵很有用。運(yùn)行到光標(biāo)(F7orCRTL-F10)—當(dāng)你想運(yùn)行到該處中斷,你可以將光標(biāo)放到源代碼窗口或者反匯編窗口中相應(yīng)的位置,按下F7;程序?qū)?huì)運(yùn)行到該位置。有一點(diǎn)要注意,然而:如果運(yùn)行流程與該處不匹配(例如,一個(gè)IF語(yǔ)句不運(yùn)行),WinDbg將不會(huì)中斷,因?yàn)椴](méi)有運(yùn)行到指定地方。運(yùn)行(F5)—運(yùn)行直到遇到斷點(diǎn)或者錯(cuò)誤事件被檢測(cè)到。你可以將“運(yùn)行”想象為正常執(zhí)行狀態(tài)。將指令設(shè)置在當(dāng)前行(CTRL-SHIFT-I)—在源代碼窗口,你可以把光標(biāo)放在一行中,使用該快捷鍵,只要你允許(例如F5或者F10),程序便從該處開(kāi)始運(yùn)行。在你想重復(fù)一些指令序列時(shí),這很有用。但是要注意一些事情。例如,寄存器和變量的數(shù)據(jù)不會(huì)象你正常運(yùn)行到該處時(shí)看到那樣。直接設(shè)置Eip—你可以為Eip寄存器設(shè)置一個(gè)數(shù)值,然后按下F5(或者F10或者其他的什么),運(yùn)行開(kāi)始于該地址。顯然易見(jiàn),該功能就象將指令設(shè)置在當(dāng)前行,除非你指定了一個(gè)匯編指令的地址。callstack幾乎運(yùn)行到某一點(diǎn),都會(huì)有一個(gè)區(qū)域作為堆棧使用;該堆棧用于存放本地狀態(tài),參數(shù)和返回地址。在內(nèi)核空間中有一個(gè)內(nèi)核棧,在用戶空間中有一個(gè)用戶棧。當(dāng)中斷發(fā)生時(shí),可能有幾個(gè)例程在當(dāng)前的棧中。例如,如果由于sioctl.sys中PrintIrpInfo的斷點(diǎn)引起指令停止執(zhí)行,使用k(“StackBacktrace”):kd>kChildEBPRetAddrf7428ba8f889b54aSIoctl!PrintIrpInfo+0x6[d:\winddk\3790.1824\src\general\ioctl\sys\sioctl.c@708]f7428c3c804e0e0dSIoctl!SioctlDeviceControl+0xfa[d:\winddk\3790.1824\src\general\ioctl\sys\sioctl.c@337]WARNING:Stackunwindinformationnotavailable.Followingframesmaybewrong.f7428c6080580e2ant!IofCallDriver+0x33f7428d00805876c2nt!CcFastCopyRead+0x3c3f7428d34804e7a8cnt!NtDeviceIoControlFile+0x28f7428d64
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 某著名企業(yè)五局天津項(xiàng)目鋁合金模板應(yīng)用案例分享
- 某著名企業(yè)競(jìng)爭(zhēng)戰(zhàn)略與管理提升咨詢項(xiàng)目建議書-正略鈞策1011
- 《GB-T 40037-2021電子商務(wù)產(chǎn)品信息描述 大宗商品》專題研究報(bào)告
- 《GB-T 22114-2021牙膏用保濕劑 甘油和聚乙二醇》專題研究報(bào)告
- 《GBT 17999.6-2008 SPF雞 微生物學(xué)監(jiān)測(cè) 第6部分:SPF雞 酶聯(lián)免疫吸附試驗(yàn)》專題研究報(bào)告
- 《FZT 64068-2019拒油防污機(jī)織粘合襯》專題研究報(bào)告深度
- 道路安全培訓(xùn)內(nèi)容記錄課件
- 道墟街道安全培訓(xùn)教育課件
- 2024胸骨捆扎固定系統(tǒng)注冊(cè)審查指導(dǎo)原則
- 返鄉(xiāng)下鄉(xiāng)創(chuàng)業(yè)培訓(xùn)課件
- 車位包銷合同協(xié)議模板
- 《FPC材料介紹》課件
- 員工轉(zhuǎn)崗協(xié)議書范本
- 四川省遂寧市射洪縣九年級(jí)2024-2025學(xué)年(上)期末化學(xué)試卷(含答案)
- 2025-2030中國(guó)器官芯片行業(yè)市場(chǎng)發(fā)展趨勢(shì)與前景展望戰(zhàn)略研究報(bào)告
- 醫(yī)院醫(yī)療保險(xiǎn)費(fèi)用審核制度
- 村衛(wèi)生室醫(yī)療質(zhì)量相關(guān)管理制度
- 非遺傳承人激勵(lì)機(jī)制探索-深度研究
- 中小學(xué)校園中匹克球推廣策略與實(shí)踐研究
- 2024年世界職業(yè)院校技能大賽高職組“體育活動(dòng)設(shè)計(jì)與實(shí)施組”賽項(xiàng)考試題庫(kù)(含答案)
- 高中地理選擇性必修一(湘教版)期末檢測(cè)卷02(原卷版)
評(píng)論
0/150
提交評(píng)論