SSDT的hook浅析

摘要:
Hook无非是拦截进程,根据自己的需要进行替换、阻塞和释放!从理论上讲,你可以钩住r3,你必须钩住r0*Ntoskrnl。exe的NtOpenProcess才是真正的执行主体。根据上面OpenProcess的过程描述,在进入内核后,OpenProcess进入Ntoskrnl。exe的ZwOpenProcess函数根据该函数的索引,找到真正内核执行器Ntoskrnl的NtOpenProcess函数。exe,然后执行它。我说Ntoskrnl.exe的ZwOpenProcess函数有一个索引。根据索引,您可以找到真正的内核执行函数Ntoskrnl。exe的NtOpenProcess函数。让我们看看ZwOpenProcess并使用windg来查看它。计数!

 ***********关于hook**********************************

  首先我们说下hook,什么是hook?hook的英文已经说明了,hook在英文中是钩的意思,计算机取其意叫钩子,而我的理解叫

  大家应该写过r3下程序,估计也写过一些r3的hook,例如有一个API是OpenProcess,功能是打开进程得到进程句柄,比如我们要结束一个进程,如果调用TerminateProcess这个API来结束进程,就必须知道进程句柄。

  那么结束一个进程的伪代码就是这样

  push PID       

  push 0

  push 2035711 //权限

  call OpenProcess

  push 0

  push eax

  call TerminateProcess

  这段代码执行,如果正常的话,这个PID的进程应该就会被结束了,这里我们来设想一下,假设我们这里call openprocess做一下修改,变成这样,

   push PID       

  push 0

  push 2035711 //权限

  call myopen 

  push 0

  push eax

  call TerminateProcess

 

  myopen这里是我自己写的一个函数,这个函数跟OpenProcess一样,也有三个参数,也有相同的返回值类型。在这个函数里,我把三个参数,传递给真正的OpenProcess,而把OpenProcess的返回值,做为myopen的返回值,那么,这套流程下来,肯定也是可以执行的,myopen函数类似这样:

SSDT的hook浅析第1张

  有童鞋要问了,这样做执行是可以执行,但是何必费力做一个包装函数,再调用原函数,这样的意义是什么?

   现在这套流程下来非常正常,我们做的这个包装函数没有意义,现在我们假设,如果有一个恶意进程PID=9527,你写这个结束程序来结束这个PID=9527的进程,这个恶意进程却给你安装了这个包装函数。但是,他稍微的修改了下,变成这样:

  SSDT的hook浅析第2张

 嘿嘿,这样下来,会怎么样?你还能结束恶意进程吗?

 当然不能

 因为你如果打开PID为9527的进程时候,得不到正确的句柄返回值,返回值为0。

 这个方法,叫hook,我们也可以在OpenProcess的函数头进行hook。

 而我把这种方法,叫截,截获后,可阻止,可改变,可放行!hook,无非是截获流程,根据自己的需要替换,阻止,放行而已!

 r3层的r0层的hook原理一样,大道至简,现在很多驱动hook一上来就说内核,ssdt,弄的大家一头雾水,其实假传万卷书,真传一句话,驱动hook就是截获api在内核的执行流程,然后根据自己的需要替换,阻止,放行。 理论上你会r3的hook,你一定会r0的hook!

*********关于SSDT**********************************

  明白了HOOK原理后,那么内核hook就很简单了,只要我们在API函数执行流程走到内核后在内核流程中进行截断,处理,就是内核hook了

 我们在内核流程的位置选择了SSDT表,那么,SSDT表是什么?

 SSDT(System Services Descriptor Table),系统服务描述符表。这个表就是一个把ring3的Win32 API和ring0的内核API联系起来。SSDT并不仅仅只包含一个庞大的地址索引表,它还包含着一些其它有用的信息,诸如地址索引的基地址、服务函数个数等。

现在我们以OpenProcess来说明,看下SSDT表在函数执行流程中起的作用!

函数的执行流程以OpenProcess是这样.先说明,下面再解释

*r3 OpenProcess进入ntdll.dll的NtOpenProcess或ZwOpenProcess函数(反正是同一个地址)

*进入内核

*进入Ntoskrnl.exe的ZwOpenProcess

*根据ZwOpenProcess的索引,找到SSDT表对应的地址,再根据SSDT表对应地址的数据(Ntoskrnl.exe的NtOpenProcess),执行函数。

*也就是Ntoskrnl.exe的NtOpenProcess才是真正的执行主体

  

 根据上面OpenProcess的流程说明,进入内核后,OpenProcess是进入了Ntoskrnl.exe的ZwOpenProcess这个函数,根据这个函数的索引,在SSDT表查找到真正的内核执行体Ntoskrnl.exe的NtOpenProcess函数,然后执行。

 首先,我们先找到SSDT表,下面我们来看一个被内核导出的结构KeServiceDescriptorTable.

