Windows 管理

了解 Windows Vista 内核:第三部分

Mark Russinovich

 

概览:

  • 可靠性
  • 可恢复性
  • 安全性

到目前为止,该系列文章涵盖了有关进程、I/O、内存管理、系统启动、关闭和电源管理方面的 Windows Vista 内核增强功能。在此第三版暨最终版

安装中,我会着眼于可靠性、可恢复性和安全性方面的功能和改进。

本系列中没有涉及的功能之一是用户帐户控制 (UAC),它由几种不同的技术组成,包括文件系统和注册表虚拟化(用于传统应用程序)、访问管理权限的提升同意及 Windows® 完整性级别机制(用于从相同帐户中隔离较低权限运行的进程与使用管理权限运行的进程)。请在以后发行的 TechNet 杂志中查阅我对 UAC 内部信息的深入探讨。

Windows Vista™ 通过许多新功能和改进提高了系统的可靠性和您对系统与应用程序问题的诊断能力。例如,内核 Windows 事件跟踪 (ETW) 记录程序总是处于运行状态,能够生成有关文件、注册表、中断以及其他活动类型的跟踪事件,并保存在循环缓冲区中。当出现问题时,新的 Windows 诊断基础结构 (WDI) 会捕获缓冲区快照,并进行本地分析或上载到 Microsoft 支持进行故障排除。

新的 Windows 性能和稳定性监视器可以帮助用户通过更改系统配置将错误(如崩溃和挂起)相互关联。强大的系统修复工具 (SRT) 取代了故障恢复控制台,用于不可启动系统的离线恢复。

有三个方面依靠对系统进行的内核级更改,即需要您认真阅读的本文中的以下方面:内核事务管理器 (KTM)、改进的崩溃处理和以前的版本。

内核事务管理器

软件开发中最繁琐的一个方面就是处理错误条件。特别是在进行高级操作的过程中,应用程序完成了一个或多个导致文件系统或注册表更改的子任务。例如,应用程序的软件更新服务可能要进行几次注册表更新,替换应用程序的可执行文件之一,而在它尝试更新第二个可执行文件时被拒绝访问。如果服务不想将应用程序留在因此导致的不一致状态,就必须跟踪所有更改并为撤销它们做好准备。测试错误恢复代码很困难,并经常跳过,因此恢复代码中的错误会让努力徒劳无功。

为 Windows Vista 编写的应用程序通过使用 NTFS 中新的事务支持和使用内核事务管理器的注册表,不费吹灰之力即可获得自动错误恢复能力。当应用程序想进行许多相关更改时,可以创建分布式事务处理协调器 (DTC) 事务和 KTM 事务处理,或直接创建 KTM 处理,并将对文件和注册表项的修改与事务关联起来。如果所有的更改成功,应用程序会提交事务同时更改生效,但是在此之前任何时候,应用程序可以回滚事务,然后放弃更改。

其有利因素在于,其他应用程序在提交事务后才能看到事务中的更改,而在 Windows Vista 和即将问世的 Windows Server®(代码名为“Longhorn”)中使用 DTC 的应用程序会通过 SQL Server™、Microsoft® Message Queue Server (MSMQ) 以及其他数据库协调其事务。因此,使用 KTM 事务的应用程序更新服务永远不会将应用程序留在不一致的状态。这就是 Windows Update 和系统还原使用事务的原因。

作为事务支持的核心,KTM 允许事务资源管理器(如 NTFS 和注册表)对应用程序所做的特定更改协调其更新。在 Windows Vista 中,NTFS 使用称为 TxF 的扩展来支持事务。注册表使用称为 TxR 的类似扩展。这些内核模式资源管理器与 KTM 一起协调事务状态,正如用户模式资源管理器使用 DTC 跨多用户模式资源管理器协调事务状态一样。第三方也可以使用 KTM 实施其自己的资源管理器。

TxF 和 TxR 都定义了一套新的文件系统和注册表 API(与现有的类似,只不过它们包含事务参数)。如果应用程序想在事务中创建文件,首先要使用 KTM 创建事务,然后将引起的事务处理传递给新文件创建 API。

