SSDT与Shadow SSDT

typedef struct _SERVICE_DESCIPTOR_TABLE
{
PULONG ServiceTableBase; // SSDT基址
PVOID ServiceCounterTableBase;// SSDT中服务被调用次数计数器,一般由sysenter 更新
ULONGLONG NumberOfService; // SSDT服务个数
PVOID ParamTableBase; // 系统服务参数表基址-系统服务参数表SSPT
}SSDTEntry, *PSSDTEntry;

SSDT服务分发表在ntoskrnl.exe,主要是Ntdll.dll的实现。比如ZwOpenProcess、ZwLoadDriver。内核符号是KeServiceDescriptorTable。
Shadow SSDT服务分发表在win32k.sys,主要是user32.dll,GDI32.dll的实现,PostMessage、SendMessage、FindWindow,Win32k.sys等。又叫SSSDT。其中Shadow SSDT的函数一般是以Ntuser\NtGdi开头的函数。
动态获得函数索引的方法:其原理是通过映射ntdll.dll模块到ring0内存空间,从它的导出表中获得函数地址,如下图所示,第一条指令mov eax,0BEh,其机器码为b8be000000,所以函数地址处过一个字节后的四字节的内容就是函数索引,也就是这里的000000be。
NTDLL.dll中的都是服务的包装函数,当调用其中的NtReadFile时,这些服务包装函数将所需的Servcie ID送入EAX寄存器,将参数堆栈帧的指针送入EDX寄存器,然后发出INT 2e中断。这条指令会将处理器切换到内核模式。

非GUI线程使用KeServiceDescriptorTable,GUI线程使用KeServiceDescriptorTableShadow,这是Windows的设计。非GUI线程如果要调用GUI服务就会用PsConvertToGuiThread把ETHREAD->ServiceTable切换为KeServiceDescriptorTableShadow,而GUI线程调用普通的Win32服务时并不需要切换,因为KeServiceDescriptorTableShadow中已经有个这张表,所以KeServiceDescriptorTableShadow可以看成是KeServiceDescriptorTable的增强版。

在windbg中查看SSDT与Shadow SSDT时使用命令:x nt!kesdestable。X命令表示是显示模块的符号。

如何查看Shadow SSDT表呢?
System系统进程是没有加载ShadowSSDT表的.所以我们必须切换到调用GUI的进程空间中查看.
1.在系统中运行 mspaint 画图工具
2.在windbg中中断.
3.输入命令.查看系统所有简要信息
!process 0 0
4.找到mspaint的EPROCESS结构.切换到这个进程上下文
.process /p EPROCESSADDRESS
5.使用x命令查找ShadowsSSDT(后续和查看SSDT表一样)
x nt!kesdestable

使用DD命令可以查看SSDT与Shadow SSDT。


SSDT HOOK的思路

参考文献:iBinary的https://www.cnblogs.com/iBinary/p/10990673.html

posted @ 2020-11-12 10:49  摔不死的笨鸟  阅读(762)  评论(0编辑  收藏  举报