Windows驱动学习(八)-- 通过InlineHook实现变速齿轮

版权声明: https://blog.csdn.net/m0_37552052/article/details/85720484

教程参考自:https://www.bilibili.com/video/av26193169/?p=9
代码地址:https://github.com/G4rb3n/Windows-Driver/tree/master/MT_InlineHook

1. 概述

之前的章节我们介绍了FSD Hook技术,这章我们来讲解一下更底层一点的Inline Hook技术。

2. 原理介绍

Inline Hook直接修改内存中任意函数的代码,将其劫持至Hook API。它的目标是系统函数,如下,第一张图是Hook之前的状态,procexp.exe进程调用ZwQuerySystemInformation()函数时,ZwQuerySystemInformation()的代码是正常的代码。第二张图是Hook后的状态,注意红框中的代码,ZwQuerySystemInformation()函数开头5个字节已被修改,变成了jmp 0x10001120,也就是我们恶意代码的地址,之后便可以开始我们的自定义操作。0x1000116A我们先进行unhook操作(脱钩),目的是将ZwQuerySystemInformation()的代码恢复。大家可能有疑惑,为什么刚修改完又要恢复回来,原因很简单,Hook的目的是当调用某个函数时,我们能劫持进程的执行流。现在我们已经劫持了进程的执行流,便可以恢复ZwQuerySystemInformation()的代码,以便我们的恶意代码可以正常调用ZwQuerySystemInformation()。执行完恶意代码后,再次挂钩,监控该函数。

1

2

3. 驱动编写

3.1 驱动入口函数

代码的原理很简单,首先获取KeUpdateSystemTime和KeQueryPerformanceCounter的地址,然后将前5个字节替换成“jmp [hook addr]”的字节码,值得注意的是,这里的hook addr应该是hook函数和被hook函数的地址差值。
3

因为执行完hook函数后还要跳回执行原函数(KeUpdateSystemTime、KeQueryPerformanceCounter),所以在修改字节码前要先保存原函数的字节码,到底要保存几个字节码呢?这就要看函数的开头了,不过至少要大于5个,因为那样我们的“jmp [hook addr]”字节码才放得下。

扫描二维码关注公众号,回复: 4841183 查看本文章

使用VS调试驱动,查看原函数的结构,来决定要保存几个字节码。但在这之前,我发现一个奇怪的现象,使用MmGetSystemRoutineAddress(“KeUpdateSystemTime”)获取到的函数地址居然是KeUpdateSystemTimeAssist函数的地址,我也不知道这是什么原因,只有微软才知道。。那我们就将错就错,获取KeUpdateSystemTimeAssist函数的结构呗。
4

该函数的开头是连着的7个字节,所以我们应该保存它的7个字节。
5

同理调试KeQueryPerformanceCounter,查看其函数结构。
6

这个函数我们应该替换前5字节。
7

后面,将保存的字节码写入跳转函数(updatetimeOriginCode、querycounterOriginCode)就行了。

3.2 fakeupdatetimeAddr函数

fakeupdatetimeAddr函数是KeUpdateSystemTime的hook函数,它先修改KeUpdateSystemTime的速度参数,然后调用原函数“KeUpdateSystemTime”。
8

3.3 updatetimeOriginCode函数

前面的nop是用来被替换为原函数的7个字节的,执行完该7个字节后跳转回KeUpdateSystemTime函数执行剩下的字节码。
9

3.4 fakequerycounterAddr函数

fakequerycounterAddr函数是KeQueryPerformanceCounter的hook函数,跟fakeupdatetimeAddr不一样,它是先调用原函数“KeQueryPerformanceCounter”,然后修改其返回值,实现变速。
10

3.5 querycounterOriginCode函数

前面的nop是用来被替换为原函数的5个字节的,执行完该5个字节后跳转回KeQueryPerformanceCounter函数执行剩下的字节码。
11

3.6 WPOFF函数

cr0寄存器是用来存储当前进程的内存属性的,这里的代码功能为从cr0获取内存属性值,修改,然后赋值回去。
12

3.7 WPON函数

WPON的代码功能则跟WPOFF相反。
13

3.8 卸载函数

14

4. 驱动测试

加载该驱动后,系统时钟变快了。
15

猜你喜欢

转载自blog.csdn.net/m0_37552052/article/details/85720484
今日推荐