av一区二区在线观看_亚洲男人的天堂网站_日韩亚洲视频_在线成人免费_欧美日韩精品免费观看视频_久草视

您的位置:首頁技術(shù)文章
文章詳情頁

Windows 2000對調(diào)試技術(shù)的支持

瀏覽:104日期:2023-08-27 15:27:01

盡管本書中的很多內(nèi)容都稱之為“ Undocumented ”,但其中的一些內(nèi)容只能通過挖掘操作系統(tǒng)的代碼才能獲取。 Windows 2000 DDK ( Device Driver Kit )提供了一個強大的調(diào)試器可以出色的完成這方面的工作。本章將從建立一個完善的調(diào)試環(huán)境開始介紹。在閱讀隨后的章節(jié)時,你會經(jīng)常的使用內(nèi)核調(diào)試器來挖掘操作系統(tǒng)內(nèi)部的各種特性。如果你對內(nèi)核調(diào)試器很是厭煩,或許你需要制作一個自己的調(diào)試工具了。因此,本章還將介紹有關(guān) Windows 2000 調(diào)試接口的文檔化和未文檔化的資料,包括微軟符號文件( Symbol File )的詳細信息。 It features two sample librarIEs with companion applications that list processes, process and system modules, and various kinds of symbol information buried inside the Windows 2000 symbol files 。做為一個特殊收獲,在本章結(jié)束時,你將得到首份有關(guān) PDB ( Microsoft Program Database )的公開文檔。

建立一個調(diào)試環(huán)境

“嗨,我不想調(diào)試 Windows 2000 程 序。在此之前,我想自己寫一個先!”當你讀到這個標題時你可能會這樣大喊出來。“很對!”我說“這就是你該去做的!”但是為什么你要以建立一個調(diào)試環(huán)境開 始這次旅行呢?答案很簡單:調(diào)試器是進入系統(tǒng)的后門。當然,這并不是調(diào)試器開發(fā)人員的主要目的。然而,當你跟蹤代碼的執(zhí)行過程或者你的程序意外的玩完時, 任何優(yōu)秀的調(diào)試器都須能夠告訴你一些有用的系統(tǒng)信息。僅僅報告一個指向 4GB 地址空間某處的 8 位 崩潰地址,然后讓你獨自一人去尋找到底發(fā)生了什么,真是無法讓人接受。調(diào)試器至少應該告訴你最后執(zhí)行的引發(fā)錯誤的代碼是哪個模塊中的代碼,而且,在理想情 況下,它還應該告訴你讓你的程序玩完的那個函數(shù)的名稱。因此,調(diào)試器通常必須知道比編程手冊還要多的系統(tǒng)信息,你可以利用這些信息來研究系統(tǒng)的內(nèi)部情況。

Windows 2000 提供了兩個調(diào)試器: WinDbg.exe (發(fā)音很像“ WindBag ”,譯注: WindBag 在俚語中指空話連篇的人)一個 Win32 GUI 程序和 i386kd.exe 一個提供與之等價功能的命令行模式程序。我曾經(jīng)同時使用過這兩個程序,最后確定 i386kd.exe 是最好的一個,因為它有一組非常強大的選項。不過,最近看來 WinDbg.exe 似乎有所改進。不過,本書中的所有例子都是與 i386kd.exe 相關(guān)的。就像你猜想的那樣, i386 前綴表示目標平臺( Intel 386 處理器家族,也包括 Pentium ) kd 是 Kernel Debugger (內(nèi)核調(diào)試器)的縮寫。 Windows 2000 內(nèi)核調(diào)試器是一個非常強大的工具。比如,他知道如何使用 Windows 2000 安裝光盤中的符號文件( Symbol files ),因此,可以給出系統(tǒng)內(nèi)存中幾乎任何地址的相關(guān)符號信息(這非常有價值)。而且,它還可以反編譯二進制代碼、將內(nèi)存信息的 16 進制轉(zhuǎn)儲數(shù)據(jù)以多種格式顯示,甚至還能顯示一些內(nèi)核關(guān)鍵結(jié)構(gòu)的布局。在調(diào)試器的在線幫助中有其命令行接口的詳細文檔。

