抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

Windows Server 2025 发布了,不过我在升级后发现 Windows Hello 仍然是用不了的,甚至在登录选项中只有 密码登录 一项,连 Windows Hello 相关的选项本身都消失了:

尝试按照 上一篇博客 的流程进行配置时发现相关登录选项并没有被加回来,无奈只好拖出 IDA 重新研究一下。

初步分析

由于这次连相关登录选项都被隐藏了,首先在 AllSystemSettings 定义里面简单翻了翻,寻找这些选项相关的页面。

通过这个 XML 可以发现,密码、PIN、指纹等设置对应的页面为 SettingsPageSignInOptions

结合之前的逆向经验,这次就直奔 SettingsHandlers_Authentication.dll 进行分析。

直接把这个 Handler 拖进 IDA 搜这个页面 ID 对应的函数,在 SystemSettings::DataModel::CSignInOptionsForDeviceList 可以看到指纹、密码等选项在构建时都被加进 List 了:

这样就排除了相关选项被删除的可能性,只能是对应的选项被隐藏了。如果相关选项直接被删除了就比较麻烦,可能得直接研究怎么在文件系统里写一份 PIN 和指纹的注册资料。

由于我们的重点还是放在 PIN 注册而不是生物识别上,这里再搜索 PinSetting 进行检查。转了一圈发现在 get_IsApplicable 函数中有一个名字就相当可疑的 BugFix_HidingWindowsHelloInServerSku Feature 检查:

通过挂调试器直接修改 get_IsApplicable 的返回可以恢复显示相关选项,所以可以确认就是这部分逻辑隐藏的。

从这个名字的字面意思看,微软大概是认为 Windows Server 里显示普通 Windows Hello 登录选项属于一个 BUG,所以在 Server 2025 系统中直接把对应选项隐藏掉了。继续往下追可以发现这个 Feature 的 ID 是 49406258

遗憾的是,我尝试直接通过 ViveTool 覆盖掉这个 Feature 并不能让相关选项显示出来。从代码逻辑上看,这个 Feature 更像是测试时用来隐藏这些选项看效果的,并不是字面意思上的 “启用后在 Server 系统里隐藏”。

后面我也尝试过注入 DLL 挂 IsOS 的钩子绕过这个检查,但不知道为什么在 Server 2022 测试成功的钩子放到 2025 后就无法触发了,不管我是挂 SHCore 还是挂 api-ms-win-shcore-sysinfo-l1-1-0 都不行,遂放弃此方案:

本来想尽可能减小对系统文件的修改,但是搞了一整天还是没解决,只好回到最原始的方案,直接 Patch 掉相关逻辑:

对另外几个设置项的函数 (FaceSettingFingerprintSetting) 如法炮制,再替换一下文件就可以正常看到相关选项了:

当然问题没有这么简单,因为选项仍然显示 该设备不符合你组织关于 Windows Hello 的要求 并且不能配置。我们只是回到了 2022 时代的开头。

又是凭据注册管理器?

先把设置 UI 放一边不管。根据之前的经验,我们应该先 Patch 一下凭据注册管理器,直接找到 PinEnrollment::SetDisablePinPolicyReason 进行一个 jnz 的改:

然后再参考最初找到那篇 Server 2019 的博客把 PinEnrollmentHelper.dllPinEnrollmentBroker.exe 从一个 Windows 11 24H2 系统里拷进系统并设置相关注册表项,再打开那篇博客提供的 PinEnroller 进行注册,就可以看到熟悉的验证密码弹窗:

能用了么?并不能,输入密码点确定后这个弹窗就消失了,然后什么都没发生。看来 2025 的问题比之前还复杂,只好继续掏出 IDA,这次加载 PinEnrollmentHelper.dll 挂到这个 PinEnroller 程序上调试。

用 dnSpyEx 看了一下一下这个程序调的是 EnrollPin 函数,而这个函数里面只有一个跳转,所以我们直接到 EnrollPinHelper 里面下断点往下追,发现追到 AddLocalPinNgcLocalAddCredential 时扔了一个 0x80090010 异常:

这是什么?对着 MS 文档一阵翻,发现这个错误码是 NTE_PERM,显然是一个权限问题:

权限问题是骗人的,折腾了半天发现是因为我用 RDP 连到机器上进行调试,但通过 RDP 是不能配置 PIN 和指纹等登录选项的,会扔这个异常。

