前面的博文已经讲了windoows内核的构成,内核模块ntoskrnl.exe,包含两个部分:执行体和内核(或微内核);其中执行体是内核模块的上层部分,对于执行体,要从以下三个角度讨论,才可以深入了解执行体,即导出函数、执行体部件、主要支持函数。
从内核结构图上,可以看出执行体由下面图所示的红线圈出的部分构成:
一、导出函数
最上面的执行体API,为应用程序的调用提供调用导出函数:
- 被导出的、可在用户模式下调用函数。对这些函数的调用接口位于ntdll.dll模块中,应用程序通过windowsAPI来间接地调用这些函数。
- 已经被导出并且可在用户模式下调用的函数,但无法通过任何一个windows API来调用的函数。这样的例子包括LPC(Local Procedure Call,本地过程调用)函数、各种查询函数(如NtQueryInfomation),以及一些专用函数,如NtCreatePageingFile等。对这些函数的调用需要直接链接ntdll.dll来完成。
- 只能在内核模式下调用的导出函数,并且在windowsDDK中关于这些函数的文档,这些函数可以被设备驱动调用。
- 供执行体之间相互调用,但未被文档化的函数,这些函数包括执行体内部使用的一组支持函数。
- 属于一个组件的内部函数。
二、包含组件
在大的方面看,执行体包含以下组件:
- 进程和线程管理器,负责创建进程和线程,以及终止进程和线程。对于进程和线程的底层支持是在内核层中提供的,执行体在内核层的基础上又添加了一些语义和功能。
- 内存管理器。此组件提供了虚拟内存功能,既负责系统地址空间的内存管理,又为每个进程提供了一个私有的地址空间,并且也支持进程间的内存共享。
- 安全引用监视器,该组件强制在本地计算机上实施安全策略,守护操作系统的资源,执行对象的保护和审计。
- I/O管理器。实现与设备无关的输入和输出功能,负责将I/O请求分发给争取的设备驱动程序以便进一步处理。
- 缓存管理器。为文件系统提供统一的数据缓存执行,允许文件系统驱动程序将磁盘上的数据映射到内存中,并通过内存管理器来协调物理内存的分配。
- 配置管理器。负责系统注册表的实现和管理。
- 即插即用管理器。负责列举设备,并为每个列举到的设备确定哪些驱动程序是必须的,然后加载并初始化这些驱动程序。当它检测到系统中的设备变化时,负责发送合适的事件通知。
- 电源管理器。负责协调电源事件,向设备驱动程序发送电源I/O通知。
三、支持函数
第三部分是执行体包含的4组主要支持函数,供以上这些执行体组件调用。差不多有三分之一的支持函数可以在windowsDDK有相应的文档说明,因为在设备驱动程序中也要调用它们,这四类如下:
- 对象管理器:它负责创建、管理和删除windows执行体对象,以及用于表达操作系统资源的抽象数据类型,比如进程、线程和各种同步对象。
- LPC设施:LPC设施负责在同一台机器上的客户进程和服务进程之间的消息传递,LPC是RPC(Remote Procedure Call,远程过程调用,关于网络客户进程和服务器进程之间的通信工业标准)的一个优化版本。
- 运行时库函数:其功能广泛,涵盖字符串处理、算术运算、数据类型转换以及安全结构处理等。
- 执行体支持例程:如系统内存分配(换页内存池和非换页内存池)、互锁的内存访问,以及对两种特殊类型的同步对象(资源和互斥体)的支持。
总之,实际执行体就是负责了整个操作系统对外的功能。我们的应用程序更多的时候是和执行体打交道。