Visual C++ 7.1Visual C++ 8.0Windows VistaVisual C++ 7.0C++/CLIWindows 2000Visual C++ 6.0Windows XPCWindowsC++
如何获取 KeServiceDescriptorTableShadow 的地址
解释如何获取 KeServiceDescriptorTableShadow 的地址
引言
本文档展示了如何获取内核变量 KeServiceDescriptorTableShadow
的地址。该变量用于向内核添加新的系统服务,或挂钩现有的系统服务。不幸的是,它没有被 ntoskrnl.exe 导出,因此我们必须手动获取其地址。
背景
通过使用 ntoskrnl.exe 导出的变量 KeServiceDescriptorTable
,我们可以获取 KeServiceDescriptorTableShadow
变量的地址。KeServiceDescriptorTableShadow
是 KeServiceDescriptorTable
变量的扩展。请参阅以下部分。
Using the Code
这两个变量的类型都是 SERVICE_DESCRIPTOR_TABLE
结构体。该结构体定义如下
typedef struct _SERVICE_DESCRIPTOR_TABLE
{
PULONG ServiceTable; // array of entry-points
PULONG puCounterTable; // array of counters
ULONG uTableSize; // number of table entries
PUCHAR pbArgumentTable; // array of byte counts
} SERVICE_DESCRIPTOR_TABLE, *PSERVICE_DESCRIPTOR_TABLE;
KeServiceDescriptorTableShadow
的第一部分与 KeServiceDescriptorTable
相同。因此,我们可以通过比较 KeServiceDescriptorTable
周围的内存来获取 KeServiceDescriptorTableShadow
的地址。在不同版本的 Windows 中,此地址是不同的。
此函数在不同版本的 Windows 中检索其地址。
PSERVICE_DESCRIPTOR_TABLE QuerySDTShadow()
{
ULONG Index;
PUCHAR SDTShadow;
UONG MajorVersion, MinorVersion, BuildNumber;
UNICODE_STRING &CSDVersion;
PsGetVersion(&MajorVersion, &MinorVersion, &BuildNumber, &CSDVersion);
__try
{
if(MajorVersion == 5 && MinorVersion == 1) // Windows XP
SDTShadow = (PUCHAR)((ULONG)&KeServiceDescriptorTable - 0x40);
else // Windows 2000, or Windows Vista
SDTShadow = (PUCHAR)((ULONG)&KeServiceDescriptorTable + 0x40);
for(Index = 0; Index < 0x1000; Index ++, SDTShadow ++)
{
KeServiceDescriptorTableShadow = (PSERVICE_DESCRIPTOR_TABLE)SDTShadow;
if(KeServiceDescriptorTableShadow == &KeServiceDescriptorTable)
continue;
if(memcmp(KeServiceDescriptorTableShadow, &KeServiceDescriptorTable, 0x10) == 0
&& ((UCHAR)KeServiceDescriptorTableShadow->ServiceTable & 3) == 0)
{
return (PSERVICE_DESCRIPTOR_TABLE)SDTShadow;
}
}
return NULL;
}
__except(1)
{
return NULL;
}
}
这段代码已经在各种环境下进行了测试,但您必须谨慎使用它。
历史
- 2008 年 5 月 26 日:初始发布