系统服务调度表SSDT及SSSDT Shadow

系统服务:由操作系统提供的一组函数(内核函数),API可以间接或者直接的调用系统服务。操作系统以动态链接库(DLL)的形式提供API。
SSDT:系统服务调度表(System  Service  Dispatch Table),该表可以基于系统服务编号进行索引,来定位函数内存地址。
SSPT:系统服务参数表(System  Service  Parameter  Table),指定系统服务函数的参数字节数。
系统有2个SSDT表, 一个是KeServiceDescriptorTable(ntoskrnl.exe导出),一个是KeServieDescriptorTableShadow(ntoskrnl.exe未导出)。两者的区别是,KeServiceDescriptorTable仅有ntoskrnel.exe中的函数一项,KeServieDescriptorTableShadow包含了ntoskrnel.exe以及win32k.sys中包含的函数。一般的ntdll.dll中的Native API的函数地址由KeServiceDescriptorTable分派,gdi.dll/user.dll的内核API调用服务地址由KeServieDescriptorTableShadow分派。

1)KeServiceDescriptorTable是内核导出的一张表,该表含有一个指针指向SSDT中包含Ntoskrnl.exe实现的核心服务,还包含一个指针指向SSPT。
KeServiceDescriptorTable结构如下:
typedef struct _ServiceDescriptorEntry {  
  unsigned int *ServiceTableBase;        //SSDT基址
  unsigned int *ServiceCounterTableBase; //SSDT中服务被调用次数的计数器
  unsigned int NumberOfServices;         //SSDT服务个数
  unsigned char *ParamTableBase;         //SSPT基址
}SSDT, *PSSDT;

下面是在windbg进行实验:
lkd> dd KeServiceDescriptorTable   //导出表
80563520  804e58b0 00000000 0000011c 805120cc
80563530  00000000 00000000 00000000 00000000
80563540  00000000 00000000 00000000 00000000
80563550  00000000 00000000 00000000 00000000
80563560  00000002 00002710 bf80c339 00000000
80563570  baecda80 f753c4a0 8a09655c 807120c0
80563580  00000000 00000000 ffea8ad6 ffffffff
80563590  52841216 01ca0418 00000000 00000000
lkd> dd 804e58b0               //SSDT基址
804e58b0  80591bfb 80585358 805e1f35 805dbc4a
804e58c0  805e1fbc 80640ce4 80642e75 80642ebe
804e58d0  805835aa 80650be3 806404a3 805e1787
804e58e0  806387ba 80586fa3 805e08e8 8062f462
804e58f0  805d9781 80571edd 805e8258 805e939e
804e5900  804e5ec4 80650bcf 805cd537 804ed822

lkd> dd 805120cc     //SSPT基址
805120cc  2c2c2018 44402c40 1818080c 0c040408
805120dc  08081810 0808040c 080c0404 2004040c
805120ec  140c1008 0c102c0c 10201c0c 20141038
805120fc  141c2424 34102010 080c0814 04040404
8051210c  0428080c 1808181c 1808180c 040c080c
8051211c  100c0010 10080828 0c08041c 00081004
8051212c  0c080408 10040828 0c0c0404 28240428
8051213c  0c0c0c30 0c0c0c18 0c10300c 0c0c0c10

2)KeServiceDescriptorTableShadow是内核未导出的另一张表,包含Ntoskrnel.exe和win32k.sys服务函数。某些网游通过挂钩按键相关函数(NtUserSendInput)防止模拟按键、(NtUserFindWindowEx)防止搜索窗口、Anti_Virus通过挂钩窗口相关的函数(NtUserPostMessage 、 NtUserQueryWindow)来防止被关闭。KeServiceDescriptorTableShadow实际上是SSDT结构 数组,也就是KeServiceDescriptorTableShadow是一组系统描述表。XP SP3下组数是4。在XP系统下,KeServiceDescriptorTableShadow表位于KeServiceDescriptorTable表上方,偏移0x40处。
下面是windbg进行实验:
lkd> dd KeServiceDescriptorTableShadow  
805634e0  804e58b0 00000000 0000011c 805120cc         //SSDT表 Ntoskrnel.exe
805634f0  bf99a000 00000000 0000029b bf99ad10         //SSDT Shdow表 Win32k.sys
80563500  00000000 00000000 00000000 00000000
80563510  00000000 00000000 00000000 00000000
80563520  804e58b0 00000000 0000011c 805120cc       //KeServiceDescriptorTable 表
80563530  00000000 00000000 00000000 00000000
80563540  00000000 00000000 00000000 00000000
80563550  00000000 00000000 00000000 00000000
由于KeServiceDescriptorTableShadow表属于未导出,因此我们需要定位地址。
定位未导出函数和结构的思想就是利用已导出函数和结构,暴力搜索内存空间。
方法一、依据KeServiceDescriptorTable的地址和两者之间的偏移
方法二、搜索KeAddSystemServiceTable导出函数
方法三、搜索线程的ServiceTable指向
方法四、MJ提出的搜索有效内存地址

你可能感兴趣的:(驱动开发学习,c,api,dll,网游,xp,2010)