日本免费全黄少妇一区二区三区-高清无码一区二区三区四区-欧美中文字幕日韩在线观看-国产福利诱惑在线网站-国产中文字幕一区在线-亚洲欧美精品日韩一区-久久国产精品国产精品国产-国产精久久久久久一区二区三区-欧美亚洲国产精品久久久久

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


{
X86_PE pe;
DWord dSize;
BOOL fPresent;
}
SPY_PAGE_ENTRY, *PSPY_PAGE_ENTRY, **PPSPY_PAGE_ENTRY;
#define SPY_PAGE_ENTRY_ sizeof (SPY_PAGE_ENTRY)
// -----------------------------------------------------------------
BOOL SpyMemoryPageEntry (PVOID pVirtual,
PSPY_PAGE_ENTRY pspe)
{
SPY_PAGE_ENTRY spe;
BOOL fOk = FALSE;
spe.pe = X86_PDE_ARRAY [X86_PDI (pVirtual)];
spe.dSize = X86_PAGE_4M;
spe.fPresent = FALSE;
if (spe.pe.pde4M.P)
{
if (spe.pe.pde4M.PS)
{
fOk = spe.fPresent = TRUE;
}
else
{
spe.pe = X86_PTE_ARRAY [X86_PAGE (pVirtual)];
spe.dSize = X86_PAGE_4K;
if (spe.pe.pte4K.P)
{
fOk = spe.fPresent = TRUE;
}
else
{
fOk = (spe.pe.pnpe.PageFile != 0);
}
}
}
if (pspe != NULL) *pspe = spe;
return fOk;
}
列表 4-22. 查詢 PDE 和 PTE
需要注意的是,SpyMemoryPageEntry() 不能識別被置換出物理內(nèi)存的 4MB 頁 。如果 PDE 指向的 4MB 頁并不存在,將無法判斷給定的線性地址是否有效的,以及該頁是否還保存在當前頁面文件中 。4MB 頁僅用于內(nèi)核內(nèi)存范圍: 0x80000000----0x9FFFFFFF。不過我從來沒見過這樣的一個頁被置換出去,即使物理內(nèi)存極端少的時候也沒有過,因此我不需要檢查任何與此相關(guān)的 page-not-present entrIEs。
IOCTL 函數(shù) SPY_IO_MEMORY_DATA
SPY_IO_MEMORY_DATA 函數(shù)是重量級函數(shù)中的一個,因為它可以復制任意數(shù)量的內(nèi)存數(shù)據(jù)到調(diào)用者提供的緩沖區(qū)中 。正如你可能還記得的那樣,用戶模式下的應用程序很容易傳入一個無效的地址 。因此,該函數(shù)在觸及源地址之前,會非常謹慎的檢驗這些地址的有效性 。記住,藍屏可以潛伏在內(nèi)核模式的任何地方 。
調(diào)用程序通過傳入一個 SPY_MEMORY_BLOCK 結(jié)構(gòu)來請求一個內(nèi)存塊中的數(shù)據(jù),在 列表 4-23 的頂部給出了該結(jié)構(gòu)體的定義,該結(jié)構(gòu)體會指定內(nèi)存塊的地址和大小 。為了方便,此處的地址被定義為一個 union,以允許將其解釋為一個字節(jié)類型的數(shù)組( PBYTE pbAddress )或解釋為一個無類型的指針( PVOID pAddress ) 。列表 4-23 中的 SpyInputMemory() 函數(shù)將從 IOCTL 的輸入緩沖區(qū)中復制該結(jié)構(gòu) 。其搭檔函數(shù) SpyOutputMemory() (在 列表 4-23 的末尾處)只是 SpyMemoryReadBlock() 的一個外包而已,列表 4-24 給出了 SpyMemoryReadBlock() 函數(shù) 。SpyOutputMemory() 的主要職責是在 SpyMemoryReadBlock() 讀取數(shù)據(jù)后,返回適當?shù)?NTSTATUS 值 。
SpyMemoryReadBlock() 通過一個 SPY_MEMORY_DATA 結(jié)構(gòu)返回它讀到的內(nèi)存數(shù)據(jù) 。該結(jié)構(gòu)定義于 列表 4-25。我選擇了一中不同的定義方式,因為 SPY_MEMORY_DATA 是一個針對變量大小的數(shù)據(jù)類型 ?;旧?,它包含一個名為 smb 的 SPY_MEMORY_BLOCK 結(jié)構(gòu),隨后是一個 WORD 類型的數(shù)組,名為 awData[]。該數(shù)組的長度由 smb 的 dBytes 成員給出 。為了允許方便的按預定大小定義 SPY_MEMORY_DATA 的全局或局部實體,該結(jié)構(gòu)的定義采用了一個宏 ----SPY_MEMORY_DATA_N()。該宏的唯一參數(shù)用于指定 awData[] 數(shù)組的大小 。實際的結(jié)構(gòu)體定義在宏定義之后,它提供的結(jié)構(gòu)體中包含一個長度為 0 的 awData[] 數(shù)組 。SPY_MEMORY_DATA__() 宏首先計算 SPY_MEMORY_DATA 結(jié)構(gòu)的全部大小,然后按這一大小分配結(jié)構(gòu)中的數(shù)組,剩下的定義允許將 WORD 型的數(shù)據(jù)加入數(shù)組或從數(shù)組中取出 。顯然,每個 WORD 的低半位包含內(nèi)存數(shù)據(jù)的字節(jié)數(shù),高半位作為標志位 ?,F(xiàn)在,僅有第 8 位有意義,用于表示位于 0—7 位的內(nèi)存字節(jié)數(shù)是否有效 。
typedef struct _SPY_MEMORY_BLOCK
{
union
{
PBYTE pbAddress;
PVOID pAddress;
};
DWORD dBytes;
}
SPY_MEMORY_BLOCK, *PSPY_MEMORY_BLOCK, **PPSPY_MEMORY_BLOCK;

推薦閱讀