Merge pull request #1702 from volatilityfoundation/1645-change-registry-processing-to-not-walk-the-process-list-in-the-registry-layer

#1645 - duplicate list_processes code
This commit is contained in:
ikelos
2025-03-11 16:30:24 +00:00
committed by GitHub
+44 -10
View File
@@ -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