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中,KeServiceDescriptorTableKeServiceDescriptorTableShadowWindows 2000有所区别。在XP中,后者位于前者的前面,而在W2K中,后者位于前者的后面。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
本实例由VS2008开发,在提供了一套驱动开发框架的同时,又演示了如何获取Shadow SSDT表函数原始地址的办法。 主要函数:ULONG GetShadowSSDT_Function_OriAddr(ULONG index); 原理说明: 根据特征码搜索导出函数KeAddSystemServiceTable来获取Shadow SSDT基址,以及通过ZwQuerySystemInformation()函数获取win32k.sys基址,然后解析PE定位到Shadow SSDT在win32k.sys的偏移地址,并通过进一步计算来得到Shadow SSDT表函数的原始地址。 这里只测试了三个函数:(460)NtUserMessageCall、(475)NtUserPostMessage和(502)NtUserSendInput,具体使用时可以举一反三,网上完整的源代码实例并不太多,希望可以帮到真正有需要的朋友。 系统环境: 在WinXP SP3系统 + 瑞星杀毒软件 打印输出: [ LemonInfo : Loading Shadow SSDT Original Address Driver... ] [ LemonInfo : 创建“设备”值为:0 ] [ LemonInfo : 创建“设备”成功... ] [ LemonInfo : 创建“符号链接”状态值为:0 ] [ LemonInfo : 创建“符号链接”成功... ] [ LemonInfo : 驱动加载成功... ] [ LemonInfo : 派遣函数(DispatchRoutine) IRP 开始... ] [ LemonInfo : 派遣函数(DispatchRoutine) IRP Enter IRP_MJ_DEVICE_CONTROL... ] [ LemonInfo : 获取ShadowSSDT表 (460)NtUserMessageCall 函数的“当前地址”为:0xB83ECFC4,“起源地址”为:0xBF80EE6B ] [ LemonInfo : 获取ShadowSSDT表 (475)NtUserPostMessage 函数的“当前地址”为:0xB83ECFA3,“起源地址”为:0xBF8089B4 ] [ LemonInfo : 获取ShadowSSDT表 (502)NtUserSendInput 函数的“当前地址”为:0xBF8C31E7,“起源地址”为:0xBF8C31E7 ] [ LemonInfo : 派遣函数(DispatchRoutine) IRP_MJ_DEVICE_CONTROL 成功执行... ] [ LemonInfo : 派遣函数(DispatchRoutine) IRP 结束... ] [ LemonInfo : UnLoading Shadow SSDT Original Address Driver... ] [ LemonInfo : 删除“符号链接”成功... ] [ LemonInfo : 删除“设备”成功... ] [ LemonInfo : 驱动卸载成功... ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值