mirror of
https://github.com/volatilityfoundation/volatility3.git
synced 2026-09-10 11:47:38 +02:00
Add in attributes and appropriate validation of TranslationLayers based on those attributes.
This commit is contained in:
@@ -476,7 +476,7 @@ class ConfigurableInterface(validity.ValidityRoutines, metaclass = ABCMeta):
|
||||
class TranslationLayerRequirement(ConstructableRequirementInterface):
|
||||
"""Class maintaining the limitations on what sort of translation layers are acceptable"""
|
||||
|
||||
def __init__(self, name, description = None, default = None, optional = False):
|
||||
def __init__(self, name, description = None, default = None, optional = False, oses = None, architectures = None):
|
||||
"""Constructs a Translation Layer Requirement
|
||||
|
||||
The configuration option's value will be the name of the layer once it exists in the store
|
||||
@@ -485,11 +485,14 @@ class TranslationLayerRequirement(ConstructableRequirementInterface):
|
||||
:param layer_name: String detailing the expected name of the required layer, this can be None if it is to be randomly generated
|
||||
:return:
|
||||
"""
|
||||
if oses is None:
|
||||
oses = []
|
||||
if architectures is None:
|
||||
self.architectures = []
|
||||
self.oses = oses
|
||||
self.architectures = architectures
|
||||
super().__init__(name, description, default, optional)
|
||||
|
||||
# TODO: Add requirements: acceptable OSes from the address_space information
|
||||
# TODO: Add requirements: acceptable arches from the available layers
|
||||
|
||||
def unsatisfied(self, context, config_path):
|
||||
"""Validate that the value is a valid layer name and that the layer adheres to the requirements"""
|
||||
value = self.config_value(context, config_path, None)
|
||||
@@ -497,6 +500,12 @@ class TranslationLayerRequirement(ConstructableRequirementInterface):
|
||||
if value not in context.memory:
|
||||
vollog.log(9, "IndexError - Layer not found in memory space: {}".format(value))
|
||||
return [path_join(config_path, self.name)]
|
||||
if self.oses and context.memory[value].os not in self.oses:
|
||||
vollog.log(9, "TypeError - Layer is not the required OS: {}".format(value))
|
||||
return [path_join(config_path, self.name)]
|
||||
if self.architectures and context.memory[value].architecture not in self.architectures:
|
||||
vollog.log(9, "TypeError - Layer is not the required Architecture: {}".format(value))
|
||||
return [path_join(config_path, self.name)]
|
||||
return []
|
||||
|
||||
if value is not None:
|
||||
|
||||
@@ -75,11 +75,33 @@ class DataLayerInterface(configuration.ConfigurableInterface, validity.ValidityR
|
||||
"""A Layer that directly holds data (and does not translate it). This is effectively a leaf node in a layer tree.
|
||||
It directly accesses a data source and exposes it within volatility."""
|
||||
|
||||
provides = {"type": "interface"}
|
||||
|
||||
def __init__(self, context, config_path, name):
|
||||
def __init__(self, context, config_path, name, architecture = "Unknown", os = "Unknown"):
|
||||
super().__init__(context, config_path)
|
||||
self._name = self._check_type(name, str)
|
||||
self._architecture = self.check_type(architecture, str)
|
||||
self._os = self._check_type(os, str)
|
||||
|
||||
# Memory specific attributes
|
||||
|
||||
@property
|
||||
def architecture(self):
|
||||
"""The architecutre of the TranslationLayer
|
||||
|
||||
This cannot be modified after construction outside of the class
|
||||
"""
|
||||
return self._architecture
|
||||
|
||||
@property
|
||||
def os(self):
|
||||
"""The operating system related to the TranslationLayer"""
|
||||
return self._os
|
||||
|
||||
@os.setter
|
||||
def os(self, value):
|
||||
"""Sets the operating system of the TranslationLayer"""
|
||||
self._os = self._check_type(value, str)
|
||||
|
||||
# Standard attributes
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
|
||||
@@ -15,9 +15,7 @@ class Intel(interfaces.layers.TranslationLayerInterface):
|
||||
"""Translation Layer for the Intel IA32 memory mapping"""
|
||||
|
||||
priority = 40
|
||||
provides = {"type": "memory",
|
||||
"architecture": "ia32"
|
||||
}
|
||||
_architecture = "Intel32"
|
||||
|
||||
def __init__(self, context, config_path, name):
|
||||
super().__init__(context, config_path, name)
|
||||
@@ -194,6 +192,7 @@ class IntelPAE(Intel):
|
||||
"""Class for handling Physical Address Extensions for Intel architectures"""
|
||||
|
||||
priority = 35
|
||||
_architecture = "Intel32"
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
@@ -211,9 +210,7 @@ class IntelPAE(Intel):
|
||||
|
||||
class Intel32e(Intel):
|
||||
priority = 30
|
||||
provides = {"type": "memory",
|
||||
"architecture": "ia64"
|
||||
}
|
||||
architecture = "Intel64"
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
@@ -7,7 +7,8 @@ class PsList(plugins.PluginInterface):
|
||||
@classmethod
|
||||
def get_requirements(cls):
|
||||
return [requirements.TranslationLayerRequirement(name = 'primary',
|
||||
description = 'Kernel Address Space'),
|
||||
description = 'Kernel Address Space',
|
||||
architectures = ["Intel32", "Intel64"]),
|
||||
requirements.SymbolRequirement(name = "ntkrnlmp",
|
||||
description = "Windows OS"),
|
||||
requirements.IntRequirement(name = 'pid',
|
||||
|
||||
Reference in New Issue
Block a user