[Beta 探究] 如何解除 Flightsigned Build 的时间炸弹

什么是 “Flightsigning”

Flightsigning 描述了使用 flight 证书对文件进行数字签名的过程。Microsoft 用于签署 Windows 系统文件的证书有 4 种常见类型:

  • PreProd – PCA 2010
  • Prod – PCA 2011
  • Flight – Development PCA 2014
  • Test – 各种各样的东西,最常见的是 MSIT Test CodeSign CA

Flight 只是 Microsoft 使用的一个特定证书/证书系列,当使用 flight 证书签名时,该版本称为 flightsigned 版本。

为什么 “Flightsigned” 版本无法在当前日期启动

用于对早期 flightsigned 版本进行签名的证书明确指定了过期时间,并设计为在系统时间超过过期时间后立即失效。这意味着一旦这些 flight 证书过期,Windows 将把这些证书数字签名的系统文件视为无效文件。

这有点像你不能用打补丁的系统文件正常启动 Windows。不同之处在于,如果签名因二进制文件的修改而无效,则可以使用 NOINTEGRITYCHECKS BCD 选项强制引导加载程序继续引导,但如果证书过期,引导加载程序将停止加载。

这意味着系统时间不得超过这些 flight 证书的到期时间,因此不能在当前日期启动 flightsigned 版本。

我为什么要写这个指南

在过去的 15 年里,我一直在玩基于 DOS 和基于“经典” NT 的 Windows 的 Beta。一周前,我突然决定玩“现代”版本的 Windows,因为我对它们一无所知。我相信从 Windows 10 测试版开始是一个很好的开始。

我选择了 Windows 10 的第一个正式预发布版本(build 9841)- 真是个错误!我认为这可能是最容易解除时间炸弹的版本,而我忽略了一个事实,即甚至没有人谈论解除它的时间炸弹。然后我读到只有 fbl_partner_eeap 版本的时间炸弹可以被删除,因为它们包含“非功能的时间炸弹,因此可以在当前日期安装”。好吧,我想挑战一下这个只有 fbl_partner_eeap 版本可以解除时间炸弹的事实,所以我选择继续尝试 9841(fbl_release flightsigned 版本)。

毫无疑问,我高估了自己的能力,意识到解除 flightsigned 版本的时间炸弹就像经历了 9 个地狱圈。嗯,你看既然我在说如何解除它的时间炸弹,很明显,我最终成功了。这是一场漫长而艰难的战斗,我花了将近一周的时间才完全击败 flightsigning。

最初,我修补了内核以启用 NOINTEGRITYCHECKS,然后将所有系统文件的所有数字签名中的所有证书替换为来自 build 9838 的非 flight 证书。是的,它成功了,但目录文件也用 flight 证书进行了数字签名。然后我去把所有的目录都换成了 9838 版本的目录——它不起作用。那么,ci.dll 的补丁似乎是唯一的出路。

因此,最后我修补了 ci.dll,然后 Windows Loaderwinload.exe/winload.efi)以加载修补后的 ci.dll,最后 Boot Manager 以加载修补后的 Windows Loader。这听起来很容易,但实际上要难得多… 其实没那么难,只是很乏味。我修补了20个文件,只是为了安全地让 Windows 10 build 9841 的 x86 版本在当前日期启动,而替换 boot.wiminstall.wimwinre.wim 的所有索引中出现的所有文件花费了更多的时间。由于这个过程非常繁琐,我不打算修补每个 flightsigned 版本的每个架构,所以我只想发布一个指南,希望它能适用于所有架构中的所有 flightsigned 版本。

观众

本指南仅供有经验的读者阅读。要理解这些过程并亲自执行修补,您必须充分了解现代版本 Microsoft Windows 的引导过程。您还应该能够理解 C/C++ 和所需架构的汇编语言。

如果您自己没有能力执行修补,我可以为您修补它们,前提是您在下面的评论部分上传所需的文件(因为我是一个大好人)。目前我只能修补 UEFI Boot Manager 和 Windows Loader,因为旧版 BIOS 的修补非常耗时。您必须上传 ci.dllwinload.efiwinresume.efibootmgr.efibootmgfw.efi。不要忘记,补丁只负责禁用证书到期检查,您仍然需要按照指南来解除时间炸弹。

如果您希望自己修补这些文件,请继续阅读以下部分。

修补 Windows 以在当前日期启动

由于存在不同的架构,即使对于相同的架构,补丁也可能不同(不同的偏移量、不同的寄存器),因此我将主要使用 C/C++ 伪代码演示补丁。

ci.dll

