From 8396b25ebd01ead34aea2985c242b214b6faab69 Mon Sep 17 00:00:00 2001 From: Vadim Troshchinskiy Date: Mon, 28 Oct 2024 08:37:09 +0100 Subject: [PATCH] Add Windows BCD decoding tool --- gitlib/bcd.py | 106 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100755 gitlib/bcd.py diff --git a/gitlib/bcd.py b/gitlib/bcd.py new file mode 100755 index 0000000..e7e00c2 --- /dev/null +++ b/gitlib/bcd.py @@ -0,0 +1,106 @@ +#!/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) \ No newline at end of file