[笔记]深入解析Windows操作系统《三》系统机制(八)

本文涉及的产品
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
云解析 DNS,旗舰版 1个月
简介: [笔记]深入解析Windows操作系统《三》系统机制(八)

3.12 内核事务管理器

软件开发的一项琐碎任务是处理各种错误条件。在有些情况下尤是如此,譬如在执行一个高层的操作过程中,应用程序已经完成了一个或多个导致文件系统或注册表发生变化的子任务。例如,一个应用程序的软件更新服务可能要进行多次注册表更新动作,再替换该应用程序的一个可执行文件,然后当它试图更新第二个可执行文件的时候被拒绝访问。如果该软件更新服务不想让这个应用程序留在最后导致的不一致状态,那么,它必须跟踪所有已经做过的改变,并且准备好撤销这些改变。测试错误恢复代码是很难的,因而常常被跳过去,所以,在恢复代码中的错误可能使得其功能根本不起作用。

应用程序可以通过使用一种称为内核事务管理器(KMT,Kernel Transaction Manager)的内核机制,以非常小的编码工作,获得自动的错误-恢复功能。内核事务管理器提供了执行此种事务所需要的设施,允许诸如用户模式下的分布式事务协调器(DTC,distributed transactioncoordinator)之类的服务充分利用这些设施。开发人员通过使用适当的API也可以利用这些服务。

KMT除了解决了如上面提到的这种大规模问题,还做了更多的事情。即使在单用户的家庭计算机上,安装一个服务补丁,或者执行一次系统恢复,都涉及文件和注册表键的大量操作。在这样的操作过程中拔掉老的Windows计算机的电源,再要成功引导系统的机会变得很渺茫。即使NT文件系统(NTFS)总是有一个日志文件,使得该文件系统总是可以保证原子操作(有关NTFS的更多信息,请参见本书下册第12章),这也只是意味着,在此过程中无论哪个文件正在被写入,它要么被全部写入,要么完全被删除―一它并不保证整个更新操作或者恢复操作。类似地,注册表在过去几年间已经有了大量的改进来处理数据被破坏的情形(有关注册表的更多信息,请参见第4章),但是这些修补也只适用于键/值这个层次。

作为事务支持的核心,KTM允许事务性的资源管理器,比如NTFS和注册表,可以为一个应用程序执行的一组修改操作协调它们的更新动作。NTFS使用一个扩展模块来支持事务,称为TxF。注册表使用一个类似的扩展,称为TxR。这些内核模式资源管理器与KTM一起工作,来协调事务的状态,就如同用户模式资源管理器使用DTC来协调跨越多个用户模式资源管理器的事务的状态。第三方也可以使用KTM来实现他们自己的资源管理器。

TxF和TxR都定义了一组新的文件系统API和注册表API,这些API与现有的API类似,只不过它们包含了一个事务参数。如果一个应用程序想要在一个事务内创建一个文件,它首先要用KTM来创建该事务,然后把结果得到的事务句柄传递给新的文件创建API。虽然后面我们还会看一看KTM的注册表和NTFS实现,但是,它们并非唯一可能的用途。实际上,KTM提供了四个系统对象,通过这四个系统对象可支持各种不同的操作。表3.27列出了这些对象。

实验:列出事务管理器

3.13 热补丁支持

重新引导一台机器以便把最新的补丁都应用上,这对于服务器来说可能会意味着一段显著的宕机时间,这也正是为什么Windows要支持运行时刻的补丁方法,称为热补丁(hot patch,或简化为hotpatch)。与之相反的是冷补丁(cold patch),它要求一次重新引导。热补丁并非只是简单地允许文件可在执行过程中被覆盖;相反地,它包括了一系列可能会被请求执行的复杂操作(这些操作也可能会组合起来)。表3.28列出了这些操作。