遂搬来显示器,直接到机器上调试,这回换了个错误码,大 ★ 成 ★ 功:

是微软 Passport Container 哒

因为另外几个 dll 没有符号,追到这里就不太能调试下去了,只能重新加载 ngclocal.dllI_NgcLocalAddCredential 断点继续,发现异常是调用 NgcCreateContainer 时出现的:

再重新加载 cryptngc.dllI_c_NgcRpcCreateContainer 断点,结果发现异常居然是 NdrClientCall3 丢的,真让人摸不着头脑:

又对着 MS 文档一阵翻,发现 0x80073B01 是 Windows Update 出错ERROR_MUI_FILE_NOT_LOADED,但是这和我们的 RPC 失败有什么关系?

百思不得其解,总之先看看调用的是哪个 RPC 服务好了,如此这般如此这般找到了我们的 RpcInterfaceInformation 结构体:

再如此这般找到了 RPC 接口的 GUID,肉眼识别可得 30034843-029d-46ec-8fff-5d12987f85c4

那么这个 GUID 对应的是什么接口呢?到注册表里简单搜一下就发现是 NgcCtnrSvc 了:

当然简单搜一下也是骗人的,真实情况是我把系统的 RPC Endpoint 翻了个底朝天也没找到,最后把整个注册表导出来把服务一个一个看过去才发现的。

总之让我们看看这个服务有什么毛病吧,乍一看好像挺正常的,他甚至正在运行:

到这里我更搞不懂了,因为看起来所有东西都是正常的,sc 查询服务状态和控制服务都没有问题。前前后后又折腾了半天,RPC 调用还是同样的报错。

服务装了,但没完全装

在我放弃之前打开 services.msc 看了一眼,发现服务的描述符居然没加载出来,并且提示错误代码 15100 (ERROR_MUI_FILE_NOT_FOUND),居然又是 MUI 文件的问题:

这下我才意识到可能在 Windows Server 2025 里可能对应的 MUI 文件真的没被 MS 放进来,系统里可能只装了 Ngc 服务的注册表和可执行文件,但没装资源文件。

打开 Windows 11 24H2 一对比果然缺了好多 Ngc 相关的 MUI 文件:

把这些文件也进行一个移花接木,再重启 NgcCtnrSvc 服务,运行 PinEnroller,终于可以正常注册 PIN 了:

注册 PIN 后到设置里检查,果然添加指纹和面部识别的选项也都可以正常工作(我没有 Windows Hello 摄像头,所以这里只添加了指纹):

总之,这样一来在 Windows Server 2025 上也可以愉快的使用 Windows Hello 进行登录了。

虽然修改了两个系统文件导致 sfc 或系统更新后可能需要再次修改,但是这是目前我能找到的最好的解决方案。

配置完成后即使这两个文件被 Windows 更新换回来,也不影响已配置的指纹和 PIN 正常用于解锁。

理论上,如果能通过注入 DLL 的方式动态的去 Hook 相关函数,可以减小对系统的侵入并避免更新后需要重复 Patch 的问题。

不过因为 Hook IsOS 函数失败,直接 Hook 检查函数的话又涉及到从 MS 服务器加载符号、解析等诸多问题,我就暂时不打算继续研究了。

修改好的文件

按照惯例,如果你手上没有 IDA 或者不想自己动手,我也在这里附上修改后的 CredentialEnrollmentManager.exeSettingsHandlers_Authentication.dll

点击下载 (2024-12-03)

我不能保证这个文件一定能工作,也不能保证它不会损坏你的计算机,你将需要自行承担可能存在的风险。如果你同意承担此风险,我会告诉你解压密码是小写的 xwtf

注意事项

和之前一样,Windows Server 的内建 Administrator 账户并不支持配置指纹解锁。需要创建一个单独的用户进行配置,如果需要管理员权限请将这个用户加入 Administrators 组。

覆盖文件的过程中可能会碰到权限问题,可以通过 NSudo 拉起一个 TrustedInstaller 权限的命令提示符完成覆盖操作。NSudo 在 Windows 11 24H2 下不工作,但是在 Windows Server 2025 是可以正常提权的。

同样,为了确保操作系统的安全性不受破坏,你应该使用 icacls /save 命令来备份被覆盖的文件并在替换完成后使用 icacls /restore 进行还原。对于新添加的文件最好也如此操作。