Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如果要保存的密钥是HKEY_LOCAL_MACHINE,为什么RegSaveKey()会失败,错误代码为5(访问被拒绝)?_C_Windows_Winapi - Fatal编程技术网

如果要保存的密钥是HKEY_LOCAL_MACHINE,为什么RegSaveKey()会失败,错误代码为5(访问被拒绝)?

如果要保存的密钥是HKEY_LOCAL_MACHINE,为什么RegSaveKey()会失败,错误代码为5(访问被拒绝)?,c,windows,winapi,C,Windows,Winapi,这个问题与所使用的编程语言无关 在Windows7SP1和Windows10Version1803中测试 症状 RegSaveKey()如果要保存的密钥是HKEY\U LOCAL\U MACHINE,则会失败,错误代码为5(访问被拒绝) 如果指定了子项,例如HKEY\U LOCAL\U MACHINE\SYSTEM,则不会发生此错误 如果键是HKEY\U CURRENT\U USER,则也不会发生此错误 第一个样本 在这里,我使用AutoIt快速编写复制错误的代码。我还将示例代码编译为.EXE,

这个问题与所使用的编程语言无关

在Windows7SP1和Windows10Version1803中测试

症状 RegSaveKey()如果要保存的密钥是
HKEY\U LOCAL\U MACHINE
,则会失败,错误代码为5(访问被拒绝)

如果指定了子项,例如
HKEY\U LOCAL\U MACHINE\SYSTEM
,则不会发生此错误

如果键是
HKEY\U CURRENT\U USER
,则也不会发生此错误

第一个样本 在这里,我使用AutoIt快速编写复制错误的代码。我还将示例代码编译为.EXE,使人们能够轻松地查看问题

第二个样本 REG.EXE,这是一个使用Visual C++编写的内置Windows工具(这就是标记包含C的原因),具有与上述完全相同的问题。这并不奇怪,因为根据我的调查,
REG.EXE SAVE
命令实际上使用了未记录的NtSaveKey()。顺便说一下,RegSaveKey()正在内部调用NtSaveKey()

REG.EXE SAVE "HKLM" "HKLM.hiv" /Y
上述命令失败,错误为“访问被拒绝”。请注意,我以管理员身份运行该命令

问题: 这个错误的原因是什么?有没有办法使RegSaveKey()适用于
HKEY\U LOCAL\U机器
(不指定子键)

更新 我的进一步测试表明,regedit.exe与上面提到的问题相同

  • HKEY\U LOCAL\U机器
    导出到
    文件失败;但是,将其导出到
    .REG
    文件会成功
  • HKEY\U LOCAL\U机器\
    导出到
    文件成功
  • HKEY\U当前用户
    导出到
    .HIV
    文件成功
  • HKEY\u当前用户\
    导出到
    文件成功

所有在内部保存注册表项的API调用。在该函数的源代码中,我们在开头看到以下内容:

    //
    // Disallow attempts to "save" the master hive
    //
    Hive = KeyControlBlock->KeyHive;

    if (Hive == &CmpMasterHive->Hive) {
        return STATUS_ACCESS_DENIED;
    }

HKEY\U LOCAL\U MACHINE
(即“\Registry\MACHINE”)位于主配置单元中,因此向调用者返回
状态“访问被拒绝”(0xc0000022)。Windows子系统将此状态代码转换为
ERROR\u ACCESS\u DENIED
(5)。

我认为该错误隐藏了真正的问题:HKEY\u LOCAL\u计算机不是物理存在的密钥。
NtSaveKey
内部调用。这个api从一开始就提供给您
STATUS\u ACCESS\u DENIED
此时您有什么可能的原因想要保存整个HKEY\u LOCAL\u MACHINE配置单元?@CareyGregory,原因是
regedit.exe
如果我们将整个HKLM密钥导出到
.REG
文件中,则可以毫无问题地完成此操作。我的进一步测试表明,如果我们将整个HKLM密钥导出到
.HIV
文件中,
regedit.exe
也会失败。这是因为regedit不会尝试从.reg文件重新创建HKLM密钥本身。它只是通过.reg文件进行枚举,并分别恢复每个键/值。我认为@PaulStelian是正确的,HKLM不是一个可以直接操作的物理键。@eryksun我看我自己的调试器--我打开
“\\registry\\machine”
键,看对象指针(
CM\u key\u BODY
),从中得到指向
KeyControlBlock->KeyHive
值的指针(
0xFFFFB481BDE23000
在我的具体案例中)与
&CmpMasterHive->Hive
@eryksun完全相同-好的,我的英语不是很好,但我只是检查不同的键-对于
\registry\machine
键,我得到了
KeyBody->KeyControlBlock->KeyHive==&CmpMasterHive->Hive
。而在另一个键上不是。即使在用户模式调试器中,我也能看到这一点。)@eryksun-在调试器中查找多个键。只有我想说的是,对于
HKLM
我们在这项检查中被拒绝访问
Hive==&CmpMasterHive->Hive
@eryksun-更准确地说,key更快
CM\u key\u CONTROL\u BLOCK
不是
HHIVE
,但它位于同一个
HHIVE
handle->CM\u KEY\u BODY->CM\u KEY\u CONTROL\u BLOCK->HHIVE
FYI,对于不熟悉此模式的人,引用特定键的每个键对象的
KeyControlBlock
字段将引用相同的键控制块(即
CM\u KEY\u CONTROL\u BLOCK
记录)。文件系统的实现方式类似。文件系统中特定文件/流的文件对象具有引用公共文件/流控制块(FCB或SCB)的
FsContext
字段。还请注意,密钥/文件对象可能由多个进程中的多个句柄引用。因此,每个对象可以有多个句柄,每个控制块可以有多个对象。