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
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!