#!/usr/bin/env python3 import hivex import argparse from hivex import Hivex from hivex.hive_types import * # Docs: # # https://www.geoffchappell.com/notes/windows/boot/bcd/objects.htm # https://learn.microsoft.com/en-us/previous-versions/windows/desktop/bcd/bcdbootmgrelementtypes #print(f"Root: {root}") def dump_all(root, depth = 0): padding = "\t" * depth children = bcd.node_children(root) if len(children) > 0: for child in children: name = bcd.node_name(child) print(f"{padding}{name}") dump_all(child, depth + 1) # print(f"Child: {child}") #print(f"Values: {num_vals}") return values = bcd.node_values(root) #print(f"Value list: {values}") for v in values: # print(f"\tValue: {v}") name = bcd.value_key(v) (type, length) = bcd.value_type(v) tname = "" value = "" if type == REG_SZ: tname = "SZ" value = bcd.value_string(v) elif type == REG_DWORD: tname = "DWORD" dval = bcd.value_dword(v) value = hex(dval) + " (" + str(bcd.value_dword(v)) + ")" elif type == REG_BINARY: tname = "BIN" (length, value) = bcd.value_value(v) value = value.hex() elif type == REG_DWORD_BIG_ENDIAN: tname = "DWORD_BE" elif type == REG_EXPAND_SZ: tname = "EXPAND SZ" elif type == REG_FULL_RESOURCE_DESCRIPTOR: tname = "RES DESC" elif type == REG_LINK: tname = "LINK" elif type == REG_MULTI_SZ: tname = "MULTISZ" (length, value) = bcd.value_value(v) value = value.decode('utf-16le') value = value.replace("\0", ";") #value = ";".join("\0".split(value)) elif type == REG_NONE: tname = "NONE" elif type == REG_QWORD: tname = "QWORD" elif type == REG_RESOURCE_LIST: tname = "RES LIST" elif type == REG_RESOURCE_REQUIREMENTS_LIST: tname = "REQ LIST" else: tname = str(type) value = "???" #value = bcd.value_string(v) print(f"{padding}{name: <16}: [{tname: <10}]; ({length: < 4}) {value}") parser = argparse.ArgumentParser( prog="Windows BCD parser", description="Parses the BCD", ) parser.add_argument("--dump", type=str, metavar='BCD file', help="Dumps the specified database") args = parser.parse_args() if args.dump: # "/home/vadim/opengnsys/winboot/boot-copy/EFI/Microsoft/Boot/BCD" bcd = Hivex(args.dump) root = bcd.root() dump_all(root)