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的主要内容,如果未能解决你的问题,请参考以下文章