TxF 和 TxR 都依赖在 Windows Server 2003 R2 中引入的公用日志文件系统或 CLFS (%SystemRoot%\System32\Clfs.sys) 的高速文件系统记录功能。TxR 和 TxF 使用 CLFS 永久性地存储提交事务之前的事务状态更改。这样可以让它们提供事务恢复并确保即使在断电时也可以恢复。除了 CLFS 日志,TxR 还创建了一组相关的日志文件,跟踪 %Systemroot%\System32\Config\Txr 中系统注册表文件的事务更改(如图 1 所示),同时还为每个用户注册表配置单元单独创建几组日志文件。TxF 在名为 \$Extend\$RmMetadata 的卷的隐藏目录中存储每个卷的事务数据。

图 1 系统注册表配置单元 TxR 记录文件

图 1** 系统注册表配置单元 TxR 记录文件 **(单击该图像获得较大视图)

增强的崩溃支持

当 Windows 遇到不可恢复的内核模式错误时(无论是由于设备驱动程序错误、硬件故障还是操作系统问题),在出现“蓝屏死机”现象和将物理内存的部分或所有内容写入崩溃转储文件(如果配置为执行此操作)后,它会尝试终止系统来防止磁盘数据的损坏。转储文件非常有用,因为当您在系统崩溃后重启时,Microsoft 在线崩溃分析 (OCA) 服务会分析这些文件找出根本原因。如果愿意,您也可以使用面向 Windows 的 Microsoft 调试工具自已进行分析。

不过,在以前的 Windows 版本中,只有在会话管理器 (%Systemroot%\System32\Smss.exe) 进程初始化分页文件后才会启用对崩溃转储文件的支持。这意味着在此之前任何严重错误会导致蓝屏,但没有转储文件。由于在 Smss.exe 启动之前,会出现大量的设备驱动程序初始化,所以早期的崩溃永远不会引起崩溃转储,因此使原因诊断极为困难。

在所有引导启动设备驱动程序初始化之后,但在系统启动驱动程序加载之前,Windows Vista 通过初始化转储文件支持,可减少无转储文件生成的时间窗口。由于这一更改,如果在引导过程开始时出现崩溃,系统就可以捕捉崩溃转储,让 OCA 帮助您解决问题。此外,Windows Vista 使用 64KB 块将数据存储到转储文件中,而以前的 Windows 版本使用 4KB 块写入文件。这一更改使得大型转储文件的写入速度最多可提高 10 倍。

应用程序崩溃处理功能在 Windows Vista 中也得以改进。在以前的 Windows 版本中,当应用程序崩溃时,它会执行未处理的异常处理程序。处理程序启动 Microsoft 应用程序错误报告 (AER) 进程 (%Systemroot%\System32\Dwwin.exe),显示对话框,指明程序崩溃,并询问您是否要向 Microsoft 发送错误报告。不过,如果崩溃时进程主线程的堆栈损坏,未处理的异常处理程序执行时会崩溃,导致内核终止进程、程序窗口立即消失,并且没有错误报告窗口。

Windows Vista 将错误处理从崩溃进程的上下文移至新服务,即 Windows 错误报告 (WER)。此服务由服务托管进程中的 DLL (%Systemroot%\System32\Wersvc.dll) 实施。在应用程序崩溃时,它仍然会执行未处理的异常处理程序,但是该处理程序会向 WER 服务发送消息,并且服务会启动 WER 错误报告进程 (%Systemroot%\System32\Werfault.exe) 以显示错误报告对话框。如果堆栈损坏并且未处理的异常处理程序崩溃,处理程序会再次执行并且再次崩溃,最终消耗所有线程的堆栈(使用内存区域),此时内核会介入,并向服务发送崩溃通知消息。

在图 2 和图 3 中,您可以看到这两种方法的对比,这两幅图表明在 Windows XP 和 Windows Vista 中 Accvio.exe(崩溃的测试程序)的进程关系,并以绿色突出显示错误报告进程。新的 Windows Vista 错误处理体系结构意味着在未尝试向 Microsoft 提供获得错误报告的情况下,程序不会再在无提示的情况下终止,这有助于软件开发人员不断改进其应用程序。

