与我合作的团队最近面临着使我们的软件与第三方虚拟化软件兼容的挑战。该软件使用内核驱动程序执行 Windows 本地注册表 API(ZwCreateKey
等)的挂钩。它通过挂钩 Ntdll 中的调用来工作。我们的软件也相当低级,在某些情况下需要访问真实的注册表而不被挂钩。
我们正在探索使用我们自己的内核驱动程序来调用ZwCreateKey
等的可能性,以我们的名义绕过它们的钩子。这实质上意味着创建一个 NT Legacy 驱动程序和一个提供我们自己的本地注册表功能的用户模式库。库和驱动程序非常简单,我们只需使用 IOCTL 将所有参数传递给ZwCreateKey
我们的驱动程序,然后我们调用内核版本的调用并返回结果。
这种方法效果很好,我们现在似乎有了一个在虚拟化时读取/写入真实注册表的系统。唯一的问题是我们的新系统似乎绕过了注册表对象上的 Windows 安全性。
ZwCreateKey
采用这样的访问掩码:
NTSTATUS ZwCreateKey(
__out PHANDLE KeyHandle,
__in ACCESS_MASK DesiredAccess,
__in POBJECT_ATTRIBUTES ObjectAttributes,
__reserved ULONG TitleIndex,
__in_opt PUNICODE_STRING Class,
__in ULONG CreateOptions,
__out_opt PULONG Disposition
);
我的理解是,虽然我们现在在内核模式下运行,但我们仍然拥有用户令牌的上下文。这应该意味着内核版本ZwCreateKey
将失败,就像访问掩码测试失败时用户一样。实际发生的情况是,即使使用有限的令牌,当我们的驱动程序被调用时,它也能够在受限用户调用时在受限部分 HKLM 中创建密钥。是什么赋予了?我们应该自己执行 ACL 检查吗?我们需要做些什么来限制我们自己在内核模式下的权限吗?非常感谢任何帮助。