SSDT入门

SSDT入门一 SSDT 1 SSDT 看来是一个兵家必争之地 无论是安全软件还是恶意代码都在上面做着手脚 图 SystemModule 揭示了系统各模块之间的依赖关系 有所简化 nbsp 从图中可以看出 所有的 Win32API 调用最后都转移到了 ntdll dll 而 ntdll dll 又将其转移到了 ntoskrnl exe ntdll dll 是一个操作系

一:SSDT 【1】
SSDT看来是一个兵家必争之地,无论是安全软件还是恶意代码都在上面做着手脚。

 

例如,由kernel32.dll导出的Win32 API函数DeviceIoControl()最终会调用由ntdll.dll导出的NtDeviceIoControlFile()。

NtDeviceIoControlFile:
mov   eax, 38h
lea   edx, [esp+4]
int   2Eh
ret   28h




“魔术”数字0x38是一个分派ID;INT 2Eh指令将跳转到中断描述符表(Interrupt Descriptor Table,IDT)的0x2e位置上存放的中断处理例程(interrupt handler)中,分配器(dispatcher)利用它从用户模式进入内核模式。

从NtDeviceIoControlFile示例给出的反汇编代码可看出,INT 2Eh随同传入CPU寄存器EAX和EDX的两个参数一起被调用。处理INT 2Eh的代码必须确定每个调用将被分配到哪个函数。这就是提供EAX中的”魔术”数字–分派ID的原因。位于ntoskrnl.exe中的中断处理例程将EAX中的数值作为一个索引来查询一个特定的表。这个表被称作系统服务表(System Service Table, SST)该表对应的C结构体—SYSTEM_SERVICE_TABLE:
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;





但是SST并不是源头,而且内核中还存在多个SST表,所以内核维护着另外一个表结构,该结构共有四个SST类型的数组,其中的前两个用于特定目的,头两个数组保留给了ntoskrnl.exe和Win32子系统(位于win32k.sys)中的内核模式部分(来自gdi32.dll和user32.dll的调用都通过Win32k的系统服务表(SST)进行分派)。ntolkrnl.exe导出了一个指针(符号为KeServiceDescriptorTable)指向其主服务描述符表(Main SDT),内核还维护了一个替代的SDT,其名称为KeServiceDescriptorTableShadow,但这个SDT并没有被导出。
这个表被称作服务描述符表(The Service Descriptor Tables, SDT)该表对应的C结构体—SERVICE_DESCRIPTOR_TABLE:
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;





啰啰嗦嗦一大堆,简单说,内核维护着_SERVICE_DESCRIPTOR_TABLE这样一个SDT结构数据,即KeServiceDescriptorTable,里面保存着ntoskrnl.exe的SST结构数据(当然还包括其他SST),其中ServiceTable指向的是由ServiceLimit个函数指针构成的数组;当执行前面提到的NtDeviceIoControlFile示例代码时,内核找到KeServiceDescriptorTable,接着找到ntoskrnl.ServiceTable,该地址是函数指针数组的首地址,所以NtDeviceIoControlFile函数地址为[ServiceTable+0x38*4]。









SSDT Call Process

【图 SSDT Call Process】SSDT查找函数地址过程

NtCreateProcess_ID

【图 NtCreateProcess_ID】NtCreateProcess ID号

IceSword
【图 IceSword】IceSword检测到NtCreateProcess被Hook

 

四:SSDT访问
也许你现在已经迫不及待的想要操控一下SSDT,好消息是,ntolkrnl.exe导出了一个指针(符号为KeServiceDescriptorTable)指向其主服务描述符表(Main SDT),从处于内核模式的模块中访问主服务描述符表是非常容易,你只需要两个C指令,首先是由extern关键字修饰的变量说明,这告诉链接器该变量并不包含在此模块中,而且不需要在链接时解析相应的符号名称,当该模块被加载到进程的地址空间后,针对该符号的引用才会动态连接到相应的模块中:
// Import SDT pointer
extern PSERVICE_DESCRIPTOR_TABLE KeServiceDescriptorTable;