图 2a Windows XP 中的应用程序错误处理

图 2a** Windows XP 中的应用程序错误处理 **(单击该图像获得较大视图)

图 2b

图 2b(单击该图像获得较大视图)

图 3a Windows Vista 中的应用程序错误处理

图 3a** Windows Vista 中的应用程序错误处理 **(单击该图像获得较大视图)

图 3b

图 3b

卷影复制

Windows XP 引入了一种称为卷影复制的技术,可生成磁盘卷的时间点快照。备份应用程序可以使用这些快照生成一致的备份映像,但是快照却被从视图中隐藏,并仅保持备份过程所持续的时间。

快照实际上并不是卷的完整副本。更确切地讲,它们是较早还原点的卷视图,由与卷扇区副本(在生成快照后已更改)重叠的活动卷数据组成。卷快照提供程序的驱动程序 (%Systemroot\%System32\Drivers\Volsnap.sys) 监视针对卷的操作,备份扇区副本后才允许扇区更改,将与快照相关的文件中的原始数据存储到卷的 System Volume Information 目录中。

Windows Server 2003 使用其共享文件夹的影副本对服务器上的管理员和客户端系统上的用户公开快照管理。此功能启用了持续快照,用户可通过 Explorer 属性对话框中的“以前的版本”选项卡访问它,因为其文件夹和文件位于服务器的文件共享部分。

Windows Vista“以前的版本”功能为所有客户端系统提供了此支持,即自动创建卷快照(通常每天一次),您可以通过使用共享文件夹影副本所用的相同界面的 Explorer 属性对话框访问快照。这样可让您查看、还原或复制您可能意外修改或删除的文件和目录的旧版本。虽然从技术角度来讲这并不是新技术,但 Windows Vista“以前的版本”实施的卷影复制优化了 Windows Server 2003 在客户端桌面环境中使用的功能。

Windows Vista 还充分利用了卷快照,以统一用户和系统数据保护机制,避免保存冗余的备份数据。当应用程序安装或配置更改造成错误或不合需要的行为时,您可以使用“系统还原”(在 Windows NT® 系列的操作系统 Windows XP 中引入的一项功能)将系统文件和数据还原成创建还原点时其存在的状态。

在 Windows XP 中,“系统还原”使用文件系统过滤器驱动程序(可以看到在文件级别的更改的一种驱动程序类型)在系统文件更改时备份其副本。在 Windows Vista 中,“系统还原”使用卷快照。当您在 Windows Vista 中使用“系统还原”用户界面返回到还原点时,您实际上是从与活动卷的还原点关联的快照复制已修改的系统文件的较早版本。

BitLocker

Windows Vista 是迄今为止最安全的 Windows 版本。除了包含 Windows Defender 反间谍软件引擎外,Windows Vista 还引入了大量的安全和纵深防御功能,包括 BitLocker™ 整卷加密功能、内核模式代码的代码签名、受保护的进程、地址空间加载随机化以及对 Windows 服务安全和用户帐户控制的改进。

操作系统在运行时只能增强其安全策略,因此当系统的物理安全可能受到危害和从操作系统之外访问数据时,您必须采取其他措施保护数据。诸如 BIOS 密码和加密的基于硬件的机制,是通常用来防止未经授权进行访问的两种技术,尤其是便携式计算机,最有可能丢失或被盗。

Windows 2000 引入了加密文件系统 (EFS),并且在其 Windows Vista 体现中,EFS 包括了对以前实施功能的许多改进,包括性能改进、支持分页文件的加密和在智能卡上存储用户 EFS 密钥。不过,您无法使用 EFS 保护对系统敏感区域的访问,如注册表配置单元文件。例如,如果组策略允许您登录到便携式计算机(甚至在没有连接到域时),您的域凭据验证程序会在注册表中缓存,因此攻击者可以使用工具获取您的域帐户密码哈希,并用来尝试使用密码破解程序获取您的密码。密码会让他们有权访问您的帐户和 EFS 文件(假设您没有把 EFS 密钥存储在智能卡上)。

