SSDT详解

节选自《Undocumented Windows 2000 Secrets》:

 

SSDT — System Services Descriptor Table ,系统服务描述符表(是一个整体的概念),共有四个表。(明确说是四个SST (System Server Table,系统服务表)类型的数组):

 

typedef NTSTATUS (NTAPI*NTPROC)();
typedef NTPROC* PNTPROC; 
#define NTPROC_ sizeof(NTPROC)

 

typedef struct _SERVICE_DESCRIPTOR_TABLE 

  SYSTEM_SERVICE_TABLE ntoskrnl;    // ntoskrnl.exe ( native api ) 
  SYSTEM_SERVICE_TABLE win32k;      // win32k.sys (gdi/user support) 
  SYSTEM_SERVICE_TABLE Table3;      // not used 
  SYSTEM_SERVICE_TABLE Table4;      // not used 

SYSTEM_DESCRIPTOR_TABLE
*PSYSTEM_DESCRIPTOR_TABLE, 
**PPSYSTEM_DESCRIPTOR_TABLE;

 

SST结构:

typedef struct _SYSTEM_SERVICE_TABLE 

  PNTPROC  ServiceTable;   // array of entry points 
  PDOWRD  CounterTable;   // array of usage counters 
  DWORD   ServiceLimit;    // number of table entries 
  PBYTE    ArgumentTable;  // array of byte counts 

SYSTEM_SERVICE_TABLE
*PSYSTEM_SERVICE_TABLE, 
**PPSYSTEM_SERVICE_TABLE;

 

      SSDT结构的头两个数组保留给了 ntoskrnl.exe 和 Win32 子系统(位于 win32k.sys)中的内核模式(kernel-mode)部分。来自 gdi32.dll 和 user32.dll 的调用都通过 Win32k 的系统服务表(SST)进行分派。Ntolkrnl.exe 导出了一个指针(符号为 KeServiceDescriptorTable)指向其主服务描述符表(Main SDT)。内核还维护了一个替代的 SDT,其名称为:
KeServiceDescriptorTableShadow,但这个 SDT 并没有被导出。从处于内核模式的模块中访问主服务描述符表(SDT)非常容易,你只需要两个 C 指令,如列表 2-2 所示。首先是由extern 关键字修饰的变量说明,这告诉链接器该变量并不包含在此模块中,而且不需要在链接时解析相应的符号名称。当该模块被加载到进程的地址空间后,针对该符号的引用才会动态连接到相应的模块中。列表 2-2 中第二个 C 指令就是这样的一个引用。将类型为PSERVER_DESCRIPTOR_TABLE 的变量赋值为 KeServiceDescriptorTable 时,就会和
ntoskrnl.exe建立一个动态连接。这很像调用一个 DLL 中的API 函数。

// Import SDT pointer

extern PSERVICE_DESCRIPTOR_TABLE KeServiceDescriptorTable;

// Create SDT reference

PSERVICE_DESCRIPTOR_TABLE psdt = KeServiceDescriptorTable;

列表 2-2   访问系统服务描述符表 


列表 2-2   访问系统服务描述符表 
     SDT 中的每个 SST 的 ServiceTable 成员都是一个指针,指向一个由函数指针构成的数组,此函数指针的类型为:NTPROC,这为 Native API提供了占位符,这种方式和在 Win32编程中使用的 PROC 类型很相似。NTPROC 的定义在前面的列表中给出。Native API函数通常返回一个 NTSTATUS 类型的代码并且使用 NTAPI 调用方式,NTAPI 实际上就是_stdcall

     ●ServiceLimit 成员保存在 ServieTable 数组中发现的入口地址的个数。在 Windows2000 中,其默认值为 248。

     ●ArgumentTable 成员是一个 BTYE类型的数组,它和 ServiceTable所指的数组一一对应,并给出其中每个函数指针所需的参数在调用者的堆栈中的字节数。此信息随 EDX寄存器提供的指针一起使用。当内核从调用者的堆栈中复制参数到自己的堆栈时就需要这些信息。   

   ●CounterTable成员在Windows 2000的Free Build版中不被使用。在Debug Build 版中,该成员指向一个 DWORD 类型的数组,作为每个函数的使用计数器(usage counters)。This information can be used for profiling purposes.  

在Windows XP中,KeServiceDescriptorTable和KeServiceDescriptorTableShadow和Windows 2000有所区别。在XP中,后者位于前者的前面,而在W2K中,后者位于前者的后面。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值