準備一次崩潰轉(zhuǎn)儲( Crash Dump

這 些都是好消息。壞消息是你在內(nèi)核調(diào)試器順從你之前,必須做一些準備工作。第一個障礙是調(diào)試通常涉及兩臺獨立的計算機(通過線路連接在一起),其中一臺運行 調(diào)試器,另一臺用于被調(diào)試。然而,如果并不需要實時調(diào)試,那么有一個簡單的方法,可以不需要第二臺機器。例如,如果一個有錯誤的程序拋出了一個未處理的異 常而引發(fā)了聲名狼藉的 NT 藍屏死機( Blue Screen Of Death, BSOD ),你可以選擇保存崩潰前的內(nèi)存映像到一個文件中,在重新啟動后,檢查這個崩潰轉(zhuǎn)儲( Crash Dump )文件。這項技術(shù)通常被叫做 post mortem (事后檢查)在拉丁文中, post mortem 意思是“ after death ”。這種方式是本書首選方法之一。在這里,我們的主要任務(wù)是研究系統(tǒng)內(nèi)存,在大多數(shù)情況下,內(nèi)存數(shù)據(jù)是來自還在工作的系統(tǒng)或者來自系統(tǒng)崩潰前內(nèi)存的一個快照( snapshot )都并不重要。然而,一些有趣的信息則需要通過內(nèi)核模式的驅(qū)動程序深入正在工作的系統(tǒng)的內(nèi)部才能觀察到,這一主題被保留在后面的章節(jié)中。

一個崩潰轉(zhuǎn)儲( Crash Dump )只是簡單將當前內(nèi)存數(shù)據(jù)寫入一個磁盤文件而已。因此,一個完整的崩潰轉(zhuǎn)儲( crash dump )文件的大小通常與系統(tǒng)物理內(nèi)存一樣大(事實上,會略微小些)。崩潰轉(zhuǎn)儲( Crash dump )是由內(nèi)核中的一個特殊程序在處理致命錯誤過程中生成的。然而,這個例程( handler )并不是立即將內(nèi)存數(shù)據(jù)寫入目標文件中。這是個不錯的處理方式,因為在系統(tǒng)崩潰后,磁盤文件系統(tǒng)可能也不能正常工作。因此,內(nèi)存映像首先被復制到頁面文件存儲器( page file storage ),這是系統(tǒng)內(nèi)存管理器的一部分。因此,你應該將你的頁面文件大小增加到至少兩倍于物理內(nèi)存。兩倍?一樣大還不夠嗎?當然 — 那只夠存放崩潰轉(zhuǎn)儲( crash dump )。要知道,在啟動時,系統(tǒng)會嘗試將崩潰轉(zhuǎn)儲( crash dump ) 映像復制到實際的磁盤文件,這意味著,如果系統(tǒng)不能及時的釋放映像數(shù)據(jù)占用的頁面文件,它就可能用盡所有的虛擬內(nèi)存。通常,系統(tǒng)會處理這種情況,它會瘋狂 的讀寫磁盤并向你拋出一個惹人厭的“虛擬內(nèi)存不足”的警告。只要你預料藍屏的概率會增大時,將頁面文件設(shè)置的足夠大,這將會為你節(jié)省很多時間。

到這兒,你應該打開 Windows 2000 的控制面板,改變?nèi)缦碌脑O(shè)置:

l 增加頁面文件到至少兩倍物理內(nèi)存的大小。

l 接下來,配置系統(tǒng)以便當藍屏發(fā)生時生成一個 崩潰轉(zhuǎn)儲( crash dump )文件。在系統(tǒng)屬性對話框里,選擇高級頁,然后單擊啟動和恢復按鈕,檢查寫入調(diào)試信息選項。你應該在下拉列表中選擇完成內(nèi)存轉(zhuǎn)儲選項。在轉(zhuǎn)儲文件對話框中輸入一個文件名和路徑,轉(zhuǎn)儲文件將會從頁面文件中復制到你指定的這個文件中。 %SystemRoot%MEMORY.DMP 是默認設(shè)置。

讓系統(tǒng)崩潰

當設(shè)置好系統(tǒng)準備一次 crash dump 后,是時候做在 Windows 2000 系統(tǒng)程序員一生中最厭惡的事了:開始讓系統(tǒng)崩潰!通常,只要達摩克利斯的劍掛在了你的頭頂上(通常是在離產(chǎn)品截止時間還有幾個小時的時候)你就會看到恐怖的藍屏。現(xiàn)在,是你自愿讓系統(tǒng)崩潰,但你可能無法找到有問題的軟件來完成這項“工作”。來試試 David Solomon 在他的《 Inside Windows NT 第二版》中提到的那個優(yōu)雅的訣竅:

“如何能可靠的產(chǎn)生一個崩潰轉(zhuǎn)儲( crash dump )文件?只需要使用 Windows NT 資源工具中的 kill.exe 工具, kill 掉 Win32 子系統(tǒng)進程( csRSS.exe )或者 Windows NT 登陸進程( winlogon.exe ),你必須有管理員權(quán)限”( Solomon [1998],p.23. )