尽管热补丁利用了内核的内部机制,但是,它们的实际实现与冷补丁并没有什么不同。补丁本身是通过Windows的更新机制(Windows Update)来提交的,通常是一个可执行文件,其中包含了一个称为Update.exe的程序,此Update.exe程序完成该补丁的提取工作,也执行相应的更新过程。然而,对于热补丁,还存在一个额外的热补丁文件,其扩展名为.hp。此文件包含一个特殊的PE头,称为.HOT1。该PE头包含了一个数据结构,描述了该文件中出现的各种补丁描述符(patch descriptor)。每一个补丁描述符指明了在原始文件中需要被补丁的偏移位置、一个验证机制(它可以包含一份老数据的简单比较、一个校验和,或者一个散列值),以及待补丁的新数据。内核将解析这些描述符,并且执行恰当的修改动作。若是被保护的进程( protected process,有关进程的更多信息,参见第5章),或者其他经过数字签名的二进制映像,在这些情况下,热补丁也必须被经过数字签名,以避免针对敏感文件或进程执行“伪造的”补丁。

注: 因为热补丁文件也包含了原始的数据,所以,热补丁机制也可以被用于在运行时刻卸载(uninstall)一个补丁。

在编译时刻对热补丁的支持,是通过在每个函数的开始处加入7个额外的字节来做到的。其中5个字节被看作前一个函数的结束部分,2个字节被看作函数前缀(function prolog)部分,也就是函数的开始。这里是一个在编译时候支持热补丁信息的函数的例子:

注意,5个nop指令并不做任何实际的事情,而NtCreateFile函数开始处的mov edi, edi也并无实质性的意义―—起码,没有发生实际的状态改变操作。因为有这7个字节可以使用,NtCreateFile前缀部分可以被变换成一个短跳转(short jump),跳至那5个指令构成的缓冲区,而这5个指令的缓冲区又被转换成一个近跳转(near jump)指令,跳至补丁后的例程。下面是被热补丁之后的NtCreateFile:

这种方法使得每个函数只增加2个字节,通过这两个字节跳转到前一个函数的对齐填充部分,这些填充字节极有可能本就在函数末尾存在的。

下面是热补丁功能的一些限制:

  • 像安全软件之类的第三方应用程序可能会阻止这样的补丁;补丁也可能与第三方应
    用程序的操作不兼容。
  • 补丁要修改一个文件的导出表或导入表。
  • 补丁要改变数据结构,修正无限循环,或者包含内联的汇编代码。

3.14 内核补丁保护

有些32位设备驱动程序以一些未被正式支持的方式来修改Windows的行为。

例如,它们通过修改系统调用表来截取系统调用,或者给内存中的内核映像打上补丁,以便为某些特定的内部函数添加功能。Microsoft在发布了针对x64的64位Windows之后不久,同时在一个丰富的第三方生态系统建立起来以前,看到了一个很好的机会来保持64位Windows的稳定性。为了防止这些类型的改变,x64 Windows实现了内核补丁保护(KPP,Kernel Patch Protection),也称作PatchGuard。KPP在系统中的任务就如同其名称所指明的—一它试图阻止那些常用于修补系统或钩住系统的技术。

表3.29列出了哪些组件或数据结构被保护了,以及保护的目的。

注: 由于有些特定的Intel 64位处理器在实现上略微不同于x64体系结构的功能集,所以,内核

需要执行运行时刻的代码补丁,以解决缺失prefetch指令的问题。即使在这些处理器上,KPP也可以阻止内核补丁,它的做法是,将这些特定的补丁免除检查。而且,因为超级监督者(Hyper-V)的启发式增强(有关超级监督者的更多信息,参见本章前面部分),内核中的某些特定函数是在引导时刻被修补的,比如交换环境(swap context)的例程。这些补丁也通过显式检查的方式得以允许通过,确保它们对于超级监督者启发式增强的内核版本是已知的补丁。

当KPP检测到以上提到的数据结构中的任何变化(以及某些其他的内部一致性检查中的变化)时,它会让系统崩溃,代码为0x109——CRITICAL_STRUCTURE_CORRUPTION。

对于用到了KPP阻止的技术的第三方开发人员来说,下面一些支持的技术可供使用:

  • 文件系统小过滤驱动程序(有关这一话题的更多信息,参见本书下册第8章),以钩住所有的文件操作,包括加载映像文件和DLL。截取了这一操作之后,可以动态地清除恶意代码,或者阻止读取已知的坏可执行文件。
  • 注册表过滤通知(有关这些通知的更多信息,参见第4章),以钩住所有的注册表操作。安全软件可以阻止对注册表关键部分的修改操作,以及根据注册表的访问模式或已知的坏注册表键来启发式地判定恶意软件。
  • 进程通知(有关这些通知的更多信息,参见第5章)。安全软件可以监视系统中所有进程和线程的执行和终止,以及DLL的加载和卸载。利用新引入的专门针对防病毒或其他安全厂商的增强通知,它们还可以有能力阻止进程的启动。
  • 对象管理器过滤(在本章前面的对象管理器章节中解释)。安全软件可以移除某些已
    经被授予进程和/或线程的特定访问权限,以防护它们自己的工具被执行某些特定的操作。

