Reduce return results from find_requirements.

This commit is contained in:
Mike Auty
2018-09-23 22:24:44 +01:00
parent 6c938869db
commit 00a118a06a
5 changed files with 32 additions and 22 deletions
+7 -4
View File
@@ -1,7 +1,7 @@
import logging
import typing
from volatility.framework import interfaces, constants, validity
from volatility.framework import constants, interfaces, validity
from volatility.framework.automagic import linux_symbol_cache
from volatility.framework.configuration import requirements
from volatility.framework.layers import intel, scanners
@@ -39,12 +39,15 @@ class LinuxSymbolFinder(interfaces.automagic.AutomagicInterface):
requirements.SymbolRequirement),
shortcut = False)
for (path, sub_path, requirement) in self._requirements:
for (sub_path, requirement) in self._requirements:
parent_path = interfaces.configuration.parent_path(sub_path)
if (isinstance(requirement, requirements.SymbolRequirement) and requirement.unsatisfied(context, path)):
for (tl_path, tl_sub_path, tl_requirement) in self._requirements:
for (tl_sub_path, tl_requirement) in self._requirements:
tl_parent_path = interfaces.configuration.parent_path(tl_sub_path)
# Find the TranslationLayer sibling to the SymbolRequirement
if (isinstance(tl_requirement, requirements.TranslationLayerRequirement) and
tl_path == path):
tl_parent_path == parent_path):
if context.config.get(tl_sub_path, None):
self._banner_scan(context, path, requirement, context.config[tl_sub_path],
progress_callback)
+8 -5
View File
@@ -10,9 +10,10 @@ import os
import struct
import typing
from volatility.framework import exceptions, layers, validity, constants
from volatility.framework import constants, exceptions, layers, validity
from volatility.framework.configuration import requirements
from volatility.framework.layers import scanners, intel
from volatility.framework.interfaces import configuration
from volatility.framework.layers import intel, scanners
from volatility.framework.symbols import intermed, native
if __name__ == "__main__":
@@ -183,7 +184,7 @@ class KernelPDBScanner(interfaces.automagic.AutomagicInterface):
context: Context on which to operate
"""
join = interfaces.configuration.path_join
for config_path, sub_config_path, requirement in self._symbol_requirements:
for sub_config_path, requirement in self._symbol_requirements:
# TODO: Potentially think about multiple symbol requirements in both the same and different levels of the requirement tree
# TODO: Consider whether a single found kernel can fulfill multiple requirements
suffix = ".json"
@@ -205,6 +206,7 @@ class KernelPDBScanner(interfaces.automagic.AutomagicInterface):
context.config[join(sub_config_path, "class")] = clazz
context.config[join(sub_config_path, "isf_url")] = isf_path
# Construct the appropriate symbol table
config_path = interfaces.configuration.parent_path(sub_config_path)
requirement.construct(context, config_path)
break
else:
@@ -330,8 +332,9 @@ class KernelPDBScanner(interfaces.automagic.AutomagicInterface):
config_path,
requirement,
requirements.SymbolRequirement)
for symbol_req_config_path, _, symbol_req in self._symbol_requirements:
if symbol_req.unsatisfied(context, symbol_req_config_path):
for sub_config_path, symbol_req in self._symbol_requirements:
parent_path = configuration.parent_path(sub_config_path)
if symbol_req.unsatisfied(context, parent_path):
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:
+7 -7
View File
@@ -382,13 +382,14 @@ class WinSwapLayers(interfaces.automagic.AutomagicInterface):
self._translation_requirement = self.find_requirements(context, config_path, requirement,
requirements.TranslationLayerRequirement,
shortcut = False)
for trans_config, trans_sub_config, trans_req in self._translation_requirement:
for trans_sub_config, trans_req in self._translation_requirement:
if not isinstance(trans_req, requirements.TranslationLayerRequirement):
# We need this so the type-checker knows we're a TranslationLayerRequirement
continue
swap_config, swap_sub_config, swap_req = self.find_swap_requirement(trans_config, trans_sub_config,
trans_req)
swap_sub_config, swap_req = self.find_swap_requirement(trans_sub_config, trans_req)
counter = 0
swap_config = interfaces.configuration.parent_path(swap_sub_config)
if swap_req and swap_req.unsatisfied(context, swap_config):
# See if any of them need constructing
for swap_location in self.config.get('single_swap_locations', []):
@@ -418,9 +419,8 @@ class WinSwapLayers(interfaces.automagic.AutomagicInterface):
def find_swap_requirement(self,
config: str,
sub_config: str,
requirement: requirements.TranslationLayerRequirement) \
-> typing.Tuple[str, str, typing.Optional[requirements.LayerListRequirement]]:
-> typing.Tuple[str, typing.Optional[requirements.LayerListRequirement]]:
"""Takes a Translation layer and returns its swap_layer requirement"""
swap_req = None
for req_name in requirement.requirements:
@@ -429,8 +429,8 @@ class WinSwapLayers(interfaces.automagic.AutomagicInterface):
swap_req = req
continue
swap_config = interfaces.configuration.path_join(sub_config, 'swap_layers')
return sub_config, swap_config, swap_req
swap_config = interfaces.configuration.path_join(config, 'swap_layers')
return swap_config, swap_req
@classmethod
def get_requirements(cls) -> typing.List[interfaces.configuration.RequirementInterface]:
+4 -4
View File
@@ -5,7 +5,7 @@ Automagic objects attempt to automatically fill configuration values that a user
import typing
from abc import ABCMeta
from volatility.framework import validity, interfaces
from volatility.framework import interfaces, validity
from volatility.framework.configuration import requirements
R = typing.TypeVar('R', bound = interfaces.configuration.RequirementInterface)
@@ -61,7 +61,7 @@ class AutomagicInterface(interfaces.configuration.ConfigurableInterface, metacla
requirement_root: interfaces.configuration.RequirementInterface,
requirement_type: typing.Union[typing.Tuple[typing.Type[R], ...], typing.Type[R]],
shortcut: bool = True) \
-> typing.List[typing.Tuple[str, str, R]]:
-> typing.List[typing.Tuple[str, R]]:
"""Determines if there is actually an unfulfilled requirement waiting
This ensures we do not carry out an expensive search when there is no requirement for a particular requirement
@@ -77,11 +77,11 @@ class AutomagicInterface(interfaces.configuration.ConfigurableInterface, metacla
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 = [] # type: typing.List[typing.Tuple[str, str, R]]
results = [] # type: typing.List[typing.Tuple[str, R]]
recurse = not shortcut
if isinstance(requirement_root, requirement_type):
if recurse or requirement_root.unsatisfied(context, config_path):
results.append((config_path, sub_config_path, requirement_root))
results.append((sub_config_path, requirement_root))
else:
recurse = True
if recurse:
@@ -18,8 +18,7 @@ import sys
import typing
from abc import ABCMeta, abstractmethod
from volatility.framework import constants, interfaces
from volatility.framework import validity
from volatility.framework import constants, interfaces, validity
from volatility.framework.interfaces.context import ContextInterface
CONFIG_SEPARATOR = "."
@@ -39,6 +38,11 @@ def path_join(*args) -> str:
return CONFIG_SEPARATOR.join(args)
def parent_path(value: str) -> str:
"""Returns the parent configuration path from a configuration path"""
return CONFIG_SEPARATOR.join(value.split(CONFIG_SEPARATOR)[:-1])
def path_depth(path: str, depth: int = 1) -> str:
"""Returns the `path` up to a certain depth