第四章 探索 Windows 2000 的內(nèi)存管理機制
翻譯: Kendiv( fcczj@263.net)
更新: Tuesday, February 22, 2005
聲明:轉(zhuǎn)載請注明出處,并保證文章的完整性,本人保留譯文的所有權(quán)利 。
請求式分頁動作
在討論 Spy 設(shè)備的 SPY_IO_MEMORY_DATA 函數(shù)時,我提到過該函數(shù)可以讀取已被置換到頁面文件中的內(nèi)存頁 。要證明這一點,首先,必須讓系統(tǒng)處于低內(nèi)存狀態(tài),以強迫它將不馬上使用的數(shù)據(jù)置換到頁面文件中 。我喜歡采用的方法如下:
1. 使用 PrintKey,將 Windows 2000 的桌面復(fù)制到剪切板中 。
2. 將該圖片粘貼到一個圖形處理程序中 。
3. 將該圖片的尺寸放到最大 。
現(xiàn)在,執(zhí)行命令: w2k_memd #16 0xC02800000 0xA0000000 0xA0001000 0xA0002000 0xC0280000,察看它在屏幕上的輸出 。你可能會驚訝 。在觸及某些 PTE 所引用的頁之前,它會獲取這些 PTE 的快照 。在地址 0xC0280000 處發(fā)現(xiàn)的四個 PTE 與地址范圍: 0xA0000000---0xA0003FFF 相關(guān),這是內(nèi)核模塊 win32k.sys 的一部分 。如 示列 4-11 所示,該地址范圍已經(jīng)被置換出去了,因為在地址 0xC0280000 的四個 DWord 都是偶數(shù),這意味著它們的最低位(即 PTE 的 P 位)為零,這表示沒有存在于物理內(nèi)存中的頁 。接下來的三塊 16 進制 Dump 信息屬于 0xA0000000 、 0xA0001000 、 0xA0002000,w2k_mem 可以毫無問題的訪問這些頁(系統(tǒng)會根據(jù)請求將它們再次換入內(nèi)存) 。
示列 4-11 觀察 PTE 的狀態(tài)變化
在開始下一節(jié)之前,請再次研究一下 示列 4-11 中的第一欄 。位于地址 0xC0280000 的四個 PTE 看上去都很像 。但事實上,它們僅有最低的三個位不同 。如果你檢查所有位于頁面文件中的 PNPE,你會發(fā)現(xiàn)它們的第 10 位都為 1。這就是為什么我在 列表 4-3 中,將該位的名字取為 PageFile。如果該位為 1,除 P 位外的所有位都將用來表示該頁在頁面文件中的位置 。
更多的命令選項
示列 4-1 給出的某些命令選項還沒有解釋過 。例如,系統(tǒng)狀態(tài)選項:o 、c 、g 、i 和b,我會在本章的最后一節(jié)介紹它們,在那兒我們將發(fā)現(xiàn)幾個 Windows 2000 內(nèi)存系統(tǒng)的秘密 。
Spy 設(shè)備的接口
現(xiàn)在你已經(jīng)知道如何使用 w2k_mem 了,該是介紹它是如何工作的了 。現(xiàn)在來看看這個程序是如何與 w2k_spy.sys 中的 Spy 設(shè)備通訊的 。
【8 《Undocumented Windows 2000 Secrets》翻譯 --- 第四章】回顧 ----- 設(shè)備 I/O 控制( Device I/O Control )
IOCTL 通訊的內(nèi)核模式端已經(jīng)由 列表 4-6 和 列表 4-7 給出了 。Spy 設(shè)備只是簡單的等待 IRP 并處理其中的某些 IRP,尤其是標(biāo)識為 IPR_MJ_DEVICE_CONTROL,其中的一些請求在用戶模式下是被禁止的 。調(diào)用 Win32 API 函數(shù) DeviceIoControl(),列表 4-27 給出了該函數(shù)的原型 ??赡苣阋呀?jīng)熟悉了 dwIocontrolCode 、 lpInBuffer 、 nInBufferSize 、 lpOutBuffer 、 nOutBufferSize 和 lpBytesReturned 參數(shù) 。事實上,它們一一對應(yīng)于: SpyDispatcher() 的 dCode 、 pInput 、 dInput 、 pOutput 、 dOutput 和 pdInfo 參數(shù),SpyDispatcher 定義于 列表 4-7。剩下的參數(shù)很快就會解釋 。hDevice 是 Spy 設(shè)備的句柄,lpOverlapped (可選的)指向一個 OVERLAPPED 結(jié)構(gòu),異步 IOCTL 需要該結(jié)構(gòu) 。我們不需要發(fā)送異步請求,所以該參數(shù)總是 NULL。
列表 4-28 列出了所有執(zhí)行基本 IOCTL 操作的外包函數(shù) 。最基本的一個是: IoControl(),該函數(shù)調(diào)用 DeviceControl() 并測試返回的輸出數(shù)據(jù)的大小 。因為 w2k_mem.exe 精確的提供了輸出緩沖區(qū)的大小,所以,輸出的字節(jié)數(shù)應(yīng)該總是等于緩沖區(qū)的大小 。ReadBinary() 是 IoControl() 的簡單版本,它不需要輸入數(shù)據(jù) 。ReadCPUInfo() 、 ReadSegment() 和 ReadPhysical() 專用于 Spy 函數(shù) SPY_IO_CPU_INFO 、 SPY_IO_SEGEMNT 和 SPY_IO_PHYSICAL,因為它們會經(jīng)常被用到 。將它們封裝為 C 函數(shù),可讀性會更好些 。
推薦閱讀
- 佐助見到穢土鼬是哪集
- Windows 2000 上配置和應(yīng)用安全模板
- 如何在 Windows 2000 中啟用自動登錄
- 2 《Undocumented Windows 2000 Secrets》翻譯 --- 第四章
- 1 《Undocumented Windows 2000 Secrets》翻譯 --- 第四章
- Windows 2000下的Raw Socket編程
- Windows 2000開發(fā)過程中一些有趣的數(shù)據(jù)
- Windows2000軟件沖突一例
- 大叔與少年什么時候開始播
- 盛世嫡妃好看嗎
