diff --git a/volatility/framework/symbols/windows/extensions/__init__.py b/volatility/framework/symbols/windows/extensions/__init__.py index f05a2553b..d5b407618 100644 --- a/volatility/framework/symbols/windows/extensions/__init__.py +++ b/volatility/framework/symbols/windows/extensions/__init__.py @@ -307,12 +307,30 @@ class _CM_KEY_BODY(objects.Struct): """This represents an open handle to a registry key and is not tied to the registry hive file format on disk.""" + def _skip_key_hive_entry_path(self, kcb_flags): + # Win10 14393 introduced an extra path element that it skips + # over by checking for Flags that contain KEY_HIVE_ENTRY + + from volatility.framework.symbols.windows.extensions.registry import RegKeyFlags + + # _CM_KEY_BODY.Trans introduced in Win10 14393 + if hasattr(self, "Trans") and RegKeyFlags.KEY_HIVE_ENTRY & kcb_flags == RegKeyFlags.KEY_HIVE_ENTRY: + return True + + return False + def get_full_key_name(self) -> str: output = [] kcb = self.KeyControlBlock while kcb.ParentKcb: if kcb.NameBlock.Name == None: break + + if self._skip_key_hive_entry_path(kcb.Flags): + kcb = kcb.ParentKcb + if not kcb: + break + output.append(kcb.NameBlock.Name.cast("string", encoding = "utf8", max_length = kcb.NameBlock.NameLength, diff --git a/volatility/framework/symbols/windows/extensions/registry.py b/volatility/framework/symbols/windows/extensions/registry.py index 30c29bc05..960d28d10 100644 --- a/volatility/framework/symbols/windows/extensions/registry.py +++ b/volatility/framework/symbols/windows/extensions/registry.py @@ -41,6 +41,32 @@ class RegValueTypes(enum.Enum): except ValueError: return cls(RegValueTypes.REG_UNKNOWN) +class RegKeyFlags(enum.Enum): + KEY_IS_VOLATILE = 0x01 + KEY_HIVE_EXIT = 0x02 + KEY_HIVE_ENTRY = 0x04 + KEY_NO_DELETE = 0x08 + KEY_SYM_LINK = 0x10 + KEY_COMP_NAME = 0x20 + KEY_PREFEF_HANDLE = 0x40 + KEY_VIRT_MIRRORED = 0x80 + KEY_VIRT_TARGET = 0x100 + KEY_VIRTUAL_STORE= 0x200 + + def __and__(self, other): + if self.__class__ is other.__class__: + return self.value & other.value + elif issubclass(other.__class__, int): + return self.value & other + return NotImplemented + + def __eq__(self, other): + if self.__class__ is other.__class__: + return self.value == other.value + elif issubclass(other.__class__, int): + return self.value == other + return NotImplemented + class _HMAP_ENTRY(objects.Struct): def get_block_offset(self) -> int: try: