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
This commit is contained in:
Mike Auty
2018-12-16 13:21:06 +00:00
parent 29d41470a4
commit 9824538bd9
30 changed files with 116 additions and 84 deletions
+6 -6
View File
@@ -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
+1 -1
View File
@@ -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):
+7 -6
View File
@@ -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
+1 -2
View File
@@ -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
+1 -1
View File
@@ -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
@@ -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 = []
+5 -6
View File
@@ -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:
+3 -2
View File
@@ -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:])
-1
View File
@@ -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
+3 -3
View File
@@ -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")
+2 -2
View File
@@ -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 = []
+2 -4
View File
@@ -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:
+3 -3
View File
@@ -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
+2 -2
View File
@@ -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")
+7 -6
View File
@@ -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