3.15 代码完整性

代码完整性(code integrity)是Windows中一项认证可执行映像(比如应用程序、DLL或驱动程序)的完整性和来源的机制,其做法是,检验映像文件的资源部分所包含的一个数字证书。这一机制与系统策略联合起来进行工作,系统策略定义了应如何强制要求签名。其中一个策略是内核模式代码签名(KMCS,Kernel Mode Code Signing)策略,它要求内核模式代码必须经过一个有效的Authenticode证书进行签名,并且此证书必须是少数几个公认的代码签名机构,比如VeriSign或Thawte,作为其根证书。

为了解决向后兼容性的问题,KMCS策略只在64位机器上才完全被强制要求,因为这些驱动程序最近已经被重新编译过了,目的就是为了能在此Windows体系结构上运行。这也进一步隐含着,一个公司或个体仍然要维护其驱动程序,并且要能够对驱动程序进行签名。然而,在32位机器上,许多老的设备随带的是过时的驱动程序,这些驱动程序甚至可能来自于一些已不复存在的公司,所以,对这些驱动程序进行签名有时候是不现实的。图3.43显示了在64位Windows机器上试图加载一个未经签名的驱动程序时显示的警告信息。

注:Windows也有第二个驱动程序签名策略,这也是即插即用管理器的一部分。该策略仅被应用在即插即用驱动程序上;与内核模式代码签名策略不同的是,该策略可以被配置成允许未经签名的即插即用驱动程序(不过在64位系统上不行,因为在64位系统上KMCS策略是优先的)。有关即插即用管理器的更多信息,请参见本书下册第8章。

注意,即使在32位机器上,当加载一个未经签名的驱动程序时,代码完整性机制也会在Code Integrity事件日志中写入一个事件。

注“受保护的媒体路径(Protected Media Path)”应用程序也可以向内核询问其完整性状态

(integrity state),这包括涉及“是否有未经签名的32位驱动程序被加载到系统中”这样的信息。在这种情形下,它们可以禁止受保护的、高清晰度的媒体播放,作为保护加密媒体流的安全性和可靠性的一种方法。

然而,代码完整性机制并不止于驱动程序加载时刻。更强的措施也存在,对于可执行代码页,它可以认证每个页面的映像内容。这要求在对驱动程序二进制文件进行签名时使用一个特殊的标志,从而产生一个目录,其中包含了该驱动程序所在的每一个可执行页面的密码学散列值。(页面是CPU上的保护单位;更多的信息,请参见本书下册第10章。)这种方法也使得可以检测到对一个已有驱动程序的修改:可能在运行时刻碰巧由其他驱动程序进行修改,或者通过一个页面文件进行修改,或者通过休眠文件攻击而实施的修改(在磁盘上修改内存的内容,然后重新加载到内存中)。针对每个页面产生散列值,也是新的过滤模型的一个要求,也是“受保护的媒体路径(Protected Media Path)”组件的要求。

本章总结

在本章中,我们看到了Windows执行体赖以建立起来的关键的基本系统机制。在下一章中,我们将会看到三个重要的、与Windows的管理基础设施有关的机制:注册表、服务,以及WMI( Windows Management Instrumentation,Windows管理规范)。

