diff --git a/volatility/framework/symbols/windows/__init__.py b/volatility/framework/symbols/windows/__init__.py index c54c23d78..589c8eba9 100644 --- a/volatility/framework/symbols/windows/__init__.py +++ b/volatility/framework/symbols/windows/__init__.py @@ -14,6 +14,7 @@ class WindowsKernelIntermedSymbols(intermed.IntermediateSymbolTable): # Set-up windows specific types self.set_type_class('_ETHREAD', extensions._ETHREAD) self.set_type_class('_LIST_ENTRY', extensions._LIST_ENTRY) + self.set_type_class('_EPROCESS', extensions._EPROCESS) @classmethod def get_requirements(cls): diff --git a/volatility/framework/symbols/windows/extensions/__init__.py b/volatility/framework/symbols/windows/extensions/__init__.py index 8833d502c..f440c1649 100644 --- a/volatility/framework/symbols/windows/extensions/__init__.py +++ b/volatility/framework/symbols/windows/extensions/__init__.py @@ -1,5 +1,6 @@ import collections.abc +from volatility.framework import interfaces from volatility.framework import objects @@ -11,6 +12,36 @@ class _ETHREAD(objects.Struct): return self.ThreadsProcess.dereference(kernel_layer) +class _EPROCESS(objects.Struct): + def add_process_layer(self, context, config_prefix, preferred_name = None): + """Constructs a new layer """ + + # Figure out a suitable name we can use for the new layer + if preferred_name is None: + preferred_name = context.memory.free_layer_name( + prefix = self.vol.layer_name + "_PID" + str(self.UniqueProcessId) + "_") + else: + if preferred_name in context.memory: + preferred_name = context.memory.free_layer_name(prefix = preferred_name) + + # Copy the parent's config and then make suitable changes + parent_layer = context.memory[self.vol.layer_name] + parent_config = parent_layer.build_configuration() + parent_config['memory_layer'] = self.vol.layer_name + # Presumably for 64-bit systems, the DTB is defined as an array, rather than an unsigned long long + if isinstance(self.Pcb.DirectoryTableBase, objects.Array): + parent_config['page_map_offset'] = self.Pcb.DirectoryTableBase.cast("unsigned long long") + + # Set the new configuration and construct the layer + config_path = interfaces.configuration.path_join(config_prefix, preferred_name) + context.config.splice(config_path, parent_config) + new_layer = parent_layer.__class__(context, config_path = config_path, name = preferred_name) + + # Add the constructed layer and return the name + context.memory.add_layer(new_layer) + return preferred_name + + class _LIST_ENTRY(objects.Struct, collections.abc.Iterable): def to_list(self, symbol_type, member, forward = True, sentinel = True, layer = None): """Returns an iterator of the entries in the list"""