mirror of
https://github.com/volatilityfoundation/volatility3.git
synced 2026-09-11 12:17:38 +02:00
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:
@@ -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
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 = []
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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:])
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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 = []
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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")
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user