日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

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

《Undocumented Windows 2000 Secrets》翻譯 --- 第四章(8)

瀏覽:192日期:2023-08-27 13:59:20

第四章 探索 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_mem +d #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è)備通訊的。

回顧 ----- 設(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ù),可讀性會更好些。

BOOL WINAPI DeviceIoControl( HANDLE hDevice,

DWORD dwIoControlCode,

PVOID lpInBuffer,

DWORD nInBufferSize,

PVOID lpOutBuffer,

DWORD nOutBufferSize,

PDWORD lpBytesReturned,

POVERLAPPED lpOverlapped);

列表 4-27. DeviceIoControl 函數(shù)的原型

BOOL WINAPI IoControl (HANDLE hDevice,

DWORD dCode,

PVOID pInput,

DWORD dInput,

PVOID pOutput,

DWORD dOutput)

{

DWORD dData = 0;

return DeviceIoControl (hDevice, dCode,

pInput, dInput,

pOutput, dOutput,

&dData, NULL)

&&

(dData == dOutput);

}

// -----------------------------------------------------------------

BOOL WINAPI ReadBinary (HANDLE hDevice,

DWORD dCode,

PVOID pOutput,

DWORD dOutput)

{

return IoControl (hDevice, dCode, NULL, 0, pOutput, dOutput);

}

// -----------------------------------------------------------------

BOOL WINAPI ReadCpuInfo (HANDLE hDevice,

PSPY_CPU_INFO psci)

{

return IoControl (hDevice, SPY_IO_CPU_INFO,

NULL, 0,

psci, SPY_CPU_INFO_);

}

// -----------------------------------------------------------------

BOOL WINAPI ReadSegment (HANDLE hDevice,

DWORD dSelector,

PSPY_SEGMENT pss)

{

return IoControl (hDevice, SPY_IO_SEGMENT,

&dSelector, DWORD_,

pss, SPY_SEGMENT_);

}

// -----------------------------------------------------------------

BOOL WINAPI ReadPhysical (HANDLE hDevice,

PVOID pLinear,

PPHYSICAL_ADDRESS ppa)

{

return IoControl (hDevice, SPY_IO_PHYSICAL,

&pLinear, PVOID_,

ppa, PHYSICAL_ADDRESS_)

&&

(ppa->LowPart || ppa->HighPart);

}

列表 4-28 幾個 IOCTL 的外包函數(shù)

到目前為止,本節(jié)列出的所有函數(shù)都需要 Spy 設(shè)備的一個句柄。現(xiàn)在,我將介紹如何獲取該句柄。這實際上是一個非常簡單的 Win32 操作,和打開文件類似。 列表 4-29 展示了 w2k_mem.exe 的命令處理例程的實現(xiàn)細(xì)節(jié)。該代碼使用 API 函數(shù) w2kFilePath() 、 w2kServiceLoad() 和 w2kServiceUnload() ,這幾個函數(shù)由 w2k_lib.dll 導(dǎo)出。如果你已經(jīng)讀過第三章中關(guān)于 Windows 2000 服務(wù)控制管理器的介紹,你應(yīng)該通過 列表 3-8 已了解了 w2kServiceLoad() 和 w2kServiceUnload() 。這些強大的函數(shù)可隨時加載或卸載內(nèi)核模式的設(shè)備驅(qū)動,并且能處理一些良性的錯誤,如,妥善的處理加載一個已經(jīng)載入內(nèi)存的驅(qū)動程序。 w2kFilePath() 是一個幫助函數(shù)。 w2k_mem.exe 調(diào)用它來獲取 Spy 驅(qū)動程序的完整路徑。

WORD awSpyFile [] = SW(DRV_FILENAME);

WORD awSpyDevice [] = SW(DRV_MODULE);

WORD awSpyDisplay [] = SW(DRV_NAME);

WORD awSpyPath [] = SW(DRV_PATH);