为了易于加密整个引导卷(包含 Windows 目录的卷),包括其所有系统文件和数据,Windows Vista 引入了整卷加密功能,称为 Windows BitLocker 驱动器加密。与由 NTFS 文件系统驱动程序实施并在文件级别操作的 EFS 不同,BitLocker 在卷级别使用整卷加密 (FVE) 驱动程序 (%Systemroot%\System32\Drivers\Fvevol.sys) 进行加密,如图 4 中图解所示。

图 4 BitLocker FVE 过滤器驱动程序

图 4** BitLocker FVE 过滤器驱动程序 **(单击该图像获得较大视图)

FVE 是过滤器驱动程序,因此它会自动查看 NTFS 发送到卷的所有 I/O 请求,在其写入时加密块,在其读取时(在初始配置使用 BitLocker 时,会使用分配到块的完整卷加密密钥 (FVEK) 读取它们)解密块。默认情况下,使用 128 位 AES 密钥和 128 位扩散器密钥加密卷。因为加密和解密发生在 I/O 系统的 NTFS 之下,所以卷在 NTFS 看来好象没有加密,并且 NTFS 甚至不需要知道已启用了 BitLocker。不过,如果您尝试从 Windows 外读取卷上的数据,它又看来象是随机数据。

FVEK 使用卷主密钥 (VMK) 加密,并存储在卷的特殊元数据区域。当您配置 BitLocker 时,会有许多关于如何保护 VMK 的选项,取决于系统的硬件功能。如果系统有符合 TPM 规范 v1.2 的受信任的平台模块 (TPM),并有相关的 BIOS 支持,则您可以使用 TPM 加密 VMK(让系统使用存储在 TPM 中的密钥或存储在 USB 闪存设备中的密钥加密 VMK),或使用 TPM 存储的密钥和在系统启动时输入的 PIN 加密密钥。对于没有 TPM 的系统,BitLocker 提供使用存储在外部 USB 闪存设备中的密钥加密 VMK 的选项。在任何情况下,您都需要一个未加密的 1.5GB NTFS 系统卷,在该卷中存储了启动管理器和引导配置数据库 (BCD)。

使用 TPM 的优势在于,如果 BIOS 或系统启动文件在启用 BitLocker 后做出更改,BitLocker 会使用 TPM 功能确保不解密 VMK 和解除对引导卷的锁定。当您第一次加密系统卷,以及每次对提及的所有组件执行更新时,BitLocker 会借助于 TPM 设备驱动程序 (%Systemroot%\System32\Drivers\Tpm.sys) 计算这些组件的 SHA-1 哈希,并将称为测量的每个哈希存储到不同的 TPM 平台配置注册表 (PCR)。接下来,它使用 TPM 密封 VMK,该操作使用存储在 TPM 中的私钥加密 TPM 和与 BitLocker 传递到 TPM 的其他数据一起存储在 PCR 中的值。然后,BitLocker 将密封的 VMK 和加密的 FVEK 存储在卷的元数据区域。

当系统启动时,它会测量自己的哈希和 PCR 加载代码,并将哈希写入 TPM 的第一个 PCR。然后,它哈希 BIOS,并将该测量存储到相应的 PCR。接下来,BIOS 按启动序列哈希下一个组件,即引导卷的主引导记录 (MBR),此过程会一直继续,直到测量操作系统加载器。运行的每个后续代码段负责测量其加载的代码,并将测量结果存储到 TPM 中相应的注册表。最后,当用户选择要启动哪个操作系统时,启动管理器 (Bootmgr) 会从卷读取加密的 VMK,并要求 TPM 取消密封。只有所有测量与密封 VMK 时相同时(包括可选的 PIN),TPM 才成功解密 VMK。

您可以考虑将此方案作为验证链,其中启动序列中的每个组件会描述 TPM 的下一个组件。只有所有描述与提供的原始描述相符时,TPM 才泄露其秘密。因此,即使卸下磁盘并装到其他系统、使用不同的操作系统启动系统或引导卷上未加密文件遭到破坏,BitLocker 也会保护加密数据。

代码完整性验证

