Improve the error handling with automagics.

This commit is contained in:
Mike Auty
2017-11-04 18:45:08 +00:00
parent 8166b0cc96
commit a4b4a8eed3
5 changed files with 27 additions and 13 deletions
+6 -2
View File
@@ -158,13 +158,17 @@ class CommandLine(object):
###
# Clever magic figures out how to fulfill each requirement that might not be fulfilled
if not args.quiet:
automagic.run(automagics, ctx, plugin, "plugins", progress_callback = progress_callback)
errors = automagic.run(automagics, ctx, plugin, "plugins", progress_callback = progress_callback)
else:
automagic.run(automagics, ctx, plugin, "plugins")
errors = automagic.run(automagics, ctx, plugin, "plugins")
# Check all the requirements and/or go back to the automagic step
unsatisfied = plugin.unsatisfied(ctx, plugin_config_path)
if unsatisfied:
for error in errors:
error_string = [x for x in error.format_exception_only()][-1]
vollog.warning("Automagic exception occured: {}".format(error_string[:-1]))
vollog.log(constants.LOGLEVEL_V, "\n".join(error.format(chain = True)))
raise RuntimeError("Unable to validate the plugin configuration: {}".format(unsatisfied))
print("\n\n")
+11 -2
View File
@@ -9,6 +9,7 @@ loading of file format types) as well as a module to reconstruct layers based on
import logging
import sys
import traceback
from volatility.framework import class_subclasses, import_files, interfaces
from volatility.framework.automagic import construct_layers, stacker, windows, pdbscan
@@ -55,6 +56,8 @@ def run(automagics, context, configurable, config_path, progress_callback = None
This is where any automagic is allowed to run, and alter the context in order to satisfy/improve all requirements
Returns a list of traceback objects that occurred during the autorun procedure
.. note:: The order of the `automagics` list is important. An `automagic` that populates configurations may be necessary
for an `automagic` that populates the context based on the configuration information.
"""
@@ -75,6 +78,12 @@ def run(automagics, context, configurable, config_path, progress_callback = None
for req in configurable.get_requirements():
requirement.add_requirement(req)
exceptions = []
for automagic in automagics:
vollog.info("Running automagic: {}".format(automagic.__class__.__name__))
automagic(context, config_path, requirement, progress_callback)
try:
vollog.info("Running automagic: {}".format(automagic.__class__.__name__))
automagic(context, config_path, requirement, progress_callback)
except Exception as excp:
exceptions.append(traceback.TracebackException.from_exception(excp))
return exceptions
+3 -7
View File
@@ -45,13 +45,9 @@ class LayerStacker(interfaces.automagic.AutomagicInterface):
if unsatisfied:
vollog.info("Unable to run LayerStacker, unsatisfied requirement: {}".format(unsatisfied))
return unsatisfied
if 'single_location' not in self.config:
vollog.info("Unable to run LayerStacker, single_location parameter not provided")
return []
location = self.config["single_location"]
if not location:
vollog.info("Unable to run LayerStacker, single_location parameter not provided")
return []
if not self.config.get('single_location', None):
raise ValueError("Unable to run LayerStacker, single_location parameter not provided")
location = self.config['single_location']
self._check_type(location, str)
self._check_type(requirement, interfaces.configuration.RequirementInterface)
+5 -2
View File
@@ -227,7 +227,8 @@ class DataLayerInterface(configuration.ConfigurableInterface, validity.ValidityR
"Scanning {} using {}".format(self.name, scanner.__class__.__name__))
yield from scan_chunk(value)
except Exception as e:
vollog.debug("Exception: {}".format(str(e)))
# We don't care the kind of exception, so catch and report on everything, yielding nothing further
vollog.debug("Scan Failure: {}".format(str(e)))
def _scan_iterator(self, scanner, min_address, max_address):
return range(min_address, max_address, scanner.chunk_size)
@@ -423,6 +424,7 @@ class ResourceAccessor(object):
if url_type == 'file':
curfile = urllib.request.urlopen(url, context = self._context)
else:
# TODO: find a way to check if we already have this file (look at http headers?)
block_size = 1028 * 8
temp_filename = os.path.join(constants.CACHE_PATH,
"data_" + hashlib.sha512(bytes(url, 'latin-1')).hexdigest())
@@ -433,7 +435,8 @@ class ResourceAccessor(object):
break
cache_file.write(block)
if self._progress_callback:
self._progress_callback("Reading file: {}".format(url))
# TODO: Figure out the size and therefore percentage complete
self._progress_callback(0, "Reading file {}".format(url))
cache_file.close()
# Re-open the cache with a different mode
curfile = open(temp_filename)
+2
View File
@@ -61,6 +61,8 @@ class FileLayer(interfaces.layers.DataLayerInterface):
self._location = self.config["location"]
self._file_ = None
self._size = None
# Instantiate the file to throw exceptions if the file doesn't open
_ = self._file
@property
def location(self):