106 lines
2.6 KiB
Python
106 lines
2.6 KiB
Python
#!/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) |