作为内核模式设备驱动程序执行的恶意软件(包括 rootkit)与内核在相同的权限级别运行,因此最难识别和删除。这类恶意软件可以修改内核和其他驱动程序的行为,以便使其变得不可见。内核模式代码功能的 Windows Vista 代码完整性,也称为内核模式代码签名 (KMCS),仅允许加载由开发人员发布和经过数字签名的设备驱动程序,这些开发人员已经过为数不多的证书颁发机构 (CA) 之一的审查。默认情况下,KMCS 在 Windows Vista 64 位系统上强制执行。

因为证书颁发机构会对其服务收取费用并进行基本的背景检查,如验证业务识别,所以很难产生在 64 位 Windows Vista 上运行的匿名内核模式恶意软件。此外,设法溜过验证进程的恶意软件可能会留下线索,这些线索在受到危害的系统发现恶意软件时,可以反击作者。KMCS 还有一些次要的用途,如在怀疑驱动程序有使客户系统崩溃的错误和解除高清晰度多媒体内容锁定(我会在稍后简单介绍)时,会向 Windows 在线崩溃分析团队提供联系信息。

KMCS 使用 Windows 十多年来一直采用的公钥加密技术,并要求内核模式代码包括由受信任证书颁发机构之一生成的数字签名。如果发布者将驱动程序提交给 Microsoft Windows 硬件质量实验室 (WHQL),并且驱动程序通过了可靠性测试,则 Microsoft 会充当签署代码的证书颁发机构。大多数发布者将通过 WHQL 获得签名;但是如果驱动程序没有 WHQL 测试程序,发布者不想提交到 WHQL 测试,或者驱动程序是在系统启动早期加载的引导启动驱动程序,则发布者必须自己签署代码。为此,他们必须首先从 Microsoft 确定为受信任内核模式代码签名的证书颁发机构之一获得代码签名证书。然后,作者通过数字方式哈希代码,通过使用私钥进行加密来签署哈希,并将证书和加密的哈希包含在代码中。

当驱动程序尝试加载时,Windows 会使用存储在证书中的公钥解密包含在代码中的哈希,然后验证哈希与代码中包含的哈希是否匹配。证书的真实性也通过相同的方式进行检查,但使用 Windows 附带的证书颁发机构的公钥。

Windows 还检查相关的证书链,一直检查到 Windows 启动加载器和操作系统内核中嵌入的根颁发机构之一。尝试加载未签名的 64 位驱动程序不应该发生在生产系统,因此不同于“即插即用”管理器(它在指向加载没有确认是否通过 WQHL 测试签名的驱动程序时显示警告对话框),64 位 Windows Vista 在阻止加载未签名驱动程序时,在无提示的情况下随时将事件写入代码完整性应用程序事件日志,如图 5 所示。32 位 Windows Vista 也检查驱动程序签名,但允许加载未签名的驱动程序。阻止它们将会破坏升级的 Windows XP 系统(要求在 Windows XP 上加载驱动程序,并且还允许支持仅存在 Windows XP 驱动程序的硬件)。不过,32 位 Windows Vista 还会在加载未签名驱动程序时将事件写入代码完整性事件日志。

图 5 未签名的驱动程序加载尝试事件

图 5** 未签名的驱动程序加载尝试事件 **(单击该图像获得较大视图)

因为代码签名通常用来将代码标记为经过严格测试的官方发行版本,所以发布者通常并不想对测试代码签名。因此,Windows Vista 包括可以使用 Bcdedit 工具(在 TechNet 杂志 2007 年 3 月份我的文章中介绍过)启用和禁用的测试签名模式,它将加载使用由内部证书颁发机构生成的测试证书经过数字签名的内核模式驱动程序。此模式设计为供程序员在开发其代码时使用。当 Windows 处于此模式时,它会在桌面上显示标记,如图 6 中所示。

图 6 Windows Vista 测试签名模式

图 6** Windows Vista 测试签名模式 **

受保护的进程