struct KeServiceDescriptorTable       
          SSDT表的指针 //这个指向系统服务函数地址表
          ServiceCounterTableBase;
          NumberOfService; //服务函数的个数
          TableBase
 end KeServiceDescriptorTable

这里第一个字段就是SSDT表的指针,我们用windbg看一下,先dd KeServiceDescriptorTable

SSDT的hook浅析第3张

第一个字段是80502b8c,这个就是SSDT表的地址了

 我们dd 80502b8c看看SSDT表

SSDT的hook浅析第4张

里面存放的都是一些NT函数地址。

之前说了Ntoskrnl.exe的ZwOpenProcess函数有个索引,根据索引在SSDT表里查找真正的内核执行体函数Ntoskrnl.exe的NtOpenProcess函数

我们看看ZwOpenProcess,用windbg查看,u nt!ZwOpenProcess

SSDT的hook浅析第5张

索引号是7Ah

那么Ntoskrnl.exe的NtOpenProcess函数应该存放的位置就是=80502b8ch(SSDT表的开始地址)+7Ah(索引)*4(每个函数的间隔),得到80502D74h

SSDT的hook浅析第6张

80502D74h处存放的地址是805C2296,这个应该是Ntoskrnl.exe的NtOpenProcess函数的地址,我们看下是不是

SSDT的hook浅析第7张

果然是的.

所以函数在由R3进R0后,要通过SSDT表的来选择最终执行的内核函数,假设我们想在内核中HOOKOpenProcess这个函数,只需要修改80502d74处存放的地址,放入我们自己写的newNtOpenProcess函数地址,在我们newNtOpenProcess函数中,进行了修改或替换或阻止或放行后执行真正的NtOpenProcess,这就是所谓的SSDThook

那么,我简单说下ssdt表中 hook OpenProcess这个函数步骤

1.先得到Ntoskrnl.exe的NtOpenProcess函数的地址(用MmGetSystemRoutineAddress函数得到内核导出函数地址)

2.再得到SSDT表中Ntoskrnl.exe的NtOpenProcess函数应该存放的位置

   (SSDT表的开始地址)+(索引)*4(每个函数的间隔)

     SSDT表的开始地址=[KeServiceDescriptorTable->SSDT表的指针]  

     索引=[Ntoskrnl.exe的zwOpenProcess地址+1]

3.自己建立一个新函数,参数和返回值要和Ntoskrnl.exe的NtOpenProcess函数一模一样

4.把自己的新函数地址写到SSDT表中我们算出来的存放位置处,(mov [(SSDT表的开始地址)+(索引)*4(每个函数的间隔)],新函数地址)

下面是部分重要代码:

SSDT的hook浅析第8张

SSDT的hook浅析第9张

SSDT的hook浅析第10张

SSDT的hook浅析第11张

执行效果如图:

 SSDT的hook浅析第12张

免责声明:文章转载自《SSDT的hook浅析》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇SpringBoot 页面国际化转化Linux系统下查找最近修改过的文件下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

随便看看

ArcGIS地图打印设置

业务流程是首先框定要打印的地图范围,这是一个自定义大小。选择帧后,预览帧,然后选择打印输出。在打印输出界面中设置后,HP绘图仪将打印地图。因此,确定该问题与ArcGIS无关,属于打印地图设置问题。...

未知账户(S1521)无法删除的问题

只有在“安全”中将所有者设置为当前管理用户后,才能删除此项。单击安全,单击高级,然后单击安全中的所有者以更改为系统的当前用户。...

[转载]su认证失败

我认为桌面用户拥有更高的安全性是合适的;但是,可以将服务器设置为允许“su”作为root用户,但不允许root用户直接登录。问题如下:1me@ubuntu:~$su2Password:˂---在安装过程中输入root用户的密码。3su:身份验证失败允许su root。这很简单。您只需要重置密码。...

Python生成pyd文件

Python的脚本文件是开源的,量化策略的安全性没有保障。那么要对Python代码进行混淆、加密保护。Python有py、pyc、pyw、pyo、pyd等文件格式。vcvarsall.bat是VC编译Python环境的文件之一。方案1:修改Python安装目录的文件设置方案2:修改注册表我采用方案1,亲测可用。测试结果,用py2exe可以正常使用pyd文件。...

js学习-es6实现枚举

最近,我大部分时间都在写dart,突然使用了js。我发现js不能直接声明枚举。目录枚举功能对象冻结()符号实现反映了不可更改值的唯一性。请注意,枚举特性枚举值不能重复,也不能修改。Switchcase可以直接判断对象。冻结()对象。方法可以冻结对象。无法更改实现constEnumSex=Object。冷冻枚举性别。人=1;安慰日志;//符号(男性)表示值co...

antd Tabs组件动态加载组件内容

Tabs的TabPane子组件不支持将属性传递给Component,并且官方示例的TabPane内容仅为简单文本。...