zoukankan      html  css  js  c++  java
  • ring0 SSDTHook

    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

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

  • 相关阅读:
    java拦截器与过滤器打印请求url与参数
    mybatis学习笔记(六)使用generator生成mybatis基础配置代码和目录结构
    【IDEA】IDEA创建Maven的Web项目并运行以及打包
    【环境变量】Linux 下三种方式设置环境变量与获取环境变量
    【Git】GitHub的SSH提交配置[
    spring配置redis注解缓存
    【查看linux配置】查看linux系统常用的命令,Linux查看系统配置常用命令
    Redis集群
    linux中wget 、apt-get、yum rpm区别
    spring+redis的集成,redis做缓存
  • 原文地址:https://www.cnblogs.com/HsinTsao/p/7427752.html
Copyright © 2011-2022 走看看