其次是创建一个对KeServiceDescriptorTable的引用:
// Create SDT reference
PSERVICE_DESCRIPTOR_TABLE psdt = KeServiceDescriptorTable;

现在,你的内核模块就可以访问SSDT数据了。

到此为止,不再深入,因为文章和文章的作者都是入门级的,至于后续SSDT Hook之类的话题,你就自己玩吧。【4】


五:附录

对SSDT也只是有个初步了解,得益于一些参考资料:

【1】本文关于SSDT的描述,基本源于<<Undocumented Windows 2000 Secrets>>一书的第二章,所以针对的是Windows 2000系统,其中文翻译参见
【Undocumented Windows 2000 Secrets 中文翻译】http://blog.csdn.net/Kendiv/category/88780.aspx

【2】内核调试工具安装包和符号文件安装包,参见
【Debugging Tools for Windows】http://www.microsoft.com/whdc/DevTools/Debugging/default.mspx

【3】搭建Windbg和VMware的内核调试环境,参见
【使用WinDbg和VMware调试NDIS中间层驱动程序】http://www.cppblog.com/aurain/archive/2009/01/04/71138.html

【4】关于SSDT Hook的文章比较多,<<简单说说SSDT>>是其中一篇,比较容易理解,参见
【简单说说SSDT】http://icylife.net/yunshu/show.php?id=435
























版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/233150.html原文链接:https://javaforall.net

(0)
上一篇 2025年8月11日 下午6:01
下一篇 2025年8月11日 下午6:22


相关推荐

  • AI赋能广告创意:n8n自动化工作流完全指南

    AI赋能广告创意:n8n自动化工作流完全指南

    2026年3月15日
    3
  • linux查看当前环境变量的命令_linux添加环境变量

    linux查看当前环境变量的命令_linux添加环境变量1.显示环境变量HOME$echo$HOME/home/redbooks2.设置一个新的环境变量hello$exportHELLO=”Hello!”$echo$HELLOHello!3.使用env命令显示所有的环境变量$envHOSTNAME=redbooks.safe.orgPVM_RSH=/usr/bin/rshShell=/bin/bashTERM=xtermHISTSIZE=1000…4.使用set命令显示所有本地定义的She

    2026年4月19日
    8
  • 费曼学习法

    费曼学习法费曼学习法我的理解:费曼学习法就是把学好的东西用简洁易懂的语言,传授给别人举例:你学完微积分,然后自己去培训班,自己做老师,传授给学生们,并且学生们都能听懂费曼学习法的四个步骤:1.确定目标

    2022年7月28日
    10
  • C++中protected访问权限问题

    C++中protected访问权限问题今天发现有这样两句话 1 基类的保护成员对于派生类的成员是可访问的 2 派生类的成员只能通过派生类对象访问基类的保护成员 派生类对一个基类对象中的受保护成员没有访问权限 这两句话看的太头晕了 其实作者应该是想表达 只有在派生类中才可以通过派生类对象访问基类的 protected 成员 看这样的代码 classBase public Base private

    2026年3月18日
    2
  • 微信小程序实现banner图轮播(动态获取数据),自动获取图片高度

    微信小程序实现banner图轮播(动态获取数据),自动获取图片高度效果图:indicator-active-color=”#007aff”//当前选中的指示点颜色js:constapp=getApp()Page({data:{//———–模拟banner图———–imgUrls:[‘/image/1545118381903.jpg’,’/imag…

    2022年5月22日
    49
  • QT基本介绍

    QT基本介绍一、什么是QT?Qt是一个跨平台的C++图形用户界面应用程序框架。它为应用程序开发者提供建立艺术级图形界面所需的所有功能。它是完全面向对象的,很容易扩展,并且允许真正的组件编程。二、发展历史1991年Qt最早由奇趣科技开发1996年进入商业领域,它也是目前流行的Linux桌面环境…

    2022年5月13日
    114

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号