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

最近从 Windows 10 迁移到了 Windows Server 2022,不过我在设置指纹解锁时发现添加按钮是灰色的,并且系统显示了错误提示 “Windows Hello 在 Windows Server 上不可用”

在 Google 上找了一圈并没有找到一个可行的方案,这篇 Windows Server 2019 的博客 给出的工具在 2022 中可以加上 PIN,但加上 PIN 后添加指纹的按钮依然是提示不可用的。看来得自己研究一下了。

初步分析

根据前面提到那篇博客给出的思路,我大致翻了一下 SettingsHandlers_User.dll,但是并没有找到和指纹解锁 / Windows Hello 有关的东西,猜测 Microsoft 对这块设置进行了重构。

我并不想去研究整个 UWP APP 的逻辑,于是打开火绒剑观察进程模块。很快就发现进入 登录选项 这个标签时会加载 SettingsHandlers_Authentication.dll,相关逻辑应该就藏在这里了。

放进 IDA 一看,这个 DLL 中确实有不少和 Windows Hello 相关的逻辑,然而点进函数我却发现这个 DLL 除了包含大量遥测、日志代码,还用了 eXtended Flow Guard,这直接让部分逻辑的静态分析变得几乎不可能。

碰到 _guard_xfg_dispatch_icall_fptr() 的时候,如果是调用 GUID 还可以去注册表翻一翻 CLSID,但碰到参数是几个寄存器的时候就只能傻眼了。

没办法直接从 UI 逻辑下手,我试图从导入表中找到 WBF 相关内容然后反向追回去,但是却发现这个 DLL 没有 WBF 相关的导入。猜测微软的设计模式和之前那篇分析 2019 的博客中提到的相同,还是把相关的注册组件拆成了一个独立组件。

除此之外,根据这个 DLL 的逻辑粗略分析,按钮的 SetupOrAddFingerprintSetting::get_IsApplicable() 只是简单的从一个变量里读取了这些信息然后直接返回,而 SetupOrAddFingerprintSetting::get_IsEnabled() 等函数是通过 XFG 动态计算的值。猜测 Windows Server 的相关检测也放到了前文提到的独立组件中,或者在进入设置页面的时候就已经全部计算好了。无论如何,我决定先放弃这个文件,看看能不能找到那个 “独立组件”。

凭据注册管理器

花了一点时间把 System32 下带 Enrollment 字样的 DLL/EXE 文件全部翻了一遍,最后我定位到了 CredentialEnrollmentManager.exe 这个文件上。

这个 EXE 的标题为 凭据注册管理器,关联到服务 CredentialEnrollmentManagerUserSvc,并且它在我们进入 登录选项 标签时会被自动启动。加之导入表中有 WinBio 相关的一系列函数以及之前那篇分析 2019 的博客提到的 EnrollPin 函数,我猜测实际的注册逻辑和判断逻辑都在这里。

PIN 注册判断

从之前在普通 Windows 10 中配置指纹的经验来看,还是必须有 PIN 才能设置指纹,所以这里先研究 PIN 的注册判断逻辑 (事实证明这个决定非常正确)。

根据函数名一个一个看,排除掉 PinEnrollment::v_IsSupported() 后很快我们就看到了 PinEnrollment::v_CanEnroll() 这个很明显是某种判断的函数。调试一下,很容易发现前面两个对自身变量的判断是通过了的,而在 PinEnrollment::CanAddPin() 这里返回了 false 导致我们不能添加 PIN“:

追进 PinEnrollment::CanAddPin(),很容易发现第一个判断 this->byteE8 就没有通过:

再花一点时间找寻找写这个内存的地方,最后找到了 PinEnrollment::RefreshPolicy() 这个函数。仔细一看,上面大多是一些读取用户配置、组策略配置之类的内容,而往下翻我们很快就看到了一个重要的判断 !IsOS(0x1Du)

这个 IsOS 是什么东西呢?让我们看看 Win32 API 文档

IsOS function (shlwapi.h)

Checks for specified operating systems and operating system features.

dwOS: A value that specifies which operating system or operating system feature to check for. One of the following values (you cannot combine values).

Return value: Returns a nonzero value if the specified operating system or operating system feature is detected, otherwise FALSE.

再结合这里传入的 0x1D 分析,很明显这就是我们要找的判断了。

打补丁

用 IDA 打一个简单的补丁 (如果你喜欢,这里换成 jnz 也行):

然后我们覆盖一下文件并杀掉之前的进程,重新进入 登录选项 标签,添加 PIN 的按钮就可以正常使用了。除此之外,添加指纹的组件也可以正常工作,看起来这个 Policy 判断是针对 Windows Hello 而不是单纯针对 PIN 的。

注意事项:文件权限

覆盖文件的过程中可能会碰到权限问题,你可以通过 NSudo 拉起一个 TrustedInstaller 权限的命令提示符完成覆盖操作。

为了确保操作系统的安全性不受破坏,你应该使用 icacls /save 命令来备份 CredentialEnrollmentManager.exe 的 ACL 并在替换完成后使用 icacls /restore 进行还原。

当然,你也可以选择手动设置 ACL,条条大路通罗马。

修改好的文件

如果你手上没有 IDA 或者不想自己动手,也可以直接使用我修改好的 CredentialEnrollmentManager.exe

点击下载 (2022-12-06)

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

注意事项:管理员账户

Windows Server 的内建 Administrator 账户并不支持配置指纹解锁。如果你尝试进行配置,就会碰到这样的错误:

日常使用 Administrator 账户也不是一个好习惯,建立一个独立的 User + Administrators 组账户就可以使用指纹解锁了。