1初识内核

本文详细解释了Windows操作系统中内核层与应用层的区别,着重探讨了3环到0环的系统调用过程,如NTDLL的作用、sysenter指令的工作原理以及KiFastSystemCall和KiFastCallEntry在64位进程中的角色。文章揭示了决定权限的关键因素,如CS和SS寄存器在系统调用中的作用。
摘要由CSDN通过智能技术生成

内核(R0)与应用层(R3)的区别

在 Windows 操作系统中,应用层和内核层是两个不同的概念,它们分别指代操作系统的不同部分和功能。

应用层:

应用层是用户直接与之交互的部分,包括各种应用程序和用户界面。
这些应用程序可以是 Microsoft Office 套件、网页浏览器、媒体播放器、游戏等等。
应用层提供了用户友好的界面和功能,使用户能够进行各种任务和操作。
内核层:

内核层是操作系统的核心部分,负责管理计算机的硬件资源和提供各种系统服务。
内核层包括操作系统内核和相关的系统服务和驱动程序。
内核层控制着硬件资源的访问和分配,处理进程管理、内存管理、文件系统、设备驱动程序等核心功能。

区别:

功能:应用层主要提供用户界面和应用程序功能,而内核层则提供底层的系统管理和资源控制功能。
访问权限:应用层一般不能直接访问硬件资源,而内核层具有访问和控制硬件资源的权限。
层级关系:内核层处于更低的系统层级,控制着系统的底层资源和功能,而应用层处于更高的层级,向用户提供接口和功能。
用户接口:应用层提供了用户友好的界面,而内核层主要是系统级别的代码,不直接与用户交互。
在操作系统中,应用程序通过操作系统提供的API(应用程序接口)与内核进行通信,从而实现对系统资源的访问和控制。这种分层设计可以提高系统的稳定性、安全性和可维护性。

3环通往0环的大门NTDLL

在 Windows 系统中,Ring 3(用户态)的程序通常通过系统调用(System Call)的方式与内核态(Ring 0)进行交互,而 ntdll.dll 是一个非常重要的动态链接库,它包含了大量的系统调用函数的实现。通过调用 ntdll.dll 中的函数,用户空间的程序可以请求操作系统内核提供的服务和功能,从而间接地与内核态进行通信。

这种方式是一种标准的方式,因为直接在用户态调用内核态的函数是不安全的。ntdll.dll 提供了一个中间接口,允许用户空间的程序通过合法的系统调用来请求内核态的服务。这些系统调用会触发操作系统内核中相应的功能,以执行特定的操作。

因此,虽然用户空间的程序不能直接进入内核态,但通过 ntdll.dll 提供的接口,它们可以间接地向内核态发出请求,从而实现与内核态的通信和交互。

通过观察3环进程调用的windowsAPI观察它是如何进入0环的

在这里插入图片描述
在CloseHandle函数头部下断发现它内部调用了ntdll.ZwClose

在这里插入图片描述
F7跟进ntdll.ZwClose函数发现他将0x32放入eax寄存器然后给edx,赋值0x7FFE0300
Call了[edx]里面的地址 最后retn 0x4返回出去 这里可以发现 这段汇编代码上下都是很多类似的汇编代码段,它们除了给eax赋值相差1之外其他的操作都一样,

在这里插入图片描述

将程序运行到call [edx]地址处,OD提示 ntdll.KiFastSystemCall,也就是说用到ntdll的所有api最终都会调用ntdll.KiFastSystemCall这个函数

在这里插入图片描述
F7跟进,ntdll.KiFastSystemCall这个函数将esp赋值给edx,然后执行了sysenter最后retn返回

在这里插入图片描述
当F7执行sysenter之后程序跳到了zwClose函数的retn 0x4处 也就是说函数已经执行完毕没有执行ntdll.KiFastSystemCall的retn

sysenter

当用户空间程序执行 sysenter 指令时,CPU 将触发从用户态到内核态的切换。这个切换是通过硬件机制实现的,包括改变特权级别、改变栈等。

在切换到内核态之前,CPU 会将当前的用户态寄存器状态保存到用户态栈中,以便后续返回用户态时能够恢复。

在执行 sysenter 指令期间,通常会涉及修改以下几个寄存器:

EIP(Instruction Pointer)指令指针寄存器:sysenter 指令会将当前用户态的指令指针(EIP)保存到内核态堆栈中,并加载内核态的系统调用入口点的地址到 EIP 中,以便在内核态中执行相应的系统调用代码。

ESP(Stack Pointer)堆栈指针寄存器:sysenter 指令会将当前用户态的堆栈指针(ESP)保存到内核态堆栈中,并加载内核态的堆栈指针到 ESP 中,以确保在内核态中使用正确的堆栈。