相关文章
|
2月前
|
存储 物联网 调度
操作系统的心脏:内核深度解析
在数字世界的构建中,操作系统扮演着基石的角色,而其核心—内核,则是这一复杂系统的灵魂。本文将深入探讨操作系统内核的工作原理,揭示它是如何管理硬件资源、运行程序以及提供系统服务的。通过理解内核的结构和功能,我们可以更好地把握计算机系统的运作机制,进而优化和创新我们的技术实践。
|
3月前
|
设计模式 算法 安全
实时操作系统(RTOS)深度解析及Java实现初探
【10月更文挑战第22天】实时操作系统(RTOS,Real-Time Operating System)是一种能够在严格的时间限制内响应外部事件并处理任务的操作系统。它以其高效、高速、可靠的特点,广泛应用于工业自动化、航空航天、医疗设备、交通控制等领域。本文将深入浅出地介绍RTOS的相关概念、底层原理、作用与功能,并探讨在Java中实现实时系统的方法。
109 1
|
2月前
|
安全 Windows
【Azure Cloud Service】在Windows系统中抓取网络包 ( 不需要另外安全抓包工具)
通常,在生产环境中,为了保证系统环境的安全和纯粹,是不建议安装其它软件或排查工具(如果可以安装,也是需要走审批流程)。 本文将介绍一种,不用安装Wireshark / tcpdump 等工具,使用Windows系统自带的 netsh trace 命令来获取网络包的步骤
73 32
|
28天前
|
安全 前端开发 Android开发
探索移动应用与系统:从开发到操作系统的深度解析
在数字化时代的浪潮中,移动应用和操作系统成为了我们日常生活的重要组成部分。本文将深入探讨移动应用的开发流程、关键技术和最佳实践,同时分析移动操作系统的核心功能、架构和安全性。通过实际案例和代码示例,我们将揭示如何构建高效、安全且用户友好的移动应用,并理解不同操作系统之间的差异及其对应用开发的影响。无论你是开发者还是对移动技术感兴趣的读者,这篇文章都将为你提供宝贵的见解和知识。
|
2月前
|
存储 负载均衡 Java
如何配置Windows主机MPIO多路径访问存储系统
Windows主机多路径(MPIO)是一种技术,用于在客户端计算机上配置多个路径到存储设备,以提高数据访问的可靠性和性能。本文以Windows2012 R2版本为例介绍如何在客户端主机和存储系统配置多路径访问。
119 13
如何配置Windows主机MPIO多路径访问存储系统
|
2月前
|
缓存 并行计算 Linux
深入解析Linux操作系统的内核优化策略
本文旨在探讨Linux操作系统内核的优化策略,包括内核参数调整、内存管理、CPU调度以及文件系统性能提升等方面。通过对这些关键领域的分析,我们可以理解如何有效地提高Linux系统的性能和稳定性,从而为用户提供更加流畅和高效的计算体验。
35 2
|
2月前
|
存储 人工智能 安全
操作系统的心脏——内核深度解析
【10月更文挑战第29天】 本文深入探讨了操作系统的核心组件——内核,包括其定义、功能、架构以及在现代计算中的重要性。通过对比不同操作系统内核的设计哲学和技术实现,揭示了内核如何影响系统性能、稳定性和安全性。此外,文章还讨论了未来内核技术的潜在发展方向,为读者提供了一个全面了解内核工作原理的平台。
|
2月前
|
存储 消息中间件 算法
深入探索操作系统的心脏——内核机制解析
本文旨在揭示操作系统核心——内核的工作原理,通过剖析其关键组件与机制,为读者提供一个清晰的内核结构图景。不同于常规摘要的概述性内容,本文摘要将直接聚焦于内核的核心概念、主要功能以及其在系统管理中扮演的角色,旨在激发读者对操作系统深层次运作原理的兴趣与理解。
|
2月前
|
开发工具 Android开发 数据安全/隐私保护
探索移动应用的世界:从开发到操作系统的全面解析
【10月更文挑战第33天】在数字化时代,移动应用已成为我们日常生活中不可或缺的一部分。本文将深入探讨移动应用的开发过程,包括编程语言、开发工具和框架的选择,以及如何构建用户友好的界面。同时,我们还将分析移动操作系统的核心功能和安全性,以帮助读者更好地理解这些应用程序是如何在各种设备上运行的。无论你是开发者还是普通用户,这篇文章都将为你揭示移动应用背后的奥秘。
|
3月前
|
Windows
.NET 隐藏/自定义windows系统光标
【10月更文挑战第20天】在.NET中,可以使用`Cursor`类来控制光标。要隐藏光标,可将光标设置为`Cursors.None`。此外,还可以通过从文件或资源加载自定义光标来更改光标的样式。例如,在表单加载时设置`this.Cursor = Cursors.None`隐藏光标,或使用`Cursor.FromFile`方法加载自定义光标文件,也可以将光标文件添加到项目资源中并通过资源管理器加载。这些方法适用于整个表单或特定控件。

推荐镜像

更多