C++ REG_SZ 到 char* 并在没有提升权限的情况下读取 HKLM

Posted

技术标签:

【中文标题】C++ REG_SZ 到 char* 并在没有提升权限的情况下读取 HKLM【英文标题】:C++ REG_SZ to char* and Reading HKLM without Elevated Permissions 【发布时间】:2010-07-04 16:55:44 【问题描述】:

所以我一直在尝试从注册表中获取 REG_SZ 值并将其存储为 char*。在浏览了互联网之后,这就是我想出的。问题是我得到的值不是注册表中存储的值,我得到了一堆随机垃圾。我如何正确获得价值?

HKEY hKey;
char value[256];
// Open the key
if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0\\", 0, KEY_QUERY_VALUE, &hKey) != ERROR_SUCCESS)

    return "";


// Read the value
DWORD dwType = REG_SZ;
DWORD dwCount = sizeof(value);
if(RegQueryValueEx(hKey, "ProcessorNameString", NULL, &dwType, (LPBYTE)&value, &dwCount) != ERROR_SUCCESS)

    RegCloseKey(hKey);
    return "";

// Cleanup and return
RegCloseKey(hKey);
return value;

还有一个简短的问题。我记得如果我的程序以 Vista/7 的管理员身份运行,那么它无法编辑 HKLM,但它仍然可以读取它吗?

【问题讨论】:

你能发布整个函数(包括它的签名)吗?似乎您正在返回一个指向本地缓冲区的指针,但如果函数的返回类型是 std::string 则不是问题,因为在这种情况下会构建并返回一个 std::string。 【参考方案1】:

已更新,因为之前的回答是错误的。)

问题可能是您正在返回value,这是一个堆栈分配的缓冲区。这只有在你声明你的函数返回char[256]时才有效——如果你试图返回char*,那么调用者将获得@987654324中第一个字节的地址@,现在指向无效的堆栈数据。您应该在堆上将value 分配为char*,这样您就可以不受惩罚地返回指针。

是否允许您读取或编辑注册表项取决于您正在读取的项应用了哪些 ACL。可以设置密钥的权限以使未提升的用户甚至无法读取密钥,但也可以设置权限以使所有用户都可以读取和写入.您在上面阅读的密钥应该对所有用户都可读,但它不能被管理员修改。

【讨论】:

【参考方案2】:

如果您的应用程序没有清单,它可能会或可能不会读取真正的 HKLM。如果它试图写入 HKLM 注册表,虚拟化将启动并将写入和读取转移到虚拟化的每用户存储。当您不是管理员时,您可以读取 HKLM,因此请务必使用 asInvoker 添加清单以防止虚拟化。

【讨论】:

【参考方案3】:

主要问题已得到解答,但与您的访问问题有关。如果您想对注册表进行写访问,则必须添加一个清单文件以将您的进程提升为管理员。

【讨论】:

【参考方案4】:

    您不应返回非静态本地声明的变量;尝试将变量声明为static char value[256];,这仍然是一种不好的做法,但可以解决您的问题;

    如果你仍然得到垃圾,也许你正在编译 UNICODE 定义。如果是这样,您正在调用RegQueryValueExW 并且您得到一个宽字符字符串(没有编译时错误,因为参数被强制转换为(LPBYTE))。尝试禁用 UNICODE 或将您的字符串定义为 TCHAR

【讨论】:

以上是关于C++ REG_SZ 到 char* 并在没有提升权限的情况下读取 HKLM的主要内容,如果未能解决你的问题,请参考以下文章

在 C++ 中连接 char 数组

动态创建矢量并在 C++ 中添加到地图

在 C++ 中提升线程

C++ 将 std::string 复制到没有空终止的 char 数组

C#:使用 char** 参数调用 C++ DLL

如何将指向 char[256] 数组的指针从 C++ 编组到 C#