mirror of
https://github.com/volatilityfoundation/volatility3.git
synced 2026-09-06 09:47:38 +02:00
Refactor the context work, to use composable objects rather than inheritable classes.
This commit is contained in:
+16
-16
@@ -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)
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
@@ -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"""
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user