LoadLibraryExW 无法加载 User32.dll

LoadLibraryExW Fails to Load User32.dll

当尝试通过 LoadLibraryExW 加载 C:\Windows\System32\user32.dll 时,失败并出现最后一个错误 ERROR_INVALID_IMAGE_HASH.

加载方式如下:

HMODULE User32Lib = LoadLibraryExW(L"C:\Windows\System32\user32.dll", NULL, LOAD_LIBRARY_REQUIRE_SIGNED_TARGET);

我查看了 DLL 本身,它是在 2020 年 4 月 8 日签署的(针对我机器上的版本),因此它应该仍然有效。

我做错了什么吗?

显然 LOAD_LIBRARY_REQUIRE_SIGNED_TARGET 要求 PE 图像在其 DLL characteristics. This is a flag that forces the memory manager in the kernel to check for a digital signature when loading the image. Refer to the linker option /INTEGRITYCHECK 中与 IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY (0x0080) 链接。

大部分系统DLL都没有这个特性。 "user32.dll" 没有,但是 "bcrypt.dll" 有:

PS C:\> $user32_hdr = get-peheader C:\Windows\System32\user32.dll
PS C:\> $bcrypt_hdr = get-peheader C:\Windows\System32\bcrypt.dll
PS C:\> '{0:x}' -f $user32_hdr.DllCharacteristics
4160
PS C:\> '{0:x}' -f $bcrypt_hdr.DllCharacteristics
41E0

我不太了解代码签名主题以及加载程序和内存管理器中的实现细节。在检查 DLL 特性中的 0x80 后,我刚刚使用调试器发现加载失败并显示 STATUS_INVALID_IMAGE_HASH in LdrpCompleteMapModule。从那里我搜索了关于此值的讨论以及与 LOAD_LIBRARY_REQUIRE_SIGNED_TARGET 相关的 /integritycheck 选项。我发现一些非官方参考资料声称后者需要前者。所以我写了一个脚本来转储系统 DLL 的 DLL 特征,以便找到一个具有 IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY 标志的。找到 "bcrypt.dll" 并检查它尚未加载后,我确认用 LOAD_LIBRARY_REQUIRE_SIGNED_TARGET 加载它确实有效。