您的位置:首页 > 其它

KeServiceDescriptorTableShadow的获取

2010-07-01 17:12 267 查看
如果没有KeServiceDescriptorTable,那么很多事情就会变得简单许多,我们只需要定义一个全局变量:
extern PSERVICE_Descriptor_TABLE    KeServiceDescriptorTable;
这样就能够引用KeServiceDescriptorTable了,就能够访问ntoskrnel下面所导出的所有函数。但是因为还有一些函数是通过win32k表导出的,这些函数都是win32k.sys的服务函数,所以要访问类似这些函数就得从shadow标结构中读取win32k表的EntryPoint。
因为KeServiceDescriptorTableShadow并不公开,所以需要从其他途径获取该结构表。现在用的比较多的一种方法是通过KeAddSystemServiceTable,遍历该函数的起始地址,查找有效内存地址(MmIsAddressValid)。因为shadow是涵盖了KeServiceDescriptorTable表的结构,在查找的过程中,就是采用和KeServiceDescriptorTable表进行匹配的方法,其中前16位需要匹配,而且两个表的起始地址不能相同(否则为同一张表),就是按照这种方法,查找获得shadow表。其实现函数如下:
#include <ntddk.h>
//KeServiceDescriptorTable的表结构
typedef struct _SERVICE_Descriptor_TABLE
{
  PVOID   ServiceTableBase;
  PULONG  ServiceCounterTableBase;
  ULONG   NumberOfService;
  ULONG   ParamTableBase;
}SERVICE_Descriptor_TABLE,*PSERVICE_Descriptor_TABLE;
//下面这句话非常重要,用来申明KeServiceDescriptorTable,方才能在以后的程序中使用
extern PSERVICE_Descriptor_TABLE    KeServiceDescriptorTable;
//下面同样是用来申明的,KeAddSystemService,这样才能使用,以此得到函数的入口地址
NTSYSAPI BOOLEAN NTAPI KeAddSystemServiceTable (
          PVOID* ServiceTable,
          ULONG Reserved,
          ULONG Limit,
          BYTE* Arguments,
          ULONG NumOfDesc);
//下面就是具体的实现函数
DWORD  GetAddrssofShadowTable()
{
int i;
unsigned char *p;
unsigned int dwordatbyte;
p=(unsigned char *)KeAddSystemServiceTable;   //由KeAddSystemServiceTable起始地址遍历
for (i=0; i<4096; i , p ) {
__try {
dwordatbyte = *(unsigned int *)p;
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
  return 0;
}
if (MmIsAddressValid((PVOID)dwordatbyte))       //检测地址是否有效,能否读写
{
  if ((PVOID)dwordatbyte == *(PVOID *)&KeServiceDescriptorTable)    //如果起始地址相同,则为同一张表,
                                                                                                             //继续循环
  {
   continue;
  }
  if (memcmp((PVOID)dwordatbyte, *(PVOID *)&KeServiceDescriptorTable, 16) == 0)  
  //比较前16位,相同则为shadow表
  {
   DbgPrint("Shadow @%x\n", dwordatbyte);
   return dwordatbyte;
  }
}
}
return 0;
}
分析具体实例如下:
分析工具:windbg
lkd>dd KeServiceDescriptorTable
8055c6e0  80504940 00000000 0000011c 80504db4
8055c6f0  00000000 00000000 00000000 00000000
8055c700  00000000 00000000 00000000 00000000
8055c710  00000000 00000000 00000000 00000000
可以看到只有ntskrnel表,下面三项都为0,采用上面方法获取到shadow地址为0x8055C6A0,察看其对应内容如下:
lkd> dd 8055c6a0
8055c6a0  80504940 00000000 0000011c 80504db4
8055c6b0  bf999280 00000000 0000029b bf999f90
8055c6c0  00000000 00000000 00000000 00000000
8055c6d0  00000000 00000000 00000000 00000000
看到前16位是相同的,符合上面的规则。
最后就是自己的一些处理,略。
全篇完。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: