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
+5 -5
View File
@@ -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])
+3 -3
View File
@@ -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)))
+3 -3
View File
@@ -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)))
+8 -4
View File
@@ -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),
+4 -3
View File
@@ -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()
+10 -4
View File
@@ -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))
+3 -3
View File
@@ -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:
+2
View File
@@ -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
+1 -1
View File
@@ -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__)
+3 -1
View File
@@ -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,
@@ -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),
+10 -2
View File
@@ -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),
+1 -1
View File
@@ -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,
+8 -2
View File
@@ -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)
+3 -2
View File
@@ -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: <generator> of processes
mods: <generator> of modules
moddump_plugin: <moddump.ModDump>
session_layers: <generator> of layers in the session to be checked
"""
pe_table_name = PEIntermedSymbols.create(self.context,