神奇,太神奇了!這個竅門不能在 Windows 2000 上工作!第一感覺,很不走運,但是從另一個角度看,這是個好消息。當你知道使用微軟自己正式發(fā)布的一個小工具就能如此輕松的破壞系統(tǒng),你會怎樣想?事實上,微軟關(guān)閉這個安全漏洞非常對。可是,我們現(xiàn)在需要一種方法來使系統(tǒng)崩潰啊。在這一點上,想想那個古老而簡單的 NT 規(guī)則:“ If anything seems to be impossible in the Win32 Word, just write a kernel-mode driver, and it will work out all right! ” Windows 2000 非常謹慎的管理 Win32 程序。它在應用程序和內(nèi)核之間構(gòu)建了一堵墻,任何企圖跨越此邊界者都會被毫不留情的解決掉。這對于系統(tǒng)的穩(wěn)定性是個好消息,但是對于編寫需要直接與硬件打交道的程序的人來說并不是個好消息。想想 Dos ,在那兒任何程序都可以直接觸及硬件,在這方面 Windows 2000 有些過分講究。但這并不意味著在 Windows 2000 中訪問硬件是不可能的。不同的是,這種訪問被限制到一個特殊類型的模塊 — 內(nèi)核模式的驅(qū)動程序( Kernel-mode driver )。

我可以告訴你,現(xiàn)在我將簡要的介紹一下 Kernel-mode driver 編程技術(shù)(這本是第三章的內(nèi)容)。眼下,這已經(jīng)足夠說明 kernel-mode driver 讓系統(tǒng)崩潰是非常容易的事。當驅(qū)動程序出錯時, Windows 2000 沒有提供一種錯誤恢復機制,這就導致即使無意中試圖執(zhí)行一個不合法的操作也會招來藍屏。當然,最簡單而且危險最小的違規(guī)動作就是讀取一個無效的內(nèi)存地址。由于系統(tǒng)顯示捕獲所有通過空指針進行的內(nèi)存訪問,這是 C 編程中一個常見的錯誤,讀取一個空指針是讓系統(tǒng)崩潰的理想動作。示例代碼中的 w2k_kill.sys driver 就是這么做的。這是一個非常簡單的程序,同時也是出現(xiàn)在本書中的第一個 kernel-mode driver 。

列表 1-1 是 w2k_kill.c 的引用部分,展示了引發(fā)藍屏的錯誤代碼。當編寫這樣無意義的代碼時,需要注意內(nèi)建于 Visual C/C++ 的優(yōu)化器可能會抵消你的努力,它會跟蹤所有的代碼并試圖消除其中任何有副作用的部分。在下面的例子中,優(yōu)化器并未起作用,因為 DriverEntry() 堅持將在 0 地址發(fā)現(xiàn)的東西作為其返回值。這意味著這個數(shù)值將會被存放到 CPU 的 EAX 寄存器中,最簡單的方法就是 MOV EAX, [0] 指令,這個指令將會拋出我們期待的異常。

NTSTATUS DriverEntry ( PDRIVER_OBJECT pDriverObject,

PUNICODE_STRING puRegistryPath )

{

return *((NTSTATUS*)0); // read through NULL pointer

}

列表 1-1 A NULL Pointer Read Operation in Kernel-Mode Crashes the System

w2k_load.exe 程序出現(xiàn)在第三章,用來用來載入并啟動 w2k_kill.sys 驅(qū)動程序。如果你在精神上做好了 kill 掉你的 Windows 2000 系統(tǒng),請按照下面的步驟來做:

l 關(guān)閉所有應用程序

l 插入本書的附帶光盤

l 在開始菜單中選擇運行

l 輸入 d:binw2k_load w2k_kill.sys ,用你 CD-ROM 的盤符替換 d: ,然后單擊確定

當單擊后, w2k_load.exe 將試圖加載 w2k_kill.sys 文件(位于光盤的 bin 目錄下)。隨后 DriverEntry() 開始執(zhí)行,藍屏出現(xiàn)了,如圖 1-3 所示,你會看到當內(nèi)存數(shù)據(jù)被轉(zhuǎn)儲到頁面文件存儲器時,屏幕上會有一個計數(shù)器從 0 逐漸增加到 100 。 如果你在啟動和恢復對話框中選中了自動重起,當崩潰轉(zhuǎn)儲完成后,系統(tǒng)會立即重新啟動。當系統(tǒng)進入等待登陸狀態(tài)后,稍等一會直到硬盤燈不再閃爍。這是因為將 崩潰轉(zhuǎn)儲數(shù)據(jù)從頁面文件復制到磁盤文件需要一定的時間,特別是你的物理內(nèi)存很大時。在此時干擾系統(tǒng),例如,將系統(tǒng)過早的關(guān)閉,可能會產(chǎn)生一個無效的崩潰轉(zhuǎn) 儲文件。

