4 《Undocumented Windows 2000 Secrets》翻譯 --- 第四章

第四章 探索 Windows 2000 的內存管理機制
翻譯: Kendiv ( fcczj@263.net)
更新: Sunday, February 17, 2005
聲明:轉載請注明出處,并保證文章的完整性,本人保留譯文的所有權利 。
盡管 Spy 設備使用可緩沖的 I/O,但它還是會檢查輸入 / 輸出緩沖區的有效性 。因為客戶端程序傳入的數據可能比所需的少或者提供的緩沖區不夠容納輸出數據 。系統不能捕獲這些語意錯誤,因為它不知道在一次 IOCTL 傳輸中所傳輸的數據的類型 。因此,SpyDispatcher() 調用幫助函數 SpyInput*() 和 SpyOutput*() 來從 I/O 緩沖區中復制或寫入數據 。這些函數僅在緩沖區大小與操作的需求相匹配時才執行 。列表 4-10 給出了基本的輸入函數,列表 4-11 給出了基本的輸出函數 。SpyInputBinary() 和 SpyOutputBinary() 被廣泛的使用,它們測試緩沖區的大小,如果 OK,則使用 Windows 2000 運行時庫函數 RtlCopyMemory() 復制被請求的數據 。剩余的函數只是上述兩個基本函數的簡單外包,用來操作常見的數據類型 DWord,BOOL,PVOID 和 HANDLE 等 。SpyOutputBlock() 復制由調用者在 SPY_MEMORY_BLOCK 結構中指定的數據塊,當然這需要首先驗證請求范圍內的字節都是可讀的 。如果傳入的輸入緩沖區的大小不正確,SpyInput*() 函數將返回 STATUS_INVALID_BUFFER_SIZE,如果輸出緩沖區比需要的小,SpyOutput*() 函數將返回 STATUS_BUFFER_TOO_SMALL。
NTSTATUS SpyInputBinary (PVOID pData,
DWORD dData,
PVOID pInput,
DWORD dInput)
{
NTSTATUS ns = STATUS_INVALID_BUFFER_SIZE;
if (dData <= dInput)
{
RtlCopyMemory (pData, pInput, dData);
ns = STATUS_SUCCESS;
}
return ns;
}
// -----------------------------------------------------------------
NTSTATUS SpyInputDword (PDWORD pdValue,
PVOID pInput,
DWORD dInput)
{
return SpyInputBinary (pdValue, DWORD_, pInput, dInput);
}
// -----------------------------------------------------------------
NTSTATUS SpyInputBool (PBOOL pfValue,
PVOID pInput,
DWORD dInput)
{
return SpyInputBinary (pfValue, BOOL_, pInput, dInput);
}
// -----------------------------------------------------------------
NTSTATUS SpyInputPointer (PPVOID ppAddress,
PVOID pInput,
DWORD dInput)
{
return SpyInputBinary (ppAddress, PVOID_, pInput, dInput);
}
// -----------------------------------------------------------------
NTSTATUS SpyInputHandle (PHANDLE phObject,
PVOID pInput,
DWORD dInput)
{
return SpyInputBinary (phObject, HANDLE_, pInput, dInput);
}
列表 4-10. 從 IOCTL 緩沖區中讀取輸入數據
NTSTATUS SpyOutputBinary (PVOID pData,
DWORD dData,
PVOID pOutput,
DWORD dOutput,
PDWORD pdInfo)
{
NTSTATUS ns = STATUS_BUFFER_TOO_SMALL;
*pdInfo = 0;
if (dData <= dOutput)
{
RtlCopyMemory (pOutput, pData, *pdInfo = dData);
ns = STATUS_SUCCESS;
}
return ns;
}
// -----------------------------------------------------------------
NTSTATUS SpyOutputBlock (PSPY_MEMORY_BLOCK psmb,
PVOID pOutput,
DWORD dOutput,
PDWORD pdInfo)
{
NTSTATUS ns = STATUS_INVALID_PARAMETER;
if (SpyMemoryTestBlock (psmb->pAddress, psmb->dBytes))
{
ns = SpyOutputBinary (psmb->pAddress, psmb->dBytes,
pOutput, dOutput, pdInfo);
}
return ns;
}
// -----------------------------------------------------------------
NTSTATUS SpyOutputDword (DWORD dValue,
PVOID pOutput,
DWORD dOutput,
PDWORD pdInfo)
{
return SpyOutputBinary (&dValue, DWORD_,
pOutput, dOutput, pdInfo);
}
// -----------------------------------------------------------------

推薦閱讀