下一代多媒体内容,如 HD-DVD、BluRay 和高级访问内容系统 (AACS) 下许可的其他格式,在以后几年内会变得更加常见。Windows Vista 包括许多技术,统称为受保护的媒体路径 (PMP),AACS 标准要求在播放此类内容时使用这些技术。PMP 包括受保护的用户模式音频 (PUMA) 和受保护的视频路径 (PVP),它们一直为音频和视频驱动程序及媒体播放机应用程序提供机制,以防止未授权软件或硬件捕获高清晰度格式的内容。

PUMA 和 PVP 定义特定于音频和视频播放机、设备驱动程序和硬件的接口和支持,但是 PMP 也依赖在 Windows Vista 中引入的一般内核机制,即称为受保护的进程。受保护的进程以标准的 Windows 进程构造为基础,该构造封装了运行的可执行映像、其 DLL、安全上下文(进程运行所在的帐户及其安全权限),及在进程内执行代码但阻止某些访问类型的线程。

标准进程实施访问控制模式,允许使用“调试程序”权限完全访问进程所有者和管理帐户。完全访问允许用户查看和修改进程的地址空间,包括映射到进程的代码和数据。用户也可以将线程注入进程。这些访问类型与 PMP 的要求不一致,因为它们允许未授权代码获取存储在播放内容的进程中的高清晰度内容和数字版权管理 (DRM) 密钥的访问权限。

受保护的进程限制访问一组受限的信息和进程管理界面,包括查询进程的映像名和终止或挂起进程。但是,内核通过一般的进程查询功能(返回有关系统上所有进程的数据)为受保护的进程提供诊断信息,因此不要求直接访问进程。访问可能会损坏只允许通过其他受保护的进程访问的媒体。

此外,为避免从内部受到危害,加载到受保护进程的所有可执行代码(包括其可执行映像和 DLL)必须由 Microsoft (WHQL) 使用受保护的环境 (PE) 标记签名,或者(如果是音频编解码器)由开发人员使用从 Microsoft 获得的 DRM 签名证书签名。因为内核模式代码可以获取任何进程的完全访问权限(包括受保护的进程),并且 32 位 Windows 允许加载未签名的内核模式代码,所以内核可为受保护的进程提供 API,以查询内核模式环境的“清洁度”,并仅在没有加载未签名代码时使用结果解除对高级内容的锁定。

识别受保护的进程

没有特定识别受保护进程的 API,但是您可以间接地根据有关它们的受限信息以及甚至无法从管理帐户进行调试来识别它们。音频设备图形隔离进程 (%Systemroot%\System32\Audiodg.exe) 用于播放使用内容加密系统 (CSS) 编码的 DVD,并在“任务管理器”窗格中标识为受保护的进程。事实上,即使使用管理权限运行,任务管理器也无法获得其命令行、虚拟化和数据执行保护状态。

查看 audiodg 受保护进程的任务管理器

查看 audiodg 受保护进程的任务管理器(单击该图像获得较大视图)

地址空间加载随机化

不管采取什么措施,如数据执行保护和增强的编译器错误检查,恶意软件作者都会继续找到缓冲区溢出漏洞,这些漏洞使他们能够感染面向网络的进程(如 Internet Explorer®、Windows 服务及第三方应用程序),获得进入系统的立足点。不过,在设法感染进程后,他们必须使用 Windows API 通过修改用户或系统配置设置来完成读取用户数据或建立永久存在的最终目的。

使用 DLL 导出的 API 入口点连接应用程序,通常由操作系统加载器处理,但是这些类型的恶意软件感染不会从加载器的服务中受益。恶意软件在以前的 Windows 版本中还没有出现过此类问题,因为对于任何特定的 Windows 版本,系统可执行映像和 DLL 总在同一个位置加载,让恶意软件假定 API 驻留在固定的地址。

Windows Vista 地址空间加载随机化 (ASLR) 功能使恶意软件不可能知道 API 的位置,方法是通过每次系统启动时在不同位置加载系统 DLL 和可执行文件。在启动进程早期,内存管理器会从用户模式地址空间顶部 16MB 区域的 256 个 64KB 对齐地址中随机选取一个作为 DLL 映像加载偏差。由于在映像标头中有新的动态重新定位标记的 DLL 加载到进程中,因此内存管理器会从映像加载偏差地址开始并继续将 DLL 选取到内存中。