在圖 1-3 中,可以看出系統(tǒng)會顯示包含出錯代碼的模塊的名稱( w2k_kill.sys ),以及引發(fā)異常的指令地址( 0xBECC3000 )。這個地址或許和你的系統(tǒng)的不同,因為它是隨硬件配置而變化的。驅(qū)動程序的加載地址通常都不確定,和 DLL 的加載地址類似。請記下顯示的地址 ---- 稍后在安裝和配置內(nèi)核調(diào)試器是你還需要它。

一點小的提示:故意讓系統(tǒng)崩潰不該是你每天都作的事。盡管有問題的 w2k_kill.sys 本 身是無害的,但在它執(zhí)行的那一刻可能并不那么走運。如果度去空指針發(fā)生時另一個線程正在做某些重要的事情,系統(tǒng)可能會在該線程有機會做清理工作之前關(guān)閉。 比如,在重起之后,活動桌面往往會抱怨發(fā)生了一些可惡的事情,它需要進行恢復。因此,在你使系統(tǒng)崩潰之前,應該仔細的檢察系統(tǒng)是否影響了重要數(shù)據(jù)并且保證 所有 cache 中的數(shù)據(jù)都被寫入了磁盤。注意,作者和出版商不會對 w2k_kill.sys 驅(qū)動程序造成的破壞負責。

譯注: 達摩克利斯希臘傳說中的敘拉古國王狄奧尼西奧斯的朝臣,據(jù)傳說其被迫坐在上懸寶劍的餐桌旁,寶劍由一根頭發(fā)系住 , 以此來暗示君王命運的多危

安裝符號文件

重新啟動后,你就有了一個 Windows 2000 系統(tǒng)的快照( snapshot ),包括一個有問題的 Kernel-mode Driver (讀取空指針時被捕獲)。觀察此快照文件和察看實際系統(tǒng)內(nèi)存是一樣的。當然,這個快照文件和動物死尸一樣 --- 不再對外界刺激有所反應,但是你現(xiàn)在不需要擔心這些。接下來你需要安裝內(nèi)核調(diào)試器需要的符號文件( symbol files ),當你分析崩潰文件時,你就會用到了。

MSDN 用戶可以在 Windows 2000 Customer Suuport – Diagnostic Tools 光盤上找到這些符號文件。插入光盤,用 IE 打開光盤上的 DBG.HTM 文件,你會看到很多安裝選項。如果你運行的是 free build 的 Windows 2000 ,你最好安裝 retail symbols 。對于 checked build 版,可以選擇安裝 debug symbols 。安裝程序會從 SYMBOLS.CAB 中復制一些 .dbg 和 .pdb 文件到系統(tǒng)符號文件目錄中。默認的系統(tǒng)符號文件目錄為: %SystemRoot%Symbols 。 %SystemRoot% 環(huán)境變量代表 Windows 2000 的安裝目錄。

在起動時, Windows 2000 內(nèi)核調(diào)試器會嘗試通過環(huán)境變量 _NT_SYMBOL_PATH 指示的路徑來尋找符號文件,所以最好正確的定義該變量。

譯注:

現(xiàn)在可以通過 Symchk.exe 工具來檢查和下載最新的符號文件,該工具隨 Debugging Tools for Windows 軟件包安裝。

微軟的文檔中對于 _NT_SYMBOL_PATH 應該指向哪里的說明有些模糊不清。在 DDK 的內(nèi)核調(diào)試一節(jié)里提到必須包含符號子目錄,即 C:WINNTSymbols 或等價目錄。而在 SDK 關(guān)于 dbghelp.dll 庫的文檔中,有關(guān)符號路徑的描述又稍微有些區(qū)別:

“該庫需要使用符號搜索路徑來定位 .dll 、 .exe 或 .sys 對應的調(diào)試符號( .dbg 文件)。它會在路徑后添加 dll 、 exe 或 sys 。例如, .dll 符號文件位于: C:WINNTSymbolsdll , .exe 文件的路徑則為: C:WINNTSymbolsexe ”

。。。。。。

“如果你設(shè)置了 _NT_SYMBOL_PATH 環(huán)境變量,符號管理器按照如下順序搜索符號文件:

