首页
社区
课程
招聘
[原创]SSDT-HOOK
发表于: 2019-4-17 10:19 17333

[原创]SSDT-HOOK

2019-4-17 10:19
17333

实验环境:win7虚拟机
示例是对内核层进行SSDT-HOOK实现保护进程的功能

一会儿会用到的API是OpenProcess,在3环也就是用户层调用此API它保存一些信息传入到0环内核层后实际调用的是ZwOpenProcess函数,所以先使用OD随意打开一个.exe可执行程序,然后在kernel32模块里面查找OpenProcess函数,经过2个jmp后进入下一层,找到一个call进入其中便是ZwOpenProcess的调用。

下面调用API代码才是我们需要注意的,每个API函数调用时在进入关键函数之前有一句汇编代码mov eax,0xXX,这是用eax保存一个调用号。

在进入内核层后,而每个调用号对应一个内核函数,为此Windows设计了一张表通过调用号作为序号,就能找到函数的地址。
Windows内核把这张函数地址表称为 : 系统服务描述表(System Service Descriptor Table ) 简称SSDT

例如根据之前截图知在调用ZwOpenProcess时调用号就是0xbe,那么我们如果通过调用号找到了函数地址,把这个地址替换成我们自己的函数,这样就能完成HOOK,类似于3环的IAT-HOOK。

在Windows内核中设计了两张系统服务描述符表,一张表是上述所说的SSDT,它只保存非用户界面相关的系统服务(例如创建文件、创建进程等);另一张表称为ShadowSSDT,它专门用于保存和用户界面相关的服务(例如创建窗口等),这两张表在内核中都使用了同一个结构体的表示:

但实际上系统共有4个系统服务描述符,其中2个就是上述的2张表,另外2个没有被使用,可能是留着将来备用的。他们用如下结构体表示:

进入0环时调用号是eax传递的,但这个调用号并不只是一个普通的数字作为索引序号,系统会把他用32位数据表示,拆分成19:1:12的格式,如下:

分析一下0-11这低12位组成一个真正的索引号,第12位表示服务表号,13-31位没有使用。
而进入内核后调用哪一张表,就由调用号中的第12位决定,为0则调用SSDT表,为1则调用ShadowSSDT表。

想要对SSDT表进行HOOK,首先要找到SSDT表,可以通过服务表找到它,服务表存在于KTHREAD结构体的偏移为0xbc的一个字段中,可双机调试使用windbg查看,输入dt _kthread,然后再找到偏移为0xbc的字段

还是要说明一点KTHREAD这个结构体是未文档化的,所以里面的数据随着系统版本的不同各个字段偏移就有可能不同,所以使用前最好用windbg确认下所需要的字段偏移。

使用PsGetCurrentThread()函数可获取当前KTHREAD的首地址。
但是需要注意的是SSDT表所在的内存页属性是只读,没有写入的权限,所以需要把该地址设置为可写入,这样才能写入自己的函数。
我使用的是CR0寄存器关闭只读属性
简单介绍下CR0寄存器:

可以看到这里使用32位寄存器,而在CR0寄存器中,我们重点关注的是3个标志位:
PE ­ 是否启用保护模式,置1则启用。
PG ­ 是否使用分页模式, 置1则开启分页模式, 此标志置1时, PE 标志也必须置1,否则CPU报异常。
WP ­ WP为1 时, 不能修改只读的内存页 , WP为0 时, 可以修改只读的内存页。

所以在进行HOOK时,只要把CR0寄存器中的WP位置为0,就能对内存进行写入操作。
操作代码如下

当然使用完成后要把只读保护属性还回去,不然会引发不可预料的严重后果

有了以上分析的基础那么现在就可以写安装内核钩子的代码了:

看一下自己写的MyZwOpenProcess函数,通过对比PID找到要保护的进程,并且是以结束进程权限PROCESS_TERMINATE(0x1)访问时,则修改权限为0使其无法访问。就达到了保护进程的目的。

生成.sys文件后使用工具安装驱动服务,然后打开任务管理器,关闭被保护的进程,就可以看到拒绝访问,到此保护进程就成功了。在这主要描述了SSDT-HOOK,HOOK的功能就可以去任意发挥了。


[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

最后于 2019-4-17 11:04 被九阳道人编辑 ,原因: 上传图片
收藏
免费 10
支持
分享
最新回复 (19)
雪    币: 26205
活跃值: (63302)
能力值: (RANK:135 )
在线值:
发帖
回帖
粉丝
2
图片没有传上去,麻烦楼主重新传一下图片哦~
2019-4-17 10:50
0
雪    币: 8
活跃值: (104)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
我觉得吧 SSDT这种帖子够多了 都快成月经帖了 就不发了呗 发点论坛没有的呀!
2019-4-17 12:43
0
雪    币: 914
活跃值: (2468)
能力值: ( LV5,RANK:68 )
在线值:
发帖
回帖
粉丝
4
好一把洛阳铲
2019-4-18 11:04
0
雪    币: 73
活跃值: (923)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
搞点X64的研究呗
2019-4-19 20:59
0
雪    币: 6124
活跃值: (4661)
能力值: ( LV6,RANK:80 )
在线值:
发帖
回帖
粉丝
6
好深的洛阳铲
2019-4-19 21:06
0
雪    币: 57
活跃值: (2433)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
7
码了有空看
2019-4-19 22:20
0
雪    币: 355
活跃值: (15)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
8
好一把洛阳铲
2019-4-26 14:42
0
雪    币: 43
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
9
看的喝了一瓶咖啡
2019-4-29 10:50
0
雪    币: 584
活跃值: (171)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
学习
2019-4-29 14:44
0
雪    币: 498
活跃值: (2324)
能力值: ( LV12,RANK:356 )
在线值:
发帖
回帖
粉丝
11
楼主加油啊,总有大佬在鄙视我们这些小白
2019-5-3 18:38
1
雪    币: 221
活跃值: (82)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
应该成立个windows技术考古研究所
2019-5-4 19:55
0
雪    币: 2428
活跃值: (159)
能力值: ( LV11,RANK:198 )
在线值:
发帖
回帖
粉丝
13
x64的可以搞吗?
2019-5-19 21:50
0
雪    币: 4
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
你好请问代码生成sys成功后加载驱动报创建句柄失败是什么意思吗?
2019-7-17 15:08
0
雪    币: 5492
活跃值: (1740)
能力值: ( LV2,RANK:150 )
在线值:
发帖
回帖
粉丝
15
在虚拟机中测试内核程序,需要先启动服务,然后才能加载驱动,网上有很多这方面相关代码的,你随便找一份就行了
2019-7-18 21:01
0
雪    币: 13
活跃值: (91)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
mark一下
2019-7-21 20:48
0
雪    币: 190
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
17
感谢楼主,这都是基础知识
2020-5-28 19:46
0
雪    币: 5
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
18
vs2019编译的时候一直提示无法解析的外部符号 __imp_KeServiceDescriptorTable
2020-7-10 14:44
0
雪    币: 5
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
19
mb_qimwvxnv vs2019编译的时候一直提示无法解析的外部符号 __imp_KeServiceDescriptorTable
知道什么问题了 这个只能用于32位 64位不行
2020-7-11 13:43
0
雪    币: 606
活跃值: (1469)
能力值: ( LV3,RANK:35 )
在线值:
发帖
回帖
粉丝
20
mark
2022-8-26 11:31
0
游客
登录 | 注册 方可回帖
返回
//