SSDT获取原始服务地址的方法与原理(灯灯灯灯,我肥来了..)

    好吧,我胡汉三肥来了..(确实肥了- -),几个月没发什么文章.其实.我也只是一个新丁~欢迎大家交流,高手勿喷,谢谢合作^_^

    对于SSDT,不知道的同学请自己百度,判断出SSDT被HOOK之后,如何恢复成原始服务地址?主要方法有两个,简单来说,一个Ring0,一个Ring3的方法(可能分类不够准确),我今天除了介绍方法之外,主要还是讲讲里面的原理吧,原理神马的才是最吸引人的对吧.

    首先科普一下基础,SSDT,就是System Service Descriptor Table,在内核中导出符号为KeServiceDescriptorTable.对于Ring3下的一些API,最终会对应于Ntdll.dll里一个Ntxxx的函数,例如CreateFile,最终调用到Ntdll.dll里的NtCreateFile这个函数,NtCreateFile最终将系统服务号放入EAX,然后CALL系统的7FFE0300处存放的一个地址(后面细说),进入到内核当中,从Ring3->Ring0,最终在Ring0当中通过传入的EAX得到对应的同名系统服务的内核地址.这样就完成了一次系统服务的调用.下面的图是ntdll!NtCreateFile的反汇编片段:


    可以看到,NtCreateFile传入的服务号是25h,对于7FFE0300h处,实际上是UserShareData!SystemCallStub,这是一个函数指针,里面存放的值可能是KiIntSystemCall或者是KiFastSystemCall的地址,在我的Xp下,存放的是KiFastSystemCall的地址,之后的流程是:KiFastSystemCall->sysenter->KiFastCallEntry->查找SSDT,call过去.有兴趣的同学可以在WRK当中搜索相关的函数去走一下流程.

    说了那么多不相关的话- -,好吧,这个SSDT的表这么理解(如果你硬是要纠结于细节的话,是KeServiceDescriptorTable->Base这个表),就是一个存放着函数指针的表,而这些函数指针指向的就是系统重要的服务例程.这个表的重要性很高,如果说有恶意的程序对这个表进行了HOOK,修改了服务例程地址为自己提供的假服务例程,那么就可以干一些坏事了.我们可以很容易的得到SSDT的具体内容,如何知道SSDT有没有被Hook,一个简单的方法就是判断SSDT中的函数指针是否是在内核(ntoskrnl.exe或ntkrnlpa.exe)的内存镜像地址范围内,这个只是单纯的检测,具体恢复需要知道原始的服务例程的原始地址.我一开始以自己很傻很天真的思路想,内核获取函数地址不就是用MmGetSystemRoutineAddress么,那么这样就可以得到原始地址了嘛,结果实现了一下发现,你妹的MmGetSystemRoutineAddress只对导出的函数(输出目录当中的函数有用),我当时就凌乱了..痛苦的把脸转向一边...

    对于KeServiceDescriptorTable是在KiInitSystem中初始化,代码如下:


    具体是通过KiServiceTable初始化的,KiServiceTable的具体内容通过反汇编内核,我这里是ntkrnlpa.exe,如下:


    可以看到,KiServiceTabl

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值