要修补的第一个文件是 ci.dll,它是负责签名验证的代码完整性库。我们不会完全删除签名验证,我们只是让它忽略过期的证书。

有一个名为 STATUS_IMAGE_CERT_EXPIRED 的状态,我们不希望 return 该状态。因此,我们需要修补可能 return STATUS_IMAGE_CERT_EXPIRED 的函数。由于不同的版本具有不同数量能够 return STATUS_IMAGE_CERT_EXPIRED 的函数,并且这些函数可能都不同,因此您应该在 ci.dll 中搜索 0x0C0000605。当您发现类似 mov ???, 0C0000605h 的内容时,请检查是什么原因导致 0C0000605h 移动到 ??? 寄存器,您会发现这样的 if 语句:

if ( condition )
{
  // certificate expired
  result = STATUS_IMAGE_CERT_EXPIRED;
}
// certificate not expired

我们需要删除 if 语句,最好是将条件跳转修补为无条件跳转,或者 NOP 掉条件跳转(取决于具体情况)。确保找到所有的 mov ???, 0C0000605h 并对其进行修补。

由于我们修改了系统文件,所以为了安全起见,还应该对 CipReportAndReprieveUMCIFailure 进行修补。在这里,我们需要让 (g_CiDeveloperMode & 1) != 0if 语句中的代码执行,无论 g_CiDeveloperMode 的值如何。

if ( (g_CiDeveloperMode & 1) != 0 )
{
  // code here
  EventDescriptor = (const EVENT_DESCRIPTOR *)CiPolicyFailureIgnored;
  *(BYTE *)a10 = 1;
  // code here
}

您应该在 TEST 指令之后找到一个条件跳转。同样,根据具体情况,你需要要么将条件跳转修补为无条件跳转,或者直接 NOP 掉它。

没有符号的额外步骤

对于 g_CiDeveloperMode 的修补,您需要首先识别 CipReportAndReprieveUMCIFailure 函数。要识别该函数,请搜索 ASCII 字符串 “This break indicates this binary is not signed correctly”,然后跳转到引用。向上滚动,直到找到对 PsGetProcessProtection 的调用,并在上面不远处看到一个 TEST 指令(test something, 10h)。一旦你找到了,你应该看到另一个 TEST 指令(test something, 1)在这条指令之上,而这个 TEST 指令就是 (g_CiDeveloperMode & 1) != 0if 语句。现在,您可以像使用调试符号一样,在它的正下方修补条件跳转。

winload.efi/winload.exe, winresume.efi/winresume.exe

由于我们修补了 ci.dll,因此必须修补 Windows Loader 以加载修补的 ci.dll。有两个东西需要修补 – 签名有效性检查(导致蓝屏显示 Windows 无法加载 xxx 的原因)和引导选项检查(防止自动修复屏幕)。

对于签名有效性检查,我们需要删除对 ImgpValidateImageHash 函数 return 值的检查。您也可以将 ImgpValidateImageHash 本身修补为 return 零,但我建议您修补 return 值检查(将复杂函数修补为仅 return 0 可能会导致不希望的效果)。首先找到 ImgpValidateImageHash 函数,跳转到引用,您应该看到 return 值被移动到另一个寄存器,然后是一个 TEST 指令。您应该修补 TEST 指令下的条件跳转,如果其跳转到 if 语句之外,则修改为无条件跳转,以避免 if 语句内的代码被执行。如果它跳转到 if 语句之内,那么您应该 NOP 掉条件跳转。代码可能是这样子的:

result = ImgpValidateImageHash(something);
if ( result < 0 )
{
  result = ImgpFilterValidationFailure(something);
  if ( result < 0 )
  {
    if ( (something & 0x20) != 0 )
      goto Label;
    result = 0;
  }
}

然后,您应该修补 BlImgQueryCodeIntegrityBootOptions,告诉 Windows Loader 忽略“已损坏”的文件,以避免每次启动 Windows 时出现“准备自动修复”屏幕。您只需要将第二个参数(IntegrityChecksDisabled,一个 PBOOLEAN)设置为 TRUE

没有符号的额外步骤

要找到 ImgpValidateImageHash 函数,请搜索 ASCII 字符串 “1.3.6.1.4.1.311.61.4.1”,然后跳转到引用。要找到 BlImgQueryCodeIntegrityBootOptions 函数,请搜索 0x16000048 直到在其下方不远处看到 0x16000049,然后继续搜索 0x16000048 直到再次在其下方看到 0x16000049

bootmgr/bootmgr.efi, memtest.exe/memtest.efi, cdboot.efi

