在7年多服务本土用户的过程中,神州网信技术团队通过对Windows源代码进行查看、分析、编译、测试、调试,支撑起百万级装机量产品的开发、交付和服务,积累了大量大型基础软件的工程化工作经验,培养了一支同时具备开源和商用操作系统源代码级别架构分析和改进能力的人才队伍。
【技术分享】专题将精选转发技术团队撰写的部分文章,与大家分享和交流。
Windows操作系统经历了一系列的版本变化,从早期版本如Windows XP、Windows Vista、Windows 7一直到当前的Windows 10和最新的Windows 11。每个主要版本的变化都会引入新功能和创新,丰富用户体验。
为了确保Windows操作系统不断演进和改进,更新扮演着至关重要的角色。这些更新不仅引入新功能,还修复安全漏洞,提升系统性能,改善整体用户体验。本文旨在探索一种研究Windows更新以及更新对系统文件所带来变化的方法。希望基于这种方法分析不同版本之间系统文件的变化,从而更深入地了解Windows更新的影响。
Windows 10 更新机制
Windows 10的更新机制在之前的文章中已有讨论,这里将进行简要回顾。Windows系统可以通过在线联网获取更新,也可以通过从目录网站下载离线更新文件(以 .msu 或 .cab 格式)进行更新。前一种方式通常由个人用户通过Windows默认的更新服务器完成,后一种方式涉及通过双击.msu文件进行离线安装,或使用命令行安装.cab文件。
在更新包的生命周期中,包括创建(内容生成和打包)、分发、安装,以及可能的替代或撤回情况。分发通常分为个人用户通过Windows默认服务器获取更新,以及企业用户利用更新管理软件(如WSUS、SCCM或第三方工具)进行更新管理。
本文将探讨更新安装过程中的系统文件变化。
WinSxS的作用
更新安装离不开WinSxS1支持。为了解释WinSxS文件夹的作用,我们将围绕两个概念进行讨论:DLL地狱和硬链接WinSxS(Windows Side by Side)文件夹位于%windir%下,首次引入Windows Vista操作系统,并在后续的Windows版本中继续存在。"DLL 地狱" 是指动态链接库(DLL)版本冲突和管理问题,这在早期的Windows版本中经常出现。在这种情况下,多个应用程序可能会依赖于同一个DLL文件的不同版本,导致冲突和不稳定性。
通过引入WinSxS,Windows可以有效地管理不同版本的DLL文件和其他系统组件。每个应用程序可以指定其所需的特定版本,而不会影响其他应用程序的需求。这种隔离和版本管理的方法可以防止DLL版本冲突,从而减轻了"DLL 地狱" 问题。
因此,WinSxS的主要目标之一就是通过提供有效的版本控制和共存性机制来解决 "DLL 地狱" 问题,从而确保系统的稳定性和向后兼容性。
硬链接是一种文件系统技术,在WinSxS文件夹内用于在不同目录之间共享文件数据,以节省磁盘空间。硬链接允许一个文件具有多个目录路径,这些路径实际上都指向同一个文件的数据,从而避免在磁盘上存储多份相同的数据副本。
在WinSxS文件夹中,通过使用硬链接来管理不同版本的系统组件。这些版本可以共享某些相同的文件,例如共享的DLL文件。通过使用硬链接,多个组件版本可以引用相同的文件数据,从而节省磁盘空间,同时确保这些版本都能访问所需的文件。
Windows提供了用于查看硬链接的内置工具,使用命令:fsutil hardlink进行查看。
正向/逆向差分机制
从Windows 10版本1809开始,Windows引入了正向/逆向差分机制2,用于系统更新。可以通过以下两个公式简要地解释这一机制:
其中,VN代表计算机当前的状态,V0代表计算机回到RTM状态,VR代表计算机更新至最新状态。计算机在安装RTM版本后的首个累积更新时,通过应用正向差分文件Δ0−>1将基础版本文件(RTM)更新至目标版本V1。此时,累积更新中同时包含的逆向差分文件Δ1−>0会被保存到用户本地计算机。在后续安装新的累积更新的时候,Δ1−>0将被用于恢复(系统)文件至RTM版本。同时,该累积更新中包含的逆向差分文件被保存到用户本地计算机,用于下次累积更新。
从两个角度重新审视 Windows 10 中的正向/逆向差分机制可以获得新的认识。首先,虽然Vx代表计算机的整体状态,但通过深入研究,Vx也可以代表计算机内部的具体文件。其次,当分别研究这两个公式时windows 判断文件存在,无论是通过逆向差分获取RTM版本文件,还是保留原始的RTM文件,在此基础上都可以应用每月的累积更新,得到对应月份的更新后文件。
有了这个思路,我们就可以继续实现通过Windows月度累积更新获取不同版本的系统文件的过程。
获取不同版本系统文件
我们以Windows 10版本22h2为测试系统,刚刚完成了7月份的累积更新(KB5028166),其系统内部版本变为19045.3208。接下来,我们将尝试获取不同版本的kernel32.dll文件,包括当前版本、RTM版本以及2023年2月份的版本。下面是具体的操作步骤:
操作步骤
1.获取指定版本的MSU文件首先打开网站,查找适用于22h2的2月份的累积更新,在搜索框中输入关键词2023-02 Windows10 22h2 x64。然后下载 KB5022834更新包,这是一个离线的.msu格式的文件。
2.展开MSU更新包至最小结构,得到差分文件。通过使用Windows中的expand工具,我们将MSU文件展开到最小单位。以下为展开的过程演示:
通过执行命令expand.exe -f:* "dd\xx.msu" extract_target_folder,我们可以将KB5022834更新包展开。展开过程中的1到4步可以使用expand命令进行,图中的红线表示待展开的文件,下一级则为被展开的内容。到达步骤4时,已经完成了展开。步骤5展示了任意打开一个文件夹后,我们可以看到f和r两个文件夹,它们包含了正向和逆向差分文件。
3.确定要处理的文件
在步骤2中展开的文件结构中,我们需要查找kernel32.dll的差分文件。其所在的文件夹是amd64_microsoft-windows-kernel32_31bf3856ad364e35_10.0.19041.2546_none_08614a550b96fd23
4. 获取系统中对应文件的f和r系统中kernel32.dll默认位于%windir%\system32目录下。然而,此目录中只有一个dll文件。如果想获取不同版本的kernel32.dll文件,首先需要将该文件恢复至RTM版本。通过查看WinSxS中的硬链接,我们可以执行以下命令获得相关信息:
fsutilhardlink list C:\Windows\System32\kernel32.dll
此命令的结果将展示硬链接的信息:
打开硬链接所在目录,
当前目录下的kernel32.dll与system32文件夹下kernel32.dll为同一个文件。同时还能够看到f和r文件夹,这里面的文件就是我们要用到的差分文件。
5. 利用差分文件生成目标文件
整个过程涉及三个版本dll文件:蓝色图标对应版本号为10.0.19041.3155的kernel32.dll文件,它是系统安装完7B累积更新后的文件;绿色图标对应版本号为10.0.19041.1的kernel32.dll文件,它就对应着刚刚安装完最初发布的22h2系统中的kernel32.dll文件;红色图标对应版本号为10.0.19041.2546的kernel32.dll文件,它是在10.0.19041.1版本的kernel32.dll文件之上应用了前向差分文件。
四个方向的差分操作通过msdelta3提供的ApplyDeltaB接口实现。此接口不区分正向与逆向,只需要提供原始文件和差分文件,即可生成目标文件。需要注意的是,delta文件携带校验码信息,在应用该delta文件的时候需要跳过校验码信息才能生效,否则报会报告格式错误4。首先,我们通过逆向操作【技术分享】探究Windows 10累积更新与系统文件变化,从当前版本的 kernel32.dll生成了RTM状态的kernel32.dll文件。接着,通过正向操作,从RTM版本的kernel32.dll生成了当前版本的kernel32.dll。随后,我们应用 了2B包中的正向差分文件,生成了版本号为10.0.19041.2546的kernel32.dll文件。最后,我们将安装完2B更新后的kernel32.dll文件逆向生成了RTM版本的kernel32.dll。
文件比较与分析
通过之前的步骤,我现在已经获取了三个不同版本的 kernel32.dll 文件。下面,我将对 RTM 版本和2023年 2月份版本的文件差异进行比较和分析。
BinDiff的使用在进行二进制文件比较与分析时,我使用了BinDiff5工具。BinDiff是一款强大的二进制文件对比工具, 专门用于比较两个不同版本的二进制文件之间的差异。该工具能够以字节为单位对比文件,识别并展示文件中的新增、删除和修改部分,帮助我们发现文件的具体差异。通过将两个文件进行精细的比较,能够深入了解系统更新对文件的影响,以及其中涉及的具体变化。
在本文的例子中,我们使用了BinDiff工具来比较不同版本的kernel32.dll文件,以揭示这些文件之间的细微但重要的变化。
简单示例这里比较一下Windows kernel32.dll的变化。我们会按照"相似度"对变化进行排序【技术分享】探究Windows 10累积更新与系统文件变化,相似度值不等于1代表存在差异。较小的相似度值表示较大的差异。
接下来,我们选择一个变化较小的函数进行示例,这里我们选用了 BackupReadReparseData函数。
右键点击后选择 "View flow graphs",即可进入二进制对比页面。在这里,我们可以清楚地看到二进制级别的差异,主要是cmp指令被替换为test指令:
右侧是原始文件,左侧是更新后的文件,主要差异被红框标注出来。右侧的代码检查了内存中a2+1132处的值,然后与0x400进行按位与操作,用以检查特定位是否被设置。如果结果不为零,条件语句中的代码将会被执行。而左侧的代码则是对内存中a2+1132处的值与0x400400进行按位与操作,然后将结果与1024进行比较。这样可以有效地检查这两个比特位是否被设置。
通过对这两段代码进行反汇编分析,我们可以发现这次变化的内容在于原先的条件判断:
if ((*(_DWORD* )(a2 + 1132) & 0x400) != 0)
变为了新的条件判断:
if ((*(_DWORD* )(a2 + 1132) & 0x400400) == 1024)
这个变化使得我们可以更有效地检查两个特定的比特位是否同时被设置。这种详细的二进制级别对比分析为我们揭示了更新包对系统文件的微小但重要的改动。
分析与结论
在本文中,我们探索了一种利用Windows 10系统更新的差分机制来获取不同版本系统文件的方法。这种方法并不是我的原创,我只是在这里复现了完整的操作步骤,并给出一些自己的思考。这种分析方法在很多方面都具有显著的优势,为系统更新的研究和分析带来了便捷和高效。以下是这种方法所带来的几大好处:
避免安装后的比较分析
相对于传统的操作方法,该方法避免了对安装后的文件进行比较分析。这种"离线"的工作方式,不仅节省了安装和配置的时间,还避免了可能对当前系统产生的影响。通过直接从更新包中提取所需文件,我们可以在独立的环境中进行分析,确保分析结果的准确性。
提高效率
这种方法无需安装更新包,不依赖于当前系统版本,并且不会对当前系统产生任何影响。我们可以轻松地获取更新对系统的改变列表,而无需检查整个系统的文件。这大大提高了获取变化文件的效率。从操作步骤中可以看到,仅需下载更新包,展开其中的差分文件,即可获得不同版本的文件。整个过程简洁明了,不需要繁琐的设置和配置。
增强分析能力
通过比较不同版本的文件,我们能够深入了解系统更新对文件的影响。这种分析方法帮助我们更好地理解更新包中的具体变化,无论是微小的细节还是更大范围的改动。通过分析差异,我们能够识别潜在的风险、改进点和系统性能的变化。
扩展应用领域
除了在本文中介绍的示例外,这种方法还有许多其他潜在的应用领域。开一下脑洞windows 判断文件存在,因为获得更新文件的效率提升,我们可以高效绘出每个月安装更新后文件的差异图;如果再结合AI的帮助,可能会加速系统安全状况分析;我们还可以将这种方法用于文件恢复、文件修复等场景,提供更精确和高效的解决方案。
综上所述,利用Windows 10系统更新的差分机制进行文件版本分析是一种高效、准确的方法。它为我们提供了一种全新的视角,让我们能够更好地理解系统的演变和变化,为系统维护、性能优化和安全研究等提供了有力的支持。在未来的研究中,我们还可以进一步探索这种方法的潜力,将其应用于更多的场景,为技术和安全研究带来更多的帮助。
参考资料
1.Manage the Component Store
2.Windows Updates usingforward and reversedifferentials
3.Delta Compression Application Programming Interfaces
4.Cannot apply patchfile using msdelta
5.BinDiff
标签: 更新包 系统文件变化 硬链接 WinSxS 文件夹 累积更新
留言评论