// -----------------------------------------------------------------

void WINAPI Execute (PPWORD ppwArguments,

DWORD dArguments)

{

SPY_VERSION_INFO svi;

DWORD dOptions, dRequest, dReceive;

WORD awPath [MAX_PATH] = L'?';

SC_HANDLE hControl = NULL;

HANDLE hDevice = INVALID_HANDLE_VALUE;

_printf (L'rnLoading '%s' (%s) ...rn',

awSpyDisplay, awSpyDevice);

if (w2kFilePath (NULL, awSpyFile, awPath, MAX_PATH))

{

_printf (L'Driver: '%s'rn',

awPath);

hControl = w2kServiceLoad (awSpyDevice, awSpyDisplay,

awPath, TRUE);

}

if (hControl != NULL)

{

_printf (L'Opening '%s' ...rn',

awSpyPath);

hDevice = CreateFile (awSpyPath, GENERIC_READ,

FILE_SHARE_READ | FILE_SHARE_WRITE,

NULL, OPEN_EXISTING,

FILE_ATTRIBUTE_NORMAL, NULL);

}

else

{

_printf (L'Unable to load the spy device driver.rn');

}

if (hDevice != INVALID_HANDLE_VALUE)

{

if (ReadBinary (hDevice, SPY_IO_VERSION_INFO,

&svi, SPY_VERSION_INFO_))

{

_printf (L'rn%s V%lu.%02lu readyrn',

svi.awName,

svi.dVersion / 100, svi.dVersion % 100);

}

dOptions = COMMAND_OPTION_NONE;

dRequest = CommandParse (hDevice, ppwArguments, dArguments,

TRUE, &dOptions);

dOptions = COMMAND_OPTION_NONE;

dReceive = CommandParse (hDevice, ppwArguments, dArguments,

FALSE, &dOptions);

if (dRequest)

{

_printf (awSummary,

dRequest, (dRequest == 1 ? awByte : awBytes),

dReceive, (dReceive == 1 ? awByte : awBytes));

}

_printf (L'rnClosing the spy device ...rn');

CloseHandle (hDevice);

}

else

{

_printf (L'Unable to open the spy device.rn');

}

if ((hControl != NULL) && gfSpyUnload)

{

_printf (L'Unloading the spy device ...rn');

w2kServiceUnload (awSpyDevice, hControl);

}

return;

}

列表 4-29. 控制 Spy 設(shè)備

請注意 列表 4-29 頂部給出的四個全局字符串的定義。常量 DRV_FILENAME 、 DRV_MODULE 、 DRV_NAME 和 DRV_PATH 來自 Spy 驅(qū)動的頭文件 w2k_spy.h 。 4-4 列出了它們的當(dāng)前值。你不會在 w2k_mem.exe 的源代碼中發(fā)現(xiàn)設(shè)備相關(guān)的定義, w2k_spy.h 提供了客戶端程序所需的一切。這非常重要:如果以后改變了任何設(shè)備相關(guān)的定義,就不需要更新任何程序文件了。只需要以新的頭文件編譯、鏈接程序即可。

列表 4-29 頂部調(diào)用的 w2kFilePath() 可以保證由全局變量 awSpyFile (見 4-4 )指定的 w2k_spy.sys 總是從 w2k_mem.exe 所在目錄中加載。接下來, 列表 4-29 中的代碼將全局字符串 awSpyDevice 和 awSpyDisplay ()傳遞給 w2kServiceLoad() ,以加載 Spy 設(shè)備的驅(qū)動。如果驅(qū)動沒有被加載,這些字符串將被保存在驅(qū)動的屬性列表中,可以由其他程序取出;否則,將保留當(dāng)前的屬性設(shè)置。盡管 列表 4-29 中的 w2kServiceLoad() 調(diào)用可返回一個句柄,但這并不是一個可用于任何 IOCTL 函數(shù)的句柄。要獲取 Spy 設(shè)備的句柄,必須使用 Win32 的多用途函數(shù) CreateFile() 。該函數(shù)可打開或創(chuàng)建 Windows 2000 中幾乎所有可被打開和創(chuàng)建的東西。如果提供了內(nèi)核設(shè)備的符號鏈接名,形如 .<SymbolicLink > 給 CreateFile() 的 lpFileName 參數(shù),那么該函數(shù)就可打開這個內(nèi)核設(shè)備。 Spy 設(shè)備的符號鏈接名是: w2k_spy ,因此, CreateFile() 的第一個參數(shù)必須是 .w2k_spy ,這正是 4-4 中的 awSpyPath 的值。