Boot Manager 也必须进行修补,才能加载修补的 Windows Loader。该修补过程与 Windows Loader 修补过程相同,只是不需要修补 BlImgQueryCodeIntegrityBootOptions。最困难的部分是修改压缩的 bootmgr 文件以用于传统 BIOS 引导。如果您使用的是 UEFI,那么在修补完这些 Boot Manager .EFI 文件后,您就完成了所有操作。

要修补压缩的 bootmgr 文件,首先需要了解其结构。它可以分为 4 个部分 —— 一个原始的 16 位 stub 加载器,一个包含压缩部分信息的自定义结构,一个 stub PE 文件,最后是压缩的 Boot Manager。

第一步是解压缩它或找到一个未压缩的副本。您应该能够在 boot.wim (WinPE)中找到一个名为 bootmgr.exe 的文件,该文件与 bootmgr 中的 Boot Manager 文件相同,只是没有被压缩。然后,您需要按照上面的 Boot Manager 修补方法进行修补。最后,您必须压缩经过修补的可执行文件并将其添加回 bootmgr。对于压缩,您可以使用 joakim 的 BOOTMGR 重新编译程序 v2。它输出一个带有硬编码 16 位 stub 的组合 bootmgr,因此我强烈建议您从输出文件中提取压缩部分,并用它替换原始 bootmgr 文件的压缩部分。当然,您还必须修改 16 位 stub 下面的自定义结构和 PE stub 的 PE 校验和。jaokim 记录了自定义结构,因此请参见 BOOTMGR 重新编译程序 v2 项目页面。PE 校验和更正有点困难,所以我反编译了一些 bootmgr 签名检查函数并将其组合成了一个程序。只需运行它来显示正确的校验和,然后将 PE stub 的 PE 校验和更改为正确的校验和。

解除时间炸弹

令人惊讶的是…也许不是,上面的长篇大论甚至与解除时间炸弹无关。如果您正确地修补了所有文件,您现在应该能够在当前日期启动 Windows,但定时炸弹仍然存在。与 Windows 10 的其他预发布版本一样,flightsigned 版本也可以按照这个 BetaArchive 的指南进行拆解。那个指南有点混乱,所以当我有时间的时候,我会为 BetaWorld 写一个更好的指南。

一些解除时间炸弹的版本和修补后的文件

感谢我同事的翻译,他友好而礼貌的留言:”thank you so much lucas for giving me this f___ing piece of s__t to translate, after translating this s__t I know more about f___ing win 10 than anyone on the f___ing net m_____f___er

编辑:感谢 Zammis Clark 提出文中错误,现已修正。同时他还指出,“最好”的方法可能是fork EfiGuard 项目并用于修改 ci.dll 中的签名检查部分,这样就不需要使用拐弯抹角的方法处理文件。

下页是英文原文 :

