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);
}
// -----------------------------------------------------------------

推荐阅读