在内核驱动中得到 KeServiceDescriptorTableShadow
头文件:
//
// svcdesctbl.h
//
#pragma once
typedef struct _KSERVICE_TABLE_DESCRIPTOR {
PULONG_PTR Base; // Service Table Base
PULONG Count; // Service Counter Table Base, Used only in checked build
ULONG Limit;
PUCHAR Number;
} KSERVICE_TABLE_DESCRIPTOR, *PKSERVICE_TABLE_DESCRIPTOR;
#define NUMBER_SERVICE_TABLES 2
__declspec(dllimport) KSERVICE_TABLE_DESCRIPTOR
KeServiceDescriptorTable[NUMBER_SERVICE_TABLES];
KSERVICE_TABLE_DESCRIPTOR * Get_KeServiceDescriptorTableShadow ();
实现文件:
//
// svcdesctbl.c
//
#include <ntddk.h>
#include "svcdesctbl.h"
__declspec(dllimport) BOOLEAN KeAddSystemServiceTable (
IN PULONG_PTR Base,
IN PULONG Count OPTIONAL,
IN ULONG Limit,
IN PUCHAR Number,
IN ULONG Index
);
/*********************************************************************
*
* 调用方式:
* 说明: 遍历系统内存空间,返回 KSERVICE_TABLE_DESCRIPTOR 结构指针
*
* 返回值: KSERVICE_TABLE_DESCRIPTOR 结构指针
* 参数1:
* 参数2:
* 修改日期:
*
*********************************************************************/
KSERVICE_TABLE_DESCRIPTOR * Get_KeServiceDescriptorTableShadow ()
{
// KeServiceDescriptorTableShadow
static KSERVICE_TABLE_DESCRIPTOR * ShadowTable = NULL;
PAGED_CODE();
if (ShadowTable)
{
return ShadowTable;
}
{
// First, obtain a pointer to KeAddSystemServiceTable
unsigned char *check = (unsigned char*) KeAddSystemServiceTable;
int i = 0;
//Initialize an instance of System Service Table, will be used to
//obtain an address from KeAddSystemServiceTable
KSERVICE_TABLE_DESCRIPTOR *rc = 0;
// Make 100 attempts to match a valid address with that of
// KeServiceDescriptorTable
for (i=0; i<100; i++)
{
__try
{
// try to obtain an address from KeAddSystemServiceTable
rc = *( KSERVICE_TABLE_DESCRIPTOR**)check;
// if this address is NOT valid OR it itself is the address of
//KeServiceDescriptorTable OR its first entry is NOT equal
//to the first entry of KeServiceDescriptorTable
if (FALSE == MmIsAddressValid (rc))
{
goto __continue__;
}
KdPrint(("rc=0x%08X KeServiceDescriptorTable=0x%08X\r\n",
rc, KeServiceDescriptorTable));
if (rc == KeServiceDescriptorTable)
{
goto __continue__;
}
if (memcmp (rc, KeServiceDescriptorTable, sizeof(*rc)) == 0)
{
// here is that we find out the
// KeServiceDescriptorTableShadow address
break;
}
__continue__:
check++; // Proceed with the next address
rc = 0; // don't forget to reset the old address
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
rc = 0;
check++;
}
}
// otherwise, there is a valid address! So return it!
ShadowTable = rc;
}
return ShadowTable;
}
//=========================================================================
// from WRK 1.2
//=========================================================================
// BOOLEAN
// KeAddSystemServiceTable (
// IN PULONG_PTR Base, IN PULONG Count OPTIONAL,
// IN ULONG Limit,
// IN PUCHAR Number,
// IN ULONG Index
// )
// {
// PAGED_CODE();
//
// if ((Index > NUMBER_SERVICE_TABLES - 1) ||
// (KeServiceDescriptorTable[Index].Base != NULL) ||
// (KeServiceDescriptorTableShadow[Index].Base != NULL)) {
// return FALSE;
// } else {
// KeServiceDescriptorTableShadow[Index].Base = Base;
// KeServiceDescriptorTableShadow[Index].Count = Count;
// KeServiceDescriptorTableShadow[Index].Limit = Limit;
// KeServiceDescriptorTableShadow[Index].Number = Number;
// if (Index != WIN32K_SERVICE_INDEX) {
// KeServiceDescriptorTable[Index].Base = Base;
// KeServiceDescriptorTable[Index].Count = Count;
// KeServiceDescriptorTable[Index].Limit = Limit;
// KeServiceDescriptorTable[Index].Number = Number;
// }
// return TRUE;
// }
// }
延伸阅读:
Obtaining KeServiceDescriptorTableShadow address in Windows XP Kernel mode
How Can I Get the Address of KeServiceDescriptorTableShadow
KeServiceDescriptorTableShadow 的获取
城里城外看 SSDT
System Calling Mechanism under Win32

近期评论