diff --git a/volatility/framework/interfaces/configuration.py b/volatility/framework/interfaces/configuration.py index 6ecce390c..d1e4cb83e 100644 --- a/volatility/framework/interfaces/configuration.py +++ b/volatility/framework/interfaces/configuration.py @@ -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: diff --git a/volatility/framework/interfaces/layers.py b/volatility/framework/interfaces/layers.py index 6e9f203db..e0c529d1b 100644 --- a/volatility/framework/interfaces/layers.py +++ b/volatility/framework/interfaces/layers.py @@ -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): diff --git a/volatility/framework/layers/intel.py b/volatility/framework/layers/intel.py index d47ca568a..595ea6ec2 100644 --- a/volatility/framework/layers/intel.py +++ b/volatility/framework/layers/intel.py @@ -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) diff --git a/volatility/plugins/windows/pslist.py b/volatility/plugins/windows/pslist.py index bcb6a0fd1..d6d044e97 100644 --- a/volatility/plugins/windows/pslist.py +++ b/volatility/plugins/windows/pslist.py @@ -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',