diff --git a/volatility/cli/__init__.py b/volatility/cli/__init__.py index b6f83bb66..14b7155e8 100644 --- a/volatility/cli/__init__.py +++ b/volatility/cli/__init__.py @@ -18,10 +18,10 @@ import volatility.framework import volatility.plugins from volatility.framework import automagic, constants, contexts, interfaces from volatility.framework.configuration import requirements -from volatility.framework.interfaces.configuration import HierarchicalDict -from volatility.framework.renderers.text import QuickTextRenderer +from volatility.framework.renderers import text # Make sure we log everything + vollog = logging.getLogger() vollog.setLevel(0) # Trim the console down by default @@ -125,7 +125,7 @@ class CommandLine(object): if args.config: with open(args.config, "r") as f: json_val = json.load(f) - ctx.config.splice(plugin_config_path, HierarchicalDict(json_val)) + ctx.config.splice(plugin_config_path, interfaces.configuration.HierarchicalDict(json_val)) # Populate the context config based on the returned args # We have already determined these elements must be descended from ConfigurableInterface @@ -174,7 +174,7 @@ class CommandLine(object): json.dump(dict(constructed.build_configuration()), f, sort_keys = True, indent = 2) # Construct and run the plugin - QuickTextRenderer().render(constructed.run()) + text.QuickTextRenderer().render(constructed.run()) def populate_requirements_argparse(self, parser, configurable): """Adds the plugin's simple requirements to the provided parser diff --git a/volatility/framework/configuration/requirements.py b/volatility/framework/configuration/requirements.py index b513f576a..6d0167a35 100644 --- a/volatility/framework/configuration/requirements.py +++ b/volatility/framework/configuration/requirements.py @@ -7,18 +7,17 @@ etc) as well as indicating what they expect to be in the context (such as partic import logging -from volatility.framework import constants -from volatility.framework.interfaces import configuration as interfaces_configuration +from volatility.framework import constants, interfaces vollog = logging.getLogger(__name__) # Allow these two to be imported directly from requirements # This helps prevent import loops since other interfaces need to be able to check instances of this -TranslationLayerRequirement = interfaces_configuration.TranslationLayerRequirement -SymbolRequirement = interfaces_configuration.SymbolRequirement +TranslationLayerRequirement = interfaces.configuration.TranslationLayerRequirement +SymbolRequirement = interfaces.configuration.SymbolRequirement -class MultiRequirement(interfaces_configuration.RequirementInterface): +class MultiRequirement(interfaces.configuration.RequirementInterface): """Class to hold multiple requirements. Technically the Interface could handle this, but it's an interface, so this is a concrete implementation. @@ -28,28 +27,28 @@ class MultiRequirement(interfaces_configuration.RequirementInterface): return self.unsatisfied_children(context, config_path) -class BooleanRequirement(interfaces_configuration.InstanceRequirement): +class BooleanRequirement(interfaces.configuration.InstanceRequirement): """A requirement type that contains a boolean value""" # Note, this must be a separate class in order to differentiate between Booleans and other instance requirements -class IntRequirement(interfaces_configuration.InstanceRequirement): +class IntRequirement(interfaces.configuration.InstanceRequirement): """A requirement type that contains a single integer""" instance_type = int -class StringRequirement(interfaces_configuration.InstanceRequirement): +class StringRequirement(interfaces.configuration.InstanceRequirement): """A requirement type that contains a single unicode string""" # TODO: Maybe add string length limits? instance_type = str -class BytesRequirement(interfaces_configuration.InstanceRequirement): +class BytesRequirement(interfaces.configuration.InstanceRequirement): """A requirement type that contains a byte string""" instance_type = bytes -class ChoiceRequirement(interfaces_configuration.RequirementInterface): +class ChoiceRequirement(interfaces.configuration.RequirementInterface): """Allows one from a choice of strings""" def __init__(self, choices, *args, **kwargs): @@ -68,11 +67,11 @@ class ChoiceRequirement(interfaces_configuration.RequirementInterface): value = self.config_value(context, config_path) if value not in self.choices: vollog.log(constants.LOGLEVEL_V, "ValueError - Value is not within the set of available choices") - return [interfaces_configuration.path_join(config_path, self.name)] + return [interfaces.configuration.path_join(config_path, self.name)] return [] -class ListRequirement(interfaces_configuration.RequirementInterface): +class ListRequirement(interfaces.configuration.RequirementInterface): """Allows for a list of a specific type of requirement (all of which must be met for this requirement to be met) to be specified This roughly correlates to allowing a number of arguments to follow a command line parameter, @@ -93,7 +92,7 @@ class ListRequirement(interfaces_configuration.RequirementInterface): :type min_elements: int """ super().__init__(*args, **kwargs) - if not isinstance(element_type, interfaces_configuration.InstanceRequirement): + if not isinstance(element_type, interfaces.configuration.InstanceRequirement): raise TypeError("ListRequirements can only contain simple InstanceRequirements") self.element_type = element_type self.min_elements = min_elements @@ -105,10 +104,10 @@ class ListRequirement(interfaces_configuration.RequirementInterface): self._check_type(value, list) if not (self.min_elements <= len(value) <= self.max_elements): vollog.log(constants.LOGLEVEL_V, "TypeError - List option provided more or less elements than allowed.") - return [interfaces_configuration.path_join(config_path, self.name)] + return [interfaces.configuration.path_join(config_path, self.name)] if not all([self._check_type(element, self.element_type) for element in value]): vollog.log(constants.LOGLEVEL_V, "TypeError - At least one element in the list is not of the correct type.") - return [interfaces_configuration.path_join(config_path, self.name)] + return [interfaces.configuration.path_join(config_path, self.name)] result = [] for element in value: subresult = self.element_type.unsatisfied(context, element) diff --git a/volatility/framework/contexts/__init__.py b/volatility/framework/contexts/__init__.py index ea7951f38..917f3cf3d 100644 --- a/volatility/framework/contexts/__init__.py +++ b/volatility/framework/contexts/__init__.py @@ -5,7 +5,6 @@ to act on multiple different contexts without them interfering eith each other. """ from volatility.framework import constants, interfaces, symbols -from volatility.framework.interfaces.configuration import HierarchicalDict class Context(interfaces.context.ContextInterface): @@ -32,7 +31,7 @@ class Context(interfaces.context.ContextInterface): super().__init__() self._symbol_space = symbols.SymbolSpace() self._memory = interfaces.layers.Memory() - self._config = HierarchicalDict() + self._config = interfaces.configuration.HierarchicalDict() # ## Symbol Space Functions @@ -43,7 +42,7 @@ class Context(interfaces.context.ContextInterface): @config.setter def config(self, value): - if not isinstance(value, HierarchicalDict): + if not isinstance(value, interfaces.configuration.HierarchicalDict): raise TypeError("Config must be of type HierarchicalDict") self._config = value diff --git a/volatility/framework/interfaces/layers.py b/volatility/framework/interfaces/layers.py index 87938139f..5b719f4a4 100644 --- a/volatility/framework/interfaces/layers.py +++ b/volatility/framework/interfaces/layers.py @@ -9,7 +9,6 @@ import multiprocessing from abc import ABCMeta, abstractmethod from volatility.framework import constants, exceptions, validity -from volatility.framework.exceptions import InvalidAddressException from volatility.framework.interfaces import configuration, context vollog = logging.getLogger(__name__) @@ -265,7 +264,7 @@ class TranslationLayerInterface(DataLayerInterface, metaclass = ABCMeta): if ignore_errors: # We should only hit this if we ignored errors, but check anyway return None, None - raise InvalidAddressException("Cannot translate {} in layer {}".format(offset, self.name)) + raise exceptions.InvalidAddressException("Cannot translate {} in layer {}".format(offset, self.name)) return mapped_offset, layer # ## Read/Write functions for mapped pages diff --git a/volatility/framework/objects/templates.py b/volatility/framework/objects/templates.py index 81768c0f7..685c20371 100644 --- a/volatility/framework/objects/templates.py +++ b/volatility/framework/objects/templates.py @@ -1,7 +1,6 @@ import logging -from volatility.framework import interfaces, validity -from volatility.framework.exceptions import SymbolError +from volatility.framework import interfaces, validity, exceptions vollog = logging.getLogger(__name__) @@ -71,7 +70,8 @@ class ReferenceTemplate(interfaces.objects.Template): """Referenced symbols must be appropriately resolved before they can provide information such as size This is because the size request has no context within which to determine the actual symbol structure. """ - raise SymbolError("Template contains no information about its structure: {}".format(self.vol.type_name)) + raise exceptions.SymbolError( + "Template contains no information about its structure: {}".format(self.vol.type_name)) size = property(_unresolved) replace_child = relative_child_offset = _unresolved diff --git a/volatility/framework/symbols/intermed.py b/volatility/framework/symbols/intermed.py index 84f896759..db355f8c6 100644 --- a/volatility/framework/symbols/intermed.py +++ b/volatility/framework/symbols/intermed.py @@ -9,7 +9,6 @@ import urllib.parse from volatility import schemas from volatility.framework import class_subclasses, constants, exceptions, interfaces, objects -from volatility.framework.exceptions import SymbolSpaceError from volatility.framework.symbols import native vollog = logging.getLogger(__name__) @@ -87,7 +86,7 @@ class IntermediateSymbolTable(interfaces.symbols.SymbolTableInterface): # Validation is expensive, but we cache to store the hashes of successfully validated json objects if validate and not schemas.validate(json_object): - raise SymbolSpaceError("File does not pass version validation: {}".format(url.geturl())) + raise exceptions.SymbolSpaceError("File does not pass version validation: {}".format(url.geturl())) metadata = json_object.get('metadata', None) diff --git a/volatility/framework/symbols/windows/extensions/__init__.py b/volatility/framework/symbols/windows/extensions/__init__.py index b638c0d10..032500ceb 100644 --- a/volatility/framework/symbols/windows/extensions/__init__.py +++ b/volatility/framework/symbols/windows/extensions/__init__.py @@ -1,8 +1,10 @@ import collections.abc from volatility.framework import constants, exceptions, objects +from volatility.framework.symbols import generic + + # Keep these in a basic module, to prevent import cycles when symbol providers require them -from volatility.framework.symbols.generic import GenericIntelProcess class _ETHREAD(objects.Struct): @@ -37,7 +39,7 @@ class _UNICODE_STRING(objects.Struct): encoding = "utf16") -class _EPROCESS(GenericIntelProcess): +class _EPROCESS(generic.GenericIntelProcess): def add_process_layer(self, context, config_prefix = None, preferred_name = None): """Constructs a new layer based on the process's DirectoryTableBase"""