具有标记组的可执行文件会得到类似的处理,在存储在其映像标头中的 16MB 基本加载地址内以随机的 64KB 对齐点加载。此外,如果使用给定的 DLL 或可执行文件的所有进程卸载后再次加载它,内存管理器会重新选择一个随机的加载位置。图 7 所示为一个 32 位 Windows Vista 系统的示例地址空间布局,包括 ASLR 选取映像加载偏差和可执行文件加载地址的区域。

图 7 ASLR 对可执行文件和 DLL 加载地址的影响

图 7** ASLR 对可执行文件和 DLL 加载地址的影响 **(单击该图像获得较大视图)

只有具有动态重新定位标记的映像(包括所有 Windows Vista DLL 和可执行文件)才能重新定位,因为移动原有映像可能会中断开发人员对其映像加载位置所做的内部假设。Visual Studio® 2005 SP1 增加了对设置标记的支持,以便第三方开发人员可以充分利用 ASLR。

将 DLL 加载地址随机分布到 256 个位置之一,并不会使恶意软件猜不出正确的 API 位置,但是它会严重限制网络蠕虫传播的速度,并且可以阻止仅有一次机会感染系统的恶意软件以可靠地运行。此外,ASLR 的重新定位策略的第二个好处是,地址空间压缩比在以前的 Windows 版本上的更加紧密,为连续内存分配创建更大的可用内存区域,减少内存管理分配以跟踪地址空间布局的页表数,以及最小化转换旁路缓冲器 (TLB) 遗漏。

服务安全性改进

Windows 服务成为理想的恶意软件目标。许多服务都提供通过网络访问其功能,这很可能会暴露远程可利用的访问系统的机会,而大多数服务运行都使用比标准用户帐户更多的权限,如果它们被恶意软件利用,则会提供在本地系统上提升权限的机会。因此,Windows 以在 Windows XP SP2 中所做的更改为始不断完善,将权限和对指定服务的访问权限降为仅其角色需要的权限。例如,Windows XP SP2 引入了本地服务和网络服务帐户(仅包括服务以前一直运行的本地系统帐户权限的子集)。这样可以在利用服务时最小化攻击者获取的访问权限。

查看运行中的 ASLR

通过使用像 Sysinternals 提供的 Process Explorer 一样的工具,在两个不同的引导会话中比较进程的 DLL 加载地址,您可以很容易看到 ASLR 的效果。在从两个不同会话截取的这两个屏幕快照中,Ntdll.dll 首先在地址 0x77A30000、然后在地址 0x77750000 加载到 Explorer。

ntdll.dll 的不同基址

ntdll.dll 的不同基址(单击该图像获得较大视图)

ntdll.dll 的不同基址

ntdll.dll 的不同基址(单击该图像获得较大视图)

在我以前的文章中,我介绍了服务如何在其会话中与用户帐户分开运行,但是 Windows Vista 还通过进一步降低分配给大多数服务对文件、注册表项及防火墙端口的权限和访问权限,以扩大其最小权限原则的使用。Windows Vista 为每种服务定义了一组唯一的新帐户,称为服务安全标识符 (SID)。服务可以对其资源设置权限,这样只有其服务 SID 拥有访问权限,避免在服务出现安全漏洞时以相同用户帐户运行的其他服务拥有访问权限。您可以使用 sc showsid 命令后接服务名称来查看服务的 SID,如图 8 所示。

图 8 查看服务 SID

图 8** 查看服务 SID **(单击该图像获得较大视图)

服务 SID 保护对特定服务所拥有资源的访问权限,但默认情况下,服务对其运行的用户帐户可以访问的所有对象仍有访问权限。例如,在“本地服务”帐户中运行的服务可能无法访问在不同进程(该进程使用参考服务 SID 的权限保护其对象)中以“本地服务”运行的另一服务创建的资源;但是,它仍可以读取和写入“本地服务”(以及“本地服务”所属的任何组,如“服务组”)有权访问的任何对象。