表 4-4. 設(shè)備相關(guān)的字符串定義

w2k_spy 常量

w2k_mem 變量

DRV_FILENAME

awSpyFile

w2k_spy.sys

DRV_MODULE

awSpyDevice

w2k_spy

DRV_NAME

awSpyDisplay

SBS Windows 2000 Spy Device

DRV_PATH

awSpyPath

. w2k_spy

如果 CreateFile() 成功,它將返回一個設(shè)備的句柄,該句柄可傳遞給 DeviceIoControl() 。 列表 4-29 中的 Execute() 函數(shù)使用該句柄來查詢 Spy 設(shè)備的版本信息,如果 IOCTL 調(diào)用成功,該信息將會在屏幕上顯示出來。接下來, CommandParser() 函數(shù)將被調(diào)用兩次,第一次調(diào)用只是簡單的檢查命令行中是否有無效的參數(shù),并顯示任何可能的錯誤。第二次調(diào)用則執(zhí)行所有的命令。我不想討論該函數(shù)的細(xì)節(jié)。 列表 4-29 中的剩余代碼是為了進行清理工作,如關(guān)閉句柄和卸載 Spy 驅(qū)動(該功能是可選的)。 w2k_mem.exe 的源代碼中還有一些有趣的代碼片斷,但我不在這里討論它們了。請參考本書光盤的 srcw2k_mem 目錄下的 w2k_mem.c 和 w2k_mem.h 。

現(xiàn)在唯一需要注意的就是 gfSpyUnload 標(biāo)志,該標(biāo)志決定是否卸載 Spy 驅(qū)動。我已經(jīng)將這個全局標(biāo)志設(shè)為了 FALSE ,因此不會自動卸載該驅(qū)動。這提高 w2k_mem.exe 或 w2k_spy.sys 的任何客戶端的性能,因為加載一個驅(qū)動需要花費一定的時間。只有第一個客戶端會產(chǎn)生加載開銷。這種設(shè)置還可避免多個客戶端間的競爭,如,一個客戶試圖卸載該驅(qū)動而此時另一個還在使用這個驅(qū)動。當(dāng)然, Windows 2000 不會卸載一個驅(qū)動,除非該驅(qū)動的所有句柄都被關(guān)閉了,但系統(tǒng)會將驅(qū)動置于 STOP_PENDING 狀態(tài),這樣新的客戶端將無法訪問此設(shè)備。不過,如果你不在一個多客戶端的環(huán)境下運行 w2k_spy.sys ,而且你需要經(jīng)常更新設(shè)備的驅(qū)動程序,你就應(yīng)該將 gfSpyUnload 標(biāo)志設(shè)為 TRUE 。

深入 Windows 2000 內(nèi)存

引入用戶模式和內(nèi)核模式的獨立 4GB 地址空間被再次劃分為多個更小的塊。正如你可能猜到的,它們中的大多數(shù)都包含未文檔化的結(jié)構(gòu),而且服務(wù)于未文檔化的地目的。其中某些東西對于任何開發(fā)系統(tǒng)診斷或調(diào)試軟件的人來說都是真正的金礦。

基本的操作系統(tǒng)信息

