Windows内核实验 ——— API调用
前言
我们之前几次的实验大多都是通过设置自己的中断函数来完成一些简单的小东西,如赋值以及修改值等,如果需要实现某高级复杂功能时便需要我们进行调用API
来快速省心省力的完成。还是和之前一样,需要我们对系统中断表进行操作,获取到 Ring 0 的权限后进行调用。
实验过程
同样的我们还是先搭建出一个中断处理的模板
1 |
|
接下来我们便从此模板下手,尝试调用 Ring 0 的有关API函数,在此之前我们需要先了解一些关于 fs 段寄存器的东西。在 Ring 3 下 fs 段寄存器的值被设置为了0x3B
,指向的是,而在内核中设置为0x30
,在 Ring 3 下 fs 指向TEB表,而在 Ring 0 中指向的是GDT表的KPCR结构,通常从 Ring 3 进入到Ring 0 时是通过中断门以及程序入口_KiSystemService
进行完成的,其完成了push与pop的操作改变fs的值来进行切换,并保存了 Ring 3 的相关结构信息
1 |
|
通过上面的方式进行切换到 Ring 0 后,我们开启中断,尝试进行对 Ring 0 的 API 进行调用,调用完后我们使用以下代码再将 fs 设置为 Ring 3 下的0x3B
1 |
|
通过上面的操作我们已经完成了从零环到三环之间的转换,我们此处尝试调用内核的内存分配函数来完成此次实验,我们使用函数指针来进行获取到对应的函数地址处理,通过这种方式来进行调用
代码如下:
1 |
|
有点奇怪的是我们运行起来上面的代码时返回的地址处的内存没有被初始化,仍然有一些数据
通过 Windbg 进行查看内存
我们尝试修改一下
发现可以被修改,当释放断点后继续运行程序时可以发现并没有蓝屏,此处猜测可能是跟 CPU Cache 有关系了,需要刷新 TLB 了
总结
此次实验中我们简单的创建了一个零环到三环的转换过程,通过一个函数指针进行获取对应的函数地址,我们通过指针来进行调用对应API接口。
或者可以使用WDM.h
中的ExAllocatePool
来进行内存的分配,但是使用该头文件需要配置WDK,搭建相关驱动环境。
但是实验中我们创建的环境切换理论上并不安全,因为我们在期间开启了中断
1 |
|
如果我们在pop
返回三环之后但在中断返回前遇到中断时便会导致系统出现蓝屏,但是因为计算机执行指令的速度十分的快,我们遇到中断的概率十分的低。处于安全性考虑我们需要在其前面加入cli
进行关闭中断,对于上述操作我们同样可以在_KiServiceExit
(零环退出函数)中看到