[Beta 探究] 如何解除 Flightsigned Build 的时间炸弹》上有114个想法

  1. 请不要发送任何请求 – 您可以自己尝试去做,这篇文章的意义是告诉大家怎么去做,而不是让你在下面发请求 – 这样的话文章就没有意义了。

    希望读读,实在不会可以在下面求助什么的,直接要成品还是算了吧。

      • I am such a nice person

        If I didn’t say send it to me and I’ll patch it for you, then I bet most people are still going to ask me to patch it for them – didn’t want them to feel guilty for asking (unless they’re those annoying BA kids). To be honest, I didn’t expect anyone to even understand my guide, especially the Chinese translation which probably isn’t that professional (sorry but it is true and you know it, my friend… if you are reading this). The guide is more or less for people with some reverse engineering experience, and for proving that flightsigned builds can indeed be debombed (often referred to as “the impossible task”). Someone in the BetaWiki Discord server actually patched a few builds by himself after reading this guide and seeking out for help. I should be able to help you as long as you don’t make me download an entire ISO or show you every single step (like which letter to type and where to click your mouse).

        I am quite busy right now so don’t expect anything from me in the coming weeks. Of course also don’t be afraid to ask me, either here or on Discord or by email (drop a comment if you need my Discord tag or email address).

  2. Thanks!
    Just replaced the files on the VHD installation, but I get this error:

    \Windows\System32\winload.efi
    0xc0000428 The digital signature for this file couldn’t be verified.

      • Hi again,

        After restart I get 0x0000605 ntoskrnl.exe maybe I need to activate it? or is a problem related to the patched files? I can’t boot with current date again…

        Thanks

        • It’s working again, maybe it was cause I restarted without shutdown and I have lot of VHDs and partitions… I don’t know but it’s working again

      • Do you know which Windows spp 10102 should replace? I tried the spp of 8.1 and 10,1507, but it doesn’t seem to work (maybe my permissions are not set well. If it’s not set well, can you help me? I’m not very good at setting the permissions of these files, thank you)

        • I believe Windows 8.1 SPP files should work. I am not an expert on debombing, so I am afraid that you’ll have to ask someone else. If you’d like me to ask some I know who is good at debombing, just reply to this comment. Thanks.

  3. Maybe you know how to port user32.dll from 9888 to 10102 ?

    I’m currently using files from 6.3.9600 and 10.0.9888 to get theme and taskbar from Windows 8.1 but I can’t run the explorer of 9888 cause the lack of one function ( IsShellManagedWindow ) starting with 10.0.9926 in user32.dll

    I tried with dll redirection but I can’t get it working…

    https://www.betaarchive.com/forum/viewtopic.php?t=41086

    Or maybe you know how to patch Start Is Back to draw the taskbar icons when I enable w8 theme msstyle on Start is back….

    Cause taskbar button themes (TaskBand) aren’t working on these beta builds when I install startisback, I’m sure is something related to the introduction of the new taskbar starting with 9926 build.

    But WDDM 2.0 is not stable until 10102 build, so this is the reason I want to get it working on this build.

    You can also run explorer.exe from 10031, 10056, 10061, 10064, 10074 on this version.

    Some users are talking about porting the start menu but I’m only interested on the taskbar (which is more or less the same as getting the previous start menu):

    https://www.betaarchive.com/forum/viewtopic.php?t=41086

    • This is what I get:
      https://i.imgur.com/NOVH72w.jpeg

      Explained here:
      https://winclassic.boards.net/thread/549/w7-w8-taskbar-on-w10

      Do you know what could it be? shell32.dll, shcore, user32.dll, dwmapi.dll, dui70.dll ??

      maybe with dependencywalker?

      It needs to be a line or a function in a .DLL…

      I can get the w8.1 theme in titlebars replacing some files but I can’t get the 9888 explorer working…

      If you can fix Start Is Back showing empty icons, I can upload .dlls if you need

      Thanks a lot!!! 🙂 🙂 🙂

        • Yes, I know since it’s not a freeware software…

          But, I want to understand the difference between win10 preRTM and RTM, cause installing the same version of startisback in preRTM doesnt draw the taskbar icons, so it needs to be something in shell32.dll or user32.dll

          Maybe you can compare these two files if I send you two versions?

          Or maybe you know which files are involved in taskbar icon drawing?

          For example if I run a concrete version of Displayfusion I csn get a different taskbar if I change some dlls… and I can see a list of files used by displayfusion to create the new taskbar, but this is not a clean way to do what I want cause it uses resources…

          So I prefer to get a skinned taskbar with startisback

          Im gonna create a discord account, do you have a link to contact you on discord?

          Thanks

          • Of couse the best will be yo get w8 1 explorer taskbar on 10102 (cause 10102 its really close to 8.1) but I think it will be easier to get 9888 taskbar since it have some w10 components and w8 taskbar…

          • Maybe you can take a look at how this application works so you can tell me which DLL is involved in taskbar button drawing…:

            https://github.com/lee-soft/ViGlance

            which is the only one that works skinning explorer taskbar buttons on these pre-RTM builds but it has some problems cause it refreshed the taskbar every time I click on it and also it’s not compatible with DPI scaling

    • So… You want 9888’s Explorer running in 10102? I don’t have those builds so if you want me to patch something you’ll have to send me 9888’s explorer.exe and user32.dll. Again, since I don’t have those builds, you’ll have to test the patched Explorer and tell me know the result. Do you have a Discord account?

  4. My 10102 works, but it’s only for startup. I want to know which Windows spp should 10102 replace? I tried 8.1 and 10 respectively, but it didn’t seem to work (this is translated by machine, and there may be errors. I’m sorry that I can’t speak English)

      • You need to replace those files in install.wim with patched ones from boot.wim. I just didn’t bother to modify install.wim. If you still need help then drop a message and I’ll email you (I can see your email address so no need to make it public).

          • Well, there are different architectures out there and the same code compiled by different (versions of) compilers with different levels of optimization will result in completely different assembly instructions. Showing examples in a higher level representation will make this guide applicable for more builds.

            The purpose of this guide is to prove that flightsigned builds can be patched to boot on the current date and to help people with sufficient reverse engineering experience to conduct their own experiments.

            I can guide you step by step if you really want me to. I feel like it might be a good idea for me to email you if that is the case, so reply to this comment if you’d like to get an email from me.

发表评论