SSDT 的全称是 System Services Descriptor Table,系统服务描述符表。
这个表就是一个把 Ring3 的 Win32 API 和 Ring0 的内核 API 联系起来。
SSDT 并不仅仅只包含一个庞大的地址索引表,它还包含着一些其它有用的信息,诸如地址索引的基地址、服务函数个数等。
通过修改此表的函数地址可以对常用 Windows 函数及 API 进行 Hook,从而实现对一些关心的系统动作进行过滤、监控的目的。
一些 HIPS、防毒软件、系统监控、注册表监控软件往往会采用此接口来实现自己的监控模块。
          
在 NT 4.0 以上的 Windows 操作系统中,默认就存在两个系统服务描述表,这两个调度表对应了两类不同的系统服务,
这两个调度表为:KeServiceDescriptorTable 和 KeServiceDescriptorTableShadow,
其中 KeServiceDescriptorTable 主要是处理来自 Ring3 层得 Kernel32.dll 中的系统调用,
而 KeServiceDescriptorTableShadow 则主要处理来自 User32.dll 和 GDI32.dll 中的系统调用,
并且 KeServiceDescriptorTable 在 ntoskrnl.exe(Windows 操作系统内核文件,包括内核和执行体层)是导出的,
而 KeServiceDescriptorTableShadow 则是没有被 Windows 操作系统所导出,
而关于 SSDT 的全部内容则都是通过 KeServiceDescriptorTable 来完成的

win32下KeSystemDescriptorTable的地址已经由ntoskrnl.exe导出, extern PKSERVICE_TABLE_DESCRIPTOR KeServiceDescriptorTable 即可获取SSDT的地址。
  在win64下,KeSystemDescriptorTable的地址没有被导出,不能通过win32下的方法获取地址。
  Win64下,我们可以通过msr寄存器获取 KiSystemCall64函数的地址,在这个函数开始地址向下搜索0x500字节左右,在通过特征码4c8d15,就能获取KeServiceDescriptorTable的地址。

Windbg下

kd>uf iSystemCall64
nt!KiSystemCall64:
fffff800`03e85640 0f01f8 swapgs
fffff800`03e85643 654889242510000000 mov qword ptr gs:[10h],rsp
fffff800`03e8564c 65488b2425a8010000 mov rsp,qword ptr gs:[1A8h]
fffff800`03e85655 6a2b push 2Bh
fffff800`03e85657 65ff342510000000 push qword ptr gs:[10h]
fffff800`03e8565f 4153 push r11
fffff800`03e85661 6a33 push 33h
。。。。。。。
fffff800`03e8575e 4889a3d8010000 mov qword ptr [rbx+1D8h],rsp
fffff800`03e85765 8bf8 mov edi,eax
fffff800`03e85767 c1ef07 shr edi,7
fffff800`03e8576a 83e720 and edi,20h
fffff800`03e8576d 25ff0f0000 and eax,0FFFh

