【问题标题】:Can a valid HKEY be NULL?有效的 HKEY 可以为 NULL 吗?
【发布时间】:2021-01-14 11:48:55
【问题描述】:

RegOpenKeyEx/RegCreateKeyEx 可以将NULL 作为有效的HKEY 值返回吗?

我正在分析QSettingshttps://code.woboq.org/qt5/qtbase/src/corelib/io/qsettings_win.cpp.html#_ZL15createOrOpenKeyiiRK7QStringi)的源代码。

如果NULL 可能是HKEY 的有效值,则QSettings 在Windows 下的实现存在错误。

【问题讨论】:

  • 有效句柄不能为 0。但无论如何实现都很糟糕 - 需要分析返回的状态码,但不是 HKEY。并将状态码返回给调用者
  • @RbMm "需要分析返回的状态码而不是 HKEY" - 这正是 QSettings 在调用注册表 API 时实际所做的。 “并将状态代码返回给调用者” - 如果调用者不需要错误代码,则不需要。有问题的代码在失败时向调用者返回一个 NULL hkey。这完全没问题,只要调用者在使用之前检查 hkey 是否为 NULL。这段代码的作用,AFAICS。
  • @AlexanderDyagilev "QSettings 在 Windows 下的实现存在错误" - 我在链接代码中没有看到与滥用 NULL hkey 相关的错误。您能否更具体地说明您认为该错误究竟是什么?
  • @Remy Lebeau if opened HKEY 可以为 NULL,然后QSettings 将其视为失败并生成错误。只有在 opened HKEY 永远不能是 NULL 的情况下才没有错误。这就是问题的全部内容。
  • @AlexanderDyagilev "如果打开 HKEY 可以为 NULL" - 它不能。这就是你的答案。

标签: qt winapi


【解决方案1】:

RegOpenKeyEx/RegCreateKeyEx 可以将 NULL 作为有效的 HKEY 值返回吗?

不,一个有效的打开HKEY永远不会为NULL。

另一方面,如果这些函数失败,则返回的HKEY 的值不确定。如果 HKEY 在失败时被设置为 NULL,Win32 API 文档并没有说明任何一种方式,因此您不能单独检查返回的 HKEY 是否为 NULL 与非调用这些函数时为NULL,例如:

HKEY hKey; // uninitialized
RegOpenKeyEx(..., &hKey, ...);
if (hKey) {
    // use hKey as needed - undefined behavior!
    RegCloseKey(hKey);
}

函数在成功时返回 0,在失败时返回非零。调用者必须查看它以确定HKEY 是否有效,例如:

HKEY hKey;
LONG res = RegOpenKeyEx(..., &hKey, ...);
if (res == ERROR_SUCCESS) {
    // use hKey as needed - OK!
    RegCloseKey(hKey);
}

而 AFAICS,QSettings 正是这样做的,在显式检测故障时将其 HKEY 变量显式设置为 NULL,这非常好。

如果 NULL 可能是 HKEY 的有效值

NULL 不是这些函数输出的有效 opened 值,因此 NULL 可用于应用程序在表示 unopened 键时将其 HKEYs 设置为。就像大多数其他 Win32 句柄/指针类型一样。

那么QSettings在Windows下的实现有bug。

我在您链接的代码中没有看到任何此类错误。 RegOpeKeyEx()/RegCreateKeyEx() 的所有使用都是正确的,他们在使用返回的HKEY 之前检查错误代码,HKEY 变量被设置为 NULL 用于未打开键,并且没有读取/正在对 NULL HKEY 执行写操作。那么漏洞在哪里呢?

【讨论】:

  • 任何打开HKEY 的证明总是非空的?
  • 再次,我在问 RegOpenKeyEx 是否有可能返回 ERROR_SUCCESS 并将 HKEY 设置为 NULL(因此它是一个有效的打开密钥)。如果是 - QSettings 有错误。如果没有 - QSettings 没有错误。但仅仅说是或否是不够的(你可能是错的)。需要一些证明。不幸的是,我在 MSDN 中没有找到任何相关内容。
  • @AlexanderDyagilev "我在问 RegOpenKeyEx 是否有可能返回 ERROR_SUCCESS 并将 HKEY 设置为 NULL" - 不,这是不可能的。我的回答的第一句话就涵盖了这一点。 “仅仅说是或否是不够的(你可能是错的)” - 我没有错。
  • @AlexanderDyagilev "不幸的是,我在 MSDN 中没有找到任何相关的内容" - 记录的唯一内容是 NULL HKEY无效的打开键是RegOverridePredefKey(),它使用 NULL 表示要映射到的打开键的 LACK。但这应该足以证明RegOpenKeyEx()/RegCreateKeyEx() 不能 在成功时返回 NULL HKEY,否则 RegOverridePredefKey() 将无法正常工作,因此 opened 键不能为 NULL。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-01-16
  • 1970-01-01
  • 1970-01-01
  • 2021-01-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多