diff --git a/volatility3/framework/plugins/windows/netstat.py b/volatility3/framework/plugins/windows/netstat.py index 1d37258ab..e81a4d723 100644 --- a/volatility3/framework/plugins/windows/netstat.py +++ b/volatility3/framework/plugins/windows/netstat.py @@ -32,6 +32,7 @@ class NetStat(interfaces.plugins.PluginInterface, timeliner.TimeLinerInterface): requirements.SymbolTableRequirement(name = "nt_symbols", description = "Windows kernel symbols"), requirements.VersionRequirement(name = 'netscan', component = netscan.NetScan, version = (1, 0, 0)), requirements.VersionRequirement(name = 'modules', component = modules.Modules, version = (1, 0, 0)), + requirements.VersionRequirement(name = 'pdbutil', component = pdbutil.PDBUtility, version = (1, 0, 0)), requirements.BooleanRequirement( name = 'include-corrupt', description = @@ -184,7 +185,8 @@ class NetStat(interfaces.plugins.PluginInterface, timeliner.TimeLinerInterface): @classmethod def parse_hashtable(cls, context: interfaces.context.ContextInterface, layer_name: str, ht_offset: int, - ht_length: int, alignment: int, net_symbol_table: str) -> Generator[interfaces.objects.ObjectInterface, None, None]: + ht_length: int, alignment: int, + net_symbol_table: str) -> Generator[interfaces.objects.ObjectInterface, None, None]: """Parses a hashtable quick and dirty. Args: @@ -288,8 +290,8 @@ class NetStat(interfaces.plugins.PluginInterface, timeliner.TimeLinerInterface): end = tcpip_module_offset + tcpip_module_size)) if not guids: - raise exceptions.VolatilityException("Did not find GUID of tcpip.pdb in tcpip.sys module @ 0x{:x}!".format( - tcpip_module_offset)) + raise exceptions.VolatilityException( + "Did not find GUID of tcpip.pdb in tcpip.sys module @ 0x{:x}!".format(tcpip_module_offset)) guid = guids[0] @@ -437,8 +439,9 @@ class NetStat(interfaces.plugins.PluginInterface, timeliner.TimeLinerInterface): tcpip_module = self.get_tcpip_module(self.context, self.config["primary"], self.config["nt_symbols"]) - tcpip_symbol_table = self.create_tcpip_symbol_table(self.context, self.config_path, self.config["primary"], - tcpip_module.DllBase, tcpip_module.SizeOfImage) + tcpip_symbol_table = pdbutil.PDBUtility.symbol_table_from_pdb( + self.context, interfaces.configuration.path_join(self.config_path, 'tcpip'), self.config["primary"], + "tcpip.pdb", tcpip_module.DllBase, tcpip_module.SizeOfImage) for netw_obj in self.list_sockets(self.context, self.config['primary'], self.config['nt_symbols'], netscan_symbol_table, tcpip_module.DllBase, tcpip_symbol_table): diff --git a/volatility3/framework/symbols/windows/pdbutil.py b/volatility3/framework/symbols/windows/pdbutil.py index ac7357f6a..5db71ca01 100644 --- a/volatility3/framework/symbols/windows/pdbutil.py +++ b/volatility3/framework/symbols/windows/pdbutil.py @@ -12,7 +12,7 @@ from typing import Any, Dict, Generator, List, Optional, Tuple, Union from urllib import request, parse from volatility3 import symbols -from volatility3.framework import constants, interfaces +from volatility3.framework import constants, interfaces, exceptions from volatility3.framework.configuration.requirements import SymbolTableRequirement from volatility3.framework.symbols import intermed from volatility3.framework.symbols.windows import pdbconv @@ -20,9 +20,11 @@ from volatility3.framework.symbols.windows import pdbconv vollog = logging.getLogger(__name__) -class PDBUtility: +class PDBUtility(interfaces.configuration.VersionableInterface): """Class to handle and manage all getting symbols based on MZ header""" + _version = (1, 0, 0) + @classmethod def symbol_table_from_offset( cls, @@ -279,6 +281,47 @@ class PDBUtility: 'mz_offset': mz_offset } + @classmethod + def symbol_table_from_pdb(cls, context: interfaces.context.ContextInterface, config_path: str, layer_name: str, + pdb_name: str, module_offset: int, module_size: int) -> str: + """Creates symbol table for a module in the specified layer_name. + + Searches the memory section of the loaded module for its PDB GUID + and loads the associated symbol table into the symbol space. + + Args: + context: The context to retrieve required elements (layers, symbol tables) from + config_path: The config path where to find symbol files + layer_name: The name of the layer on which to operate + module_offset: This memory dump's module image offset + module_size: The size of the module for this dump + + Returns: + The name of the constructed and loaded symbol table + """ + + guids = list( + cls.pdbname_scan(context, + layer_name, + context.layers[layer_name].page_size, [bytes(pdb_name, 'latin-1')], + start = module_offset, + end = module_offset + module_size)) + + if not guids: + raise exceptions.VolatilityException( + "Did not find GUID of tcpip.pdb in tcpip.sys module @ 0x{:x}!".format(module_offset)) + + guid = guids[0] + + vollog.debug("Found {}: {}-{}".format(guid["pdb_name"], guid["GUID"], guid["age"])) + + return cls.load_windows_symbol_table(context, + guid["GUID"], + guid["age"], + guid["pdb_name"], + "volatility3.framework.symbols.intermed.IntermediateSymbolTable", + config_path = config_path) + class PdbSignatureScanner(interfaces.layers.ScannerInterface): """A :class:`~volatility3.framework.interfaces.layers.ScannerInterface`