CS(Code Segment)代码段寄存器:sysenter 指令会将内核代码段的选择子加载到 CS 寄存器中,以指示处理器在内核模式下执行的代码段。

SS(Stack Segment)堆栈段寄存器:根据您提供的信息,有时 sysenter 执行后会将 SS 寄存器的值修改为内核数据段的选择子(通常是 0x10),以确保在内核态执行时使用正确的堆栈段。

修改EIP
CPU 从 MSR 176寄存器(IA32_SYSENTER_EIP) 中读取系统调用服务例程的入口地址,并将 EIP 设置为该地址。此时,CPU 开始执行系统调用服务例程。

同时,CPU 将代码段选择子MSR 0x174(IA32_SYSENTER_CS) 中保存的值加载到 CS 寄存器中,以确保从正确的代码段中获取指令执行。这确保了在内核态下执行的指令是合法的
在执行 sysenter 指令后,处理器会自动从 IA32_SYSENTER_ESP 中读取内核态栈的地址,并将其加载到 ESP 寄存器中,以便在内核态下执行的指令和数据都能够正确地被管理。

总结,执行了sysenter指令后CPU将修改包括 ESP、CS 、SS和 EIP 寄存器,
在这里插入图片描述

查看MSR176

在这里插入图片描述
现在知道调用sysenter函数之后他转到nt!KiFastCallEntry内核函数来执行了,

KiFastCallEntry

将win70x86下C:\Windows\System32\ntoskrnl.exe拖进IDA查看KiFastCallEntry函数,
在这里插入图片描述
KiFastCallEntry函数中修改了 FS DS ES ESP Eflag 寄存器

X64系统下64位进程

在这里插入图片描述
直接查看64位进程中ntdll中的Zwclose可以看到它是调用SYSCALL指令进入内核层

SYSCALL

将 RIP 的值赋予 RCX:

在这一步,处理器将当前指令执行的地址(RIP)保存到 RCX 寄存器中。这个操作的目的是保存当前用户态代码的位置,以便在特权级别切换完成后返回用户态执行。

将 MSR_LSTAR 寄存器里的值赋予 RIP:

MSR_LSTAR 寄存器(0xC0000082)存储了内核的入口地址,通常指向 KiSystemCall64 函数,该函数是Windows内核中用于处理系统调用的入口点。
在进行特权级别切换时,处理器将 MSR_LSTAR 寄存器中的值加载到 RIP 寄存器中,从而使处理器开始执行内核态的代码。

将 RFLAGS 赋给 R11:

RFLAGS 寄存器存储了当前代码的状态标志,例如进位标志、零标志等。
在这一步,处理器将当前用户态代码的 RFLAGS 寄存器的值保存到 R11 寄存器中。这个值在后续恢复用户态时可能会用到。

将 MSR_FMASK 寄存器的值赋给 EFLAG:

MSR_FMASK 寄存器(0xC0000084)存储了标志寄存器中哪些标志位是可以修改的。
在这一步,处理器将 MSR_FMASK 寄存器的值加载到 EFLAG 寄存器中,可能是为了限制在内核态下的代码执行时的标志位的修改。

将 MSR_STAR 寄存器值的[32:47]的值赋给 CS 加 8 赋给 SS:

MSR_STAR 寄存器(0xC0000081)存储了特权级别切换的各种段选择子的值。
这一步将 MSR_STAR 寄存器值的[32:47](即内核代码段选择子)的值加载到 CS 寄存器
同时,MSR_STAR 寄存器值的[32:47]的值加载到 SS 寄存器中,并加上 8。

通过这些步骤,处理器完成了从用户态到内核态的特权级别切换,使得执行流程转移到了操作系统内核中,开始执行相应的系统调用服务。

执行syscall切换进内核后寄存器的状态
执行syscall切换进内核后寄存器的状态

KiSystemCall64

在这里插入图片描述
通过windbg读取MSR_LSTAR 寄存器(0xC0000082)寄存器得到地址就是KiSystemCall64的地址该函数是Windows内核中用于处理系统调用的入口点。

将内核文件放入IDA在这里插入图片描述
swapgs:swapgs指令是x86_64架构中的一条汇编指令,用于交换当前CPU的GS寄存器和内核的GS寄存器(通常指向内核线程信息块)。这个指令在特权级别切换时被用来保存当前用户态的GS寄存器的值,以便于在内核态恢复时能够正确地恢复GS寄存器的值。
在64位下GS 寄存器的作用就相当于32位下FS,它在应用层存放的也是线程环境快TEB,在执行swapgs指令后它存放了内核的线程信息块。

决定权限的关键因素

不管是32位还是64位 决定权限关键因素CS,SS寄存器。

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值