diff --git a/volatility/framework/symbols/windows/__init__.py b/volatility/framework/symbols/windows/__init__.py index 589c8eba9..55d81442f 100644 --- a/volatility/framework/symbols/windows/__init__.py +++ b/volatility/framework/symbols/windows/__init__.py @@ -15,6 +15,7 @@ class WindowsKernelIntermedSymbols(intermed.IntermediateSymbolTable): self.set_type_class('_ETHREAD', extensions._ETHREAD) self.set_type_class('_LIST_ENTRY', extensions._LIST_ENTRY) self.set_type_class('_EPROCESS', extensions._EPROCESS) + self.set_type_class('_UNICODE_STRING', extensions._UNICODE_STRING) @classmethod def get_requirements(cls): diff --git a/volatility/framework/symbols/windows/extensions/__init__.py b/volatility/framework/symbols/windows/extensions/__init__.py index 67ed92690..923c723fe 100644 --- a/volatility/framework/symbols/windows/extensions/__init__.py +++ b/volatility/framework/symbols/windows/extensions/__init__.py @@ -13,6 +13,12 @@ class _ETHREAD(objects.Struct): """Return the EPROCESS that owns this thread""" return self.ThreadsProcess.dereference(kernel_layer) +class _UNICODE_STRING(objects.Struct): + @property + def String(self): + if not self._context.memory[self.vol.layer_name].is_valid(self.Buffer): + return "" + return self.Buffer.dereference().cast("string", max_length = self.Length, errors = "replace", encoding = "utf16") class _EPROCESS(objects.Struct): def add_process_layer(self, context, config_prefix = None, preferred_name = None): @@ -53,6 +59,20 @@ class _EPROCESS(objects.Struct): context.memory.add_layer(new_layer) return preferred_name + def load_order_modules(self): + + config_prefix = "dlllist" + proc_layer_name = self.add_process_layer(self._context, config_prefix) + + proc_layer = self._context.memory[proc_layer_name] + if not proc_layer.is_valid(self.Peb): + raise StopIteration + + object_factory = self._context.object_factory("ntkrnlmp") + peb = object_factory("_PEB", layer_name = proc_layer_name, offset = self.Peb) + + for entry in peb.Ldr.InLoadOrderModuleList.to_list("ntkrnlmp!_LDR_DATA_TABLE_ENTRY", "InLoadOrderLinks"): + yield entry class _LIST_ENTRY(objects.Struct, collections.abc.Iterable): def to_list(self, symbol_type, member, forward = True, sentinel = True, layer = None): diff --git a/volatility/plugins/windows/dlllist.py b/volatility/plugins/windows/dlllist.py new file mode 100644 index 000000000..70bd5bebe --- /dev/null +++ b/volatility/plugins/windows/dlllist.py @@ -0,0 +1,40 @@ +import volatility.framework.interfaces.plugins as plugins +import volatility.plugins.windows.pslist as pslist +from volatility.framework.configuration import requirements +from volatility.framework.renderers import TreeGrid +from volatility.framework.renderers.format_hints import Hex + +class DllList(plugins.PluginInterface): + @classmethod + def get_requirements(cls): + return [requirements.TranslationLayerRequirement(name = 'primary', + description = 'Kernel Address Space'), + requirements.SymbolRequirement(name = "ntkrnlmp", + description = "Windows OS"), + requirements.IntRequirement(name = 'pid', + description = "Process ID", + optional = True)] + + def _generator(self, procs): + + for proc in procs: + + for entry in proc.load_order_modules(): + + yield (0, (proc.UniqueProcessId, + proc.ImageFileName.cast("string", max_length = proc.ImageFileName.vol.count, + errors = 'replace'), + Hex(entry.DllBase), Hex(entry.SizeOfImage), + entry.BaseDllName.String, entry.FullDllName.String)) + + def run(self): + + plugin = pslist.PsList(self.context, "plugins.DllList") + + return TreeGrid([("PID", int), + ("Process", str), + ("Base", Hex), + ("Size", Hex), + ("Name", str), + ("Path", str)], + self._generator(plugin.list_processes()))