【问题标题】:RegCreateKeyExW not creating keysRegCreateKeyExW 不创建密钥
【发布时间】:2021-02-15 21:10:25
【问题描述】:

我正在尝试在 HKEY_CURRENT_USER 配置单元下创建注册表项。我正在利用RegCreateKeyExWfunction。我已经阅读了该函数的Microsoft documentation,并且相信我调用它是正确的。但是,返回值不是ERROR_SUCCESS,因为正在执行捕获失败的 if 语句中的代码。调用GetLastError 时,错误文本表明操作已成功执行。检查注册表时,我可以确认没有创建密钥。我正在运行具有管理权限的代码,因为这是运行 VS 的安全上下文。下面是代码:

Registry.cpp

int createRegistryKey(HKEY hiveHandle, LPCWSTR registryKeySequence) {

    HKEY keyHandle;

    if (RegCreateKeyExW(HKEY_CURRENT_USER, registryKeySequence, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &keyHandle, NULL)  != ERROR_SUCCESS) {

        wchar_t buf[256];
        FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
            NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
            buf, (sizeof(buf) / sizeof(wchar_t)), NULL);

        /* Display error */
        std::wcout << "Creating key/s failed: " << buf << std::endl;

        //return -1;

    }
    else {

        std::wcout << "Keys added successfuly" << std::endl;

    }

    RegCloseKey(keyHandle);
    RegCloseKey(hiveHandle);

    return 0;
}

下面是调用上述函数的代码:

fodhelperBypass.cpp

#include <iostream>
#include <Windows.h>
#include "registry.h"

int main() {

    HKEY hiveHandle;

    /* Get handle to HKCU hive*/
    if (RegOpenCurrentUser(KEY_SET_VALUE, &hiveHandle) != ERROR_SUCCESS) {

        wchar_t buf[256];
        FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
            NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
            buf, (sizeof(buf) / sizeof(wchar_t)), NULL);

        /* Display error */
        std::wcout << "Opening hive failed: " << buf << std::endl;

        return -1;

    }
    else {

        std::wcout << "HKCU Hive opened successfully" << std::endl;

    }

    createRegistryKey(hiveHandle, L"\\SOFTWARE\\TestKey\\");
}

我相信我使用了正确的访问权限 (KEY_CREATE_SUB_KEY),但已更改为使用 KEY_ALL_ACCESS,但这似乎没有帮助。文档说,即使它们的键存在,也应该返回一个句柄,但这不是我所看到的。

我尝试使用 disposition 参数来进一步了解到底发生了什么,但是即使在 VS 调试视图中,我也得到了 0x00000000 的值,与文档中所述的预期值相比,这毫无意义。 0x00000001L 用于创建,0x00000002L 用于打开的密钥。我什至创建了一个 if、else if、else 语句,它首先捕获 disposition == REG_CREATED_NEW_KEY 然后 disposition == REG_OPENED_EXISTING_KEY 和 else 语句捕获 disposition 不等于任一值的情况。这是我每次测试时都会执行的 else 语句。

谁能告诉我这里缺少什么?

【问题讨论】:

  • 传入返回的实际错误代码而不是GetLastError() 时会发生什么? (无论如何,原始错误代码是什么?)
  • 如果“..return 值不是 ERROR_SUCCESS [和] 错误文本 [来自 GetLastError() 表明操作已成功执行。”;基本上,首先尝试隔离 GetLastError() 是否使观察结果复杂化,这可以通过将其与返回值进行比较和/或完全消除它来完成。 (希望的结果是可以消除或解释一半的问题。)
  • GetLastError 在这里没用。返回值是错误代码。这是什么?
  • 返回的原始错误代码是 161,不确定我在哪里查找。
  • “如果函数失败,则返回值是在 Winerror.h 中定义的非零错误代码”,来自 Microsoft 文档。所以我使用FormatMessage 函数从中得到一个有意义的错误?

标签: winapi visual-c++ registry


【解决方案1】:

这里出现了两个问题;首先,正如@David Heffernan 所指出的,调用GetLastError() 并没有提供有关所遇到错误的有意义的信息。最初阅读微软文档时,我没有正确阅读有关错误代码的信息。

如果函数失败,则返回值是 Winerror.h 中定义的非零错误代码。您可以使用带有 FORMAT_MESSAGE_FROM_SYSTEM 标志的 FormatMessage 函数来获取错误的一般描述。

更改错误处理代码,并将RegCreateKeyExW 的返回值提供给FormatMessage(),而不是GetLastError() 的错误代码,产生了一个更有意义的错误:ERROR_BAD_PATHNAME(代码 161)。

int createRegistryKey(HKEY hiveHandle, LPCWSTR registryKeySequence) {

    HKEY keyHandle;

    LSTATUS result;
    result = RegCreateKeyExW(hiveHandle, registryKeySequence, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &keyHandle, NULL);
    
    if (result != ERROR_SUCCESS) {

        wchar_t buf[256];
        FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
            NULL, result, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
            buf, (sizeof(buf) / sizeof(wchar_t)), NULL);

        /* Display error */
        std::wcout << "Creating key/s failed: " << buf << std::endl;

        return -1;

    }
    else {

        std::wcout << "Keys added successfuly" << std::endl;

    }

    RegCloseKey(keyHandle);

    return 0;

}

经过一些测试,很明显在向lpSubKey 提供数据时,前面的反斜杠有问题:

createRegistryKey(hiveHandle, L"\\SOFTWARE\\TestKey\\");

删除字符串开头的双反斜杠后,代码按预期执行。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-15
    相关资源
    最近更新 更多