How to extract the standard registry value type from a legitimate unknown value type?

1

Background

I notice there are many legitimate unknown value types in the HKEY_LOCAL_MACHINE of Windows 10. These are just a few of them:

  • 0x100000 [HKEY_LOCAL_MACHINE\SYSTEM\DriverDatabase\DriverPackages\hidbthle.inf_amd64_55f7f576bf549669\Configurations\HidBthLE.NT\Device] "WUDF"
  • 0x200000 [HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\Class{4d36e96c-e325-11ce-bfc1-08002be10318}\Configuration\Reset\Driver] "DevLoader"
  • 0x40007 [HKEY_LOCAL_MACHINE\SYSTEM\DriverDatabase\DriverPackages\cdrom.inf_amd64_21e18060f597c313\Configurations\cdrom_install\Services\cdrom] "AutoRunAlwaysDisable"
  • 0xffff0009 [HKEY_LOCAL_MACHINE\SYSTEM\Setup\Upgrade\NetworkDriverBackup\Control\NetworkSetup2\Interfaces{0176DBBA-3617-44FF-BA79-90375AAC4B6A}\Properties{a111f1f4-5923-47c0-9a68-d0bafb577901}\0004] "(Default)"
  • 0xffff000d [HKEY_LOCAL_MACHINE\SYSTEM\Setup\Upgrade\NetworkDriverBackup\Control\NetworkSetup2\Filters{171C5016-3D19-4CB2-9556-63E586EE5010}\Properties{a111f1f7-5923-47c0-9a68-d0bafb577901}\0002] "(Default)"
  • 0xffff100d [HKEY_LOCAL_MACHINE\SYSTEM\Setup\Upgrade\NetworkDriverBackup\Control\NetworkSetup2\Filters{E475CF9A-60CD-4439-A75F-0079CE0E18A1}\Properties{a111f1f0-5923-47c0-9a68-d0bafb577901}\0052] "(Default)"
  • 0xffff2012 [HKEY_LOCAL_MACHINE\SYSTEM\Setup\Upgrade\NetworkDriverBackup\Control\NetworkSetup2\Clients{54494F4E-5441-4B53-CCB9-061A6EC4BF6E}\Properties{a111f1f1-5923-47c0-9a68-d0bafb577901}\0002] "(Default)"

Interestingly, NirSoft RegScanner interprets the value type 0xffff0009 as REG_FULL_RESOURCE_DESCRIPTOR (0x09).

Since the predefined constants defined in "winnt.h" (see below) are no more than one byte, my temporary conclusion is that we should AND the value type reported by RegQueryValueEx() with 0x000000ff. However, I'm not sure about this.

#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)

Updates

I just found some discussions about this on the internet:

However, for some value types, e.g. 0xffff100d, AND it with 0x000000ff, I get 0x0d. The problem is there is no standard value types that is defined as 0x0d in Windows header files.

I still suspect there is a way to conclude the standard value type from a legitimate unknown value type.

Please note that I'm not trying to understand how the data should be interpreted. I'm talking about how to extract the standard registry value type from a legitimate unknown registry value type.

This impacts to how we should treat a value type returned by RegQueryValueEx() in our code. Perhaps, the lesson is don't conclude in a hurry that an unknown value type is really unknown; we need to further test the value type with a bitmask.

Question

How to extract the standard registry value type from a legitimate unknown value type?

c
windows
winapi
asked on Stack Overflow May 20, 2018 by Aeoliyan • edited May 20, 2018 by Aeoliyan

1 Answer

3

registry subsystem not interpret (and not check) the Type value of key. it simply store or load it as DWORD data. as result we in principle can use any value for type with any data. say for example we can do

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);
}

in other words we can use types 0x87654321 and 0x12345678 instead REG_SZ and REG_DWORD for example. any value for type is a legitimate. the Type is only hint for actual data type. but we for example also can store string with REG_DWORD type or DWORD with REG_SZ type. we can save 0 or not 0-terminating string

How to extract the standard registry value type from a legitimate unknown value type?

legitimate here excess word. in general case - no way. if you dont know what here saved and what sense of this. we say can display value as REG_BINARY - reinterpreted bytes.

for another example, in win10 i view under

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

several subkeys with values which type is 0xFFFF0012 and 0xFFFF0019 despite actual value data is REG_SZ (easy visible that this is 0-terminating unicode strings) the 0xFFFF0012 and 0xFFFF0019 - this is some additional information for those who understand this keys sense. they know (hardcode) that actual data here is 0-termanated wide char string. and use Type as some additional information (flags ?). anyway - if key/value unknown for you - how you can use it values, if you not understand sense of it. even if know format. for display in UI - only option raw hex view

answered on Stack Overflow May 20, 2018 by RbMm

User contributions licensed under CC BY-SA 3.0