diff --git a/volatility/framework/plugins/windows/procdump.py b/volatility/framework/plugins/windows/procdump.py index dc2471143..e1a629de4 100644 --- a/volatility/framework/plugins/windows/procdump.py +++ b/volatility/framework/plugins/windows/procdump.py @@ -18,6 +18,8 @@ vollog = logging.getLogger(__name__) class ProcDump(interfaces.plugins.PluginInterface): """Dumps process executable images.""" + _version = (1,1,0) + @classmethod def get_requirements(cls) -> List[interfaces.configuration.RequirementInterface]: # Since we're calling the plugin, make sure we have the plugin's requirements @@ -32,54 +34,61 @@ class ProcDump(interfaces.plugins.PluginInterface): requirements.PluginRequirement(name = 'pslist', plugin = pslist.PsList, version = (1, 0, 0)), ] - def _generator(self, procs): - + @classmethod + def process_dump(cls, proc) pe_table_name = intermed.IntermediateSymbolTable.create(self.context, self.config_path, "windows", "pe", class_types = pe.class_types) - for proc in procs: - process_name = utility.array_to_string(proc.ImageFileName) + proc_id = "Unknown" + try: + proc_id = proc.UniqueProcessId + proc_layer_name = proc.add_process_layer() - proc_id = "Unknown" - try: - proc_id = proc.UniqueProcessId - proc_layer_name = proc.add_process_layer() - - peb = self._context.object(self.config["nt_symbols"] + constants.BANG + "_PEB", + peb = self._context.object(self.config["nt_symbols"] + constants.BANG + "_PEB", layer_name = proc_layer_name, offset = proc.Peb) - dos_header = self.context.object(pe_table_name + constants.BANG + "_IMAGE_DOS_HEADER", + dos_header = self.context.object(pe_table_name + constants.BANG + "_IMAGE_DOS_HEADER", offset = peb.ImageBaseAddress, layer_name = proc_layer_name) - filedata = interfaces.plugins.FileInterface("pid.{0}.{1:#x}.dmp".format( - proc.UniqueProcessId, peb.ImageBaseAddress)) + filedata = interfaces.plugins.FileInterface("pid.{0}.{1:#x}.dmp".format( + proc.UniqueProcessId, peb.ImageBaseAddress)) - for offset, data in dos_header.reconstruct(): - filedata.data.seek(offset) - filedata.data.write(data) + for offset, data in dos_header.reconstruct(): + filedata.data.seek(offset) + filedata.data.write(data) + + return filedata, None - self.produce_file(filedata) - result_text = "Stored {}".format(filedata.preferred_filename) + except ValueError: + result_text = "PE parsing error" - except ValueError: - result_text = "PE parsing error" + except exceptions.SwappedInvalidAddressException as exp: + result_text = "Process {}: Required memory at {:#x} is inaccessible (swapped)".format( + proc_id, exp.invalid_address) - except exceptions.SwappedInvalidAddressException as exp: - result_text = "Process {}: Required memory at {:#x} is inaccessible (swapped)".format( - proc_id, exp.invalid_address) + except exceptions.PagedInvalidAddressException as exp: + result_text = "Process {}: Required memory at {:#x} is not valid (process exited?)".format( + proc_id, exp.invalid_address) - except exceptions.PagedInvalidAddressException as exp: - result_text = "Process {}: Required memory at {:#x} is not valid (process exited?)".format( - proc_id, exp.invalid_address) + except exceptions.InvalidAddressException as exp: + result_text = "Process {}: Required memory at {:#x} is not valid (incomplete layer {}?)".format( + proc_id, exp.invalid_address, exp.layer_name) - except exceptions.InvalidAddressException as exp: - result_text = "Process {}: Required memory at {:#x} is not valid (incomplete layer {}?)".format( - proc_id, exp.invalid_address, exp.layer_name) + + return None, result_text + + def _generator(self, procs): + + for proc in procs: + process_name = utility.array_to_string(proc.ImageFileName) + filedata, result_text = self.process_dump(proc) + self.produce_file(filedata) + result_text = "Stored {}".format(filedata.preferred_filename) yield (0, (proc.UniqueProcessId, process_name, result_text))