Skip to content

Instantly share code, notes, and snippets.

@nv1t
Created January 20, 2026 15:03
Show Gist options
  • Select an option

  • Save nv1t/c044ce93204428c1f938d79433ed4d2b to your computer and use it in GitHub Desktop.

Select an option

Save nv1t/c044ce93204428c1f938d79433ed4d2b to your computer and use it in GitHub Desktop.
Offline Windows Product Key extractor. A Python script designed to parse the SOFTWARE registry hive from a mounted Windows drive. Uses regipy for hive parsing and includes logic to decode the binary DigitalProductId for both legacy (Win7) and modern (Win8/10/11) installations. Optimized for use with uv.
# /// script
# dependencies = [
# "regipy",
# ]
# ///
"""
Extracts the Windows Product Key from an offline Registry Hive (SOFTWARE).
Usage: uv run extract_key.py /path/to/mounted/Windows/System32/config/SOFTWARE
"""
import os
import argparse
from regipy import RegistryHive
def decode_key(digital_product_id):
"""Decodes the binary DigitalProductId into the 5x5 Product Key format."""
if not digital_product_id or len(digital_product_id) < 67:
return None
data = bytearray(digital_product_id)
key_offset = 52
is_win8 = (data[66] // 6) & 1
data[66] = (data[66] & 0xF7) | ((is_win8 & 2) * 4)
chars = "BCDFGHJKMPQRTVWXY2346789"
key = ""
last = 0
for i in range(24, -1, -1):
current = 0
for j in range(14, -1, -1):
current = current * 256
current = data[j + key_offset] + current
data[j + key_offset] = current // 24
current = current % 24
key = chars[current] + key
last = current
if is_win8 == 1:
key_part = key[1:last+1]
insert = "N"
key = key_part + insert + key[last+1:]
return "-".join([key[i:i+5] for i in range(0, 25, 5)])
def main():
parser = argparse.ArgumentParser(description="Extract Windows Key from an offline SOFTWARE Hive.")
parser.add_argument("hive_path", help="Path to the SOFTWARE hive file")
args = parser.parse_args()
if not os.path.exists(args.hive_path):
print(f"[-] Error: File not found at {args.hive_path}")
return
try:
hive = RegistryHive(args.hive_path)
target_path = r"\Microsoft\Windows NT\CurrentVersion"
node = hive.get_key(target_path)
values = {v.name: v.value for v in node.iter_values()}
raw_id = values.get('DigitalProductId') or values.get('DigitalProductId4')
if isinstance(raw_id, str):
raw_id = raw_id.encode('iso-8859-1')
if raw_id:
product_key = decode_key(raw_id)
product_name = values.get('ProductName', 'Unknown Version')
print(f"\nOS: {product_name}\nKey: {product_key}\n")
else:
print("[-] DigitalProductId not found.")
except Exception as e:
print(f"[-] Error: {e}")
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment