文章目录
- 需求和设计目标
- 总体结构
- 可移植性
- 对称多处理
- 可伸缩性
- 关键的系统组件
- Windows子系统
- Ntdll.dll
- 执行体
- 内核
- 硬件支持
- 硬件抽象层HAL
- 设备驱动程序
- Windows驱动程序模型
- 执行体组件常用的绝大多数函数名前缀
- 系统进程
- 空闲进程
- 中断和DPC
- System进程和系统线程
- 会话管理器
- Winlogon、LSASS和Userinit
- 服务控制管理器
需求和设计目标
扩展性
可移植性
可靠性和健壮性
兼容性
性能
总体结构
四种基本的用户模式描述如下:
固定的(或硬性指定的)系统支持进程:不是由服务控制管理器启动的,非Windows服务,如登录进程和会话管理器
服务进程:Windows服务的运行通常要独立于用户登录
用户应用程序:有6种类型:32位、64位等
环境子系统服务器进程:实现了操作系统环境得到支持部分。这里的环境指的是:操作系统展示给用户或程序员的个性化部分。
在Windows下,用户应用程序并不直接调用原始的Windows操作系统服务,相反它们通过一个或者多个子系统动态链接库(DLL)来发起调用。
Windows的内核模式组件包括:
Windows执行体:包含了基本的操作系统服务
Windows内核:由一组低层次的操作系统功能构成
设备驱动程序:包括硬件设备驱动程序,也包括文件系统和网络驱动程序
硬件抽象层(HAL):一层特殊的代码,把内核、设备驱动程序和Windows执行体的其余部分,跟与平台相关的硬件差异隔离开来
窗口和图形系统:实现了图形用户界面函数
可移植性
Windows主要通过以下两种方法实现可移植性,以支持多种硬件体系结构和平台。
Windows的分层设计:系统的底层部分是与处理器体系结构相关的,或者是与平台相关的,这些部分被隔离到独立的模块中,因此系统的高层部分可以不考虑系统结构之间的差异,也不用关心硬件平台上的差异。内核和硬件抽象层为操作系统提供了可移植性的可能。
Windows的绝大部分代码是C语言编写的,少部分是C++编写的。
对称多处理
多任务:在多个执行线程之间共享同一个处理器的操作系统技术。Windows是一个对称多处理(SMP)操作系统。在这些处理器中没有主处理器——操作系统和用户线程可以被调度到任何一个处理器上运行。而且所有的处理器共享唯一的内存空间。
非对称多处理(ASMP)的不同:在一个典型的非对称多处理系统中,操作系统选择其中一个处理器来执行操作系统内核代码,而其他的处理器只运行用户代码。
超线程: 是Intel引入的一项技术,可以在一个物理处理器上提供多个逻辑处理器。每个逻辑处理器都有它自己的CPU状态,但是执行引擎和芯片上的高速缓存则是共享的。
可伸缩性
以下特性对Windows作为一个成功的多处理器系统起到了至关重要的作用:
1)能够在任何一个可用的处理器上运行操作系统代码,也可以同时在多个处理器上运行系统代码
2)在单个进程内执行多个线程,这些线程可以在不同的处理器上并行地执行
3)内核内部以及设备驱动程序和服务器进程内部的细粒度同步,使得多个组件可以并行在多个处理器上运行
4)诸如I/O完成端口之类的编程机制,使得可以实现高效的多线程服务器进程,并且这样的程序在多处理器系统上有很好的伸缩性
关键的系统组件
子系统启动信息被保存在注册表键HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\SubSystems的下面
Required值列出了当系统引导时加载的子系统,该值有2个字符串:Windows和Debug。Windows值包含了Windows子系统的文件规范,Csrss.exe代表了客户/服务器运行时子系统,Windows子系统进程之所以被称为Csrss.exe是因为在Windows NT的原始设计中,所有的子系统都位于全局唯一的环境子系统进程中,作为该进程中的线程来执行。Debug值是空的,因为只是内部测试使用。Optional值表明了OS/2和POSIX子系统将被按需启动。注册表值Kmode包含了Windows子系统的内核模式部分的文件名Win32k.sys。
环境子系统的角色是:将Windows基本系统服务的部分子集暴露给应用程序。每个子系统都提供了对于Windows原生服务不同部分的访问能力。
每一个可执行的映像被绑定到一个(且是唯一的)子系统上。当一个映像文件被运行时创建进程的代码会检查映像头部的子系统类型代码,所以它可以通知正确的子系统,有新的进程被创建了。
当一个应用程序调用子系统DLL中的某个函数时,可能发现:
1)该函数完全是在该子系统DLL中实现的,在用户模式下运行,因此运行的结果是被返回给调用者的
2)该函数要求调用Windows执行体一次或者多次
3)该函数要求在环境子系统进程中完成某些工作
Windows子系统
Windows子系统是由以下几个主要的组件构成:环境子系统进程Csrss.exe、内核模式设备驱动程序Win32k.sys、子系统DLL、图形设备驱动程序。
环境子系统进程Csrss.exe包含以下支持:
1)控制台(文本)窗口
2)创建或删除进程和线程
3)对16位虚拟DOS机(VDM)进程的一部分支持
4)其他一些函数以及几个自然语言支持函数
内核模式设备驱动程序:
1)窗口管理器:控制窗口提示,管理屏幕输出,采集来自键盘、鼠标和其他设备的输入,同时也负责将用户的消息传递传递给应用程序
2)图形设备接口GDI:专门针对图形输出设备的函数库,其中包含线、文本和图形的绘制函数、以及绘图控制函数
子系统DLL:已经文档化的Windows API函数,翻译成Ntoskrnl.exe和Win32k.sys中恰当的且绝大多数未文档化内核模式系统服务调用
图形设备驱动程序:指与硬件相关的图形显示器驱动程序、打印机驱动程序和视频微端口驱动程序。
Ntdll.dll
Ntdll.dll是一个特殊的系统支持库,主要是用于子系统DLL。包含两种类型的函数:
1)系统服务分发存根,会调用Windows执行体系统服务
2)内部支持函数,供子系统、子系统DLL以及其他的原生映像文件使用
执行体
Windows执行体是Ntoskrnl.exe中的上层。执行体包含以下类型的函数:
——可在用户模式下调用的导出函数,这些函数称为系统服务,并且通过Ntdll被导出
——可通过DevieIoControl函数来调用的设备驱动器函数
——只能在内核模式下调用的导出函数,并且这些函数在Windows DDK或者Windows IFS Kit中已经文档化
——在内核模式下调用,但未在Windows DDK或IFS Kit中文档化的导出函数
——定义为全局符号但是未被导出的函数
——未定义为全局符号,而是在一个模块内部的函数
执行体包含了以下主要组件:
——配置管理器:负责系统注册表的实现和管理
——进程和线程管理器:创建或终止进程和线程。针对进程和线程的底层支持是在Windows的内核中实现:而执行体则在这些底层对象的基础上又加上了附加的语义和功能
——安全引用监视器SRM:强制在本地计算机上实行安全策略,守护着操作系统的资源,执行对运行时对象的保护和审计
——I/O管理器:实现了与设备无关的I/O操作,负责将这些操作分派到恰当的设备驱动程序以供进一步处理
——即插即用(PnP)管理器:任务是支持一个特定的设备,确定哪些驱动程序时必需的,同时也负责加载这些驱动程序
——电源管理器:负责协调电源事件,并且向设备驱动程序产生电源管理I/O通知
——WDM Windows管理规范例程:允许设备驱动程序可以发布有关性能和配置的信息,以及接收来自用户模式WMI服务的命令
——高速缓存管理器:提高了以文件为基础的I/O操作的性能(做法是:让最近引用过的磁盘数据驻留在主内存中以便快速访问)
——内存管理器:实现了虚拟内存。是一个内存管理方案:为每个进程提供了一个巨大的私有地址空间,其数量可以大大超过当前可用的物理内存
——逻辑预取器:加速系统和进程的启动过程。对于要在系统或进程启动过程中引用的数据,它优化了这些数据的加载过程
Windows执行体还包含四组主要的支持函数:
——对象管理器:它创建、管理和删除Windows执行体对象和抽象数据类型
——LPC设施:在同一台机器上的客户进程和服务器进程之间传递信息。LPC是RPC(远过程调用)的一个更加灵活的优化版本。RPC:指跨网络的客户进程和服务器进程之间的通信设施工业标准。
——一组涉及范围广泛的公共运行库函数
——执行体支持例程
内核
内核是由Ntoskrnl.exe中的一组函数以及对于硬件体系结构的底层支持构成的。
内核对象:帮助内核控制好中心处理过程,并且支持执行体对象的创建工作。
控制对象的内核对象建立了有关控制各种操作系统功能的语义,包括APC对象、DPC(延迟过程调用)对象,以及I/O管理器使用的一些对象。
分发器对象的内核对象融合了同步的能力,它们改变或者影响了线程的调度。分发器对象包括内核线程、互斥体(内部称为突变体)、事件、内核事件对、信号量、定时器,以及可等待的定时器
硬件支持
内核的另一个主要任务是将执行体和设备驱动程序从Windows所支持的各种硬件体系结构中抽象出来,或者隔离出这些变种之间的差异。包括要处理各种功能方面的变化情况。
硬件抽象层HAL
HAL是一个可加载的、内核模式的模块,提供了针对Windows当前运行所在的硬件平台的底层接口。隐藏了与硬件相关的细节以及多处理器通信机制——任何与体系结构相关或者与机器相关的功能。
设备驱动程序
设备驱动程序是可加载的内核模式模块(通常以.sys结尾),它们在I/O管理器和相应的硬件之间建立起链接。设备驱动程序运行在内核模式下,位于以下三种执行环境之一:
1)在发起I/O功能的用户线程的环境中
2)在内核模式系统线程的环境中
3)作为一个中断的结果(因此它不在任何特定的进程或者线程的执行环境中)
设备驱动程序有以下六种类型:
——硬件设备驱动程序:通过HAL操纵硬件,从而将输出写到物理设备或网络中,或者从物理设备或网络上接收输入
——文件系统驱动程序:是指可以接受面向文件的I/O请求,并且将这些请求转换成针对某一特定设备的I/O请求
——文件系统过滤器驱动程序
——网络重定向器和服务器:分别是指那些将文件系统I/O请求传递给网络上某一台机器,或者从网络上接收此类请求的文件系统驱动程序
——协议驱动程序:实现了一些协议相关的驱动程序
——内核流式过滤器驱动程序:驱动程序被串接起来,以便对数据流进行信号处理
若想在系统中添加用户编写的内核模式代码,安装驱动程序是唯一的方法。
Windows驱动程序模型
从WDM(Windows Driver Model)看有以下三种驱动程序:
——总线型驱动程序:为总线控制器、适配器、桥或任何带有子设备的设备提供服务。总线驱动程序是必需的驱动程序,通常Miscrosoft会提供此类驱动程序;系统中的每一种总线类型都有一个总线驱动程序。
——功能型驱动程序:是主要的设备驱动程序,为相应设备提供了可操作的接口。功能型驱动程序也是必需的,除非相应的设备可以直接使用。根据定义功能型驱动程序最了解某一特定的设备,而且它往往是唯一能访问与该设备相关的寄存器的驱动程序。
——过滤性驱动程序:用来为某一设备(或已有的驱动程序)增加新的功能,或者修改来自其他设备的I/O请求或应答。过滤性驱动程序是可选的,可以有任意数目,可以放在一个功能型驱动程序之上或之下,也可以放在总线型驱动程序之上。
在WDM驱动程序环境中,对于一个设备而言并不是由单个驱动程序来控制它的所有方面。在大多数情况下,低层次的过滤型驱动程序改变设备硬件的行为。上层的过滤型驱动程序通常为一个设备提供一些增值特性。
查看已安装的设备驱动程序方法:
1)运行——Msinfo32,回车——打开“系统信息”程序——“软件环境”项——“系统驱动程序”,如下:
设备驱动程序的定义位置和Windows服务进程的位置是一样的:HKLM\SYSTEM\CurrentControlSet\Services
type值为1表示是设备驱动程序。
2)使用Drivers工具
执行体组件常用的绝大多数函数名前缀
——每个都会使用前缀的变形形式——前缀的第一个字母后面跟一个i(代表internal即内部的),或者整个前缀后面跟一个p(private私有的)来标记内部函数
常用的前缀有:
前缀 | 组件 |
---|---|
Cc | 高速缓存管理器Cache Manager |
Cm | 配置管理器Configuration manager |
Ex | 执行体支持例程Executive support routines |
FsRtl | 文件系统驱动程序运行库File system driver run-time library |
Hal | 硬件抽象层Hardware abstraction layer |
Io | I/O管理器 I/O manager |
Ke | 内核Kernel |
Lpc | 本地过程调用 Local procedure call |
Lsa | 本地安全认证Local Security Authority |
Mm | 内存管理器 Memory manager |
Nt | Windows系统服务 Windows system services |
Ob | 对象管理器Object manager |
Po | 电源管理器Power Manager |
Pp | PnP管理器 PnP manager |
Ps | 进程支持Process support |
Rtl | 运行库Run-time library |
Se | 安全性 Security |
Wmi | Windows管理规范 Windows Management Instrumentation |
Zw | 以Nt开头的系统服务入口点的镜像,把原先的访问模式设置为内核模式,从而消除参数的有效性检查过程,因为Nt系统服务只有当原来的访问模式为用户模式时才进行参数检查 |
一般导出函数的命名格式是:<前缀><操作><对象>
前缀:导出该例程的内部组件
操作:说明了在对象或者资源上做了什么工作
对象:标记了是在什么上进行操作的
例如KeInitializeThread:Ke、Initialize、Thread(分配并建立内核线程对象的例程)
系统进程
Windows系统会出现的系统进程:
——空闲(Idle)进程(每个CPU一个线程,占用空闲的CPU时间)
——System进程(包含大多数内核模式系统进程)
——会话管理器(Smss.exe)
——Windows子系统(Csrss.exe)
——登录进程(Winlogon.exe)
——服务控制管理器(Services.exe)和它创建的子服务进程(如系统提供的通用服务宿主进程Svchost.exe)
——本地安全认证服务器(Lsass.exe)
ps:空闲进程和System进程并不是完整的进程,因为它们并不是在运行一个用户模式的可执行文件。
空闲进程
并不会运行一个实际的用户模式映像文件,即在Windows目录下没有对应名称的文件。而且不同的工具中该进程的显示名称是不同的。
中断和DPC
虽然显示在进程列表中,但并不是进程。之所以被显示是因为它们所消耗的CPU时间并没有计算在任何一个进程中。任务管理器将中断和DPC时间包含在系统空闲时间中。
System进程和系统线程
System进程是一种特殊线程的母体,只能在内核模式下运行,称为内核模式系统线程。系统线程具备普通用户模式线程的所有属性和环境,但不同在于:1)它们只在内核模式下运行系统空间中加载的代码,无论这些代码是否在Ntoskrnl.exe中,还是在任何其他加载进来的设备驱动程序中;2)系统线程没有一个用户进程地址空间,因此任何的动态存储空间都必须从操作系统的内存堆中分配。
内核会创建一个称为平衡集管理器的系统线程,它每秒钟被唤醒一次,因此有可能发出各种与调度和内存管理相关的事件。高速管理器也使用系统线程来实现“预读”和“滞后写”I/O。
在默认情况下系统线程是属于System进程的,但是一个设备驱动程序可以在任何的进程中创建系统线程,因此这些线程可以访问到该进程用户模式地址空间中的数据。
会话管理器
会话管理器是系统中第一个创建的用户模式进程。负责完成执行体和内核初始化的内核模式系统线程在最后阶段创建了实际的Smss进程。也会启动子系统进程Csrss.exe和Winlogon.exe进程,后续Winlogon进程依次会创建其他的系统进程。(在注册表HKLM\SYSTEM\CurrentControlSet\Control\Session Manager下可找到Smss的初始化步骤的配置信息)
Smss中的主线程在执行初始化步骤之后,一直在Csrss和Winlogon的进程句柄上等待。若这两个进程中的任何一个非正常终止了,则Smss会让系统崩溃(STATUS_SYSTEM_PROCESS_TERMINATED或0xC000021A)。
终端服务会话的创建是由Smss完成的,当Smss接到一个创建会话请求时,首先调用NtSetSystemInformation请求建立内核模式的会话数据结构。再依次调用内部的内存管理器函数MmSessionCreate建立起会话虚拟地址空间,该地址空间中包含会话中的换页内存池、以及由Win32子系统的内核模式部分(Win32k.sys)和其他的会话空间设备驱动程序所分配的、属于每个会话的数据结构,接着Smss为该会话创建Winlogon和Csrss的实例。
Winlogon、LSASS和Userinit
Windows登录进程处理交互式用户的登录和注销。当安全注意序列SAS组合键被按下时Winlogon就会接到一个用户登录的请求。使用SAS的原因是为了保护用户避免那些模拟登录过程的口令窃听程序(用户模式应用程序不可能截取这一键盘序列)。
登录过程的身份识别和认证是在一个名为GINA(图形识别和认证)的可替换DLL中实现的。一旦用户名和口令被捕捉到,就会送到本地安全认证服务器进程进行认证。LSASS调用适当的认证包以执行实际的验证操作,在成功完成认证后,LSASS调用安全引用监视器中的一个函数生成一个访问令牌对象,该对象包含了当前用户的安全轮廓,接着Winlogon利用这个访问令牌创建该用户会话中的初始进程。这些初始进程被存储在注册表键HKLM\SOFTWARE\Miscrosoft\Windows NT\CurrentVersion\Winlogon下的注册表值Userinit中(默认是Userinit.exe,但可以列出多个映像值)。
Useinit执行该用户环境中的一些初始化工作,接着在注册表中查找shell值,并且创建一个进程来运行系统定义的外壳程序(默认是explorer.exe)。接着Useinit退出,这也是为什么Explorer在进程树中没有父进程的原因——父进程已退出。
Winlogon不仅当用户登录和注销时是活动的,而且无论何时当它截取到键盘的SAS时也是活动的。
服务控制管理器
之前说过:Windows中的“服务”可以是一个服务器进程,也可以是一个设备驱动程序。这里的服务指的是用户模式的进程。
服务控制管理器是一个特殊的系统进程,运行的映像文件是Services.exe,负责启动、停止服务进程,也负责与这些服务进程进行交互。所谓的服务程序,实际上只是调用了一些特殊Windows函数的Windows映像。它们通过这些特殊的Windows函数,与服务控制管理器进行交互,以便执行相关的动作。
服务有三种名称:在系统中正在运行的进程名、注册表中的内部名称、以及在Services管理工具中给出的显示名。想从一个服务进程映射到该进程所包含的服务,可以使用tlist /s命令。在服务进程和所运行服务之间并不总是一一对应的,因为有的服务与其他的服务共享一个进程。