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

本文涉及的产品
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: [笔记]深入解析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管理规范)。

相关文章
|
14天前
|
机器学习/深度学习 存储 人工智能
让模型评估模型:构建双代理RAG评估系统的步骤解析
在当前大语言模型(LLM)应用开发中,评估模型输出的准确性成为关键问题。本文介绍了一个基于双代理的RAG(检索增强生成)评估系统,使用生成代理和反馈代理对输出进行评估。文中详细描述了系统的构建过程,并展示了基于四种提示工程技术(ReAct、思维链、自一致性和角色提示)的不同结果。实验结果显示,ReAct和思维链技术表现相似,自一致性技术则呈现相反结果,角色提示技术最为不稳定。研究强调了多角度评估的重要性,并提供了系统实现的详细代码。
41 10
让模型评估模型:构建双代理RAG评估系统的步骤解析
|
5天前
|
移动开发 Android开发 数据安全/隐私保护
移动应用与系统的技术演进:从开发到操作系统的全景解析随着智能手机和平板电脑的普及,移动应用(App)已成为人们日常生活中不可或缺的一部分。无论是社交、娱乐、购物还是办公,移动应用都扮演着重要的角色。而支撑这些应用运行的,正是功能强大且复杂的移动操作系统。本文将深入探讨移动应用的开发过程及其背后的操作系统机制,揭示这一领域的技术演进。
本文旨在提供关于移动应用与系统技术的全面概述,涵盖移动应用的开发生命周期、主要移动操作系统的特点以及它们之间的竞争关系。我们将探讨如何高效地开发移动应用,并分析iOS和Android两大主流操作系统的技术优势与局限。同时,本文还将讨论跨平台解决方案的兴起及其对移动开发领域的影响。通过这篇技术性文章,读者将获得对移动应用开发及操作系统深层理解的钥匙。
|
6天前
|
算法 调度
操作系统的心脏:深入解析进程调度算法
本文旨在深入探讨现代操作系统中的核心功能之一——进程调度。进程调度算法是操作系统用于分配CPU时间片给各个进程的机制,以确保系统资源的高效利用和公平分配。本文将详细介绍几种主要的进程调度算法,包括先来先服务(FCFS)、短作业优先(SJF)、时间片轮转(RR)以及优先级调度(PS)。我们将分析每种算法的基本原理、优缺点及其适用场景。同时,本文还将讨论多级反馈队列(MFQ)调度算法,并探讨这些算法在实际应用中的表现及未来发展趋势。通过深入解析这些内容,希望能够为读者提供对操作系统进程调度机制的全面理解。
|
22天前
|
域名解析 缓存 网络协议
域名系统DNS_基础知识
域名系统(DNS)使我们能够通过易记的域名访问互联网资源,而非直接使用IP地址。DNS采用层次树状结构,由多个分量组成,如顶级域名(如.com或.cn)位于最右侧。域名长度限制为255个字符,各级域名由相应管理机构监管,顶级域名由ICANN管理。DNS分为国家顶级域名、通用顶级域名和反向域等。域名解析涉及根域名、顶级域名及权限域名服务器,通过递归和迭代查询完成。为提高效率,DNS使用分布式服务器和高速缓存技术。
|
19天前
|
算法 Linux 调度
操作系统的心脏:现代操作系统架构的深度解析
本文深入探讨了现代操作系统的架构设计,重点分析了进程管理、内存管理和文件系统等核心组件。通过对Linux和Windows两大主流操作系统的比较,揭示了不同设计哲学在实际应用中的表现。旨在为操作系统开发者提供参考,同时帮助普通用户更好地理解其设备背后的软件机制。 ##
35 2
|
8天前
|
测试技术 UED 开发者
软件测试的艺术:从代码审查到用户反馈的全景探索在软件开发的宇宙中,测试是那颗确保星系正常运转的暗物质。它或许不总是站在聚光灯下,但无疑是支撑整个系统稳定性与可靠性的基石。《软件测试的艺术:从代码审查到用户反馈的全景探索》一文,旨在揭开软件测试这一神秘面纱,通过深入浅出的方式,引领读者穿梭于测试的各个环节,从细微处着眼,至宏观视角俯瞰,全方位解析如何打造无懈可击的软件产品。
本文以“软件测试的艺术”为核心,创新性地将技术深度与通俗易懂的语言风格相结合,绘制了一幅从代码审查到用户反馈全过程的测试蓝图。不同于常规摘要的枯燥概述,这里更像是一段旅程的预告片,承诺带领读者经历一场从微观世界到宏观视野的探索之旅,揭示每一个测试环节背后的哲学与实践智慧,让即便是非专业人士也能领略到软件测试的魅力所在,并从中获取实用的启示。
|
2月前
|
监控 网络协议 Java
Tomcat源码解析】整体架构组成及核心组件
Tomcat,原名Catalina,是一款优雅轻盈的Web服务器,自4.x版本起扩展了JSP、EL等功能,超越了单纯的Servlet容器范畴。Servlet是Sun公司为Java编程Web应用制定的规范,Tomcat作为Servlet容器,负责构建Request与Response对象,并执行业务逻辑。
Tomcat源码解析】整体架构组成及核心组件
|
2月前
|
存储 NoSQL Redis
redis 6源码解析之 object
redis 6源码解析之 object
58 6
|
20天前
|
存储 缓存 Java
什么是线程池?从底层源码入手,深度解析线程池的工作原理
本文从底层源码入手,深度解析ThreadPoolExecutor底层源码,包括其核心字段、内部类和重要方法,另外对Executors工具类下的四种自带线程池源码进行解释。 阅读本文后,可以对线程池的工作原理、七大参数、生命周期、拒绝策略等内容拥有更深入的认识。
什么是线程池?从底层源码入手,深度解析线程池的工作原理
|
24天前
|
开发工具
Flutter-AnimatedWidget组件源码解析
Flutter-AnimatedWidget组件源码解析

推荐镜像

更多
下一篇
无影云桌面