因此,Windows Vista 引入了称为限制写入服务的新受限服务类型,可让服务仅对其服务 SID、Everyone 组及分配到登录会话的 SID 可访问的对象允许写入访问权限。为了实现这一点,它会使用重新引入 Windows 2000 的受限 SID 类型。当打开对象的进程是限制写入服务时,访问 - 检查算法会发生变化,这样尚未以受限和非受限方式分配到进程的 SID 就无法用来为进程授予对象的写入权限。您可以使用以下命令查看服务是否受限:

sc qsidtype [service]

另一个变化是让服务更容易阻止在相同帐户中运行的其他服务对其创建的服务拥有访问权限。在以前的 Windows 版本中,对象的创建者也是对象的所有者,而且所有者能够读取和更改其对象的权限,允许其对自己对象的完全访问权限。Windows Vista 引入了新的所有者权限 SID,如果在对象的权限中存在 SID,则 SID 可以限制所有者对其对象的访问权限,甚至会删除设置和查询权限的权利。

对 Windows Vista 中服务安全模式的进一步改进,可以让服务开发人员确切地指定当服务在系统上注册时,此服务需要什么安全权限才能操作。例如,如果服务需要生成审核事件,它就可以列出“审核”权限。

当“服务控制管理器”启动托管一个或多个 Windows 服务的进程时,它就为在该进程中仅包括服务所需权限的进程创建了一个安全令牌(列出进程用户帐户、组成员身份和安全权限的内核对象)。如果服务指定了其运行的帐户不可用的权限,则服务无法启动。当“本地服务”帐户进程中未运行任何需要(例如)“调试程序”权限的服务时,“服务控制管理器”会从进程的安全令牌中剥夺此权限。因此,如果服务进程被破坏,恶意代码无法利用进程中运行的服务未明确请求的权限。sc qprivs 命令会报告服务已请求的权限。

结束语

本文结束了我对 Windows Vista 内核更改分析的三部曲。有些功能和改进我没有涉及或提及,如面向应用程序开发人员的新的工作线程池、新的同步机制(如共享读取器/编写器锁定)、服务线程标记、对在线 NTFS 磁盘检查和卷大小调整的支持以及称为高级本地过程调用 (ALPC) 的新内核 IPC 机制。您可以在计划于 2007 年底发行的下一版《Windows Internals》(Windows 内部结构)中了解有关这些功能和其他功能的详细信息。

查看限制写入服务

在 Windows Vista 上只有一种托管服务进程托管受限服务,您可以使用进程查看工具(如 Process Explorer)将它识别为具有以下命令行的进程:

svchost -k LocalServiceNoNetwork

配置在此进程中运行的服务包括基本筛选引擎、诊断策略服务、Windows 防火墙、性能日志和警报及 Windows Media® Center 服务启动程序。

此屏幕显示文本格式的基本筛选引擎的服务 SID (NT SERVICE\BFE),第一次列出时有受限标记,再次列出时没有受限标记,因此进程对该帐户可以访问的资源拥有访问权限。不过,它不必对“本地服务”帐户通常可以访问的其他对象拥有访问权限。例如,因为 NT AUTHORITY\SERVICE 帐户不会在有受限标记的进程令牌中出现,所以进程无法修改仅对令牌(有受限标记)中此帐户而不是其他帐户授予写入权限的对象。

在此进程中运行的服务还会限制其权限,因为在属性对话框底部列出的权限是可用于“本地服务”帐户的子集。

服务上的 SID 标记

服务上的 SID 标记(单击该图像获得较大视图)

Mark Russinovich 是 Microsoft 平台和服务部门的技术人员。他是《Microsoft Windows Internals》(Microsoft Windows 内部结构)(Microsoft Press, 2004) 的合著者之一,并经常在 IT 和开发人员会议上演讲,包括 Microsoft Tech•Ed(微软技术大会)和 PDC(微软程序员大会)。在 Microsoft 收购了 Mark Russinovich 与其他人创办的 Winternals Software 之后,Mark Russinovich 也随之加入了 Microsoft。他还创建了 Sysinternals,在这里他发布了许多流行的实用工具,包括 Process Explorer、Filemon 和 Regmon。

© 2008 Microsoft Corporation 与 CMP Media, LLC.保留所有权利;不得对全文或部分内容进行复制.