From fb36db098efd35a7b950e0043aa2c311b2c9a0ee Mon Sep 17 00:00:00 2001 From: Analyst Date: Mon, 4 Mar 2019 11:02:53 -0600 Subject: [PATCH] add the modscan plugin --- .../framework/plugins/windows/modscan.py | 87 +++++++++++++++++++ .../framework/plugins/windows/poolscanner.py | 6 ++ 2 files changed, 93 insertions(+) create mode 100644 volatility/framework/plugins/windows/modscan.py diff --git a/volatility/framework/plugins/windows/modscan.py b/volatility/framework/plugins/windows/modscan.py new file mode 100644 index 000000000..915606470 --- /dev/null +++ b/volatility/framework/plugins/windows/modscan.py @@ -0,0 +1,87 @@ +# This file was contributed to the Volatility Framework Version 3. +# Copyright (C) 2018 Volatility Foundation. +# +# THE LICENSED WORK IS PROVIDED UNDER THE TERMS OF THE Volatility Contributors +# Public License V1.0("LICENSE") AS FIRST COMPLETED BY: Volatility Foundation, +# Inc. ANY USE, PUBLIC DISPLAY, PUBLIC PERFORMANCE, REPRODUCTION OR DISTRIBUTION +# OF, OR PREPARATION OF SUBSEQUENT WORKS, DERIVATIVE WORKS OR DERIVED WORKS BASED +# ON, THE LICENSED WORK CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS LICENSE AND ITS +# TERMS, WHETHER OR NOT SUCH RECIPIENT READS THE TERMS OF THE LICENSE. "LICENSED +# WORK,” “RECIPIENT" AND “DISTRIBUTOR" ARE DEFINED IN THE LICENSE. A COPY OF THE +# LICENSE IS LOCATED IN THE TEXT FILE ENTITLED "LICENSE.txt" ACCOMPANYING THE +# CONTENTS OF THIS FILE. IF A COPY OF THE LICENSE DOES NOT ACCOMPANY THIS FILE, A +# COPY OF THE LICENSE MAY ALSO BE OBTAINED AT THE FOLLOWING WEB SITE: +# https://www.volatilityfoundation.org/license/vcpl_v1.0 +# +# Software distributed under the License is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the +# specific language governing rights and limitations under the License. +# + +from typing import Iterable + +import volatility.framework.interfaces.plugins as plugins +from volatility.framework import renderers, interfaces, exceptions +from volatility.framework.configuration import requirements +from volatility.framework.renderers import format_hints +import volatility.framework.plugins.windows.poolscanner as poolscanner + +class ModScan(plugins.PluginInterface): + """Scans for modules present in a particular windows memory image""" + + @classmethod + def get_requirements(cls): + return [ + requirements.TranslationLayerRequirement( + name = 'primary', description = 'Memory layer for the kernel', architectures = ["Intel32", "Intel64"]), + requirements.SymbolTableRequirement(name = "nt_symbols", description = "Windows kernel symbols"), + ] + + @classmethod + def scan_modules(cls, + context: interfaces.context.ContextInterface, + layer_name: str, + symbol_table: str) -> \ + Iterable[interfaces.objects.ObjectInterface]: + """Scans for modules using the poolscanner module and constraints""" + + constraints = poolscanner.PoolScanner.builtin_constraints(symbol_table, [b'MmLd']) + + for result in poolscanner.PoolScanner.generate_pool_scan(context, + layer_name, + symbol_table, + constraints): + + _constraint, mem_object, _header = result + yield mem_object + + def _generator(self): + for mod in self.scan_modules(self.context, + self.config['primary'], + self.config['nt_symbols']): + + try: + BaseDllName = mod.BaseDllName.get_string() + except exceptions.InvalidAddressException: + BaseDllName = "" + + try: + FullDllName = mod.FullDllName.get_string() + except exceptions.InvalidAddressException: + FullDllName = "" + + yield (0, ( + format_hints.Hex(mod.vol.offset), + format_hints.Hex(mod.DllBase), + format_hints.Hex(mod.SizeOfImage), + BaseDllName, + FullDllName, + )) + + def run(self): + return renderers.TreeGrid([("Offset", format_hints.Hex), + ("Base", format_hints.Hex), + ("Size", format_hints.Hex), + ("Name", str), + ("Path", str)], + self._generator()) diff --git a/volatility/framework/plugins/windows/poolscanner.py b/volatility/framework/plugins/windows/poolscanner.py index 511e2537c..fa55743c5 100644 --- a/volatility/framework/plugins/windows/poolscanner.py +++ b/volatility/framework/plugins/windows/poolscanner.py @@ -232,6 +232,12 @@ class PoolScanner(plugins.PluginInterface): object_type = "Driver", size = (248, None), page_type = PoolType.PAGED | PoolType.NONPAGED | PoolType.FREE), + # kernel modules + PoolConstraint( + b'MmLd', + type_name = symbol_table + constants.BANG + "_LDR_DATA_TABLE_ENTRY", + size = (76, None), + page_type = PoolType.PAGED | PoolType.NONPAGED | PoolType.FREE), ] if not tags_filter: