diff --git a/volatility3/framework/plugins/banners.py b/volatility3/framework/plugins/banners.py index eea39206d..69a1ee2b7 100644 --- a/volatility3/framework/plugins/banners.py +++ b/volatility3/framework/plugins/banners.py @@ -4,10 +4,11 @@ import logging from typing import List -from volatility3.framework import interfaces, renderers, layers +from volatility3.framework import constants, interfaces, layers, renderers from volatility3.framework.configuration import requirements from volatility3.framework.layers import scanners from volatility3.framework.renderers import format_hints +from volatility3.framework.symbols.windows import pdbutil vollog = logging.getLogger(__name__) @@ -16,6 +17,7 @@ class Banners(interfaces.plugins.PluginInterface): """Attempts to identify potential linux banners in an image""" _required_framework_version = (2, 0, 0) + _version = (1, 1, 0) @classmethod def get_requirements(cls) -> List[interfaces.configuration.RequirementInterface]: @@ -28,6 +30,11 @@ class Banners(interfaces.plugins.PluginInterface): component=scanners.RegExScanner, version=(1, 0, 0), ), + requirements.VersionRequirement( + name="pdb_signature_scanner", + component=pdbutil.PdbSignatureScanner, + version=(1, 0, 0), + ), ] def _generator(self): @@ -42,6 +49,7 @@ class Banners(interfaces.plugins.PluginInterface): cls, context: interfaces.context.ContextInterface, layer_name: str ): """Identifies banners from a memory image""" + # Look for likely linux/mac banners layer = context.layers[layer_name] for offset in layer.scan( context=context, @@ -64,6 +72,25 @@ class Banners(interfaces.plugins.PluginInterface): format_hints.Hex(offset), str(data, encoding="latin-1", errors="?"), ) + yield from cls.locate_windows_banners(context, layer_name) + + @classmethod + def locate_windows_banners( + cls, context: interfaces.context.ContextInterface, layer_name: str + ): + layer = context.layers[layer_name] + kernel_pdb_names = [ + bytes(name + ".pdb", "utf-8") + for name in constants.windows.KERNEL_MODULE_NAMES + ] + for guid, age, pdb_name, offset in layer.scan( + context=context, + scanner=pdbutil.PdbSignatureScanner(kernel_pdb_names), + ): + yield ( + format_hints.Hex(offset), + f"{pdb_name.decode('latin-1')}|{guid}|{age}", + ) def run(self): return renderers.TreeGrid( diff --git a/volatility3/framework/symbols/windows/pdbutil.py b/volatility3/framework/symbols/windows/pdbutil.py index 5f5c8cac8..af86f6997 100644 --- a/volatility3/framework/symbols/windows/pdbutil.py +++ b/volatility3/framework/symbols/windows/pdbutil.py @@ -525,6 +525,10 @@ class PdbSignatureScanner(interfaces.layers.ScannerInterface): .. note:: The pdb_names must be a list of byte strings, unicode strs will not match against the data scanned """ + _version = (1, 0, 0) + + _required_framework_version = (2, 27, 0) + overlap = 0x4000 """The size of overlap needed for the signature to ensure data cannot hide between two scanned chunks""" thread_safe = True