From 9824538bd9bdbd497ff03bf0f2f67f581bbf4ec6 Mon Sep 17 00:00:00 2001 From: Mike Auty Date: Sun, 16 Dec 2018 13:14:43 +0000 Subject: [PATCH] Numerous pycharm warnings resolved This includes: * Better ways of checking empty lists * Not shadowing builtin functions like filter * Preventing invalid slash warnings by marking strings as regexps * Removing unnecessary brackets * Lowercase variable names * Adding/updating parameters in docstrings * Removing unused code (lines not chunks) * Change in not a member tests * Changing some methods to static * Shorting range membership checks * Missing parameters * Make some exception handlers more specific * Don't define a lambda to a variable * A few more instance checks to help type checkers --- volatility/framework/automagic/linux.py | 12 ++++++------ volatility/framework/automagic/mac.py | 2 +- volatility/framework/automagic/pdbscan.py | 13 +++++++------ volatility/framework/automagic/stacker.py | 3 +-- volatility/framework/automagic/windows.py | 2 +- volatility/framework/configuration/requirements.py | 6 +++++- volatility/framework/contexts/__init__.py | 11 +++++------ volatility/framework/layers/__init__.py | 5 +++-- volatility/framework/layers/intel.py | 1 - volatility/framework/layers/physical.py | 6 +++--- volatility/framework/layers/registry.py | 4 ++-- volatility/framework/objects/__init__.py | 6 ++---- volatility/framework/plugins/__init__.py | 6 +++--- volatility/framework/renderers/__init__.py | 4 ++-- volatility/framework/symbols/intermed.py | 13 +++++++------ volatility/plugins/linux/bash.py | 10 +++++----- volatility/plugins/linux/elfs.py | 6 +++--- volatility/plugins/linux/malfind.py | 6 +++--- volatility/plugins/linux/pslist.py | 12 ++++++++---- volatility/plugins/mac/pslist.py | 7 ++++--- volatility/plugins/timeliner.py | 14 ++++++++++---- volatility/plugins/windows/handles.py | 6 +++--- volatility/plugins/windows/info.py | 2 ++ volatility/plugins/windows/poolscanner.py | 2 +- volatility/plugins/windows/pslist.py | 4 +++- volatility/plugins/windows/registry/printkey.py | 8 ++++---- volatility/plugins/windows/ssdt.py | 12 ++++++++++-- volatility/plugins/windows/vaddump.py | 2 +- volatility/plugins/windows/vadinfo.py | 10 ++++++++-- volatility/plugins/windows/verinfo.py | 5 +++-- 30 files changed, 116 insertions(+), 84 deletions(-) diff --git a/volatility/framework/automagic/linux.py b/volatility/framework/automagic/linux.py index 7651b6fd4..d7a574ca9 100644 --- a/volatility/framework/automagic/linux.py +++ b/volatility/framework/automagic/linux.py @@ -122,7 +122,7 @@ class LinuxUtilities(object): # either 1) smeared out of memory or 2) de-allocated and corresponding structures overwritten # we return an empty string in this case to avoid confusion with something like a handle to the root # directory (e.g., "/") - if ret_path == []: + if not ret_path: return "" ret_val = '/'.join([str(p) for p in ret_path if p != ""]) @@ -161,10 +161,10 @@ class LinuxUtilities(object): sym_addr = dentry.d_op.d_dname - symbols = list(dentry.context.symbol_space.get_symbols_by_location(sym_addr)) + symbs = list(dentry.context.symbol_space.get_symbols_by_location(sym_addr)) - if len(symbols) == 1: - sym = symbols[0].split(constants.BANG)[1] + if len(symbs) == 1: + sym = symbs[0].split(constants.BANG)[1] if sym == "sockfs_dname": pre_name = "socket" @@ -271,7 +271,7 @@ class LinuxUtilities(object): """Determines the offset of the actual DTB in physical space and its symbol offset""" init_task_symbol = symbol_table + constants.BANG + 'init_task' init_task_json_address = context.symbol_space.get_symbol(init_task_symbol).address - swapper_signature = b"swapper(\/0|\x00\x00)\x00\x00\x00\x00\x00\x00" + swapper_signature = rb"swapper(\/0|\x00\x00)\x00\x00\x00\x00\x00\x00" module = context.module(symbol_table, layer_name, 0) for offset in context.memory[layer_name].scan(scanner = scanners.RegExScanner(swapper_signature), @@ -281,7 +281,7 @@ class LinuxUtilities(object): init_task = module.object(type_name = 'task_struct', offset = init_task_address) if init_task.pid != 0: continue - elif (init_task.has_member('state') and init_task.state.cast('unsigned int') != 0): + elif init_task.has_member('state') and init_task.state.cast('unsigned int') != 0: continue # This we get for free diff --git a/volatility/framework/automagic/mac.py b/volatility/framework/automagic/mac.py index c2939d3da..1cb1be34e 100644 --- a/volatility/framework/automagic/mac.py +++ b/volatility/framework/automagic/mac.py @@ -124,7 +124,7 @@ class MacUtilities(object): @classmethod def _scan_generator(cls, context, layer_name, progress_callback): - darwin_signature = b"Darwin Kernel Version \d{1,3}\.\d{1,3}\.\d{1,3}: [^\x00]+\x00" + darwin_signature = rb"Darwin Kernel Version \d{1,3}\.\d{1,3}\.\d{1,3}: [^\x00]+\x00" for offset in context.memory[layer_name].scan(scanner = scanners.RegExScanner(darwin_signature), context = context, progress_callback = progress_callback): diff --git a/volatility/framework/automagic/pdbscan.py b/volatility/framework/automagic/pdbscan.py index c4ace914b..bb00590ee 100644 --- a/volatility/framework/automagic/pdbscan.py +++ b/volatility/framework/automagic/pdbscan.py @@ -59,9 +59,9 @@ class PdbSignatureScanner(interfaces.layers.ScannerInterface): (g3, g2, g1, g0, g5, g4, g7, g6, g8, g9, ga, gb, gc, gd, ge, gf, a) = \ self._RSDS_format.unpack(data[sig + 4:name_offset]) - GUID = (16 * '{:02X}').format(g0, g1, g2, g3, g4, g5, g6, g7, g8, g9, ga, gb, gc, gd, ge, gf) + guid = (16 * '{:02X}').format(g0, g1, g2, g3, g4, g5, g6, g7, g8, g9, ga, gb, gc, gd, ge, gf) if sig < self.chunk_size: - yield (GUID, a, pdb_name, data_offset + sig) + yield (guid, a, pdb_name, data_offset + sig) sig = data.find(b"RSDS", sig + 1) @@ -145,6 +145,7 @@ class KernelPDBScanner(interfaces.automagic.AutomagicInterface): context: The context in which the `requirement` lives config_path: The path within the `context` for the `requirement`'s configuration variables requirement: The root of the requirement tree to search for :class:~`volatility.framework.interfaces.layers.TranslationLayerRequirement` objects to scan + progress_callback: Means of providing the user with feedback during long processes Returns: A list of (layer_name, scan_results) @@ -179,15 +180,14 @@ class KernelPDBScanner(interfaces.automagic.AutomagicInterface): Args: context: Context on which to operate + valid_kernels: A list of offsets where valid kernels have been found """ join = interfaces.configuration.path_join for sub_config_path, requirement in self._symbol_requirements: # TODO: Potentially think about multiple symbol requirements in both the same and different levels of the requirement tree # TODO: Consider whether a single found kernel can fulfill multiple requirements - suffix = ".json" if valid_kernels: # TODO: Check that the symbols for this kernel will fulfill the requirement - kernel = None for virtual_layer in valid_kernels: _kvo, kernel = valid_kernels[virtual_layer] filter_string = os.path.join(kernel['pdb_name'], kernel['GUID'] + "-" + str(kernel['age'])) @@ -220,9 +220,10 @@ class KernelPDBScanner(interfaces.automagic.AutomagicInterface): Args: context: Context on which to operate and provide the kernel virtual offset + valid_kernels: List of valid kernels and offsets """ for virtual_layer in valid_kernels: - # Sit the virtual offset under the TranslationLayer it applies to + # Set the virtual offset under the TranslationLayer it applies to kvo_path = interfaces.configuration.path_join(context.memory[virtual_layer].config_path, 'kernel_virtual_offset') kvo, kernel = valid_kernels[virtual_layer] @@ -253,7 +254,7 @@ class KernelPDBScanner(interfaces.automagic.AutomagicInterface): kvo = kernel['mz_offset'] + (1 << (vlayer.bits_per_register - 1)) try: kvp = vlayer.mapping(kvo, 0) - if (any([(p == kernel['mz_offset'] and l == physical_layer_name) for (_, p, _, l) in + if (any([(p == kernel['mz_offset'] and layer_name == physical_layer_name) for (_, p, _, layer_name) in kvp])): valid_kernels[virtual_layer_name] = (kvo, kernel) # Sit the virtual offset under the TranslationLayer it applies to diff --git a/volatility/framework/automagic/stacker.py b/volatility/framework/automagic/stacker.py index d21481f1e..5ec5cbed1 100644 --- a/volatility/framework/automagic/stacker.py +++ b/volatility/framework/automagic/stacker.py @@ -73,8 +73,7 @@ class LayerStacker(interfaces.automagic.AutomagicInterface): Args: context: Context on which to operate config_path: Configuration path under which to store stacking data - location: File URL for the underlying physical layer - requirements: List of requirements, each of which has the stack built on the first suitable (sub-)requirement + requirement: Requirement that should have layers stacked on it progress_callback: Function to provide callback progress """ # If we're cached, find Now we need to find where to apply the stack configuration diff --git a/volatility/framework/automagic/windows.py b/volatility/framework/automagic/windows.py index 4211c6e93..f490478d4 100644 --- a/volatility/framework/automagic/windows.py +++ b/volatility/framework/automagic/windows.py @@ -296,7 +296,7 @@ class WintelStacker(interfaces.automagic.StackerLayerInterface): base_layer = context.memory[layer_name] if isinstance(base_layer, intel.Intel): return None - if (base_layer.metadata.get('os', None) not in ['Windows', 'Unknown']): + if base_layer.metadata.get('os', None) not in ['Windows', 'Unknown']: return None layer = config_path = None diff --git a/volatility/framework/configuration/requirements.py b/volatility/framework/configuration/requirements.py index 4e22821c8..d1d059718 100644 --- a/volatility/framework/configuration/requirements.py +++ b/volatility/framework/configuration/requirements.py @@ -220,7 +220,11 @@ class TranslationLayerRequirement(configuration.ConstructableRequirementInterfac Args: name: Name of the configuration requirement - layer_name: String detailing the expected name of the required layer, this can be None if it is to be randomly generated + description: Description of the configuration requirement + default: A default value (should not be used for TranslationLayers) + optional: Whether the translation layer is required or not + oses: A list of valid operating systems which can satisfy this requirement + architectures: A list of valid architectures which can satisfy this requirement """ if oses is None: oses = [] diff --git a/volatility/framework/contexts/__init__.py b/volatility/framework/contexts/__init__.py index e8a6961be..11d1f62ee 100644 --- a/volatility/framework/contexts/__init__.py +++ b/volatility/framework/contexts/__init__.py @@ -146,12 +146,11 @@ class Module(interfaces.context.ModuleInterface): **kwargs) -> interfaces.objects.ObjectInterface: """Returns an object created using the symbol_table_name and layer_name of the Module - @param symbol_name: Name of the symbol (within the module) to construct, type_name and offset must not be specified - @type symbol_name: str - @param type_name: Name of the type (within the module) to construct, offset must be specified and symbol_name must not - @type type_name: str - @param offset: The location (absolute within memory), type_name must be specified and symbol_name must not - @type offset: int + Args: + symbol_name: Name of the symbol (within the module) to construct, type_name and offset must not be specified + type_name: Name of the type (within the module) to construct, offset must be specified and symbol_name must not + offset: The location (absolute within memory), type_name must be specified and symbol_name must not + native_layer_name: Name of the layer in which constructed objects are made (for pointers) """ type_arg = None # type: Optional[Union[str, interfaces.objects.Template]] if symbol_name is not None: diff --git a/volatility/framework/layers/__init__.py b/volatility/framework/layers/__init__.py index 978e8649a..6de289a47 100644 --- a/volatility/framework/layers/__init__.py +++ b/volatility/framework/layers/__init__.py @@ -67,7 +67,7 @@ class ResourceAccessor(object): temp_filename = os.path.join(constants.CACHE_PATH, "data_" + hashlib.sha512(bytes(url, 'latin-1')).hexdigest()) - if not temp_filename in self._cached_files or not os.path.exists(temp_filename): + if temp_filename not in self._cached_files or not os.path.exists(temp_filename): vollog.info("Caching file at: {}".format(temp_filename)) try: @@ -154,7 +154,8 @@ class JarHandler(urllib.request.BaseHandler): http://developer.java.sun.com/developer/onlineTraining/protocolhandlers/ """ - def default_open(self, req): + @staticmethod + def default_open(req): """Handles the request if it's the jar scheme""" if req.type == 'jar': subscheme, remainder = req.full_url.split(":")[1], ":".join(req.full_url.split(":")[2:]) diff --git a/volatility/framework/layers/intel.py b/volatility/framework/layers/intel.py index 9b0b678cc..da4651e16 100644 --- a/volatility/framework/layers/intel.py +++ b/volatility/framework/layers/intel.py @@ -207,7 +207,6 @@ class Intel(interfaces.layers.TranslationLayerInterface): @property def dependencies(self) -> List[str]: """Returns a list of the lower layer names that this layer is dependent upon""" - # TODO: Add in the whole buffalo return [self._base_layer] + self._swap_layers @classmethod diff --git a/volatility/framework/layers/physical.py b/volatility/framework/layers/physical.py index 411b7730c..6b2fc9a03 100644 --- a/volatility/framework/layers/physical.py +++ b/volatility/framework/layers/physical.py @@ -37,7 +37,7 @@ class BufferDataLayer(interfaces.layers.DataLayerInterface): """Reads the data from the buffer""" if not self.is_valid(address, length): invalid_address = address - if self.minimum_address < address and address <= self.maximum_address: + if self.minimum_address < address <= self.maximum_address: invalid_address = self.maximum_address + 1 raise exceptions.InvalidAddressException(self.name, invalid_address, "Offset outside of the buffer boundaries") @@ -115,7 +115,7 @@ class FileLayer(interfaces.layers.DataLayerInterface): """Reads from the file at offset for length""" if not self.is_valid(offset, length): invalid_address = offset - if self.minimum_address < offset and offset <= self.maximum_address: + if self.minimum_address < offset <= self.maximum_address: invalid_address = self.maximum_address + 1 raise exceptions.InvalidAddressException(self.name, invalid_address, "Offset outside of the buffer boundaries") @@ -137,7 +137,7 @@ class FileLayer(interfaces.layers.DataLayerInterface): """ if not self.is_valid(offset, len(data)): invalid_address = offset - if self.minimum_address < offset and offset <= self.maximum_address: + if self.minimum_address < offset <= self.maximum_address: invalid_address = self.maximum_address + 1 raise exceptions.InvalidAddressException(self.name, invalid_address, "Data segment outside of the " + self.name + " file boundaries") diff --git a/volatility/framework/layers/registry.py b/volatility/framework/layers/registry.py index df25d053c..bb85ebbbd 100644 --- a/volatility/framework/layers/registry.py +++ b/volatility/framework/layers/registry.py @@ -168,7 +168,7 @@ class RegistryHive(interfaces.layers.TranslationLayerInterface): """Translates a single cell index to a cell memory offset and the suboffset within it""" # Ignore the volatile bit when determining maxaddr validity - if (offset & 0x7fffffff > self._maxaddr): + if offset & 0x7fffffff > self._maxaddr: raise RegistryInvalidIndex("Mapping request for value greater than maxaddr") volatile = self._mask(offset, 31, 31) >> 31 @@ -187,7 +187,7 @@ class RegistryHive(interfaces.layers.TranslationLayerInterface): ignore_errors: bool = False) -> Iterable[Tuple[int, int, int, str]]: # TODO: Check the offset and offset + length are not outside the norms - if (length < 0): + if length < 0: raise ValueError("Mapping length of RegistryHive must be positive or zero") response = [] diff --git a/volatility/framework/objects/__init__.py b/volatility/framework/objects/__init__.py index 1e9d21af3..32fad3b6f 100644 --- a/volatility/framework/objects/__init__.py +++ b/volatility/framework/objects/__init__.py @@ -27,8 +27,7 @@ def convert_data_to_value(data: bytes, float_vals = "zzezfzzzd" if data_format.length > len(float_vals) or float_vals[data_format.length] not in "efd": raise TypeError("Invalid float size") - struct_format = ("<" if data_format.byteorder == 'little' else ">") + \ - float_vals[data_format.length] + struct_format = ("<" if data_format.byteorder == 'little' else ">") + float_vals[data_format.length] elif struct_type in [bytes, str]: struct_format = str(data_format.length) + "s" else: @@ -55,8 +54,7 @@ def convert_value_to_data(value: Union[int, float, bytes, str, bool], float_vals = "zzezfzzzd" if data_format.length > len(float_vals) or float_vals[data_format.length] not in "efd": raise TypeError("Invalid float size") - struct_format = ("<" if data_format.byteorder == 'little' else ">") + \ - float_vals[data_format.length] + struct_format = ("<" if data_format.byteorder == 'little' else ">") + float_vals[data_format.length] elif struct_type in [bytes, str]: struct_format = str(data_format.length) + "s" else: diff --git a/volatility/framework/plugins/__init__.py b/volatility/framework/plugins/__init__.py index 70cc94106..ea89a016e 100644 --- a/volatility/framework/plugins/__init__.py +++ b/volatility/framework/plugins/__init__.py @@ -25,9 +25,9 @@ def run_plugin(context: interfaces.context.ContextInterface, context: The volatility context to operate on automagics: A list of automagic modules to run to augment the context plugin: The plugin to run - plugin_config_path: The path within the context's config containing the plugin's configuration - write_config: Whether to record the configuration options after processing the automagic but before running - quiet: Whether or not to output progress information + base_config_path: The path within the context's config containing the plugin's configuration + progress_callback: Callback function to provide feedback for ongoing processes + file_consumer: Object to pass any generated files to Returns: The constructed plugin object diff --git a/volatility/framework/renderers/__init__.py b/volatility/framework/renderers/__init__.py index 0d8814715..2a9457dca 100644 --- a/volatility/framework/renderers/__init__.py +++ b/volatility/framework/renderers/__init__.py @@ -249,7 +249,7 @@ class TreeGrid(interfaces.renderers.TreeGrid): newpath = parent_path + str(position) tree_item = TreeNode(newpath, self, parent, values) for node, _ in children[position:]: - self.visit(node, lambda child, _: child.path_changed(newpath, True)) + self.visit(node, lambda child, _: child.path_changed(newpath, True), None) children.insert(position, (tree_item, [])) return tree_item @@ -259,7 +259,7 @@ class TreeGrid(interfaces.renderers.TreeGrid): def max_depth(self): """Returns the maximum depth of the tree""" - return self.visit(None, lambda n, a: max(a, self.path_depth(n)), ) + return self.visit(None, lambda n, a: max(a, self.path_depth(n)), 0) _T = TypeVar("_T") diff --git a/volatility/framework/symbols/intermed.py b/volatility/framework/symbols/intermed.py index 14b0709d3..856f1681b 100644 --- a/volatility/framework/symbols/intermed.py +++ b/volatility/framework/symbols/intermed.py @@ -253,11 +253,11 @@ class ISFormatTable(interfaces.symbols.SymbolTableInterface, metaclass = ABCMeta # TODO: Check the format and make use of the other metadata def _validate_json(self) -> None: - if (not 'user_types' in self._json_object or - not 'base_types' in self._json_object or - not 'metadata' in self._json_object or - not 'symbols' in self._json_object or - not 'enums' in self._json_object): + if ('user_types' not in self._json_object or + 'base_types' not in self._json_object or + 'metadata' not in self._json_object or + 'symbols' not in self._json_object or + 'enums' not in self._json_object): raise exceptions.SymbolSpaceError("Malformed JSON file provided") def metadata(self) -> Optional[interfaces.symbols.MetadataInterface]: @@ -334,7 +334,8 @@ class Version1Format(ISFormatTable): elif type_name == 'enum': update = self._lookup_enum(dictionary['name']) elif type_name == 'bitfield': - update = {'start_bit': dictionary['bit_position'], 'end_bit': dictionary['bit_length']} + update = {'start_bit': dictionary['bit_position'], + 'end_bit': dictionary['bit_length']} update['base_type'] = self._interdict_to_template(dictionary['type']) # We do *not* call native_template.clone(), since it slows everything down a lot # We require that the native.get_type method always returns a newly constructed python object diff --git a/volatility/plugins/linux/bash.py b/volatility/plugins/linux/bash.py index cceea9911..f02306acc 100644 --- a/volatility/plugins/linux/bash.py +++ b/volatility/plugins/linux/bash.py @@ -50,7 +50,7 @@ class Bash(plugins.PluginInterface, timeliner.TimeLinerInterface): continue proc_layer_name = task.add_process_layer() - if proc_layer_name == None: + if not proc_layer_name: continue proc_layer = self.context.memory[proc_layer_name] @@ -79,7 +79,7 @@ class Bash(plugins.PluginInterface, timeliner.TimeLinerInterface): yield (0, (task.pid, task_name, hist.get_time_object(), hist.get_command())) def run(self): - filter = pslist.PsList.create_filter([self.config.get('pid', None)]) + filt = pslist.PsList.create_filter([self.config.get('pid', None)]) plugin = pslist.PsList.list_tasks @@ -91,17 +91,17 @@ class Bash(plugins.PluginInterface, timeliner.TimeLinerInterface): self._generator(plugin(self.context, self.config['primary'], self.config['vmlinux'], - filter = filter))) + filter = filt))) def generate_timeline(self): - filter = pslist.PsList.create_filter([self.config.get('pid', None)]) + filt = pslist.PsList.create_filter([self.config.get('pid', None)]) plugin = pslist.PsList.list_tasks for row in self._generator(plugin(self.context, self.config['primary'], self.config['vmlinux'], - filter = filter)): + filter = filt)): _depth, row_data = row description = "{} ({}): \"{}\"".format(row_data[0], row_data[1], row_data[3]) yield (description, timeliner.TimeLinerType.CREATED, row_data[2]) diff --git a/volatility/plugins/linux/elfs.py b/volatility/plugins/linux/elfs.py index eaaafa4d0..4168d84b2 100644 --- a/volatility/plugins/linux/elfs.py +++ b/volatility/plugins/linux/elfs.py @@ -26,7 +26,7 @@ class Elfs(plugins.PluginInterface): def _generator(self, tasks): for task in tasks: proc_layer_name = task.add_process_layer() - if proc_layer_name == None: + if not proc_layer_name: continue proc_layer = self.context.memory[proc_layer_name] @@ -50,7 +50,7 @@ class Elfs(plugins.PluginInterface): )) def run(self): - filter = pslist.PsList.create_filter([self.config.get('pid', None)]) + filt = pslist.PsList.create_filter([self.config.get('pid', None)]) plugin = pslist.PsList.list_tasks @@ -63,4 +63,4 @@ class Elfs(plugins.PluginInterface): self._generator(plugin(self.context, self.config['primary'], self.config['vmlinux'], - filter = filter))) + filter = filt))) diff --git a/volatility/plugins/linux/malfind.py b/volatility/plugins/linux/malfind.py index b31f8024c..e8383a044 100644 --- a/volatility/plugins/linux/malfind.py +++ b/volatility/plugins/linux/malfind.py @@ -27,7 +27,7 @@ class Malfind(interfaces_plugins.PluginInterface): """ proc_layer_name = task.add_process_layer() - if proc_layer_name == None: + if not proc_layer_name: return proc_layer = self.context.memory[proc_layer_name] @@ -64,7 +64,7 @@ class Malfind(interfaces_plugins.PluginInterface): disasm)) def run(self): - filter = pslist.PsList.create_filter([self.config.get('pid', None)]) + filt = pslist.PsList.create_filter([self.config.get('pid', None)]) plugin = pslist.PsList.list_tasks @@ -78,4 +78,4 @@ class Malfind(interfaces_plugins.PluginInterface): self._generator(plugin(self.context, self.config['primary'], self.config['vmlinux'], - filter = filter))) + filter = filt))) diff --git a/volatility/plugins/linux/pslist.py b/volatility/plugins/linux/pslist.py index 00d47b134..1b1ab65b1 100644 --- a/volatility/plugins/linux/pslist.py +++ b/volatility/plugins/linux/pslist.py @@ -20,13 +20,16 @@ class PsList(interfaces_plugins.PluginInterface): @classmethod def create_filter(cls, pid_list: List[int] = None) -> Callable[[int], bool]: - filter = lambda _: False # FIXME: mypy #4973 or #2608 pid_list = pid_list or [] filter_list = [x for x in pid_list if x is not None] if filter_list: - filter = lambda x: x not in filter_list - return filter + def filter_func(x): + return x not in filter_list + + return filter_func + else: + return lambda _: False def _generator(self): for task in self.list_tasks(self.context, @@ -54,7 +57,8 @@ class PsList(interfaces_plugins.PluginInterface): init_task = vmlinux.object(symbol_name = "init_task") for task in init_task.tasks: - yield task + if not filter(task): + yield task def run(self): return renderers.TreeGrid([("PID", int), diff --git a/volatility/plugins/mac/pslist.py b/volatility/plugins/mac/pslist.py index cbcb1e095..bce628034 100644 --- a/volatility/plugins/mac/pslist.py +++ b/volatility/plugins/mac/pslist.py @@ -9,6 +9,7 @@ from volatility.framework.objects import utility vollog = logging.getLogger(__name__) + class PsList(interfaces_plugins.PluginInterface): """Lists the processes present in a particular mac memory image""" @@ -35,7 +36,7 @@ class PsList(interfaces_plugins.PluginInterface): self.config['primary'], self.config['darwin'], filter = self.create_filter([self.config.get('pid', None)])): - pid = task.p_pid + pid = task.p_pid ppid = task.p_ppid name = utility.array_to_string(task.p_comm) yield (0, (pid, ppid, name)) @@ -51,7 +52,7 @@ class PsList(interfaces_plugins.PluginInterface): """Lists all the tasks in the primary layer""" aslr_shift = mac.MacUtilities.find_aslr(context, mac_symbols, layer_name) - darwin = context.module(mac_symbols, layer_name, aslr_shift) + darwin = context.module(mac_symbols, layer_name, aslr_shift) proc = darwin.object(symbol_name = "allproc").lh_first seen = {} @@ -61,7 +62,7 @@ class PsList(interfaces_plugins.PluginInterface): break else: seen[proc.vol.offset] = 1 - + yield proc proc = proc.p_list.le_next.dereference() diff --git a/volatility/plugins/timeliner.py b/volatility/plugins/timeliner.py index 7a2751ed4..40615c7a4 100644 --- a/volatility/plugins/timeliner.py +++ b/volatility/plugins/timeliner.py @@ -47,9 +47,15 @@ class Timeliner(interfaces.plugins.PluginInterface): plugin_list = list(framework.class_subclasses(TimeLinerInterface)) # Get the filter from the configuration - filter_func = lambda _n, _s: True + def passthrough(_n, _s): + return True + + filter_func = passthrough if selected_list: - filter_func = lambda name, selected: any([s in name for s in selected]) + def filter_plugins(name, selected): + return any([s in name for s in selected]) + + filter_func = filter_plugins return [plugin_class for plugin_class in plugin_list if filter_func(plugin_class.__name__, selected_list)] @@ -99,7 +105,6 @@ class Timeliner(interfaces.plugins.PluginInterface): # Use all the plugins if there's no filter self.usable_plugins = self.usable_plugins or self.get_usable_plugins() self.automagics = self.automagics or automagic.available(self._context) - sep = configuration.CONFIG_SEPARATOR runable_plugins = [] # Identify plugins that we can run which output datetimes @@ -114,7 +119,8 @@ class Timeliner(interfaces.plugins.PluginInterface): self._progress_callback, self._file_consumer) - runable_plugins.append(plugin) + if isinstance(plugin, TimeLinerInterface): + runable_plugins.append(plugin) except exceptions.UnsatisfiedException as excp: # Remove the failed plugin from the list and continue vollog.debug("Unable to satisfy {}: {}".format(plugin_class.__name__, excp.unsatisfied)) diff --git a/volatility/plugins/windows/handles.py b/volatility/plugins/windows/handles.py index 6efa07995..576680208 100644 --- a/volatility/plugins/windows/handles.py +++ b/volatility/plugins/windows/handles.py @@ -204,7 +204,7 @@ class Handles(interfaces_plugins.PluginInterface): subtype = subtype, count = int(count)) layer_object = self.context.memory[virtual] - masked_offset = layer_object._mask(offset, 0, layer_object._maxvirtaddr) + masked_offset = (offset & layer_object.maximum_address) for entry in table: @@ -251,8 +251,8 @@ class Handles(interfaces_plugins.PluginInterface): layer_name = self.config["primary"], symbol_table = self.config["nt_symbols"]) cookie = self.find_cookie(context = self.context, - layer_name = self.config["primary"], - symbol_table = self.config["nt_symbols"]) + layer_name = self.config["primary"], + symbol_table = self.config["nt_symbols"]) for proc in procs: diff --git a/volatility/plugins/windows/info.py b/volatility/plugins/windows/info.py index 70e281bb0..0347a12b9 100644 --- a/volatility/plugins/windows/info.py +++ b/volatility/plugins/windows/info.py @@ -40,6 +40,8 @@ class Info(plugins.PluginInterface): virtual_layer_name = self.config["primary"] virtual_layer = self.context.memory[virtual_layer_name] + if not isinstance(virtual_layer, layers.intel.Intel): + raise TypeError("Virtual Layer is not an intel layer") native_types = self.context.symbol_space[self.config["nt_symbols"]].natives diff --git a/volatility/plugins/windows/poolscanner.py b/volatility/plugins/windows/poolscanner.py index 4aeea282c..4932e63cb 100644 --- a/volatility/plugins/windows/poolscanner.py +++ b/volatility/plugins/windows/poolscanner.py @@ -2,6 +2,7 @@ import enum import logging from typing import Optional, Tuple, List, Generator +import volatility.plugins.windows.handles as handles from volatility.framework import constants, interfaces, renderers, validity, exceptions, symbols from volatility.framework.configuration import requirements from volatility.framework.interfaces import plugins, configuration @@ -9,7 +10,6 @@ from volatility.framework.layers import scanners from volatility.framework.renderers import format_hints from volatility.framework.symbols import intermed from volatility.framework.symbols.windows import extensions -import volatility.plugins.windows.handles as handles vollog = logging.getLogger(__name__) diff --git a/volatility/plugins/windows/pslist.py b/volatility/plugins/windows/pslist.py index 4c1782cd2..e08387dc5 100644 --- a/volatility/plugins/windows/pslist.py +++ b/volatility/plugins/windows/pslist.py @@ -2,7 +2,7 @@ import datetime from typing import Callable, Iterable, List import volatility.framework.interfaces.plugins as plugins -from volatility.framework import renderers, interfaces +from volatility.framework import renderers, interfaces, layers from volatility.framework.configuration import requirements from volatility.framework.renderers import format_hints from volatility.plugins import timeliner @@ -84,6 +84,8 @@ class PsList(plugins.PluginInterface, timeliner.TimeLinerInterface): else: layer_name = self.config['primary'] memory = self.context.memory[layer_name] + if not isinstance(memory, layers.intel.Intel): + raise TypeError("Primary layer is not an intel layer") (_, offset, _, _) = list(memory.mapping(offset = proc.vol.offset, length = 0))[0] yield (0, (proc.UniqueProcessId, diff --git a/volatility/plugins/windows/registry/printkey.py b/volatility/plugins/windows/registry/printkey.py index 28d140e92..8a3b6ca88 100644 --- a/volatility/plugins/windows/registry/printkey.py +++ b/volatility/plugins/windows/registry/printkey.py @@ -6,7 +6,7 @@ import volatility.framework.interfaces.plugins as plugins from volatility.framework import objects, renderers, exceptions from volatility.framework.configuration import requirements from volatility.framework.layers.registry import RegistryHive -from volatility.framework.renderers import TreeGrid, conversion +from volatility.framework.renderers import TreeGrid, conversion, format_hints from volatility.framework.symbols.windows.extensions.registry import RegValueTypes vollog = logging.getLogger(__name__) @@ -97,8 +97,8 @@ class PrintKey(plugins.PluginInterface): reg_config_path = self.make_subconfig(hive_offset = hive_offset, base_layer = self.config['primary'], nt_symbols = self.config['nt_symbols']) + hive = RegistryHive(self.context, reg_config_path, name = 'hive' + hex(hive_offset)) try: - hive = RegistryHive(self.context, reg_config_path, name = 'hive' + hex(hive_offset)) self.context.memory.add_layer(hive) # Walk it @@ -116,7 +116,7 @@ class PrintKey(plugins.PluginInterface): vollog.debug("Invalid address identified in Hive: {}".format(hex(excp.invalid_address))) result = (0, (renderers.UnreadableValue(), - renderers.format_hints.Hex(hive.hive_offset), + format_hints.Hex(hive.hive_offset), "Key", self.config.get('key', "ROOT"), renderers.UnreadableValue(), @@ -127,7 +127,7 @@ class PrintKey(plugins.PluginInterface): def run(self): return TreeGrid(columns = [('Last Write Time', datetime.datetime), - ('Hive Offset', renderers.format_hints.Hex), + ('Hive Offset', format_hints.Hex), ('Type', str), ('Key', str), ('Name', str), diff --git a/volatility/plugins/windows/ssdt.py b/volatility/plugins/windows/ssdt.py index 033909920..198b6f9f2 100644 --- a/volatility/plugins/windows/ssdt.py +++ b/volatility/plugins/windows/ssdt.py @@ -69,10 +69,18 @@ class SSDT(plugins.PluginInterface): is_kernel_64 = symbols.symbol_table_is_64bit(self.context, self.config["nt_symbols"]) if is_kernel_64: array_subtype = "long" - find_address = lambda func: kvo + service_table_address + (func >> 4) + + def kvo_calulator(func): + return kvo + service_table_address + (func >> 4) + + find_address = kvo_calulator else: array_subtype = "unsigned long" - find_address = lambda func: func + + def passthrough(func): + return func + + find_address = passthrough functions = ntkrnlmp.object(type_name = "array", offset = kvo + service_table_address, subtype = ntkrnlmp.get_type(array_subtype), diff --git a/volatility/plugins/windows/vaddump.py b/volatility/plugins/windows/vaddump.py index daa016a58..585fd4b0d 100644 --- a/volatility/plugins/windows/vaddump.py +++ b/volatility/plugins/windows/vaddump.py @@ -62,7 +62,7 @@ class VadDump(interfaces_plugins.PluginInterface): self.produce_file(filedata) result_text = "Stored {}".format(filedata.preferred_filename) - except Exception: + except exceptions.InvalidAddressException: result_text = "Unable to dump {0:#x} - {1:#x}".format(vad.get_start(), vad.get_end()) yield (0, (proc.UniqueProcessId, diff --git a/volatility/plugins/windows/vadinfo.py b/volatility/plugins/windows/vadinfo.py index f7d76e14d..ed5e45b4a 100644 --- a/volatility/plugins/windows/vadinfo.py +++ b/volatility/plugins/windows/vadinfo.py @@ -76,9 +76,15 @@ class VadInfo(interfaces_plugins.PluginInterface): def _generator(self, procs): - filter_func = lambda _: False + def passthrough(_): + return False + + filter_func = passthrough if self.config.get('address', None) is not None: - filter_func = lambda x: x.get_start() not in [self.config['address']] + def filter_function(x): + return x.get_start() not in [self.config['address']] + + filter_func = filter_function for proc in procs: process_name = utility.array_to_string(proc.ImageFileName) diff --git a/volatility/plugins/windows/verinfo.py b/volatility/plugins/windows/verinfo.py index a59157266..eda602539 100644 --- a/volatility/plugins/windows/verinfo.py +++ b/volatility/plugins/windows/verinfo.py @@ -41,6 +41,7 @@ class VerInfo(interfaces_plugins.PluginInterface): """Get File and Product version information from PE files Args: + context: volatility context on which to operate pe_table_name: name of the PE table layer_name: name of the layer containing the PE file base_address: base address of the PE (where MZ is found) @@ -69,7 +70,7 @@ class VerInfo(interfaces_plugins.PluginInterface): pe_data.close() - return (major, minor, product, build) + return major, minor, product, build def _generator(self, procs: Generator[interfaces.objects.ObjectInterface, None, None], @@ -80,7 +81,7 @@ class VerInfo(interfaces_plugins.PluginInterface): Args: procs: of processes mods: of modules - moddump_plugin: + session_layers: of layers in the session to be checked """ pe_table_name = PEIntermedSymbols.create(self.context,