如果你注意過 示列 4-1 下半部分的幫助信息,你會發(fā)該節(jié)的標(biāo)題是:“系統(tǒng)狀態(tài)選項”。現(xiàn)在試試名為“顯示操作系統(tǒng)信息”的選項: +o 。 示列 4-12 給出了在我的機器上使用該選項的輸出結(jié)果。這里顯示的信息都是 SPY_OS_INFO 結(jié)構(gòu)的內(nèi)容,該結(jié)構(gòu)定義與 列表 4-13 ,由 Spy 設(shè)備函數(shù) SpyOutputOsInfo() 實際創(chuàng)建該結(jié)構(gòu),此函數(shù)也包含在 列表 4-13 中。在 示列 4-12 中,你可以看到位于 4GB 地址空間中的進程的一些典型地址。例如,有效的用戶地址范圍是: 0x00010000 ---- 0x7FFFFFFF 。你可能閱讀過其他有關(guān) Windows NT 或 2000 的程序設(shè)計書籍,用戶模式的第一個和最后一個 64KB 線性內(nèi)存區(qū)域是“不能訪問區(qū)域”,訪問這一區(qū)域?qū)⒁l(fā)一個錯誤(參見第五章, Solomon 1998 ), W2k_mem.exe 輸出證明了這一點。

示列 4-12. 顯示操作系統(tǒng)信息

示列 4-12 中的最后三行包含的信息非常有趣,它們都是有關(guān)系統(tǒng)的。這些信息大部分都取自位于地址 0xFFDF0000 處的 SharedUserData 區(qū)域中。系統(tǒng)在該處維護一個名為 KUSER_SHARED_DATA 的結(jié)構(gòu),該結(jié)構(gòu)定義于 DDK 頭文件 ntddk.h 。

