C语言 如何从合法的未知值类型中提取标准注册表值类型?



Background

我注意到Windows 10 HKEY_LOCAL_MACHINE中有许多合法的未知值类型。这些只是其中的一小部分:

  • 0x100000[HKEY_LOCAL_MACHINESYSTEMDriverDatabaseDriverPackageshidbthle.inf_amd64_55f7f576bf549669ConfigurationsHidBthLE.NTDevice] "WUDF"
  • 0x200000 [HKEY_LOCAL_MACHINESYSTEMControlSet001ControlClass{4d36e96c-e325-11ce-bfc1-08002be10318}ConfigurationResetDriver] "DevLoader"
  • 0x40007[HKEY_LOCAL_MACHINESYSTEMDriverDatabaseDriverPackagescdrom.inf_amd64_21e18060f597c313Configurationscdrom_installServicescdrom] "AutoRunAlwaysDisable"
  • 0xffff0009[HKEY_LOCAL_MACHINESYSTEMSetupUpgradeNetworkDriverBackupControlNetworkSetup2Interfaces{0176DBBA-3617-44FF-BA79-90375AAC4B6A}Properties{a111f1f4-5923-47c0-9a68-d0bafb577901}004] "(Default)"
  • 0xffff000d[HKEY_LOCAL_MACHINESYSTEMSetupUpgradeNetworkDriverBackupControlNetworkSetup2Filters{171C5016-3D19-4CB2-9556-63E586EE5010}Properties{a111f1f7-5923-47c0-9a68-d0bafb577901}002] "(Default)"
  • 0xffff100d[HKEY_LOCAL_MACHINESYSTEMSetupUpgradeNetworkDriverBackupControlNetworkSetup2Filters{E475CF9A-60CD-4439-A75F-0079CE0E18A1}Properties{a111f1f0-5923-47c0-9a68-d0bafb577901}052] "(Default)"
  • 0xffff2012[HKEY_LOCAL_MACHINESYSTEMSetupUpgradeNetworkDriverBackupControlNetworkSetup2Clients{54494F4E-5441-4B53-CCB9-061A6EC4BF6E}Properties{a111f1f1-5923-47c0-9a68-d0bafb577901}002] "(Default)"

有趣的是,NirSoft RegScanner将值类型0xffff0009解释为REG_FULL_RESOURCE_DESCRIPTOR(0x09(。

由于在"winnt.h"(见下文(中定义的预定义常量不超过一个字节,我的临时结论是我们应该RegQueryValueEx((报告的值类型与0x000000ff。但是,我不确定这一点。

#define REG_NONE                    ( 0ul ) // No value type
#define REG_SZ                      ( 1ul ) // Unicode nul terminated string
#define REG_EXPAND_SZ               ( 2ul ) // Unicode nul terminated string
// (with environment variable references)
#define REG_BINARY                  ( 3ul ) // Free form binary
#define REG_DWORD                   ( 4ul ) // 32-bit number
#define REG_DWORD_LITTLE_ENDIAN     ( 4ul ) // 32-bit number (same as REG_DWORD)
#define REG_DWORD_BIG_ENDIAN        ( 5ul ) // 32-bit number
#define REG_LINK                    ( 6ul ) // Symbolic Link (unicode)
#define REG_MULTI_SZ                ( 7ul ) // Multiple Unicode strings
#define REG_RESOURCE_LIST           ( 8ul ) // Resource list in the resource map
#define REG_FULL_RESOURCE_DESCRIPTOR ( 9ul ) // Resource list in the hardware description
#define REG_RESOURCE_REQUIREMENTS_LIST ( 10ul )
#define REG_QWORD                   ( 11ul ) // 64-bit number
#define REG_QWORD_LITTLE_ENDIAN     ( 11ul ) // 64-bit number (same as REG_QWORD)

更新

我刚刚在互联网上找到了一些关于这个的讨论:

  • https://github.com/williballenthin/python-registry/issues/31
  • https://github.com/williballenthin/python-registry/issues/62

但是,对于某些值类型,例如0xffff100d并且带有0x000000ff,我得到0x0d。问题是没有在 Windows 头文件中定义为0x0d的标准值类型。

我仍然怀疑有一种方法可以从合法的未知值类型中得出标准值类型。

请注意,我不想理解应该如何解释数据。我说的是如何从合法的未知注册表值类型中提取标准注册表值类型。

这会影响我们应该如何处理代码中 RegQueryValueEx(( 返回的值类型。也许,教训是不要急于得出结论,未知值类型确实是未知的;我们需要使用位掩码进一步测试值类型。

问题

如何从合法的未知值类型中提取标准注册表值类型?

注册表子系统不解释(也不检查(键的Type值。 它只是将其存储或加载为DWORD数据。 因此,我们原则上可以对任何数据使用任何类型值。 例如我们可以做

HKEY hKey;
if (!RegOpenKeyExW(hRootKey, lpSubKey, 0, KEY_SET_VALUE, &hKey))
{
RegSetValueExW(hKey, 0, 0, 0x87654321, (PBYTE)L"demo", sizeof(L"demo"));
DWORD ticks = GetTickCount();
RegSetValueExW(hKey, L"TickCount", 0, 0x12345678, (PBYTE)&ticks, sizeof(ticks));
RegCloseKey(hKey);
}

换句话说,我们可以使用类型0x876543210x12345678而不是REG_SZREG_DWORD。 类型的任何值都是合法的。Type只是实际数据类型的提示。 但是例如,我们也可以存储REG_DWORD类型的字符串或REG_SZ类型的DWORD。 我们可以保存 0 或不 0 终止字符串

如何从合法注册表值类型中提取标准注册表值类型 未知值类型?

合法在这里多余的词。 在一般情况下 - 没办法。 如果你不知道这里保存了什么,这有什么意义。 我们说可以将值显示为REG_BINARY- 重新解释的字节。

再举一个例子,在 Win10 中,我在

HKEY_LOCAL_MACHINE
SYSTEM
Setup
Upgrade
NetworkDriverBackup
Control
NetworkSetup2
Clients
{54494F4E-5441-4B53-CCB9-061A6EC4BF6E}
Properties
{a111f1f0-5923-47c0-9a68-d0bafb577901}

几个子项,其值类型为0xFFFF0012,尽管实际值数据0xFFFF0019,但REG_SZ(很容易看到这是以 0 结尾的 Unicode 字符串(0xFFFF00120xFFFF0019- 对于那些了解此键感的人来说,这是一些额外的信息。他们知道(硬编码(这里的实际数据是 0 分宽字符字符串。并将Type用作一些附加信息(标志?无论如何 - 如果你不知道键/值 - 如果你不理解它的意义,你如何使用它的值。即使知道格式。用于在 UI 中显示 - 仅选项原始十六进制视图

最新更新