mirror of
https://github.com/volatilityfoundation/volatility3.git
synced 2026-09-11 12:17:38 +02:00
Refactor requirement finding recursion since we use it a lot.
This commit is contained in:
@@ -161,30 +161,6 @@ class KernelPDBScanner(interfaces.automagic.AutomagicInterface):
|
||||
results.update(self.recurse_pdb_finder(context, sub_config_path, subreq))
|
||||
return results
|
||||
|
||||
def recurse_symbol_requirements(self, context, config_path, requirement):
|
||||
"""Determines if there is actually an unfulfilled symbol requirement waiting
|
||||
|
||||
This ensures we do not carry out an expensive search when there is no requirement for a particular symbol table.
|
||||
|
||||
:param context: Context on which to operate
|
||||
:type context: ~volatility.framework.interfaces.context.ContextInterface
|
||||
:param config_path: Configuration path of the top-level requirement
|
||||
:type config_path: str
|
||||
:param requirement: Top-level requirement whose subrequirements will all be searched
|
||||
:type requirement: ~volatility.framework.interfaces.configuration.RequirementInterface
|
||||
:return: A list of tuples containing the config_path, sub_config_path and requirement identifying the SymbolRequirements
|
||||
"""
|
||||
sub_config_path = interfaces.configuration.path_join(config_path, requirement.name)
|
||||
results = []
|
||||
if isinstance(requirement, interfaces.configuration.SymbolRequirement):
|
||||
# TODO: check if this is a windows symbol requirement, otherwise ignore it
|
||||
if requirement.unsatisfied(context, config_path):
|
||||
results.append((config_path, sub_config_path, requirement))
|
||||
else:
|
||||
for subreq in requirement.requirements.values():
|
||||
results += self.recurse_symbol_requirements(context, sub_config_path, subreq)
|
||||
return results
|
||||
|
||||
def recurse_symbol_fulfiller(self, context):
|
||||
"""Fulfills the SymbolRequirements in `self._symbol_requirements` found by the `recurse_symbol_requirements`.
|
||||
|
||||
@@ -326,12 +302,15 @@ class KernelPDBScanner(interfaces.automagic.AutomagicInterface):
|
||||
|
||||
def __call__(self, context, config_path, requirement, progress_callback = None):
|
||||
# TODO: Check if we really need to search for pdbs
|
||||
if "pdbscan" not in context.symbol_space:
|
||||
context.symbol_space.append(native.NativeTable("pdbscan", native.std_ctypes))
|
||||
self._symbol_requirements = self.recurse_symbol_requirements(context, config_path, requirement)
|
||||
if self._symbol_requirements:
|
||||
potential_kernels = self.recurse_pdb_finder(context, config_path, requirement, progress_callback)
|
||||
self.valid_kernels = self.determine_valid_kernels(context, potential_kernels, progress_callback)
|
||||
if self.valid_kernels:
|
||||
self.recurse_symbol_fulfiller(context)
|
||||
self.set_kernel_virtual_offset(context)
|
||||
if requirement.unsatisfied(context, config_path):
|
||||
if "pdbscan" not in context.symbol_space:
|
||||
context.symbol_space.append(native.NativeTable("pdbscan", native.std_ctypes))
|
||||
# TODO: check if this is a windows symbol requirement, otherwise ignore it
|
||||
self._symbol_requirements = self.find_requirements(context, config_path, requirement,
|
||||
interfaces.configuration.SymbolRequirement)
|
||||
if self._symbol_requirements:
|
||||
potential_kernels = self.recurse_pdb_finder(context, config_path, requirement, progress_callback)
|
||||
self.valid_kernels = self.determine_valid_kernels(context, potential_kernels, progress_callback)
|
||||
if self.valid_kernels:
|
||||
self.recurse_symbol_fulfiller(context)
|
||||
self.set_kernel_virtual_offset(context)
|
||||
|
||||
@@ -47,6 +47,32 @@ class AutomagicInterface(interfaces_configuration.ConfigurableInterface, metacla
|
||||
def __call__(self, context, config_path, configurable, progress_callback = None):
|
||||
"""Runs the automagic over the configurable"""
|
||||
|
||||
def find_requirements(self, context, config_path, requirement_root, requirement_type, shortcut = True):
|
||||
"""Determines if there is actually an unfulfilled symbol requirement waiting
|
||||
|
||||
This ensures we do not carry out an expensive search when there is no requirement for a particular symbol table.
|
||||
|
||||
:param context: Context on which to operate
|
||||
:type context: ~volatility.framework.interfaces.context.ContextInterface
|
||||
:param config_path: Configuration path of the top-level requirement
|
||||
:type config_path: str
|
||||
:param requirement: Top-level requirement whose subrequirements will all be searched
|
||||
:type requirement: ~volatility.framework.interfaces.configuration.RequirementInterface
|
||||
:return: A list of tuples containing the config_path, sub_config_path and requirement identifying the SymbolRequirements
|
||||
"""
|
||||
sub_config_path = interfaces_configuration.path_join(config_path, requirement_root.name)
|
||||
results = []
|
||||
recurse = not shortcut
|
||||
if isinstance(requirement_root, requirement_type):
|
||||
if not shortcut or requirement_root.unsatisfied(context, config_path):
|
||||
results.append((config_path, sub_config_path, requirement_root))
|
||||
else:
|
||||
recurse = True
|
||||
if recurse:
|
||||
for subreq in requirement_root.requirements.values():
|
||||
results += self.find_requirements(context, sub_config_path, subreq, requirement_type, shortcut)
|
||||
return results
|
||||
|
||||
|
||||
class StackerLayerInterface(validity.ValidityRoutines, metaclass = ABCMeta):
|
||||
"""Class that takes a lower layer and attempts to build on it
|
||||
|
||||
Reference in New Issue
Block a user