mirror of
https://github.com/volatilityfoundation/volatility3.git
synced 2026-09-28 20:44:52 +02:00
Add in the intial works at a stacking plugin to emulate volatility 2 address space stacking.
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import sys
|
||||
|
||||
from volatility.framework import class_subclasses, import_files, interfaces
|
||||
from volatility.framework.automagic import construct_layers, stacker, windows
|
||||
from volatility.framework.configuration import MultiRequirement
|
||||
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ if __name__ == "__main__":
|
||||
|
||||
import struct
|
||||
|
||||
from volatility.framework import automagic, interfaces, layers, validity
|
||||
from volatility.framework import interfaces, layers, validity
|
||||
from volatility.framework.configuration import requirements
|
||||
|
||||
PAGE_SIZE = 0x1000
|
||||
@@ -142,12 +142,10 @@ class PageMapScanner(interfaces.layers.ScannerInterface):
|
||||
yield (test, result)
|
||||
|
||||
|
||||
class PageMapOffsetHelper(interfaces.automagic.AutomagicInterface):
|
||||
class IntelHelper(interfaces.automagic.AutomagicInterface, interfaces.automagic.StackerLayerInterface):
|
||||
priority = 20
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.tests = [DtbTest32bit(), DtbTest64bit(), DtbTestPae()]
|
||||
stack_order = 90
|
||||
tests = [DtbTest32bit(), DtbTest64bit(), DtbTestPae()]
|
||||
|
||||
def branch_leave(self, node, config_path):
|
||||
"""Ensure we're called on internal nodes as well as external"""
|
||||
@@ -157,17 +155,9 @@ class PageMapOffsetHelper(interfaces.automagic.AutomagicInterface):
|
||||
def __call__(self, context, config_path, requirement):
|
||||
useful = []
|
||||
sub_config_path = interfaces.configuration.path_join(config_path, requirement.name)
|
||||
if isinstance(requirement, requirements.TranslationLayerRequirement):
|
||||
if (isinstance(requirement, requirements.TranslationLayerRequirement) and
|
||||
requirement.requirements.get("class", None)):
|
||||
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,
|
||||
interfaces.configuration.path_join(config_path, requirement.name))
|
||||
|
||||
# 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__ ==
|
||||
@@ -189,6 +179,20 @@ class PageMapOffsetHelper(interfaces.automagic.AutomagicInterface):
|
||||
for subreq in requirement.requirements.values():
|
||||
self(context, sub_config_path, subreq)
|
||||
|
||||
@classmethod
|
||||
def stack(cls, context, layer_name):
|
||||
"""Attempts to determine and stack an intel layer on a physical layer where possible"""
|
||||
hits = context.memory[layer_name].scan(context, PageMapScanner(cls.tests))
|
||||
new_layer = None
|
||||
for test, dtb in hits:
|
||||
new_layer = context.memory.free_layer_name("IntelLayer")
|
||||
layer = test.layer_type(context,
|
||||
config_path = interfaces.configuration.path_join("IntelHelper", new_layer),
|
||||
name = new_layer,
|
||||
page_map_offset = dtb)
|
||||
break
|
||||
return new_layer
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
import argparse
|
||||
|
||||
@@ -8,9 +8,29 @@ class AutomagicInterface(validity.ValidityRoutines, metaclass = ABCMeta):
|
||||
|
||||
priority = 10
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
|
||||
@abstractmethod
|
||||
def __call__(self, context, config_path, configurable):
|
||||
"""Runs the automagic over the configurable"""
|
||||
|
||||
|
||||
class StackerLayerInterface(validity.ValidityRoutines, metaclass = ABCMeta):
|
||||
"""Class that takes a lower layer and attempts to build on it
|
||||
|
||||
stack_order determines the order (from low to high) that stacking layers
|
||||
should be attempted lower levels should have lower stack_orders
|
||||
"""
|
||||
|
||||
stack_order = 0
|
||||
|
||||
@classmethod
|
||||
@abstractmethod
|
||||
def stack(self, context, layer_name):
|
||||
"""Method to determine whether this builder can operate on the named layer,
|
||||
If so, modify the context appropriately.
|
||||
|
||||
Returns the name of any new_layer stacked on top of this layer or None
|
||||
The stacking is therefore strictly linear rather than tree driven.
|
||||
|
||||
Configuration options provided by the context are ignored, and defaults
|
||||
are to be used by this method to build a space where possible
|
||||
"""
|
||||
|
||||
Reference in New Issue
Block a user