Geoff Chappell, Software Analyst
License values in Windows Vista are stored in the registry as the binary data for one registry value:
Key | HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\ProductOptions |
Value | ProductPolicy |
Type | REG_BINARY |
The binary data for the ProductPolicy value is interpreted by the kernel as providing data for an essentially arbitrary number of named license values. (The number is not quite arbitrary, however. The kernel imposes an upper limit of 0x0923 values. The derivation seems to be that the total size of ProductPolicy data is restricted to 64KB, and then since each value with a name and non-trivial data will need at least 0x1C bytes, there can be at most 0x0923 values.)
Though a handful of license values are meaningful to the kernel, most are held by the kernel as black boxes for whatever component may be interested. The kernel exports several functions for access to the license data and to manage a record of whether the license data has been tampered with:
The last of these, ZwQueryLicenseValue, is also callable from user mode through the NTDLL exports NtQueryLicenseValue and ZwQueryLicenseValue.
The binary data for the ProductPolicy value is in three parts:
The header provides the sizes of the two parts that follow it.
Offset | Size | Value |
---|---|---|
0x00 | dword | total size, including this header |
0x04 | dword | size of values array that follows this header |
0x08 | dword | size of end marker that follows the values array |
0x0C | dword | unknown |
0x10 | dword | must be 1, perhaps as version number |
Each value is described in three parts:
The sizes of both the value and its data are in the header:
Offset | Size | Value |
---|---|---|
0x00 | word | total size, including this header |
0x02 | word | size of name |
0x04 | word | type of data |
0x06 | word | size of data |
0x08 | dword | flags |
0x0C | dword | unknown |
The data type follows the familiar scheme for registry data: REG_SZ (0x01) for a string, REG_BINARY (0x03) for binary data and REG_DWORD (0x04) for a dword.
For the flags, only the 0x01 and 0x02 bits are valid. If the 0x01 bit is set, then the value requires something that is apparently called proxy support.
The end marker is necessarily a dword with the value 0x45.