Add in a first draft of a Module and context.module call.

This commit is contained in:
Mike Auty
2017-04-21 21:50:26 +01:00
parent ff41d4e5b0
commit 60ded760b6
3 changed files with 79 additions and 12 deletions
+54 -6
View File
@@ -4,9 +4,8 @@ This has been made an object to allow quick swapping and changing of contexts, t
to act on multiple different contexts without them interfering eith each other.
"""
from volatility.framework import interfaces, symbols
from volatility.framework import interfaces, symbols, constants
from volatility.framework.interfaces.configuration import HierarchicalDict
from volatility.framework.utility import adapters
__author__ = 'mike'
@@ -97,9 +96,58 @@ class Context(interfaces.context.ContextInterface):
object_info = interfaces.objects.ObjectInformation(layer_name = layer_name,
offset = offset))
def object_factory(self, symbol_table):
"""This method is DEPRECATED and provided only as a convenience.
def module(self, module_name, layer_name, offset):
"""Create a module object """
It will be removed in volatility 3.0.0 final release.
return Module(self, module_name, layer_name, offset)
class Module(interfaces.context.Module):
def object(self, symbol_name = None, type_name = None, offset = None, **kwargs):
"""Returns an object created using the symbol_table and layer_name of the Module
@param symbol_name: Name of the symbol (within the module) to construct, type_name and offset must not be specified
@type symbol_name: str
@param type_name: Name of the type (within the module) to construct, offset must be specified and symbol_name must not
@type type_name: str
@param offset: The location (absolute within memory), type_name must be specified and symbol_name must not
@type offset: int
"""
return adapters.object_factory(self, symbol_table)
symbol_type = symbol_name and not (type_name or offset)
type_type = (type_name and offset) and not symbol_name
if symbol_type and type_type or not (symbol_type or type_type):
raise ValueError("One of symbol_name, or type_name & offset, must be specified to construct a module")
if symbol_type is not None:
self._check_type(symbol_name, str)
if constants.BANG in symbol_name:
raise ValueError("Symbol_name cannot reference another module")
symbol = self._context.symbol_space.get_symbol(self._module_name + constants.BANG + symbol_name)
if symbol.type is None:
raise ValueError("Symbol {} has no associated type information".format(symbol_name))
type_arg = symbol.type
offset = symbol.address + self._offset
else:
self._check_type(type_name, str)
self._check_type(offset, int)
if constants.BANG in type_name:
raise ValueError("Type_name cannot reference another module")
type_arg = self._module_name + constants.BANG + type_name
return self._context.object(type_arg, self._layer_name, offset, **kwargs)
def wrap(method):
"""Returns a symbol using the symbol_table of the Module"""
def wrapper(self, name):
self._check_type(name, str)
if constants.BANG in name:
raise ValueError("Name cannot reference another module")
return getattr(self._context.symbol_space, method)(self._module_name + constants.BANG + name)
return wrapper
get_symbol = wrap('get_symbol')
get_type = wrap('get_type')
get_enum = wrap('get_enum')
has_symbol = wrap('has_symbol')
has_type = wrap('has_type')
has_enum = wrap('has_enum')
@@ -7,6 +7,8 @@ notably the object constructor function, `object`, which will construct a symbol
import copy
from abc import ABCMeta, abstractmethod, abstractproperty
from volatility.framework import validity
class ContextInterface(object, metaclass = ABCMeta):
"""All context-like objects must adhere to the following interface.
@@ -63,3 +65,21 @@ class ContextInterface(object, metaclass = ABCMeta):
Memory constraints may become an issue for this function depending on how much is actually stored in the context"""
return copy.deepcopy(self)
class Module(validity.ValidityRoutines, metaclass = ABCMeta):
"""Maintains state concerning a particular loaded module in memory
This object is OS-independent.
"""
def __init__(self, context, module_name, layer_name, offset):
self._context = self._check_type(context, ContextInterface)
self._module_name = self._check_type(module_name, str)
self._layer_name = self._check_type(layer_name, str)
self._offset = self._check_type(offset, int)
super().__init__()
@abstractmethod
def object(self, symbol_name = None, type_name = None, offset = None):
"""Returns an object created using the symbol_table and layer_name of the Module"""
+5 -6
View File
@@ -1,7 +1,6 @@
import volatility.framework.interfaces.plugins as plugins
from volatility.framework.configuration import requirements
from volatility.framework.renderers import TreeGrid
from volatility.framework.utility import adapters
class PsList(plugins.PluginInterface):
@@ -33,13 +32,13 @@ class PsList(plugins.PluginInterface):
layer_name = self.config['primary']
# We only use the object factory to demonstrate how to use one
object_factory = adapters.object_factory(self.context, "ntkrnlmp")
kvo = self.config['primary.kernel_virtual_offset']
ps_aph_offset = kvo + self.context.symbol_space.get_symbol("ntkrnlmp!PsActiveProcessHead").address
list_entry = object_factory("_LIST_ENTRY", layer_name = layer_name, offset = ps_aph_offset)
ntkrnlmp = self.context.module("ntkrnlmp", layer_name = layer_name, offset = kvo)
ps_aph_offset = ntkrnlmp.get_symbol("PsActiveProcessHead").address
list_entry = ntkrnlmp.object(type_name = "_LIST_ENTRY", offset = kvo + ps_aph_offset)
reloff = self.context.symbol_space.get_type("ntkrnlmp!_EPROCESS").relative_child_offset("ActiveProcessLinks")
eproc = object_factory("_EPROCESS", layer_name = layer_name, offset = list_entry.vol.offset - reloff)
eproc = ntkrnlmp.object(type_name = "_EPROCESS", offset = list_entry.vol.offset - reloff)
for proc in eproc.ActiveProcessLinks:
yield proc