nt!KiSystemServiceRepeat:
fffff800`03e85772 4c8d15c7202300 lea r10,[nt!KeServiceDescriptorTable (fffff800`040b7840)]
fffff800`03e85779 4c8d1d00212300 lea r11,[nt!KeServiceDescriptorTableShadow (fffff800`040b7880)]
fffff800`03e85780 f7830001000080000000 test dword ptr [rbx+100h],80h
fffff800`03e8578a 4d0f45d3 cmovne r10,r11
fffff800`03e8578e 423b441710 cmp eax,dword ptr [rdi+r10+10h]
fffff800`03e85793 0f83e9020000 jae nt!KiSystemServiceExit+0x1a7 (fffff800`03e85a82)

注意蓝色字节内容, KiSystemCall64的开始地址是fffff800`03e85640, 第二个蓝色标记处发现了KeServiceDescriptorTable,这条指令地址是fffff800`03e85772,对应的字节为4c8d15478c2300,Lea的对应字节为4c8d15,所以后边的字节478c2300为偏移地址,注意地址是反过来的,真正偏移地址是 00238c47,偏移地址是针对这条指令最后一个字节的地址的偏移,所以需要在加7字节,由此可得KeServiceDescriptorTable地址为:
fffff800`03e85772 + 00238c47 + 7 = fffff800`040b7840。
 
我们可以dd KeServiceDescriptorTable看一下地址
2: kd> dd KeServiceDescriptorTable
fffff800`040b7840 03e87300 fffff800 00000000 00000000
fffff800`040b7850 00000191 00000000 03e87f8c fffff800
fffff800`040b7860 00000000 00000000 00000000 00000000
fffff800`040b7870 00000000 00000000 00000000 00000000
fffff800`040b7880 03e87300 fffff800 00000000 00000000
fffff800`040b7890 00000191 00000000 03e87f8c fffff800
fffff800`040b78a0 00161f00 fffff960 00000000 00000000
fffff800`040b78b0 0000033b 00000000 00163c1c fffff960

可以看出上述计算是正确的。

ring0 SSDTHook的更多相关文章

  1. ring0 SSDTHook 实现x64/x86

    #include "HookSSDT.h" #include <ntimage.h> #define SEC_IMAGE 0x001000000 ULONG32 __N ...

  2. ring0 关于SSDTHook使用的绕过页面写保护的原理与实现

    原博:http://www.cnblogs.com/hongfei/archive/2013/06/18/3142162.html 为了安全起见,Windows XP及其以后的系统将一些重要的内存页设 ...

  3. ring0 恢复SSDTHook

    原理: 用ZwQuerySystemInformation 功能号为11(SystemModuleInformation)  得到所有系统模块的地址 遍历搜索得到ntos模块的基地址 读Ntos模块到 ...

  4. SSDTHook实例--编写稳定的Hook过滤函数

    解说怎样写Hook过滤函数,比方NewZwOpenProcess.打开进程. 非常多游戏保护都会对这个函数进行Hook. 因为我们没有游戏保护的代码,无法得知游戏公司是怎样编写这个过滤函数. 我看到非 ...

  5. Hook集合----SSDTHook(x86 Win7)

    最近在学习Ring0层Hook的一些知识点,很久就写完SSDTHook的代码了,但是一直没有整理成笔记,最近有时间也就整理整理. 介绍: SSDTHook 实质是利用Ntoskrnl.exe 中全局导 ...

  6. 函数调用关于从Ring3转到Ring0 ESP堆栈变化

    在ring0堆栈获取ring3堆栈方式 第一种方式 [esp+4] == [esp+参数个数*4+4] 如果这里不相等就需要用第二种方式 [[esp+参数个数*4+8]] 这里面的值就是Ring3的堆 ...

  7. ring0

    Intel的x86处理器是通过Ring级别来进行访问控制的,级别共分4层,RING0,RING1,RING2,RING3.Windows只使用其中的两个级别RING0和RING3. RING0层拥有最 ...

  8. 对付ring0 inline hook

    对付ring0 inline hook的基本思路是这样的,自己写一个替换的内核函数,以NtOpenProcess为例,就是MyNtOpenProcess.然后修改SSDT表,让系统服务进入自己的函数M ...

  9. ring0 与 ring3 层之间的交互

    在进行Windows的ring0层开发时,必不可免的要与 ring3 层进行交互.进行数据间的相互传输.可用的方法有DeviceIoCntrol,ReadFile.我平常都是用的DeviceIoCon ...

随机推荐

  1. GIL 线程池 进程池 同步 异步 阻塞 非阻塞

    1.GIL 是一个全局解释器锁,是一种互斥锁 为什么需要GIL锁:因为一个python.exe进程中只有一份解释器,如果这个进程开启了多个线程都要执行代码 多线程之间要竞争解释器,一旦竞争就有可能出现 ...

  2. Ubuntu 14.04下MySQL服务器和客户端的安装

    下面进行简单的配置 安装完成后通过修改/etc/mysql/my.cnf(此文件为mysql的配置文件).将文件中的binding-address=127.0.0.1注释掉.其它配置根据需要更改. H ...

  3. sql函数将1,2,3转换为表

    /****** Object: UserDefinedFunction [dbo].[splitstring_to_table] Script Date: 2017/7/11 9:35:58 **** ...

  4. java中所有开源注解收集

    @resource: resource全名为@Resource ,用来激活一个命名资源(namedresource)的依赖注入,在JavaEE应用程序中,该注解被典型地转换为绑定于JNDI conte ...

  5. 用sphinx-doc优雅的写文档

    Sphinx 是一个工具,它使得创建一个智能而美丽的文档变得简单.作者Georg Brandl,基于BSD许可证. 起初为写 Python 文档而诞生的 Sphinx,支持为各种语言生成软件开发文档. ...

  6. vue懒加载 路由 router 的编写(resolve)

    如果用import引入的话,当项目打包时路由里的所有component都会打包在一个js中,造成进入首页时,需要加载的内容过多,时间相对比较长.当你用require这种方式引入的时候,会将你的comp ...

  7. my30_表碎片整理

    确认表的类型与存储引擎,是否全部是innodb select TABLE_SCHEMA,TABLE_NAME,TABLE_TYPE,ENGINE,VERSION,ROW_FORMAT,TABLE_RO ...

  8. JavaSE---对象序列化

    1.对象序列化机制 允许把内存中的Java对象转换成平台无关的二进制流,从而可以将二进制流持久保存到磁盘 或 在网络中直接传输: (目的:使得对象可以脱离程序的运行而独立存在) package com ...

  9. Head First 设计模式笔记(模版方法模式)

    1.定义: 在一个方法中定义一个算法骨架,而将一些步骤延迟到子类中.模版方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤. 2.类图:  3.说明: 模版方法可以理解为一个方法里面包 ...

  10. [转]AngularJS+UI Router(1) 多步表单

    本文转自:https://www.zybuluo.com/dreamapplehappy/note/54448 多步表单的实现   在线demo演示地址https://rawgit.com/dream ...