Introduction
This article shows how to get the address of KeServiceDescriptorTableShadow
kernel variable. This variable is used to add new system services to kernel, or hook an existing system service. Unfortunately, it is not exported by ntoskrnl.exe, so we have to get its address manually.
Background
Using KeServiceDescriptorTable
variable exported by ntoskrnl.exe, we can get the address of KeServiceDescriptorTableShadow
variable. KeServiceDescriptorTableShadow
is an extension of KeServiceDescriptorTable
variable. Please see the following section.
Using the Code
The type of two variables is SERVICE_DESCRIPTOR_TABLE
structure. This structure is defined as follows:
typedef struct _SERVICE_DESCRIPTOR_TABLE
{
PULONG ServiceTable; PULONG puCounterTable; ULONG uTableSize; PUCHAR pbArgumentTable; } SERVICE_DESCRIPTOR_TABLE, *PSERVICE_DESCRIPTOR_TABLE;
The first part of KeServiceDescriptorTableShadow
is the same as KeServiceDescriptorTable
. And so we could get the address of KeServiceDescriptorTableShadow
by comparing memories around KeServiceDescriptorTable
. In different version of Windows, this address is different.
This function retrieves its address in different version of 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) SDTShadow = (PUCHAR)((ULONG)&KeServiceDescriptorTable - 0x40);
else 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;
}
}
This code was tested in various environments, but you must use it carefully.
History
- 26th May, 2008: Initial post