1. 應用程序的當前工作目錄

2. _NT_SYMBOL_PATH 指示的目錄

3. _NT_ALT_SYMBOL_PATH 指示的目錄

4. SYSTMEROOT 指示的目錄

這樣看來把 _NT_SYMBOL_PATH 設(shè)定為 C:WINNT 似乎要好于 C:WINNTSymbols ,為了確定哪種說法是正確的。我試驗了這兩種方法,很高興它們都能正常的工作。

配置內(nèi)核調(diào)試器

構(gòu)建調(diào)試環(huán)境的最后一步就是安裝和配置內(nèi)核調(diào)試器。如果你已經(jīng)安裝了 Windows 2000 DDK ,那你可以在 NTDDKbin 目錄中找到調(diào)試器。內(nèi)核調(diào)試器的可執(zhí)行文件名為 i386kd.exe 。另一種方法是從 Windows 2000 Customer Support---Diagnostic Tools 光盤中安裝。

為了使用前面我們得到的崩潰轉(zhuǎn)儲文件,你需要使用 i368kd 的 –Z 選項。示例如下:

i386kd –z C:WINNTMEMORY.DMF

成功打開我們的 crash dump 后,你會看到類似圖 1-7 所示的東東, kd> 提示符會出現(xiàn),這表示內(nèi)核調(diào)試器已經(jīng)準備接受命令了。在開始之前,請檢查符號搜索路徑是否正確。列出的啟動信息,表示調(diào)試器已經(jīng)加載了三個擴展 DLL 。 i386kd.exe 一個強大的特性就是其擴展機制,這允許第三方采用獨立的 DLL 來擴展其基本功能。對于這些擴展的命令,要在其前面加上!號以區(qū)分內(nèi)建的命令。

如圖 1-7 所示,我輸入了一個內(nèi)建命令: u becc3000 , u 的含義是“反編譯( unassembel )”, becc3000 是開始反編譯的 16 進制地址。默認情況下,均采用 16 進制,但你也可也通過命令來改變此默認值。命令為: n 10 ,此后默認所有數(shù)字都是 10 進制表示。你可以使用 0x 前綴來表示這是一個 16 進制數(shù)。地址 becc3000 就是 w2k_kill.sys 引起系統(tǒng)崩潰的地方。請使用你在藍屏時看到的地址。如果一切正確的話,你會看到 mov eax, [00000000] 指令,如上圖所示。如果沒有看到的話,你可能沒有使用正確的崩潰轉(zhuǎn)儲文件。 mov eax, [00000000] 指令表示從虛擬地址(也可稱作線性地址) 0x00000000 讀取一個 32 位的數(shù)值到 CPU 寄存器 EAX 中,這明顯是列表 1-1 中 *(NTSTATUS*)0) 表達式的實現(xiàn),等同于讀取空指針的操作。沒有針對此類錯誤的異常處理例程,因此,系統(tǒng)在藍屏上會顯示 KMODE_EXCEPTION_NOT_HANDLED ,如圖 1-3 所示。如果你想知道有關(guān)此錯誤信息更多的東西請參考《 The NT Insider 》( Open Systems Resources 1999b )。

主站蜘蛛池模板: 国产一区二区视频在线 | 亚洲欧美激情精品一区二区 | 成人精品久久日伦片大全免费 | 草久久久 | 中文字幕亚洲欧美日韩在线不卡 | 欧美性猛交一区二区三区精品 | 天天艹天天干天天 | 久久亚洲欧美日韩精品专区 | av天天看| 91人人视频在线观看 | 精品国偷自产在线 | 亚洲精品av在线 | 久久久久国产精品午夜一区 | 久久精品亚洲精品国产欧美kt∨ | 亚洲成人精选 | 91精品国产91久久久久久不卞 | 一二区成人影院电影网 | 国产精品揄拍一区二区久久国内亚洲精 | 日本一区二区三区四区 | 国产成人在线观看免费 | 欧美大片一区 | 国产成人在线一区二区 | 亚洲狠狠 | 日韩中文字幕av | 日本一区二区三区精品视频 | 免费国产视频在线观看 | av小说在线 | 中文字幕av第一页 | 精品国产乱码久久久久久中文 | 男人天堂久久 | 狠狠的干| 成人在线精品视频 | 精品国产免费人成在线观看 | 黄色网一级片 | 一级片在线视频 | 日本久久精品视频 | 亚洲伊人a| 欧美激情综合五月色丁香小说 | 亚洲 中文 欧美 日韩 在线观看 | 日韩在线观看视频一区 | 黄视频免费观看 |