【发布时间】:2018-05-28 19:40:51
【问题描述】:
这个问题与所使用的编程语言无关。
在 Windows 7 SP1 和 Windows 10 版本 1803 中测试。
症状
如果要保存的密钥是HKEY_LOCAL_MACHINE,RegSaveKey() 会失败并返回错误代码 5(访问被拒绝)。
如果指定了子键,则不会发生此错误,例如HKEY_LOCAL_MACHINE\SYSTEM.
如果密钥为HKEY_CURRENT_USER,也不会发生此错误。
第一个样本
在这里,我使用 AutoIt 快速编写 a sample code 以重现错误。我还把示例代码编译成.EXE,方便大家看问题。
第二个样本
REG.EXE,这是一个内置的Windows工具使用Visual C++编写(这就是为什么标签包含C),与上面提到的完全相同的问题.这并不奇怪,因为根据我的调查,REG.EXE SAVE 命令实际上使用了未记录的 NtSaveKey()。顺便说一句,RegSaveKey() 在内部调用 NtSaveKey()。
REG.EXE SAVE "HKLM" "HKLM.hiv" /Y
上述命令失败并出现错误“访问被拒绝”。请注意,我以 Administrator 身份运行命令。
问题
这个错误的原因是什么?有没有办法让 RegSaveKey() 适用于HKEY_LOCAL_MACHINE(不指定子键)?
更新
我进一步的测试表明regedit.exe和上面提到的一样。
- 将
HKEY_LOCAL_MACHINE导出到.HIV文件失败;但是,将其导出到.REG文件会成功。 - 将
HKEY_LOCAL_MACHINE\<subkey>导出到.HIV文件成功。 - 将
HKEY_CURRENT_USER导出到.HIV文件成功。 - 将
HKEY_CURRENT_USER\<subkey>导出到.HIV文件成功。
【问题讨论】:
-
我认为错误隐藏了真正的问题:HKEY_LOCAL_MACHINE 不是实际存在的密钥。
-
NtSaveKey内部调用CmSaveKey。这个 api 最开始Disallow attempts to "save" the master hive - 并在这个line 返回给你STATUS_ACCESS_DENIED -
你有什么可能的原因想要保存整个 HKEY_LOCAL_MACHINE 配置单元?
-
@CareyGregory,原因是如果我们将整个 HKLM 密钥导出到
.REG文件中,regedit.exe可以毫无问题地做到这一点。我的进一步测试表明,如果我们将整个 HKLM 密钥导出到.HIV文件中,regedit.exe也会失败。 -
这是因为 regedit 不会尝试从 .reg 文件重新创建 HKLM 密钥本身。它只是枚举 .reg 文件并单独恢复每个键/值。我认为@PaulStelian 是正确的,HKLM 不是您可以直接操作的物理密钥。