Refactor the context work, to use composable objects rather than inheritable classes.

This commit is contained in:
Mike Auty
2015-01-19 23:57:49 +00:00
parent 38a85cfc0b
commit 3a28d7ae41
8 changed files with 118 additions and 105 deletions
+16 -16
View File
@@ -30,7 +30,12 @@ def test_symbols():
def utils_load_as():
return framework.contexts.ContextWindowsX86()()
# TODO: This should hold the smarts for determining the physical layers and guessing at various values and so on
c = framework.contexts
factory = c.ContextFactory([c.physical.PhysicalContextModifier(None),
c.intel.IntelContextModifier(None),
c.windows.WindowsContextModifier(None)])
return factory()
def test_memory():
@@ -42,24 +47,24 @@ def test_memory():
ctx.symbol_space.append(ntkrnlmp)
base = layers.physical.FileLayer(ctx, 'data', filename = 'trig_data.bin')
base = layers.physical.FileLayer(ctx, 'physical', filename = 'trig_data.bin')
ctx.memory.add_layer(base)
val = ctx.object('ntkrnlmp!TEST_POINTER', 'data', 0)
val = ctx.object('ntkrnlmp!TEST_POINTER', 'physical', 0)
print(hex(val.point1.test1), val.point1.test2)
def test_kdbgfind():
ctx = utils_load_as()
base = layers.physical.FileLayer(ctx, 'data', filename = '/home/mike/memory/xp-laptop-2005-06-25.img')
base = layers.physical.FileLayer(ctx, 'physical', filename = '/home/mike/memory/xp-laptop-2005-06-25.img')
ctx.memory.add_layer(base)
intel = layers.intel.Intel(ctx, 'intel', 'data', page_map_offset = 0x39000)
intel = layers.intel.Intel(ctx, 'kernel', 'physical', page_map_offset = 0x39000)
ctx.memory.add_layer(intel)
def intel32(ctx):
base = layers.physical.FileLayer(ctx, 'data', filename = '/home/mike/memory/xp-laptop-2005-06-25.img')
base = layers.physical.FileLayer(ctx, 'physical', filename = '/home/mike/memory/xp-laptop-2005-06-25.img')
ctx.memory.add_layer(base)
intel = layers.intel.Intel(ctx, 'intel', 'data', page_map_offset = 0x39000)
intel = layers.intel.Intel(ctx, 'kernel', 'physical', page_map_offset = 0x39000)
x = [0x823c87c0, 0x81fdf020, 0x81f5a3b8, 0x81f8eb10, 0x820e0da0, 0x82199668, 0x81fa5aa0, 0x81fa8650, 0x81faba78,
0x81fa8240, 0x81f8dda0, 0x81f6e7e8, 0x81f9a670, 0x81f5f020, 0x8202bda0, 0x82113c48, 0x81f67500, 0x81f6ca90,
0x820dd588, 0x82025608, 0x81faf280, 0x821125d0, 0x82076558, 0x81f68518, 0x82059da0, 0x81f6db28, 0x82021a78,
@@ -70,9 +75,9 @@ def intel32(ctx):
def intelpae(ctx):
base = layers.physical.FileLayer(ctx, 'data', filename = '/home/mike/memory/private/jon-fres.dmp')
base = layers.physical.FileLayer(ctx, 'physical', filename = '/home/mike/memory/private/jon-fres.dmp')
ctx.memory.add_layer(base)
intel = layers.intel.IntelPAE(ctx, 'intel', 'data', page_map_offset = 0x319000)
intel = layers.intel.IntelPAE(ctx, 'intel', 'physical', page_map_offset = 0x319000)
x = [0x81bcc830, 0x81989940, 0x81915020, 0x8192ad18, 0x818fa7b8, 0x818f6da0, 0x818d1020, 0x818b2878, 0x8189f180,
0x8188db58, 0x81884a40, 0x818766b0, 0x8185a948, 0x8183ad70, 0x81826020, 0x818a64c8, 0x81818020, 0x81800020,
0x817ff460, 0x817eb020, 0x817e9020, 0x817a62a8, 0x817a4b28, 0x81865020, 0x817972c0]
@@ -82,7 +87,7 @@ def intelpae(ctx):
def intel32e(ctx):
base = layers.physical.FileLayer(ctx, 'data', filename = '/home/mike/memory/private/ikelos-winxpsp2-x64.dmp')
ctx.memory.add_layer(base)
intel = layers.intel.Intel32e(ctx, 'intel', 'data', page_map_offset = 0x3c3000)
intel = layers.intel.Intel32e(ctx, 'kernel', 'data', page_map_offset = 0x3c3000)
x = [0xfffffadffa517c20, 0xfffffadffa2c9510, 0xfffffadffb16a660, 0xfffffadff9d77c20, 0xfffffadffb0fe040,
0xfffffadffb0f2040, 0xfffffadffb0c2040, 0xfffffadffb0b7c20, 0xfffffadffb087c20, 0xfffffadffb06a760,
0xfffffadffb039c20, 0xfffffadffb02c040, 0xfffffadffafe9c20, 0xfffffadffafa7040, 0xfffffadffaf2e040,
@@ -113,14 +118,9 @@ def test_translation():
def test_plugin():
ctx = utils_load_as()
base = layers.physical.FileLayer(ctx, 'data', filename = '/home/mike/memory/private/jon-fres.dmp')
ctx.add_layer(base)
intel = layers.intel.IntelPAE(ctx, 'intel', 'data', page_map_offset = 0x319000)
ctx.add_layer(intel)
import volatility.plugins.windows.pslist as pslist
eproc = pslist.PsList.kernel_process_from_physical_process(ctx, 'data', 'intel', 0x192ad18)
eproc = pslist.PsList.kernel_process_from_physical_process(ctx, 'physical', 'kernel', 0x192ad18)
for proc in eproc.ActiveProcessLinks:
print(proc.UniqueProcessId)
+24 -60
View File
@@ -1,71 +1,35 @@
from volatility.framework import validity
from volatility.framework.symbols import native
import volatility
from volatility.framework import layers
from volatility.framework.symbols import vtypes, native, windows
__author__ = 'mike'
from volatility.framework import interfaces
from volatility.framework.contexts import intel, physical, windows
class ContextPhysicalLoaderInterface(interfaces.context.ContextFactoryInterface):
def construct_physical_layers(self, context):
# TODO: Add in the physical layer automagic to determine the layering
# Ideally allow for the plugin to specify the layering, but if not then guess at the best one
base = layers.physical.FileLayer(context, 'data', filename = '/home/mike/memory/private/jon-fres.dmp')
context.add_layer(base)
class ContextFactory(validity.ValidityRoutines, list):
"""Class to establish and load the appropriate components of the context for a given operating system"""
def __setitem__(self, key, value):
self._type_check(value)
super(ContextFactory, self).__setitem__(key, value)
def get_config_options(self):
"""Returns all the possible configuration options that might be required for this particular ContextFactory"""
# TODO: Chainmap the options from each component
for modifier in self:
modifier.get_config_options()
### NATIVE TYPES
def __call__(self):
"""Constructs a standard context based on the architecture information
class Context32Bit(ContextPhysicalLoaderInterface):
def construct_context(self):
"""Creates a base context with the 32-bit NativeTables"""
native_list = native.x86NativeTable
return volatility.framework.Context(native_list)
Returns a new context with all appropriate modifications (symbols, layers, etc)
"""
context = volatility.framework.Context(native.x86NativeTable)
for modifier in self:
modifier(context = context)
return context
class Context64Bit(ContextPhysicalLoaderInterface):
def construct_context(self):
"""Creates a base context with the 32-bit NativeTables"""
native_list = native.x64NativeTable
return volatility.framework.Context(native_list)
### INTEL SPACES
class ContextIntel(Context32Bit):
def construct_architecture(self, context):
# TODO: Determine the DTB
intel = layers.intel.Intel(context, 'kernel', 'data', page_map_offset = 0x319000)
context.add_layer(intel)
class ContextIntelPAE(Context32Bit):
def construct_architecture(self, context):
# TODO: Determine the DTB
intel = layers.intel.IntelPAE(context, 'kernel', 'data', page_map_offset = 0x319000)
context.add_layer(intel)
class ContextIntelX64(Context64Bit):
def construct_architecture(self, context):
# TODO; Determine the DTB
intel = layers.intel.Intel32e(context, 'kernel', 'data', page_map_offset = 0x319000)
context.add_layer(intel)
### Operating Systems
class ContextWindowsX86(ContextIntel):
# TODO: Only import the vtypes during init
def __init__(self):
from volatility.framework import xp_sp2_x86_vtypes
self._virtual_types = xp_sp2_x86_vtypes.ntkrnlmp_types
def construct_os_symbols(self, context):
virtual_types = self._virtual_types
ntkrnlmp = vtypes.VTypeSymbolTable('ntkrnlmp', virtual_types, context.symbol_space.natives)
ntkrnlmp.set_structure_class('_ETHREAD', windows._ETHREAD)
ntkrnlmp.set_structure_class('_LIST_ENTRY', windows._LIST_ENTRY)
context.symbol_space.append(ntkrnlmp)
+17
View File
@@ -0,0 +1,17 @@
from volatility.framework import interfaces, layers
__author__ = 'mike'
class IntelContextModifier(interfaces.context.ContextModifierInterface):
def __init__(self, config):
pass
@classmethod
def get_config_options(cls):
pass
def __call__(self, context):
# TODO: Attempt to determine whether the image is 32, PAE or x64 (although the context must already know whether it is x64)
intel = layers.intel.IntelPAE(context, 'kernel', 'physical', page_map_offset = 0x319000)
context.add_layer(intel)
+19
View File
@@ -0,0 +1,19 @@
from volatility.framework import interfaces, layers
__author__ = 'mike'
class PhysicalContextModifier(interfaces.context.ContextModifierInterface):
def __init__(self, filename):
self.filename = '/home/mike/memory/private/jon-fres.dmp'
@classmethod
def get_config_options(cls):
pass
def __call__(self, context):
# TODO: Add in the physical layer automagic to determine the layering
# Ideally allow for the plugin to specify the layering, but if not then guess at the best one
base = layers.physical.FileLayer(context, 'physical', filename = self.filename)
context.add_layer(base)
+23
View File
@@ -0,0 +1,23 @@
from volatility.framework import interfaces
from volatility.framework.symbols import vtypes, windows
__author__ = 'mike'
class WindowsContextModifier(interfaces.context.ContextModifierInterface):
# TODO: Only import the vtypes only when necessary
def __init__(self, config):
from volatility.framework import xp_sp2_x86_vtypes
self._virtual_types = xp_sp2_x86_vtypes.ntkrnlmp_types
@classmethod
def get_config_options(cls):
pass
def __call__(self, context):
virtual_types = self._virtual_types
ntkrnlmp = vtypes.VTypeSymbolTable('ntkrnlmp', virtual_types, context.symbol_space.natives)
ntkrnlmp.set_structure_class('_ETHREAD', windows._ETHREAD)
ntkrnlmp.set_structure_class('_LIST_ENTRY', windows._LIST_ENTRY)
context.symbol_space.append(ntkrnlmp)
+7 -27
View File
@@ -45,32 +45,12 @@ class ContextInterface(object, metaclass = ABCMeta):
"""
class ContextFactoryInterface(object, metaclass = ABCMeta):
"""Class to establish and load the appropriate components of the context for a given operating system"""
def __call__(self):
"""Constructs a standard context based on the architecture information
The context is modified
"""
context = self.construct_context()
self.construct_physical_layers(context)
self.construct_architecture(context)
self.construct_os_symbols(context)
return context
class ContextModifierInterface(object, metaclass = ABCMeta):
@classmethod
@abstractmethod
def get_config_options(cls):
"""Returns all the options that might need to be passed to modify the context"""
@abstractmethod
def construct_context(self):
"""Returns a context based on some native types"""
@abstractmethod
def construct_physical_layers(self, context):
"""Adds a 'physical' layer to the context that should be used by the architecture, and any additional layers that might be usable by the architecture"""
@abstractmethod
def construct_architecture(self, context):
"""Applies the architecture mapping layer, using the primary 'physical' layer and any other layers it can additionally make use of"""
@abstractmethod
def construct_os_symbols(self, context):
"""Add the appropriate symbols for the operating system"""
def __call__(self, context):
"""Modifies the context in place"""
+10 -1
View File
@@ -15,7 +15,7 @@ class SymbolTableInterface(validity.ValidityRoutines):
if name:
self._type_check(name, str)
self.name = name or None
self._native_structures = native_structures
self.natives = native_structures
# ## Required Constant symbol functions
@@ -52,6 +52,15 @@ class SymbolTableInterface(validity.ValidityRoutines):
"""Returns None or a symbol_space for handling space specific native types"""
return self._native_structures
@natives.setter
def natives(self, value):
"""Checks the natives value and then applies it internally
WARNING: This allows changing the underlying size of all the other structures referenced in the symbolspace
"""
self._type_check(value, NativeTableInterface)
self._native_structures = value
# ## Functions for overriding classes
def set_structure_class(self, name, clazz):
+2 -1
View File
@@ -7,6 +7,7 @@ Created on 7 Feb 2013
import collections
from volatility.framework import objects, interfaces, exceptions
from volatility.framework.symbols import native, vtypes
class SymbolType(object):
@@ -100,7 +101,7 @@ class SymbolSpace(collections.Mapping):
if child.vol.structure_name not in self._resolved:
traverse_list.append(child.vol.structure_name)
self._resolved[child.vol.structure_name] = self._weak_resolve(SymbolType.STRUCTURE,
child.vol.structure_name)
child.vol.structure_name)
# Stash the replacement
replacements.add((traverser, child))
elif child.children: