diff --git a/volatility/cli/__init__.py b/volatility/cli/__init__.py index cfed1ed45..03e54165a 100644 --- a/volatility/cli/__init__.py +++ b/volatility/cli/__init__.py @@ -53,14 +53,15 @@ class CommandLine(object): # UI fills in the config: ctx = contexts.Context() - ctx.config["plugins.pslist.primary.class"] = "volatility.framework.layers.intel.Intel" + ctx.config["plugins.pslist.primary.class"] = "volatility.framework.layers.intel.IntelPAE" + ctx.config["plugins.pslist.primary.memory_layer.class"] = "volatility.framework.layers.physical.FileLayer" + ctx.config[ "plugins.pslist.primary.memory_layer.filename"] = "/run/media/mike/disk/memory/xp-laptop-2005-07-04-1430.img" - ctx.config["plugins.pslist.offset"] = 0x823c87c0 + ctx.config["plugins.pslist.offset"] = 0x023c87c0 - ctx.config["plugins.pslist.primary.memory_layer.class"] = "volatility.framework.layers.physical.FileLayer" ctx.config["plugins.pslist.primary.memory_layer.filename"] = "/run/media/mike/disk/memory/private/jon-fres.dmp" - ctx.config["plugins.pslist.offset"] = 0x81bcc830 + ctx.config["plugins.pslist.offset"] = 0x01bcc830 ctx.config["plugins.pslist.ntkrnlmp.class"] = "volatility.framework.symbols.windows.WindowsKernelVTypeSymbols" ctx.config["plugins.pslist.ntkrnlmp.vtype_pymodule"] = "volatility.framework.symbols.windows.xp_sp2_x86_vtypes" @@ -75,9 +76,6 @@ class CommandLine(object): automagics = automagic.available() automagic.run(automagics, ctx, plugin, "plugins") - import pdb - pdb.set_trace() - # Check all the requirements and/or go back to the automagic step if not plugin.validate(ctx, config_path): raise RuntimeError("Unable to validate the plugin configuration") diff --git a/volatility/framework/automagic/construct_layers.py b/volatility/framework/automagic/construct_layers.py index 0c7d47ec4..16e989a75 100644 --- a/volatility/framework/automagic/construct_layers.py +++ b/volatility/framework/automagic/construct_layers.py @@ -1,28 +1,31 @@ -from volatility.framework.configuration import requirements +import logging + from volatility.framework.interfaces import automagic as automagic_interface, configuration as config_interface +vollog = logging.getLogger(__name__) -class ConstructLayers(automagic_interface.AutomagicInterface): + +class ConstructionMagic(automagic_interface.AutomagicInterface): """Runs through the requirement tree and from the bottom up attempts to construct all TranslationLayerRequirements""" priority = 10 def __call__(self, context, requirement, config_path): - print("Processing", config_path, requirement.name) if not requirement.validate(context, config_path): # Having called validate at the top level tells us both that we need to dig deeper # but also ensures that TranslationLayerRequirements have got the correct subrequirements if their class is populated success = True + subreq_config_path = config_interface.path_join(config_path, requirement.name) for subreq in requirement.requirements.values(): - subreq_config_path = config_interface.path_join(config_path, requirement.name) self(context, subreq, subreq_config_path) valid = subreq.validate(context, subreq_config_path) # We want to traverse optional paths, so don't check until we've tried to validate if not valid and not subreq.optional: + vollog.debug("Failed on requirement " + subreq.name) success = False if not success: return False - elif isinstance(requirement, requirements.TranslationLayerRequirement): + elif isinstance(requirement, config_interface.ConstructableRequirementInterface): # We know all the subrequirements are filled, so let's populate requirement.construct(context, config_path) return True diff --git a/volatility/framework/automagic/windows.py b/volatility/framework/automagic/windows.py index 2ddba07dc..f13353e2a 100644 --- a/volatility/framework/automagic/windows.py +++ b/volatility/framework/automagic/windows.py @@ -1,4 +1,6 @@ +from volatility.framework import automagic from volatility.framework.configuration import requirements +from volatility.framework.interfaces import configuration as config_interface if __name__ == "__main__": import os @@ -129,11 +131,16 @@ class SelfReferentialTest(object): return response +class PageMapScanner(interfaces.layers.ScannerInterface): + def __call__(self, data, data_offset): + pass + + class PageMapOffsetHelper(automagic_interface.AutomagicInterface): priority = 20 def __init__(self): - self.tests = dict([(test.layer_type, test) for test in [DtbTest32bit(), DtbTest64bit(), DtbTestPae()]]) + self.tests = [DtbTest32bit(), DtbTest64bit(), DtbTestPae()] def branch_leave(self, node, config_path): """Ensure we're called on internal nodes as well as external""" @@ -141,23 +148,44 @@ class PageMapOffsetHelper(automagic_interface.AutomagicInterface): return True def __call__(self, context, requirement, config_path): + useful = [] + sub_config_path = config_interface.path_join(config_path, requirement.name) if isinstance(requirement, requirements.TranslationLayerRequirement): - # Determine if a class has been chosen - # If a class hasn't been chosen, look through the underlying config for appropriate parameters - # If possible run scan and choose an appropriate class - # Once an appropriate class has been chosen, attempt to determine the page_map_offset value - pass + class_req = requirement.requirements["class"] + if not class_req.validate(context, sub_config_path): + # All the intel spaces require the same kind of parameters, so pick one for the requirements + context.config.branch(config_path) + automagic.run(context, layers.intel.Intel, + config_interface.path_join(config_path, requirement.name)) - # hits = scan(self.context, memory_layer, useful) - # for test in useful: - # if hits.get(test.layer_type, []): - # self.context.config[prefix + "page_map_offset"] = hits[test.layer_type][0] - # else: - # # Delete the node rather than fixing the constraints, - # # since the requirements haven't changed, but some of the candidates are no longer valid - # # If the constraints were global across the tree, then tagging the constraints may be more useful - # del node.candidates[test.layer_type] - return True + # If a class hasn't been chosen, look through the underlying config for appropriate parameters + # If possible run scan and choose an appropriate class + pass + + for test in self.tests: + if (test.layer_type.__module__ + "." + test.layer_type.__name__ == + class_req.config_value(context, sub_config_path)): + useful.append(test) + + print(repr(requirement.requirements)) + + # Determine if a class has been chosen + # Once an appropriate class has been chosen, attempt to determine the page_map_offset value + if ("memory_layer" in requirement.requirements and + requirement.requirements["memory_layer"].validate(context, sub_config_path)): + physical_layer = requirement.requirements["memory_layer"].config_value(context, sub_config_path) + # TODO: Convert to scanner framework + # context.memory[physical_layer].scan(context, scanner) + hits = scan(context, physical_layer, useful) + # TODO: At this point, we know the class, so ditch the other tests + for test in useful: + if hits.get(test.layer_type, []): + context.config[config_interface.path_join(sub_config_path, "page_map_offset")] = \ + hits[test.layer_type][0] + requirement.construct(context, config_path) + else: + for subreq in requirement.requirements.values(): + self(context, subreq, sub_config_path) if __name__ == '__main__': diff --git a/volatility/framework/configuration/requirements.py b/volatility/framework/configuration/requirements.py index a969ac89e..d06bb784b 100644 --- a/volatility/framework/configuration/requirements.py +++ b/volatility/framework/configuration/requirements.py @@ -130,7 +130,9 @@ class SymbolRequirement(config_interface.ConstructableRequirementInterface): if name in context.symbol_space: raise ValueError("Symbol space already contains a SymbolTable by the same name") - args = {"name": name} + args = {"context": context, + "config_path": config_path, + "name": name} config_path = config_interface.path_join(config_path, self.name) if not all([subreq.validate(context, config_path) for subreq in self.requirements.values() if diff --git a/volatility/framework/symbols/windows/__init__.py b/volatility/framework/symbols/windows/__init__.py index 9eb9e7ea4..a27edbb7c 100644 --- a/volatility/framework/symbols/windows/__init__.py +++ b/volatility/framework/symbols/windows/__init__.py @@ -10,8 +10,7 @@ class WindowsKernelVTypeSymbols(vtypes.VTypeSymbolTable): def __init__(self, context, config_path, name, vtype_pymodule, vtype_variable): # FIXME: Make natives another requirement, or in some way hand it in when building the vtype_table - vtypes.VTypeSymbolTable.__init__(self, name, vtype_pymodule, vtype_variable, - context.context.symbol_space.natives) + vtypes.VTypeSymbolTable.__init__(self, name, vtype_pymodule, vtype_variable, context.symbol_space.natives) # Set-up windows specific types self.set_type_class('_ETHREAD', extensions._ETHREAD) diff --git a/volatility/plugins/windows/pslist.py b/volatility/plugins/windows/pslist.py index f51b726d3..c21b8d0aa 100644 --- a/volatility/plugins/windows/pslist.py +++ b/volatility/plugins/windows/pslist.py @@ -1,8 +1,6 @@ import volatility.framework.interfaces.plugins as plugins from volatility.framework.configuration import requirements from volatility.framework.renderers import TreeGrid -from volatility.framework.symbols import vtypes -from volatility.framework.symbols.windows import xp_sp2_x86_vtypes class PsList(plugins.PluginInterface): @@ -37,10 +35,9 @@ class PsList(plugins.PluginInterface): errors = 'replace'))) def run(self): - # Use the primary twice until we figure out how to specify base layers of a particular translation layer eproc = self.kernel_process_from_physical_process(self.context, - self.config['primary'], + self.config['primary.memory_layer'], self.config['primary'], self.config['offset'])