windows系统中核心态R0和用户态R3之间的通信

权限级别

系统核心态指的是R0,用户态指的是R3,系统代码在核心态下运行,用户代码在用户态下运行。系统中一共有四个权限级别,R1和R2运行设备驱动,R0到R3权限依次降低,R0和R3的权限分别为最高和最低。从windows体系结构图可以看出在用户态可以调用的函数接口都在ntdll.dll中,在用户态运行的系统要控制系统时,或者要运行系统代码就必须取得R0权限。特级环图和windows 体系结构图如下所示:
特级环图
windows 体系结构图

进程内存

每一进程在运行前,系统都会为它分配4GB的私有内存,其中2G为内核内存,2G为用户内存。windows内存的逻辑地址分为两种:一种是段选择寄存器,另一种是偏移地址。进程在运行时就必然要涉及虚拟地址到物理地址的翻译,CPU在进行地址翻译时,先通过分段机制计算出一个虚拟地址,再通过页表机制将虚拟地址映射到物理地址,从而存取物理内存中的数据和指令。进程内存布局如下所示:
进程内存布局

R3和R0通信

windows分为应用层和内核层,当应用进程调用一个I/O的API时,那么这个api一定封装在某个dll库中,
但不管这个dll是什么,到最后都会调用ntdll中的native api函数。native api函数是成对出现的,分别以Nt和Zw开头。

当kernel.dll中的api调用ntdll.dll执行时,会完成参数的检查工作,再调用一个中断进入到内核态,在内核态中有一个SSDT(系统服务描述符表),它相当于一个数组,里面存放的是与ntdll.dll对应的SSDT系统服务处理函数,这些函数都是内核态下的函数,执行这些函数也意味着执行内核代码。

Nt*系列的api会直接调用对应的函数代码。而以ZW开头的API则通过KiSystemService跳转到对应的函数代码,这两种调用都会对内核中的previousMode产生改变,在用户模式下调用Native api,则还是用户模式,如果在内核模式下调用Native api,则为内核态。当previous为用户态时,将会对用户态传递过来的参数进行检查,而内核态不会。应用程序调用内核API的过程图如下所示:

应用程序调用内核API的过程

内核主要由各种驱动文件(*.sys)组成,这些驱动有的是系统自带的,有的是软件产商提供的,驱动加载之后,会生成对应的设备对象并可以向R3提供一个可供访问的和打开的符号链接,例如:“??\C:\”等。内核驱动执行了DriverEntry函数时,内核就可以接受R3发送过来的信息了。在内核驱动中有许多分发派遣函数来响应和应用层的的调用请求,每一个应用层负责I/O的API都对应一个内核中的分发派遣函数。驱动文件图和windows驱动框架模型如下所示:
驱动文件驱动文件
windows驱动框架模型

发布了30 篇原创文章 · 获赞 48 · 访问量 1106

猜你喜欢

转载自blog.csdn.net/qq_33526144/article/details/103503011