diff --git a/volatility3/framework/layers/registry.py b/volatility3/framework/layers/registry.py index 48dd2b624..9444df675 100644 --- a/volatility3/framework/layers/registry.py +++ b/volatility3/framework/layers/registry.py @@ -14,7 +14,7 @@ from volatility3.framework.configuration.requirements import ( from volatility3.framework.exceptions import InvalidAddressException from volatility3.framework.layers import linear from volatility3.framework.symbols import intermed -from volatility3.plugins.windows import pslist +from volatility3.framework.symbols.windows import extensions vollog = logging.getLogger(__name__) @@ -65,16 +65,15 @@ class RegistryHive(linear.LinearlyMappedLayer): # Win10 17063 introduced the Registry process to map most hives. Check # if it exists and update RegistryHive._base_layer - for proc in pslist.PsList.list_processes( - context=self.context, kernel_module_name=self.config["kernel_module_name"] - ): - proc_name = proc.ImageFileName.cast( - "string", max_length=proc.ImageFileName.vol.count, errors="replace" + try: + registry_proc = self._find_registry_process() + if registry_proc: + self._base_layer = registry_proc.add_process_layer() + except ValueError: + vollog.log( + constants.LOGLEVEL_VVVV, + "Error walking process list, results may not be valid.", ) - if proc_name == "Registry" and proc.InheritedFromUniqueProcessId == 4: - proc_layer_name = proc.add_process_layer() - self._base_layer = proc_layer_name - break self._base_block = self.hive.BaseBlock.dereference() @@ -96,6 +95,41 @@ class RegistryHive(linear.LinearlyMappedLayer): f"Exception when setting hive {self.name} max address, using {hex(self._maxaddr)}", ) + def _find_registry_process(self) -> Optional[extensions.EPROCESS]: + """Walk the active process list and return the Registry process if it exists. Duplicates + PsList.list_processes() since pulling in the plugin causes problems. + + Returns: + The Registry EPROCESS object if it exists, or None + """ + + kernel = self.context.modules.get(self.config["kernel_module_name"]) + + if not kernel or not kernel.offset: + raise ValueError( + "Intel layer does not have an associated kernel virtual offset, failing" + ) + + ps_aph_offset = kernel.get_symbol("PsActiveProcessHead").address + list_entry = kernel.object(object_type="_LIST_ENTRY", offset=ps_aph_offset) + reloff = kernel.get_type("_EPROCESS").relative_child_offset( + "ActiveProcessLinks" + ) + eproc = kernel.object( + object_type="_EPROCESS", + offset=list_entry.vol.offset - reloff, + absolute=True, + ) + + for proc in eproc.ActiveProcessLinks: + proc_name = proc.ImageFileName.cast( + "string", max_length=proc.ImageFileName.vol.count, errors="replace" + ) + if proc_name == "Registry" and proc.InheritedFromUniqueProcessId == 4: + return proc + + return None + def _get_hive_maxaddr(self, volatile): return ( self._hive_maxaddr_volatile if volatile else self._hive_maxaddr_non_volatile