標(biāo)簽: Windows系統(tǒng)
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
另类激情亚洲| 日韩成人亚洲| 玖玖精品视频| 日韩在线卡一卡二| 免费久久99精品国产自在现线| 亚洲天堂成人| 五月天久久网站| 午夜久久福利| 亚洲一区日韩在线| 男人的天堂久久精品| 亚洲日产av中文字幕| 日本少妇精品亚洲第一区| 天堂精品久久久久| 国产欧美日韩精品一区二区免费| 综合激情网...| 国产乱码精品一区二区亚洲| 久久精品国产福利| 青青青免费在线视频| 久久久久久美女精品| 激情91久久| 日韩影院免费视频| 欧美一区91| 欧美www视频在线观看| 久久久精品午夜少妇| 日韩视频不卡| 日韩精品国产精品| 麻豆91精品91久久久的内涵| 日韩中文字幕高清在线观看| 99riav1国产精品视频| 蜜臀va亚洲va欧美va天堂| 日韩二区三区在线观看| 美女视频黄免费的久久| 麻豆精品蜜桃| 一区二区国产在线观看| 国产乱人伦丫前精品视频| 日韩中文在线电影| 日韩精品一二三四| 国产精品第一国产精品| 欧美日韩免费观看视频| 免费日韩av| 国产精品一区高清| 日韩av首页| 亚洲精品欧美| 国产精品成人一区二区不卡| 91精品一区国产高清在线gif| 在线国产精品一区| 精品久久久中文字幕| 欧美日韩四区| 国产精品亚洲产品| 欧美不卡高清一区二区三区| 亚洲欧美网站在线观看| 国产一区精品福利| 水蜜桃久久夜色精品一区的特点 | 久久久9色精品国产一区二区三区| 亚洲欧美日韩精品一区二区| 国产麻豆精品久久| 偷拍欧美精品| 国产欧美一区二区三区米奇| 亚洲91久久| 日本天堂一区| 日韩欧美少妇| 欧美亚洲福利| 亚洲精品中文字幕乱码| 久久精品一区| 三级一区在线视频先锋| 精品日韩一区| 蜜桃av一区二区在线观看| 欧美国产偷国产精品三区| 日韩精品一二三区| 一本大道色婷婷在线| 日本视频在线一区| 尹人成人综合网| 国产福利一区二区三区在线播放| 偷拍欧美精品| 精品国产欧美日韩| 亚洲天堂免费| 91精品国产91久久久久久黑人| 日本视频在线一区| 亚洲一级在线| 欧美日韩水蜜桃| 久久亚洲资源中文字| 亚洲精品女人| 尹人成人综合网| 中国字幕a在线看韩国电影| 日韩精品高清不卡| 亚洲中午字幕| 久久中文亚洲字幕| 免费在线日韩av| 日韩一区二区三区高清在线观看 | 精品一区毛片| 91视频久久| 美女视频黄久久| 日韩精品第一| 午夜在线精品| 久久精品成人| а√天堂8资源中文在线| 国产精品毛片视频| 中文字幕日本一区二区| 欧美女激情福利| 92国产精品| 国产精品mm| 欧美在线看片| 日韩精品久久久久久久软件91| 在线一区视频| 欧美午夜精品一区二区三区电影| 国产一区二区三区免费在线 | 国产一区二区三区探花| 国产精品第一| 国产精品色在线网站| 日韩av午夜在线观看| 亚欧成人精品| 亚洲人成在线影院| 中文字幕av一区二区三区四区| 图片区亚洲欧美小说区| 久久网站免费观看| 亚洲成人二区| 91久久国产| 好吊一区二区三区| 黄色亚洲大片免费在线观看| 亚洲精品一二三区区别| 欧美日韩国产一区二区三区不卡| 久久久久国产精品一区二区| 精精国产xxxx视频在线播放| 欧美13videosex性极品| 在线看片国产福利你懂的| 高清av一区| 国产精品99在线观看| 98精品久久久久久久| 麻豆精品蜜桃视频网站| 久久av资源| 国产在线观看91一区二区三区| 国产69精品久久| 日韩三区免费| 黄色成人在线网址| 亚洲图片久久| 欧美中文高清| 麻豆国产91在线播放| 精品国产aⅴ| 亚洲1234区| 欧美特黄一区| 日本不卡视频在线观看| 国产亚洲精品美女久久久久久久久久| 国产精品网在线观看| 九九久久国产| 亚洲成a人片| 香蕉久久国产| 日韩av一区二区三区四区| 欧美国产亚洲精品| 伊人久久视频| 在线视频亚洲| 国产情侣久久| 日韩精品不卡一区二区| 亚洲男女av一区二区| 日本中文字幕不卡| 精品三级在线观看视频| 欧美日韩中文字幕一区二区三区| 在线亚洲激情| 国产精品亚洲综合久久| 欧洲一区二区三区精品| 亚洲午夜电影| 亚洲色图国产| 欧美国产专区| 99视频精品全部免费在线视频| 久久av一区| 国产精品久久久一区二区| 成人精品视频| 国产精品毛片| 欧美国产中文高清| 欧美福利在线| 欧美一区久久| 久久婷婷一区| 亚洲精品免费观看| 91综合视频| 蜜臀va亚洲va欧美va天堂| 国产精品亚洲综合色区韩国| 99久久久久国产精品| 日本天堂一区| 99精品小视频| 国产精品一区免费在线| 欧美日韩色图| 日本成人手机在线| 日韩一区电影| 日韩av一区二区在线影视| 成人av三级| 日韩激情一二三区| 久久久久久久久99精品大| 91免费精品国偷自产在线在线| 中文字幕在线高清| 中文字幕乱码亚洲无线精品一区| 久久永久免费| 蜜桃av一区二区在线观看| 国产在线观看91一区二区三区| 久久福利一区| 给我免费播放日韩视频| 色狠狠一区二区三区| 国产成人精品三级高清久久91| 亚洲精品中文字幕99999| 日韩高清欧美| 国产精品三级| 亚洲天堂日韩在线|