Skip to content

Instantly share code, notes, and snippets.

@gsuberland
Last active April 7, 2022 12:55
Show Gist options
  • Save gsuberland/df14a41b2e256bf03af8a93ff8169bfa to your computer and use it in GitHub Desktop.
Save gsuberland/df14a41b2e256bf03af8a93ff8169bfa to your computer and use it in GitHub Desktop.
Dump Windows ProductPolicy Structure in C#
// dump ProductPolicy data structure from Windows
// ref: https://www.geoffchappell.com/studies/windows/km/ntoskrnl/api/ex/slmem/productpolicy.htm
using (var pok = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(@"SYSTEM\ControlSet001\Control\ProductOptions", false))
{
byte[] policy = (byte[])pok.GetValue(@"ProductPolicy");
using (var ms = new MemoryStream(policy))
using (var br = new BinaryReader(ms))
{
Console.WriteLine("total license data size (including header): {0}", br.ReadUInt32());
Console.WriteLine("size of all entries: {0}", br.ReadUInt32());
Console.WriteLine("size of of ending marker: {0}", br.ReadUInt32());
Console.WriteLine("unknown: {0}", br.ReadUInt32());
Console.WriteLine("license data version: {0}", br.ReadUInt32());
Console.WriteLine();
while (ms.Position < ms.Length)
{
var entryPos = ms.Position;
var entrySize = br.ReadUInt16();
Console.WriteLine("entry offset: 0x{0:X8}", ms.Position);
Console.WriteLine("total size of entry: {0}", entrySize);
ushort sizeOfName = br.ReadUInt16();
if (entrySize == 69 /* nice */ && sizeOfName == 0)
{
Console.WriteLine();
Console.WriteLine("No more entries.");
break;
}
Console.WriteLine("size of name: {0}", sizeOfName);
var dataType = br.ReadUInt16();
Console.WriteLine("type of data: {0}", dataType);
ushort sizeOfData = br.ReadUInt16();
Console.WriteLine("size of data: {0}", sizeOfData);
Console.WriteLine("flags: {0}", br.ReadUInt32());
Console.WriteLine("unknown: {0}", br.ReadUInt32());
Console.WriteLine("name offset: 0x{0:X8}", ms.Position);
var nameBytes = br.ReadBytes(sizeOfName);
Console.WriteLine("name: {0}", Encoding.Unicode.GetString(nameBytes, 0, nameBytes.Length));
Console.WriteLine("data offset: 0x{0:X8}", ms.Position);
var dataBytes = br.ReadBytes(sizeOfData);
if (dataType == 4)
{
Console.WriteLine("value: {0}", BitConverter.ToUInt32(dataBytes, 0));
}
ms.Seek(entryPos + entrySize, SeekOrigin.Begin);
Console.WriteLine();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment