mirror of
https://github.com/volatilityfoundation/volatility3.git
synced 2026-09-09 19:27:39 +02:00
linted with ruff (ruff check . --fix)
This commit is contained in:
@@ -101,7 +101,7 @@ class Volatility2Test(VolatilityTest):
|
||||
print(f" Tested volatility2 imageinfo with image {image.filepath}: {end_time - start_time}")
|
||||
with open(os.path.join(self.output_directory, f'vol2_imageinfo_{image_hash}_stdout'), "wb") as f:
|
||||
f.write(vol2_completed.stdout)
|
||||
image.vol2_profile = re.search(b"Suggested Profile\(s\) : ([^,]+)", vol2_completed.stdout)[1]
|
||||
image.vol2_profile = re.search(rb"Suggested Profile\(s\) : ([^,]+)", vol2_completed.stdout)[1]
|
||||
|
||||
|
||||
class RekallTest(VolatilityTest):
|
||||
|
||||
@@ -145,8 +145,7 @@ class PDBConvertor:
|
||||
"""Generates the metadata necessary for this object"""
|
||||
dbg = self._pdb.STREAM_DBI
|
||||
last_bytes = str(binascii.hexlify(self._pdb.STREAM_PDB.GUID.Data4), 'ascii')[-16:]
|
||||
guidstr = u'{:08x}{:04x}{:04x}{}'.format(self._pdb.STREAM_PDB.GUID.Data1, self._pdb.STREAM_PDB.GUID.Data2,
|
||||
self._pdb.STREAM_PDB.GUID.Data3, last_bytes)
|
||||
guidstr = f'{self._pdb.STREAM_PDB.GUID.Data1:08x}{self._pdb.STREAM_PDB.GUID.Data2:04x}{self._pdb.STREAM_PDB.GUID.Data3:04x}{last_bytes}'
|
||||
pdb_data = {
|
||||
"GUID": guidstr.upper(),
|
||||
"age": self._pdb.STREAM_PDB.Age,
|
||||
@@ -195,7 +194,7 @@ class PDBConvertor:
|
||||
try:
|
||||
sects = self._pdb.STREAM_SECT_HDR_ORIG.sections
|
||||
omap = self._pdb.STREAM_OMAP_FROM_SRC
|
||||
except AttributeError as e:
|
||||
except AttributeError:
|
||||
# In this case there is no OMAP, so we use the given section
|
||||
# headers and use the identity function for omap.remap
|
||||
sects = self._pdb.STREAM_SECT_HDR.sections
|
||||
|
||||
@@ -28,7 +28,7 @@ if __name__ == '__main__':
|
||||
|
||||
schema = None
|
||||
if args.schema:
|
||||
with open(os.path.abspath(args.schema), 'r') as s:
|
||||
with open(os.path.abspath(args.schema)) as s:
|
||||
schema = json.load(s)
|
||||
|
||||
failures = []
|
||||
@@ -36,7 +36,7 @@ if __name__ == '__main__':
|
||||
try:
|
||||
if os.path.exists(filename):
|
||||
print(f"[?] Validating file: {filename}")
|
||||
with open(filename, 'r') as t:
|
||||
with open(filename) as t:
|
||||
test = json.load(t)
|
||||
|
||||
if args.schema:
|
||||
|
||||
@@ -57,7 +57,7 @@ formatter = logging.Formatter("%(levelname)-8s %(name)-12s: %(message)s")
|
||||
console.setFormatter(formatter)
|
||||
|
||||
|
||||
class PrintedProgress(object):
|
||||
class PrintedProgress:
|
||||
"""A progress handler that prints the progress value and the description
|
||||
onto the command line."""
|
||||
|
||||
@@ -126,9 +126,7 @@ class CommandLine:
|
||||
"--help",
|
||||
action="help",
|
||||
default=argparse.SUPPRESS,
|
||||
help="Show this help message and exit, for specific plugin options use '{} <pluginname> --help'".format(
|
||||
parser.prog
|
||||
),
|
||||
help=f"Show this help message and exit, for specific plugin options use '{parser.prog} <pluginname> --help'",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-c",
|
||||
@@ -360,9 +358,7 @@ class CommandLine:
|
||||
subparser = parser.add_subparsers(
|
||||
title="Plugins",
|
||||
dest="plugin",
|
||||
description="For plugin specific options, run '{} <plugin> --help'".format(
|
||||
self.CLI_NAME
|
||||
),
|
||||
description=f"For plugin specific options, run '{self.CLI_NAME} <plugin> --help'",
|
||||
action=volargparse.HelpfulSubparserAction,
|
||||
metavar="PLUGIN",
|
||||
)
|
||||
@@ -416,7 +412,7 @@ class CommandLine:
|
||||
|
||||
# UI fills in the config, here we load it from the config file and do it before we process the CL parameters
|
||||
if args.config:
|
||||
with open(args.config, "r") as f:
|
||||
with open(args.config) as f:
|
||||
json_val = json.load(f)
|
||||
ctx.config.splice(
|
||||
plugin_config_path,
|
||||
@@ -722,9 +718,7 @@ class CommandLine:
|
||||
if isinstance(requirement, requirements.ListRequirement):
|
||||
if not isinstance(value, list):
|
||||
raise TypeError(
|
||||
"Configuration for ListRequirement was not a list: {}".format(
|
||||
requirement.name
|
||||
)
|
||||
f"Configuration for ListRequirement was not a list: {requirement.name}"
|
||||
)
|
||||
value = [requirement.element_type(x) for x in value]
|
||||
if not inspect.isclass(configurables_list[configurable]):
|
||||
@@ -797,7 +791,7 @@ class CommandLine:
|
||||
fd, self._name = tempfile.mkstemp(
|
||||
suffix=".vol3", prefix="tmp_", dir=output_dir
|
||||
)
|
||||
self._file = io.open(fd, mode="w+b")
|
||||
self._file = open(fd, mode="w+b")
|
||||
CLIFileHandler.__init__(self, filename)
|
||||
for item in dir(self._file):
|
||||
if not item.startswith("_") and item not in (
|
||||
@@ -870,9 +864,7 @@ class CommandLine:
|
||||
requirement, interfaces.configuration.RequirementInterface
|
||||
):
|
||||
raise TypeError(
|
||||
"Plugin contains requirements that are not RequirementInterfaces: {}".format(
|
||||
configurable.__name__
|
||||
)
|
||||
f"Plugin contains requirements that are not RequirementInterfaces: {configurable.__name__}"
|
||||
)
|
||||
if isinstance(requirement, interfaces.configuration.SimpleTypeRequirement):
|
||||
additional["type"] = requirement.instance_type
|
||||
|
||||
@@ -76,7 +76,7 @@ class ColumnFilter:
|
||||
if self.regex:
|
||||
return re.search(self.pattern, f"{item}")
|
||||
return self.pattern in f"{item}"
|
||||
except IOError:
|
||||
except OSError:
|
||||
return False
|
||||
|
||||
def found(self, row: List[Any]) -> bool:
|
||||
|
||||
@@ -467,7 +467,7 @@ class JsonRenderer(CLIRenderer):
|
||||
|
||||
def output_result(self, outfd, result):
|
||||
"""Outputs the JSON data to a file in a particular format"""
|
||||
outfd.write("{}\n".format(json.dumps(result, indent=2, sort_keys=True)))
|
||||
outfd.write(f"{json.dumps(result, indent=2, sort_keys=True)}\n")
|
||||
|
||||
def render(self, grid: interfaces.renderers.TreeGrid):
|
||||
outfd = sys.stdout
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
import argparse
|
||||
import gettext
|
||||
import re
|
||||
from typing import List, Optional, Sequence, Any, Union
|
||||
from typing import Optional, Sequence, Any, Union
|
||||
|
||||
|
||||
# This effectively overrides/monkeypatches the core argparse module to provide more helpful output around choices
|
||||
|
||||
@@ -282,9 +282,7 @@ class VolShell(cli.CommandLine):
|
||||
for plugin in volshell_plugin_list:
|
||||
subparser = parser.add_argument_group(
|
||||
title=plugin.capitalize(),
|
||||
description="Configuration options based on {} options".format(
|
||||
plugin.capitalize()
|
||||
),
|
||||
description=f"Configuration options based on {plugin.capitalize()} options",
|
||||
)
|
||||
self.populate_requirements_argparse(subparser, volshell_plugin_list[plugin])
|
||||
configurables_list[plugin] = volshell_plugin_list[plugin]
|
||||
@@ -331,7 +329,7 @@ class VolShell(cli.CommandLine):
|
||||
|
||||
# UI fills in the config, here we load it from the config file and do it before we process the CL parameters
|
||||
if args.config:
|
||||
with open(args.config, "r") as f:
|
||||
with open(args.config) as f:
|
||||
json_val = json.load(f)
|
||||
ctx.config.splice(
|
||||
plugin_config_path,
|
||||
|
||||
@@ -585,7 +585,6 @@ class NullFileHandler(io.BytesIO, interfaces.plugins.FileHandlerInterface):
|
||||
|
||||
def writelines(self, lines: Iterable[bytes]):
|
||||
"""Dummy method"""
|
||||
pass
|
||||
|
||||
def write(self, b: bytes):
|
||||
"""Dummy method"""
|
||||
|
||||
@@ -56,9 +56,7 @@ def require_interface_version(*args) -> None:
|
||||
if len(args):
|
||||
if args[0] != interface_version()[0]:
|
||||
raise RuntimeError(
|
||||
"Framework interface version {} is incompatible with required version {}".format(
|
||||
interface_version()[0], args[0]
|
||||
)
|
||||
f"Framework interface version {interface_version()[0]} is incompatible with required version {args[0]}"
|
||||
)
|
||||
if len(args) > 1:
|
||||
if args[1] > interface_version()[1]:
|
||||
@@ -70,7 +68,7 @@ def require_interface_version(*args) -> None:
|
||||
)
|
||||
|
||||
|
||||
class NonInheritable(object):
|
||||
class NonInheritable:
|
||||
def __init__(self, value: Any, cls: Type) -> None:
|
||||
self.default_value = value
|
||||
self.cls = cls
|
||||
@@ -187,9 +185,7 @@ def import_file(module: str, path: str, ignore_errors: bool = False) -> List[str
|
||||
traceback.TracebackException.from_exception(e).format(chain=True)
|
||||
)
|
||||
)
|
||||
vollog.debug(
|
||||
"Failed to import module {} based on file: {}".format(module, path)
|
||||
)
|
||||
vollog.debug(f"Failed to import module {module} based on file: {path}")
|
||||
failures.append(module)
|
||||
if not ignore_errors:
|
||||
raise
|
||||
|
||||
@@ -173,9 +173,7 @@ class LinuxIntelStacker(interfaces.automagic.StackerLayerInterface):
|
||||
if aslr_shift & 0xFFF != 0 or kaslr_shift & 0xFFF != 0:
|
||||
continue
|
||||
vollog.debug(
|
||||
"Linux ASLR shift values determined: physical {:0x} virtual {:0x}".format(
|
||||
kaslr_shift, aslr_shift
|
||||
)
|
||||
f"Linux ASLR shift values determined: physical {kaslr_shift:0x} virtual {aslr_shift:0x}"
|
||||
)
|
||||
return kaslr_shift, aslr_shift
|
||||
|
||||
|
||||
@@ -184,7 +184,7 @@ class MacIntelStacker(interfaces.automagic.StackerLayerInterface):
|
||||
aslr_shift = 0
|
||||
|
||||
for offset, banner in offset_generator:
|
||||
banner_major, banner_minor = [int(x) for x in banner[22:].split(b".")[0:2]]
|
||||
banner_major, banner_minor = (int(x) for x in banner[22:].split(b".")[0:2])
|
||||
|
||||
tmp_aslr_shift = offset - cls.virtual_to_physical_address(
|
||||
version_json_address
|
||||
|
||||
@@ -215,9 +215,7 @@ class KernelPDBScanner(interfaces.automagic.AutomagicInterface):
|
||||
return (virtual_layer_name, kvo, kernel)
|
||||
else:
|
||||
vollog.debug(
|
||||
"Potential kernel_virtual_offset did not map to expected location: {}".format(
|
||||
hex(kvo)
|
||||
)
|
||||
f"Potential kernel_virtual_offset did not map to expected location: {hex(kvo)}"
|
||||
)
|
||||
except exceptions.InvalidAddressException:
|
||||
vollog.debug(
|
||||
|
||||
@@ -106,7 +106,6 @@ class CacheManagerInterface(interfaces.configuration.VersionableInterface):
|
||||
|
||||
def add_identifier(self, location: str, operating_system: str, identifier: str):
|
||||
"""Adds an identifier to the store"""
|
||||
pass
|
||||
|
||||
def find_location(
|
||||
self, identifier: bytes, operating_system: Optional[str]
|
||||
@@ -120,18 +119,15 @@ class CacheManagerInterface(interfaces.configuration.VersionableInterface):
|
||||
Returns:
|
||||
The location of the symbols file that matches the identifier
|
||||
"""
|
||||
pass
|
||||
|
||||
def get_local_locations(self) -> Iterable[str]:
|
||||
"""Returns a list of all the local locations"""
|
||||
pass
|
||||
|
||||
def update(self):
|
||||
"""Locates all files under the symbol directories. Updates the cache with additions, modifications and removals.
|
||||
This also updates remote locations based on a cache timeout.
|
||||
|
||||
"""
|
||||
pass
|
||||
|
||||
def get_identifier_dictionary(
|
||||
self, operating_system: Optional[str] = None, local_only: bool = False
|
||||
@@ -145,15 +141,12 @@ class CacheManagerInterface(interfaces.configuration.VersionableInterface):
|
||||
Returns:
|
||||
A dictionary of identifiers mapped to a location
|
||||
"""
|
||||
pass
|
||||
|
||||
def get_identifier(self, location: str) -> Optional[bytes]:
|
||||
"""Returns an identifier based on a specific location or None"""
|
||||
pass
|
||||
|
||||
def get_identifiers(self, operating_system: Optional[str]) -> List[bytes]:
|
||||
"""Returns all identifiers for a particular operating system"""
|
||||
pass
|
||||
|
||||
def get_location_statistics(
|
||||
self, location: str
|
||||
@@ -572,6 +565,6 @@ class RemoteIdentifierFormat:
|
||||
try:
|
||||
subrbf = RemoteIdentifierFormat(location)
|
||||
yield from subrbf.process(identifiers, operating_system)
|
||||
except IOError:
|
||||
except OSError:
|
||||
vollog.debug(f"Remote file not found: {location}")
|
||||
return identifiers
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
import logging
|
||||
import os
|
||||
from typing import Any, Callable, Iterable, List, Optional, Tuple
|
||||
from typing import Callable, List, Optional, Tuple
|
||||
|
||||
from volatility3.framework import constants, interfaces, layers
|
||||
from volatility3.framework.automagic import symbol_cache
|
||||
|
||||
@@ -664,9 +664,7 @@ class ModuleRequirement(
|
||||
if value is not None:
|
||||
vollog.log(
|
||||
constants.LOGLEVEL_V,
|
||||
"TypeError - Module Requirement only accepts string labels: {}".format(
|
||||
repr(value)
|
||||
),
|
||||
f"TypeError - Module Requirement only accepts string labels: {repr(value)}",
|
||||
)
|
||||
return {config_path: self}
|
||||
|
||||
|
||||
@@ -356,7 +356,7 @@ class SizedModule(Module):
|
||||
return size or 0
|
||||
|
||||
@property # type: ignore # FIXME: mypy #5107
|
||||
@functools.lru_cache()
|
||||
@functools.lru_cache
|
||||
def hash(self) -> str:
|
||||
"""Hashes the module for equality checks.
|
||||
|
||||
|
||||
@@ -94,7 +94,7 @@ class HierarchicalDict(collections.abc.Mapping):
|
||||
raise TypeError(f"Separator must be a one character string: {separator}")
|
||||
self._separator = separator
|
||||
self._data: Dict[str, ConfigSimpleType] = {}
|
||||
self._subdict: Dict[str, "HierarchicalDict"] = {}
|
||||
self._subdict: Dict[str, HierarchicalDict] = {}
|
||||
if isinstance(initial_dict, str):
|
||||
initial_dict = json.loads(initial_dict)
|
||||
if isinstance(initial_dict, dict):
|
||||
@@ -182,9 +182,7 @@ class HierarchicalDict(collections.abc.Mapping):
|
||||
else:
|
||||
if not isinstance(value, HierarchicalDict):
|
||||
raise TypeError(
|
||||
"HierarchicalDicts can only store HierarchicalDicts within their structure: {}".format(
|
||||
type(value)
|
||||
)
|
||||
f"HierarchicalDicts can only store HierarchicalDicts within their structure: {type(value)}"
|
||||
)
|
||||
self._subdict[key] = value
|
||||
|
||||
@@ -498,9 +496,7 @@ class SimpleTypeRequirement(RequirementInterface):
|
||||
if not isinstance(value, self.instance_type):
|
||||
vollog.log(
|
||||
constants.LOGLEVEL_V,
|
||||
"TypeError - {} requirements only accept {} type: {}".format(
|
||||
self.name, self.instance_type.__name__, repr(value)
|
||||
),
|
||||
f"TypeError - {self.name} requirements only accept {self.instance_type.__name__} type: {repr(value)}",
|
||||
)
|
||||
return {config_path: self}
|
||||
return {}
|
||||
|
||||
@@ -188,7 +188,6 @@ class DataLayerInterface(
|
||||
the object unreadable (exceptions will be thrown using a
|
||||
DataLayer after destruction)
|
||||
"""
|
||||
pass
|
||||
|
||||
@classmethod
|
||||
def get_requirements(cls) -> List[interfaces.configuration.RequirementInterface]:
|
||||
@@ -361,9 +360,7 @@ class DataLayerInterface(
|
||||
data += self.context.layers[layer_name].read(address, chunk_size)
|
||||
except exceptions.InvalidAddressException:
|
||||
vollog.debug(
|
||||
"Invalid address in layer {} found scanning {} at address {:x}".format(
|
||||
layer_name, self.name, address
|
||||
)
|
||||
f"Invalid address in layer {layer_name} found scanning {self.name} at address {address:x}"
|
||||
)
|
||||
|
||||
if len(data) > scanner.chunk_size + scanner.overlap:
|
||||
@@ -721,7 +718,7 @@ class LayerContainer(collections.abc.Mapping):
|
||||
raise NotImplementedError("Cycle checking has not yet been implemented")
|
||||
|
||||
|
||||
class DummyProgress(object):
|
||||
class DummyProgress:
|
||||
"""A class to emulate Multiprocessing/threading Value objects."""
|
||||
|
||||
def __init__(self) -> None:
|
||||
|
||||
@@ -46,7 +46,7 @@ class FileHandlerInterface(io.RawIOBase):
|
||||
def preferred_filename(self, filename: str):
|
||||
"""Sets the preferred filename"""
|
||||
if self.closed:
|
||||
raise IOError("FileHandler name cannot be changed once closed")
|
||||
raise OSError("FileHandler name cannot be changed once closed")
|
||||
if not isinstance(filename, str):
|
||||
raise TypeError("FileHandler preferred filenames must be strings")
|
||||
if os.path.sep in filename:
|
||||
|
||||
@@ -26,7 +26,11 @@ from typing import (
|
||||
Union,
|
||||
)
|
||||
|
||||
Column = NamedTuple("Column", [("name", str), ("type", Any)])
|
||||
|
||||
class Column(NamedTuple):
|
||||
name: str
|
||||
type: Any
|
||||
|
||||
|
||||
RenderOption = Any
|
||||
|
||||
@@ -98,11 +102,11 @@ class TreeNode(abc.Sequence, metaclass=ABCMeta):
|
||||
"""
|
||||
|
||||
|
||||
class BaseAbsentValue(object):
|
||||
class BaseAbsentValue:
|
||||
"""Class that represents values which are not present for some reason."""
|
||||
|
||||
|
||||
class Disassembly(object):
|
||||
class Disassembly:
|
||||
"""A class to indicate that the bytes provided should be disassembled
|
||||
(based on the architecture)"""
|
||||
|
||||
@@ -137,7 +141,7 @@ ColumnsType = List[Tuple[str, BaseTypes]]
|
||||
VisitorSignature = Callable[[TreeNode, _Type], _Type]
|
||||
|
||||
|
||||
class TreeGrid(object, metaclass=ABCMeta):
|
||||
class TreeGrid(metaclass=ABCMeta):
|
||||
"""Class providing the interface for a TreeGrid (which contains TreeNodes)
|
||||
|
||||
The structure of a TreeGrid is designed to maintain the structure of the tree in a single object.
|
||||
|
||||
@@ -250,7 +250,6 @@ class BaseSymbolTableInterface:
|
||||
|
||||
def clear_symbol_cache(self) -> None:
|
||||
"""Clears the symbol cache of this symbol table."""
|
||||
pass
|
||||
|
||||
|
||||
class SymbolSpaceInterface(collections.abc.Mapping):
|
||||
@@ -378,7 +377,7 @@ class NativeTableInterface(BaseSymbolTableInterface):
|
||||
return []
|
||||
|
||||
|
||||
class MetadataInterface(object):
|
||||
class MetadataInterface:
|
||||
"""Interface for accessing metadata stored within a symbol table."""
|
||||
|
||||
def __init__(self, json_data: Dict) -> None:
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
# This file is Copyright 2021 Volatility Foundation and licensed under the Volatility Software License 1.0
|
||||
# which is available at https://www.volatilityfoundation.org/license/vsl-v1.0
|
||||
#
|
||||
import contextlib
|
||||
import logging
|
||||
import struct
|
||||
from typing import Tuple, Optional
|
||||
@@ -138,7 +137,7 @@ class WindowsCrashDump32Layer(segmented.SegmentedLayer):
|
||||
ulong_bitmap_array = summary_header.get_buffer_long()
|
||||
# outer_index points to a 32 bits array inside a list of arrays,
|
||||
# each bit indicating a page mapping state
|
||||
for outer_index in range(0, ulong_bitmap_array.vol.count):
|
||||
for outer_index in range(ulong_bitmap_array.vol.count):
|
||||
ulong_bitmap = ulong_bitmap_array[outer_index]
|
||||
# All pages in this 32 bits array are mapped (speedup iteration process)
|
||||
if ulong_bitmap == 0xFFFFFFFF:
|
||||
@@ -166,7 +165,7 @@ class WindowsCrashDump32Layer(segmented.SegmentedLayer):
|
||||
seg_first_bit = None
|
||||
# Some pages in this 32 bits array are mapped and some aren't
|
||||
else:
|
||||
for inner_bit_position in range(0, 32):
|
||||
for inner_bit_position in range(32):
|
||||
current_bit = outer_index * 32 + inner_bit_position
|
||||
page_mapped = ulong_bitmap & (1 << inner_bit_position)
|
||||
if page_mapped:
|
||||
@@ -220,9 +219,7 @@ class WindowsCrashDump32Layer(segmented.SegmentedLayer):
|
||||
for idx, (start_position, mapped_offset, length, _) in enumerate(segments):
|
||||
vollog.log(
|
||||
constants.LOGLEVEL_VVVV,
|
||||
"Segment {}: Position {:#x} Offset {:#x} Length {:#x}".format(
|
||||
idx, start_position, mapped_offset, length
|
||||
),
|
||||
f"Segment {idx}: Position {start_position:#x} Offset {mapped_offset:#x} Length {length:#x}",
|
||||
)
|
||||
|
||||
self._segments = segments
|
||||
|
||||
@@ -76,13 +76,13 @@ class Intel(linear.LinearlyMappedLayer):
|
||||
self._index_shift = math.ceil(math.log2(struct.calcsize(self._entry_format)))
|
||||
|
||||
@classproperty
|
||||
@functools.lru_cache()
|
||||
@functools.lru_cache
|
||||
def page_shift(cls) -> int:
|
||||
"""Page shift for the intel memory layers."""
|
||||
return cls._page_size_in_bits
|
||||
|
||||
@classproperty
|
||||
@functools.lru_cache()
|
||||
@functools.lru_cache
|
||||
def page_size(cls) -> int:
|
||||
"""Page size for the intel memory layers.
|
||||
|
||||
@@ -91,25 +91,25 @@ class Intel(linear.LinearlyMappedLayer):
|
||||
return 1 << cls._page_size_in_bits
|
||||
|
||||
@classproperty
|
||||
@functools.lru_cache()
|
||||
@functools.lru_cache
|
||||
def page_mask(cls) -> int:
|
||||
"""Page mask for the intel memory layers."""
|
||||
return ~(cls.page_size - 1)
|
||||
|
||||
@classproperty
|
||||
@functools.lru_cache()
|
||||
@functools.lru_cache
|
||||
def bits_per_register(cls) -> int:
|
||||
"""Returns the bits_per_register to determine the range of an
|
||||
IntelTranslationLayer."""
|
||||
return cls._bits_per_register
|
||||
|
||||
@classproperty
|
||||
@functools.lru_cache()
|
||||
@functools.lru_cache
|
||||
def minimum_address(cls) -> int:
|
||||
return 0
|
||||
|
||||
@classproperty
|
||||
@functools.lru_cache()
|
||||
@functools.lru_cache
|
||||
def maximum_address(cls) -> int:
|
||||
return (1 << cls._maxvirtaddr) - 1
|
||||
|
||||
@@ -251,12 +251,7 @@ class Intel(linear.LinearlyMappedLayer):
|
||||
if INTEL_TRANSLATION_DEBUGGING:
|
||||
vollog.log(
|
||||
constants.LOGLEVEL_VVVV,
|
||||
"Entry {} at index {} gives data {} as {}".format(
|
||||
hex(entry),
|
||||
hex(index),
|
||||
hex(struct.unpack(self._entry_format, entry_data)[0]),
|
||||
name,
|
||||
),
|
||||
f"Entry {hex(entry)} at index {hex(index)} gives data {hex(struct.unpack(self._entry_format, entry_data)[0])} as {name}",
|
||||
)
|
||||
|
||||
# Read out the new entry from memory
|
||||
|
||||
@@ -48,7 +48,7 @@ if HAS_LEECHCORE:
|
||||
try:
|
||||
self._handle = leechcorepyc.LeechCore(self._device)
|
||||
except TypeError:
|
||||
raise IOError(f"Unable to open LeechCore device {self._device}")
|
||||
raise OSError(f"Unable to open LeechCore device {self._device}")
|
||||
return self._handle
|
||||
|
||||
def fileno(self):
|
||||
|
||||
@@ -236,7 +236,7 @@ class QemuSuspendLayer(segmented.NonLinearlySegmentedLayer):
|
||||
if self._architecture is None:
|
||||
vollog.log(
|
||||
constants.LOGLEVEL_VV,
|
||||
f"QEVM architecture could not be determined",
|
||||
"QEVM architecture could not be determined",
|
||||
)
|
||||
|
||||
# Once all segments have been read, determine the PCI hole if any
|
||||
|
||||
@@ -156,9 +156,7 @@ class RegistryHive(linear.LinearlyMappedLayer):
|
||||
else:
|
||||
# It doesn't matter that we use KeyNode, we're just after the first two bytes
|
||||
vollog.debug(
|
||||
"Unknown Signature {} (0x{:x}) at offset {}".format(
|
||||
signature, cell.u.KeyNode.Signature, cell_offset
|
||||
)
|
||||
f"Unknown Signature {signature} (0x{cell.u.KeyNode.Signature:x}) at offset {cell_offset}"
|
||||
)
|
||||
return cell
|
||||
|
||||
@@ -178,9 +176,7 @@ class RegistryHive(linear.LinearlyMappedLayer):
|
||||
if not root_node.vol.type_name.endswith(constants.BANG + "_CM_KEY_NODE"):
|
||||
raise RegistryFormatException(
|
||||
self.name,
|
||||
"Encountered {} instead of _CM_KEY_NODE".format(
|
||||
root_node.vol.type_name
|
||||
),
|
||||
f"Encountered {root_node.vol.type_name} instead of _CM_KEY_NODE",
|
||||
)
|
||||
node_key = [root_node]
|
||||
if key.endswith("\\"):
|
||||
|
||||
@@ -57,7 +57,7 @@ def cascadeCloseFile(new_fp: IO[bytes], original_fp: IO[bytes]) -> IO[bytes]:
|
||||
return new_fp
|
||||
|
||||
|
||||
class ResourceAccessor(object):
|
||||
class ResourceAccessor:
|
||||
"""Object for opening URLs as files (downloading locally first if
|
||||
necessary)"""
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ import re
|
||||
from typing import Generator, List, Tuple
|
||||
|
||||
|
||||
class MultiRegexp(object):
|
||||
class MultiRegexp:
|
||||
"""Algorithm for multi-string matching."""
|
||||
|
||||
def __init__(self) -> None:
|
||||
|
||||
@@ -22,8 +22,8 @@ def bswap_32(value: int) -> int:
|
||||
|
||||
|
||||
def bswap_64(value: int) -> int:
|
||||
low = bswap_32((value >> 32))
|
||||
high = bswap_32((value & 0xFFFFFFFF))
|
||||
low = bswap_32(value >> 32)
|
||||
high = bswap_32(value & 0xFFFFFFFF)
|
||||
|
||||
return ((high << 32) | low) & 0xFFFFFFFFFFFFFFFF
|
||||
|
||||
|
||||
@@ -119,7 +119,7 @@ class LayerWriter(plugins.PluginInterface):
|
||||
# Update the filename, which may have changed if a file
|
||||
# with the same name already existed.
|
||||
output_name = file_handle.preferred_filename
|
||||
except IOError as excp:
|
||||
except OSError as excp:
|
||||
yield 0, (f"Layer cannot be written to {output_name}: {excp}",)
|
||||
|
||||
yield 0, (f"Layer has been written to {output_name}",)
|
||||
|
||||
@@ -53,7 +53,7 @@ class Check_idt(interfaces.plugins.PluginInterface):
|
||||
address_mask = self.context.layers[vmlinux.layer_name].address_mask
|
||||
|
||||
# hw handlers + system call
|
||||
check_idxs = list(range(0, 20)) + [128]
|
||||
check_idxs = list(range(20)) + [128]
|
||||
|
||||
if is_32bit:
|
||||
if vmlinux.has_type("gate_struct"):
|
||||
|
||||
@@ -103,7 +103,7 @@ class Check_syscall(plugins.PluginInterface):
|
||||
|
||||
try:
|
||||
func_addr = vmlinux.get_symbol(syscall_entry_func).address
|
||||
except exceptions.SymbolError as e:
|
||||
except exceptions.SymbolError:
|
||||
# if we can't find the disassemble function then bail and rely on a different method
|
||||
return 0
|
||||
|
||||
|
||||
@@ -462,7 +462,7 @@ class InodePages(plugins.PluginInterface):
|
||||
f.seek(current_fp)
|
||||
f.write(page_bytes)
|
||||
|
||||
except IOError as e:
|
||||
except OSError as e:
|
||||
vollog.error("Unable to write to file (%s): %s", filename, e)
|
||||
|
||||
def _generator(self):
|
||||
|
||||
@@ -125,9 +125,7 @@ class Maps(plugins.PluginInterface):
|
||||
proc_layer_name = task.add_process_layer()
|
||||
except exceptions.InvalidAddressException as excp:
|
||||
vollog.debug(
|
||||
"Process {}: invalid address {} in layer {}".format(
|
||||
pid, excp.invalid_address, excp.layer_name
|
||||
)
|
||||
f"Process {pid}: invalid address {excp.invalid_address} in layer {excp.layer_name}"
|
||||
)
|
||||
return None
|
||||
vm_size = vm_end - vm_start
|
||||
|
||||
@@ -133,7 +133,7 @@ class PsScan(interfaces.plugins.PluginInterface):
|
||||
)
|
||||
elif len(kernel_layer.dependencies) == 0:
|
||||
vollog.error(
|
||||
f"Kernel layer has no dependencies, meaning there is no memory layer for this plugin to scan."
|
||||
"Kernel layer has no dependencies, meaning there is no memory layer for this plugin to scan."
|
||||
)
|
||||
raise exceptions.LayerException(
|
||||
kernel_layer_name, f"Layer {kernel_layer_name} has no dependencies"
|
||||
|
||||
@@ -115,9 +115,7 @@ class Maps(interfaces.plugins.PluginInterface):
|
||||
proc_layer_name = task.add_process_layer()
|
||||
except exceptions.InvalidAddressException as excp:
|
||||
vollog.debug(
|
||||
"Process {}: invalid address {} in layer {}".format(
|
||||
pid, excp.invalid_address, excp.layer_name
|
||||
)
|
||||
f"Process {pid}: invalid address {excp.invalid_address} in layer {excp.layer_name}"
|
||||
)
|
||||
return None
|
||||
vm_size = vm_end - vm_start
|
||||
|
||||
@@ -143,9 +143,7 @@ class Timeliner(interfaces.plugins.PluginInterface):
|
||||
times = self.timeline.get((plugin_name, item), {})
|
||||
if times.get(timestamp_type, None) is not None:
|
||||
vollog.debug(
|
||||
"Multiple timestamps for the same plugin/file combination found: {} {}".format(
|
||||
plugin_name, item
|
||||
)
|
||||
f"Multiple timestamps for the same plugin/file combination found: {plugin_name} {item}"
|
||||
)
|
||||
times[timestamp_type] = timestamp
|
||||
self.timeline[(plugin_name, item)] = times
|
||||
|
||||
@@ -84,9 +84,7 @@ class CmdLine(interfaces.plugins.PluginInterface):
|
||||
result_text = f"Required memory at {exp.invalid_address:#x} is not valid (process exited?)"
|
||||
|
||||
except exceptions.InvalidAddressException as exp:
|
||||
result_text = "Process {}: Required memory at {:#x} is not valid (incomplete layer {}?)".format(
|
||||
proc_id, exp.invalid_address, exp.layer_name
|
||||
)
|
||||
result_text = f"Process {proc_id}: Required memory at {exp.invalid_address:#x} is not valid (incomplete layer {exp.layer_name}?)"
|
||||
|
||||
yield (0, (proc.UniqueProcessId, process_name, result_text))
|
||||
|
||||
|
||||
@@ -95,9 +95,7 @@ class Consoles(interfaces.plugins.PluginInterface):
|
||||
|
||||
except exceptions.InvalidAddressException as excp:
|
||||
vollog.debug(
|
||||
"Process {}: invalid address {} in layer {}".format(
|
||||
proc_id, excp.invalid_address, excp.layer_name
|
||||
)
|
||||
f"Process {proc_id}: invalid address {excp.invalid_address} in layer {excp.layer_name}"
|
||||
)
|
||||
|
||||
@classmethod
|
||||
@@ -176,12 +174,7 @@ class Consoles(interfaces.plugins.PluginInterface):
|
||||
)
|
||||
|
||||
vollog.debug(
|
||||
"Determined OS Version: {}.{} {}.{}".format(
|
||||
kuser.NtMajorVersion,
|
||||
kuser.NtMinorVersion,
|
||||
vers.MajorVersion,
|
||||
vers.MinorVersion,
|
||||
)
|
||||
f"Determined OS Version: {kuser.NtMajorVersion}.{kuser.NtMinorVersion} {vers.MajorVersion}.{vers.MinorVersion}"
|
||||
)
|
||||
|
||||
if nt_major_version == 10 and arch == "x64":
|
||||
@@ -260,9 +253,7 @@ class Consoles(interfaces.plugins.PluginInterface):
|
||||
if ver:
|
||||
conhost_mod_version = ver[3]
|
||||
vollog.debug(
|
||||
"Determined conhost.exe's FileVersion: {}".format(
|
||||
conhost_mod_version
|
||||
)
|
||||
f"Determined conhost.exe's FileVersion: {conhost_mod_version}"
|
||||
)
|
||||
else:
|
||||
vollog.debug("Could not determine conhost.exe's FileVersion.")
|
||||
@@ -311,12 +302,7 @@ class Consoles(interfaces.plugins.PluginInterface):
|
||||
|
||||
else:
|
||||
raise NotImplementedError(
|
||||
"This version of Windows is not supported: {}.{} {}.{}!".format(
|
||||
nt_major_version,
|
||||
nt_minor_version,
|
||||
vers.MajorVersion,
|
||||
vers_minor_version,
|
||||
)
|
||||
f"This version of Windows is not supported: {nt_major_version}.{nt_minor_version} {vers.MajorVersion}.{vers_minor_version}!"
|
||||
)
|
||||
|
||||
vollog.debug(f"Determined symbol filename: {filename}")
|
||||
|
||||
@@ -5,9 +5,9 @@ import contextlib
|
||||
import datetime
|
||||
import logging
|
||||
import re
|
||||
from typing import List, Optional, Type
|
||||
from typing import List
|
||||
|
||||
from volatility3.framework import constants, exceptions, interfaces, renderers
|
||||
from volatility3.framework import exceptions, interfaces, renderers
|
||||
from volatility3.framework.configuration import requirements
|
||||
from volatility3.framework.renderers import conversion, format_hints
|
||||
from volatility3.framework.symbols import intermed
|
||||
@@ -199,16 +199,7 @@ class DllList(interfaces.plugins.PluginInterface, timeliner.TimeLinerInterface):
|
||||
_depth, row_data = row
|
||||
if not isinstance(row_data[6], datetime.datetime):
|
||||
continue
|
||||
description = (
|
||||
"DLL Load: Process {} {} Loaded {} ({}) Size {} Offset {}".format(
|
||||
row_data[0],
|
||||
row_data[1],
|
||||
row_data[4],
|
||||
row_data[5],
|
||||
row_data[3],
|
||||
row_data[2],
|
||||
)
|
||||
)
|
||||
description = f"DLL Load: Process {row_data[0]} {row_data[1]} Loaded {row_data[4]} ({row_data[5]}) Size {row_data[3]} Offset {row_data[2]}"
|
||||
yield (description, timeliner.TimeLinerType.CREATED, row_data[6])
|
||||
|
||||
def run(self):
|
||||
|
||||
@@ -192,13 +192,7 @@ class DumpFiles(interfaces.plugins.PluginInterface):
|
||||
|
||||
for memory_object, layer, extension in dump_parameters:
|
||||
cache_name = EXTENSION_CACHE_MAP[extension]
|
||||
desired_file_name = "file.{0:#x}.{1:#x}.{2}.{3}.{4}".format(
|
||||
file_obj.vol.offset,
|
||||
memory_object.vol.offset,
|
||||
cache_name,
|
||||
ntpath.basename(obj_name),
|
||||
extension,
|
||||
)
|
||||
desired_file_name = f"file.{file_obj.vol.offset:#x}.{memory_object.vol.offset:#x}.{cache_name}.{ntpath.basename(obj_name)}.{extension}"
|
||||
|
||||
file_handle = cls.dump_file_producer(
|
||||
file_obj, memory_object, open_method, layer, desired_file_name
|
||||
|
||||
@@ -92,7 +92,7 @@ class Envars(interfaces.plugins.PluginInterface):
|
||||
except (
|
||||
exceptions.InvalidAddressException,
|
||||
registry.RegistryFormatException,
|
||||
) as excp:
|
||||
):
|
||||
vollog.log(
|
||||
constants.LOGLEVEL_VVV,
|
||||
"Error while parsing global environment variables keys (some keys might be excluded)",
|
||||
@@ -113,7 +113,7 @@ class Envars(interfaces.plugins.PluginInterface):
|
||||
except (
|
||||
exceptions.InvalidAddressException,
|
||||
registry.RegistryFormatException,
|
||||
) as excp:
|
||||
):
|
||||
vollog.log(
|
||||
constants.LOGLEVEL_VVV,
|
||||
"Error while parsing user environment variables keys (some keys might be excluded)",
|
||||
@@ -134,7 +134,7 @@ class Envars(interfaces.plugins.PluginInterface):
|
||||
except (
|
||||
exceptions.InvalidAddressException,
|
||||
registry.RegistryFormatException,
|
||||
) as excp:
|
||||
):
|
||||
vollog.log(
|
||||
constants.LOGLEVEL_VVV,
|
||||
"Error while parsing volatile environment variables keys (some keys might be excluded)",
|
||||
|
||||
@@ -55,7 +55,7 @@ class GetServiceSIDs(interfaces.plugins.PluginInterface):
|
||||
)
|
||||
|
||||
# Get service sids dictionary (we need only the service sids).
|
||||
with open(sids_json_file_name, "r") as file_handle:
|
||||
with open(sids_json_file_name) as file_handle:
|
||||
self.servicesids = json.load(file_handle)["service sids"]
|
||||
|
||||
@classmethod
|
||||
|
||||
@@ -58,7 +58,7 @@ class GetSIDs(interfaces.plugins.PluginInterface):
|
||||
)
|
||||
|
||||
# Get all the sids from the json file.
|
||||
with open(sids_json_file_name, "r") as file_handle:
|
||||
with open(sids_json_file_name) as file_handle:
|
||||
sids_json_data = json.load(file_handle)
|
||||
self.servicesids = sids_json_data["service sids"]
|
||||
self.well_known_sids = sids_json_data["well known"]
|
||||
@@ -122,7 +122,7 @@ class GetSIDs(interfaces.plugins.PluginInterface):
|
||||
except (
|
||||
exceptions.InvalidAddressException,
|
||||
layers.registry.RegistryFormatException,
|
||||
) as excp:
|
||||
):
|
||||
continue
|
||||
try:
|
||||
value_data = node.decode_data()
|
||||
@@ -156,7 +156,7 @@ class GetSIDs(interfaces.plugins.PluginInterface):
|
||||
ValueError,
|
||||
exceptions.InvalidAddressException,
|
||||
layers.registry.RegistryFormatException,
|
||||
) as excp:
|
||||
):
|
||||
continue
|
||||
except (KeyError, exceptions.InvalidAddressException):
|
||||
continue
|
||||
|
||||
@@ -12,20 +12,15 @@ from volatility3.plugins.windows import pslist, vadinfo
|
||||
|
||||
vollog = logging.getLogger(__name__)
|
||||
|
||||
VadData = NamedTuple(
|
||||
"VadData",
|
||||
[
|
||||
("protection", str),
|
||||
("path", str),
|
||||
],
|
||||
)
|
||||
|
||||
DLLData = NamedTuple(
|
||||
"DLLData",
|
||||
[
|
||||
("path", str),
|
||||
],
|
||||
)
|
||||
class VadData(NamedTuple):
|
||||
protection: str
|
||||
path: str
|
||||
|
||||
|
||||
class DLLData(NamedTuple):
|
||||
path: str
|
||||
|
||||
|
||||
### Useful references on process hollowing
|
||||
# https://cysinfo.com/detecting-deceptive-hollowing-techniques/
|
||||
@@ -146,9 +141,7 @@ class HollowProcesses(interfaces.plugins.PluginInterface):
|
||||
"""
|
||||
image_base = self._get_image_base(proc)
|
||||
if image_base is not None and image_base != proc.SectionBaseAddress:
|
||||
yield "The ImageBaseAddress reported from the PEB ({:#x}) does not match the process SectionBaseAddress ({:#x})".format(
|
||||
image_base, proc.SectionBaseAddress
|
||||
)
|
||||
yield f"The ImageBaseAddress reported from the PEB ({image_base:#x}) does not match the process SectionBaseAddress ({proc.SectionBaseAddress:#x})"
|
||||
|
||||
def _check_exe_protection(
|
||||
self, proc, vads: Dict[int, VadData], __
|
||||
@@ -166,13 +159,9 @@ class HollowProcesses(interfaces.plugins.PluginInterface):
|
||||
base = proc.SectionBaseAddress
|
||||
|
||||
if base not in vads:
|
||||
yield "There is no VAD starting at the base address of the process executable ({:#x})".format(
|
||||
base
|
||||
)
|
||||
yield f"There is no VAD starting at the base address of the process executable ({base:#x})"
|
||||
elif vads[base].protection != "PAGE_EXECUTE_WRITECOPY":
|
||||
yield "Unexpected protection ({}) for VAD hosting the process executable ({:#x}) with path {}".format(
|
||||
vads[base].protection, base, vads[base].path
|
||||
)
|
||||
yield f"Unexpected protection ({vads[base].protection}) for VAD hosting the process executable ({base:#x}) with path {vads[base].path}"
|
||||
|
||||
def _check_dlls_protection(
|
||||
self, _, vads: Dict[int, VadData], dlls: Dict[int, DLLData]
|
||||
@@ -184,9 +173,7 @@ class HollowProcesses(interfaces.plugins.PluginInterface):
|
||||
|
||||
# PAGE_EXECUTE_WRITECOPY is the only valid permission for mapped DLLs and .exe files
|
||||
if vads[dll_base].protection != "PAGE_EXECUTE_WRITECOPY":
|
||||
yield "Unexpected protection ({}) for DLL in the PEB's load order list ({:#x}) with path {}".format(
|
||||
vads[dll_base].protection, dll_base, dlls[dll_base].path
|
||||
)
|
||||
yield f"Unexpected protection ({vads[dll_base].protection}) for DLL in the PEB's load order list ({dll_base:#x}) with path {dlls[dll_base].path}"
|
||||
|
||||
def _generator(self, procs):
|
||||
checks = [
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
# This file is Copyright 2024 Volatility Foundation and licensed under the Volatility Software License 1.0
|
||||
# which is available at https://www.volatilityfoundation.org/license/vsl-v1.0
|
||||
|
||||
import logging, io, pefile
|
||||
import logging
|
||||
import io
|
||||
import pefile
|
||||
from volatility3.framework.symbols import intermed
|
||||
from volatility3.framework import renderers, interfaces, exceptions, constants
|
||||
from volatility3.framework.configuration import requirements
|
||||
@@ -119,9 +121,7 @@ class IAT(interfaces.plugins.PluginInterface):
|
||||
)
|
||||
except exceptions.InvalidAddressException as excp:
|
||||
vollog.debug(
|
||||
"Process {}: invalid address {} in layer {}".format(
|
||||
proc_id, excp.invalid_address, excp.layer_name
|
||||
)
|
||||
f"Process {proc_id}: invalid address {excp.invalid_address} in layer {excp.layer_name}"
|
||||
)
|
||||
continue
|
||||
|
||||
|
||||
@@ -106,9 +106,7 @@ class Malfind(interfaces.plugins.PluginInterface):
|
||||
proc_layer_name = proc.add_process_layer()
|
||||
except exceptions.InvalidAddressException as excp:
|
||||
vollog.debug(
|
||||
"Process {}: invalid address {} in layer {}".format(
|
||||
proc_id, excp.invalid_address, excp.layer_name
|
||||
)
|
||||
f"Process {proc_id}: invalid address {excp.invalid_address} in layer {excp.layer_name}"
|
||||
)
|
||||
return None
|
||||
|
||||
@@ -211,9 +209,7 @@ class Malfind(interfaces.plugins.PluginInterface):
|
||||
file_output = file_handle.preferred_filename
|
||||
except (exceptions.InvalidAddressException, OverflowError) as excp:
|
||||
vollog.debug(
|
||||
"Unable to dump PE with pid {0}.{1:#x}: {2}".format(
|
||||
proc.UniqueProcessId, vad.get_start(), excp
|
||||
)
|
||||
f"Unable to dump PE with pid {proc.UniqueProcessId}.{vad.get_start():#x}: {excp}"
|
||||
)
|
||||
|
||||
yield (
|
||||
|
||||
@@ -53,9 +53,7 @@ class Memmap(interfaces.plugins.PluginInterface):
|
||||
proc_layer = self.context.layers[proc_layer_name]
|
||||
except exceptions.InvalidAddressException as excp:
|
||||
vollog.debug(
|
||||
"Process {}: invalid address {} in layer {}".format(
|
||||
pid, excp.invalid_address, excp.layer_name
|
||||
)
|
||||
f"Process {pid}: invalid address {excp.invalid_address} in layer {excp.layer_name}"
|
||||
)
|
||||
continue
|
||||
|
||||
@@ -80,11 +78,7 @@ class Memmap(interfaces.plugins.PluginInterface):
|
||||
except exceptions.InvalidAddressException:
|
||||
file_output = "Error outputting to file"
|
||||
vollog.debug(
|
||||
"Unable to write {}'s address {} to {}".format(
|
||||
proc_layer_name,
|
||||
offset,
|
||||
file_handle.preferred_filename,
|
||||
)
|
||||
f"Unable to write {proc_layer_name}'s address {offset} to {file_handle.preferred_filename}"
|
||||
)
|
||||
|
||||
yield (
|
||||
|
||||
@@ -177,9 +177,7 @@ class Modules(interfaces.plugins.PluginInterface):
|
||||
except exceptions.InvalidAddressException:
|
||||
vollog.log(
|
||||
constants.LOGLEVEL_VVV,
|
||||
"Process {} does not have a valid Session or a layer could not be constructed for it".format(
|
||||
proc_id
|
||||
),
|
||||
f"Process {proc_id} does not have a valid Session or a layer could not be constructed for it",
|
||||
)
|
||||
continue
|
||||
|
||||
|
||||
@@ -169,12 +169,7 @@ class NetScan(interfaces.plugins.PluginInterface, timeliner.TimeLinerInterface):
|
||||
)
|
||||
|
||||
vollog.debug(
|
||||
"Determined OS Version: {}.{} {}.{}".format(
|
||||
kuser.NtMajorVersion,
|
||||
kuser.NtMinorVersion,
|
||||
vers.MajorVersion,
|
||||
vers.MinorVersion,
|
||||
)
|
||||
f"Determined OS Version: {kuser.NtMajorVersion}.{kuser.NtMinorVersion} {vers.MajorVersion}.{vers.MinorVersion}"
|
||||
)
|
||||
|
||||
if nt_major_version == 10 and arch == "x64":
|
||||
@@ -272,9 +267,7 @@ class NetScan(interfaces.plugins.PluginInterface, timeliner.TimeLinerInterface):
|
||||
if ver:
|
||||
tcpip_mod_version = ver[3]
|
||||
vollog.debug(
|
||||
"Determined tcpip.sys's FileVersion: {}".format(
|
||||
tcpip_mod_version
|
||||
)
|
||||
f"Determined tcpip.sys's FileVersion: {tcpip_mod_version}"
|
||||
)
|
||||
else:
|
||||
vollog.debug("Could not determine tcpip.sys's FileVersion.")
|
||||
@@ -316,12 +309,7 @@ class NetScan(interfaces.plugins.PluginInterface, timeliner.TimeLinerInterface):
|
||||
|
||||
else:
|
||||
raise NotImplementedError(
|
||||
"This version of Windows is not supported: {}.{} {}.{}!".format(
|
||||
nt_major_version,
|
||||
nt_minor_version,
|
||||
vers.MajorVersion,
|
||||
vers_minor_version,
|
||||
)
|
||||
f"This version of Windows is not supported: {nt_major_version}.{nt_minor_version} {vers.MajorVersion}.{vers_minor_version}!"
|
||||
)
|
||||
|
||||
vollog.debug(f"Determined symbol filename: {filename}")
|
||||
@@ -510,17 +498,8 @@ class NetScan(interfaces.plugins.PluginInterface, timeliner.TimeLinerInterface):
|
||||
for i in row_data
|
||||
]
|
||||
description = (
|
||||
"Network connection: Process {} {} Local Address {}:{} "
|
||||
"Remote Address {}:{} State {} Protocol {} ".format(
|
||||
row_data[7],
|
||||
row_data[8],
|
||||
row_data[2],
|
||||
row_data[3],
|
||||
row_data[4],
|
||||
row_data[5],
|
||||
row_data[6],
|
||||
row_data[1],
|
||||
)
|
||||
f"Network connection: Process {row_data[7]} {row_data[8]} Local Address {row_data[2]}:{row_data[3]} "
|
||||
f"Remote Address {row_data[4]}:{row_data[5]} State {row_data[6]} Protocol {row_data[1]} "
|
||||
)
|
||||
yield (description, timeliner.TimeLinerType.CREATED, row_data[9])
|
||||
|
||||
|
||||
@@ -311,9 +311,7 @@ class NetStat(interfaces.plugins.PluginInterface, timeliner.TimeLinerInterface):
|
||||
part_table.Partitions.count = part_count
|
||||
|
||||
vollog.debug(
|
||||
"Found TCP connection PartitionTable @ 0x{:x} (partition count: {})".format(
|
||||
part_table_addr, part_count
|
||||
)
|
||||
f"Found TCP connection PartitionTable @ 0x{part_table_addr:x} (partition count: {part_count})"
|
||||
)
|
||||
entry_offset = context.symbol_space.get_type(obj_name).relative_child_offset(
|
||||
"ListEntry"
|
||||
@@ -624,9 +622,7 @@ class NetStat(interfaces.plugins.PluginInterface, timeliner.TimeLinerInterface):
|
||||
proto = "TCPv6"
|
||||
else:
|
||||
vollog.debug(
|
||||
"TCP Endpoint @ 0x{:2x} has unknown address family 0x{:x}".format(
|
||||
netw_obj.vol.offset, netw_obj.get_address_family()
|
||||
)
|
||||
f"TCP Endpoint @ 0x{netw_obj.vol.offset:2x} has unknown address family 0x{netw_obj.get_address_family():x}"
|
||||
)
|
||||
proto = "TCPv?"
|
||||
|
||||
|
||||
@@ -645,7 +645,7 @@ class PESymbols(interfaces.plugins.PluginInterface):
|
||||
and wanted_addresses_identifier not in wanted_symbols
|
||||
):
|
||||
vollog.warning(
|
||||
f"Invalid `wanted_symbols` sent to `find_symbols`. addresses and names keys both misssing."
|
||||
"Invalid `wanted_symbols` sent to `find_symbols`. addresses and names keys both misssing."
|
||||
)
|
||||
return
|
||||
|
||||
|
||||
@@ -64,27 +64,30 @@ class PEDump(interfaces.plugins.PluginInterface):
|
||||
"""
|
||||
Returns the filename of the dump file or None
|
||||
"""
|
||||
with open_method(file_name) as file_handle:
|
||||
try:
|
||||
dos_header = context.object(
|
||||
pe_table_name + constants.BANG + "_IMAGE_DOS_HEADER",
|
||||
offset=base,
|
||||
layer_name=layer_name,
|
||||
)
|
||||
try:
|
||||
file_handle = open_method(file_name)
|
||||
|
||||
for offset, data in dos_header.reconstruct():
|
||||
file_handle.seek(offset)
|
||||
file_handle.write(data)
|
||||
except (
|
||||
IOError,
|
||||
exceptions.VolatilityException,
|
||||
OverflowError,
|
||||
ValueError,
|
||||
) as excp:
|
||||
vollog.debug(f"Unable to dump PE file at offset {base}: {excp}")
|
||||
return None
|
||||
dos_header = context.object(
|
||||
pe_table_name + constants.BANG + "_IMAGE_DOS_HEADER",
|
||||
offset=base,
|
||||
layer_name=layer_name,
|
||||
)
|
||||
|
||||
return file_handle.preferred_filename
|
||||
for offset, data in dos_header.reconstruct():
|
||||
file_handle.seek(offset)
|
||||
file_handle.write(data)
|
||||
except (
|
||||
OSError,
|
||||
exceptions.VolatilityException,
|
||||
OverflowError,
|
||||
ValueError,
|
||||
) as excp:
|
||||
vollog.debug(f"Unable to dump PE file at offset {base}: {excp}")
|
||||
return None
|
||||
finally:
|
||||
file_handle.close()
|
||||
|
||||
return file_handle.preferred_filename
|
||||
|
||||
@classmethod
|
||||
def dump_ldr_entry(
|
||||
@@ -116,12 +119,7 @@ class PEDump(interfaces.plugins.PluginInterface):
|
||||
if layer_name is None:
|
||||
layer_name = ldr_entry.vol.layer_name
|
||||
|
||||
file_name = "{}{}.{:#x}.{:#x}.dmp".format(
|
||||
prefix,
|
||||
ntpath.basename(name),
|
||||
ldr_entry.vol.offset,
|
||||
ldr_entry.DllBase,
|
||||
)
|
||||
file_name = f"{prefix}{ntpath.basename(name)}.{ldr_entry.vol.offset:#x}.{ldr_entry.DllBase:#x}.dmp"
|
||||
|
||||
return cls.dump_pe(
|
||||
context,
|
||||
@@ -143,11 +141,7 @@ class PEDump(interfaces.plugins.PluginInterface):
|
||||
pid: int,
|
||||
base: int,
|
||||
) -> Optional[str]:
|
||||
file_name = "PE.{:#x}.{:d}.{:#x}.dmp".format(
|
||||
proc_offset,
|
||||
pid,
|
||||
base,
|
||||
)
|
||||
file_name = f"PE.{proc_offset:#x}.{pid:d}.{base:#x}.dmp"
|
||||
|
||||
return PEDump.dump_pe(
|
||||
context, pe_table_name, layer_name, open_method, file_name, base
|
||||
|
||||
@@ -39,7 +39,7 @@ class Privs(interfaces.plugins.PluginInterface):
|
||||
)
|
||||
|
||||
# Get service sids dictionary (we need only the service sids).
|
||||
with open(sids_json_file_name, "r") as file_handle:
|
||||
with open(sids_json_file_name) as file_handle:
|
||||
temp_json = json.load(file_handle)["privileges"]
|
||||
self.privilege_info = {
|
||||
int(priv_num): temp_json[priv_num] for priv_num in temp_json
|
||||
|
||||
@@ -14,7 +14,6 @@ from volatility3.plugins.windows import (
|
||||
info,
|
||||
pslist,
|
||||
psscan,
|
||||
sessions,
|
||||
thrdscan,
|
||||
)
|
||||
|
||||
|
||||
@@ -232,10 +232,8 @@ class HiveList(interfaces.plugins.PluginInterface):
|
||||
for hive in hg:
|
||||
if hive.vol.offset in seen:
|
||||
vollog.debug(
|
||||
"Hivelist found an already seen offset {} while "
|
||||
"traversing forwards, this should not occur".format(
|
||||
hex(hive.vol.offset)
|
||||
)
|
||||
f"Hivelist found an already seen offset {hex(hive.vol.offset)} while "
|
||||
"traversing forwards, this should not occur"
|
||||
)
|
||||
break
|
||||
seen.add(hive.vol.offset)
|
||||
@@ -249,18 +247,14 @@ class HiveList(interfaces.plugins.PluginInterface):
|
||||
forward_invalid = hg.invalid
|
||||
if forward_invalid:
|
||||
vollog.debug(
|
||||
"Hivelist failed traversing the list forwards at {}, traversing backwards".format(
|
||||
hex(forward_invalid)
|
||||
)
|
||||
f"Hivelist failed traversing the list forwards at {hex(forward_invalid)}, traversing backwards"
|
||||
)
|
||||
hg = HiveGenerator(cmhive, forward=False)
|
||||
for hive in hg:
|
||||
if hive.vol.offset in seen:
|
||||
vollog.debug(
|
||||
"Hivelist found an already seen offset {} while "
|
||||
"traversing backwards, list walking met in the middle".format(
|
||||
hex(hive.vol.offset)
|
||||
)
|
||||
f"Hivelist found an already seen offset {hex(hive.vol.offset)} while "
|
||||
"traversing backwards, list walking met in the middle"
|
||||
)
|
||||
break
|
||||
seen.add(hive.vol.offset)
|
||||
@@ -281,10 +275,8 @@ class HiveList(interfaces.plugins.PluginInterface):
|
||||
# by walking the list, so revert to scanning, and walk the list forwards and backwards from each
|
||||
# found hive
|
||||
vollog.debug(
|
||||
"Hivelist failed traversing backwards at {}, a different "
|
||||
"location from forwards, revert to scanning".format(
|
||||
hex(backward_invalid)
|
||||
)
|
||||
f"Hivelist failed traversing backwards at {hex(backward_invalid)}, a different "
|
||||
"location from forwards, revert to scanning"
|
||||
)
|
||||
for hive in hivescan.HiveScan.scan_hives(
|
||||
context, layer_name, symbol_table
|
||||
@@ -320,9 +312,7 @@ class HiveList(interfaces.plugins.PluginInterface):
|
||||
yield linked_hive
|
||||
except exceptions.InvalidAddressException:
|
||||
vollog.debug(
|
||||
"InvalidAddressException when traversing hive {} found from scan, skipping".format(
|
||||
hex(hive.vol.offset)
|
||||
)
|
||||
f"InvalidAddressException when traversing hive {hex(hive.vol.offset)} found from scan, skipping"
|
||||
)
|
||||
|
||||
def run(self) -> renderers.TreeGrid:
|
||||
|
||||
@@ -39,7 +39,7 @@ class UserAssist(interfaces.plugins.PluginInterface, timeliner.TimeLinerInterfac
|
||||
os.path.join(os.path.dirname(__file__), "userassist.json"), "rb"
|
||||
) as fp:
|
||||
self._folder_guids = json.load(fp)
|
||||
except IOError:
|
||||
except OSError:
|
||||
vollog.error("Usersassist data file not found")
|
||||
|
||||
@classmethod
|
||||
@@ -308,9 +308,7 @@ class UserAssist(interfaces.plugins.PluginInterface, timeliner.TimeLinerInterfac
|
||||
)
|
||||
except exceptions.InvalidAddressException as excp:
|
||||
vollog.debug(
|
||||
"Invalid address identified in lower layer {}: {}".format(
|
||||
excp.layer_name, excp.invalid_address
|
||||
)
|
||||
f"Invalid address identified in lower layer {excp.layer_name}: {excp.invalid_address}"
|
||||
)
|
||||
except KeyError:
|
||||
vollog.debug(
|
||||
|
||||
@@ -172,9 +172,7 @@ class Skeleton_Key_Check(interfaces.plugins.PluginInterface):
|
||||
|
||||
except exceptions.InvalidAddressException:
|
||||
vollog.debug(
|
||||
"Unable to construct cSystems array at given offset: {:x}".format(
|
||||
array_start
|
||||
)
|
||||
f"Unable to construct cSystems array at given offset: {array_start:x}"
|
||||
)
|
||||
array = None
|
||||
|
||||
@@ -291,9 +289,7 @@ class Skeleton_Key_Check(interfaces.plugins.PluginInterface):
|
||||
|
||||
except exceptions.InvalidAddressException as excp:
|
||||
vollog.debug(
|
||||
"Process {}: invalid address {} in layer {}".format(
|
||||
proc_id, excp.invalid_address, excp.layer_name
|
||||
)
|
||||
f"Process {proc_id}: invalid address {excp.invalid_address} in layer {excp.layer_name}"
|
||||
)
|
||||
|
||||
return None, None
|
||||
|
||||
@@ -170,9 +170,7 @@ class Strings(interfaces.plugins.PluginInterface):
|
||||
proc_layer_name = process.add_process_layer()
|
||||
except exceptions.InvalidAddressException as excp:
|
||||
vollog.debug(
|
||||
"Process {}: invalid address {} in layer {}".format(
|
||||
proc_id, excp.invalid_address, excp.layer_name
|
||||
)
|
||||
f"Process {proc_id}: invalid address {excp.invalid_address} in layer {excp.layer_name}"
|
||||
)
|
||||
continue
|
||||
|
||||
|
||||
@@ -85,9 +85,7 @@ class SvcList(svcscan.SvcScan):
|
||||
layer_name = proc.add_process_layer()
|
||||
except exceptions.InvalidAddressException:
|
||||
vollog.warning(
|
||||
"Unable to access memory of services.exe running with PID: {}".format(
|
||||
proc.UniqueProcessId
|
||||
)
|
||||
f"Unable to access memory of services.exe running with PID: {proc.UniqueProcessId}"
|
||||
)
|
||||
continue
|
||||
|
||||
|
||||
@@ -26,13 +26,9 @@ from volatility3.plugins.windows.registry import hivelist
|
||||
vollog = logging.getLogger(__name__)
|
||||
|
||||
|
||||
ServiceBinaryInfo = NamedTuple(
|
||||
"ServiceBinaryInfo",
|
||||
[
|
||||
("dll", Union[str, interfaces.renderers.BaseAbsentValue]),
|
||||
("binary", Union[str, interfaces.renderers.BaseAbsentValue]),
|
||||
],
|
||||
)
|
||||
class ServiceBinaryInfo(NamedTuple):
|
||||
dll: Union[str, interfaces.renderers.BaseAbsentValue]
|
||||
binary: Union[str, interfaces.renderers.BaseAbsentValue]
|
||||
|
||||
|
||||
class SvcScan(interfaces.plugins.PluginInterface):
|
||||
@@ -306,9 +302,7 @@ class SvcScan(interfaces.plugins.PluginInterface):
|
||||
proc_layer_name = task.add_process_layer()
|
||||
except exceptions.InvalidAddressException as excp:
|
||||
vollog.debug(
|
||||
"Process {}: invalid address {} in layer {}".format(
|
||||
proc_id, excp.invalid_address, excp.layer_name
|
||||
)
|
||||
f"Process {proc_id}: invalid address {excp.invalid_address} in layer {excp.layer_name}"
|
||||
)
|
||||
continue
|
||||
|
||||
|
||||
@@ -82,7 +82,7 @@ class ThrdScan(interfaces.plugins.PluginInterface, timeliner.TimeLinerInterface)
|
||||
ethread.get_exit_time()
|
||||
) # datetime.datetime object / volatility3.framework.renderers.UnparsableValue object
|
||||
except exceptions.InvalidAddressException:
|
||||
vollog.debug("Thread invalid address {:#x}".format(ethread.vol.offset))
|
||||
vollog.debug(f"Thread invalid address {ethread.vol.offset:#x}")
|
||||
return None
|
||||
|
||||
return (
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#
|
||||
|
||||
import logging
|
||||
from typing import Callable, Iterable, List, Generator
|
||||
from typing import Iterable, List, Generator
|
||||
|
||||
from volatility3.framework import interfaces, constants
|
||||
from volatility3.framework.configuration import requirements
|
||||
|
||||
@@ -141,7 +141,7 @@ class Timers(interfaces.plugins.PluginInterface):
|
||||
if dpc.DeferredRoutine == 0:
|
||||
continue
|
||||
deferred_routine = dpc.DeferredRoutine
|
||||
except Exception as e:
|
||||
except Exception:
|
||||
continue
|
||||
|
||||
module_symbols = list(
|
||||
|
||||
@@ -191,7 +191,7 @@ class unhooked_system_calls(interfaces.plugins.PluginInterface):
|
||||
|
||||
# gather processes on small_idx since these are the malware infected ones
|
||||
for pid, pname in cb[small_idx]:
|
||||
ps.append("{:d}:{}".format(pid, pname))
|
||||
ps.append(f"{pid:d}:{pname}")
|
||||
|
||||
proc_names = ", ".join(ps)
|
||||
|
||||
|
||||
@@ -169,9 +169,7 @@ class VadInfo(interfaces.plugins.PluginInterface):
|
||||
proc_layer_name = proc.add_process_layer()
|
||||
except exceptions.InvalidAddressException as excp:
|
||||
vollog.debug(
|
||||
"Process {}: invalid address {} in layer {}".format(
|
||||
proc_id, excp.invalid_address, excp.layer_name
|
||||
)
|
||||
f"Process {proc_id}: invalid address {excp.invalid_address} in layer {excp.layer_name}"
|
||||
)
|
||||
return None
|
||||
|
||||
|
||||
@@ -212,9 +212,7 @@ class VerInfo(interfaces.plugins.PluginInterface):
|
||||
proc_layer_name = proc.add_process_layer()
|
||||
except exceptions.InvalidAddressException as excp:
|
||||
vollog.debug(
|
||||
"Process {}: invalid address {} in layer {}".format(
|
||||
proc_id, excp.invalid_address, excp.layer_name
|
||||
)
|
||||
f"Process {proc_id}: invalid address {excp.invalid_address} in layer {excp.layer_name}"
|
||||
)
|
||||
continue
|
||||
|
||||
|
||||
@@ -88,9 +88,7 @@ class TreeNode(interfaces.renderers.TreeNode):
|
||||
val = values[index]
|
||||
if not isinstance(val, (column.type, interfaces.renderers.BaseAbsentValue)):
|
||||
raise TypeError(
|
||||
"Values item with index {} is the wrong type for column {} (got {} but expected {})".format(
|
||||
index, column.name, type(val), column.type
|
||||
)
|
||||
f"Values item with index {index} is the wrong type for column {column.name} (got {type(val)} but expected {column.type})"
|
||||
)
|
||||
# TODO: Consider how to deal with timezone naive/aware datetimes (and alert plugin uses to be precise)
|
||||
# if isinstance(val, datetime.datetime):
|
||||
@@ -189,9 +187,7 @@ class TreeGrid(interfaces.renderers.TreeGrid):
|
||||
is_simple_type = issubclass(column_type, self.base_types)
|
||||
if not is_simple_type:
|
||||
raise TypeError(
|
||||
"Column {}'s type is not a simple type: {}".format(
|
||||
name, column_type.__class__.__name__
|
||||
)
|
||||
f"Column {name}'s type is not a simple type: {column_type.__class__.__name__}"
|
||||
)
|
||||
converted_columns.append(interfaces.renderers.Column(name, column_type))
|
||||
self.RowStructure = RowStructureConstructor(
|
||||
|
||||
@@ -171,7 +171,7 @@ class IntermediateSymbolTable(interfaces.symbols.SymbolTableInterface):
|
||||
(indicating that only additive changes have been made) than
|
||||
the consumer (in this case, the file reader).
|
||||
"""
|
||||
major, minor, patch = [int(x) for x in version.split(".")]
|
||||
major, minor, patch = (int(x) for x in version.split("."))
|
||||
supported_versions = [x for x in versions if x[0] == major and x[1] >= minor]
|
||||
if not supported_versions:
|
||||
raise ValueError(
|
||||
|
||||
@@ -798,7 +798,7 @@ class RadixTree(IDStorage):
|
||||
return True
|
||||
|
||||
|
||||
class PageCache(object):
|
||||
class PageCache:
|
||||
"""Linux Page Cache abstraction"""
|
||||
|
||||
def __init__(
|
||||
|
||||
@@ -1469,7 +1469,7 @@ class mount(objects.StructType):
|
||||
|
||||
def next_peer(self):
|
||||
table_name = self.vol.type_name.split(constants.BANG)[0]
|
||||
mount_struct = "{0}{1}mount".format(table_name, constants.BANG)
|
||||
mount_struct = f"{table_name}{constants.BANG}mount"
|
||||
offset = self._context.symbol_space.get_type(
|
||||
mount_struct
|
||||
).relative_child_offset("mnt_share")
|
||||
@@ -2487,7 +2487,7 @@ class address_space(objects.StructType):
|
||||
|
||||
class page(objects.StructType):
|
||||
@property
|
||||
@functools.lru_cache()
|
||||
@functools.lru_cache
|
||||
def pageflags_enum(self) -> Dict:
|
||||
"""Returns 'pageflags' enumeration key/values
|
||||
|
||||
|
||||
@@ -1081,7 +1081,7 @@ class KTIMER(objects.StructType):
|
||||
return self.Header.Type in self.VALID_TYPES
|
||||
|
||||
def get_due_time(self):
|
||||
return "{0:#010x}:{1:#010x}".format(self.DueTime.HighPart, self.DueTime.LowPart)
|
||||
return f"{self.DueTime.HighPart:#010x}:{self.DueTime.LowPart:#010x}"
|
||||
|
||||
def get_dpc(self):
|
||||
"""Return Dpc, and if Windows 7 or later, decode it"""
|
||||
@@ -1388,7 +1388,7 @@ class SHARED_CACHE_MAP(objects.StructType):
|
||||
)
|
||||
|
||||
# Iterate through the entries
|
||||
for counter in range(0, self.VACB_ARRAY):
|
||||
for counter in range(self.VACB_ARRAY):
|
||||
# Check if the VACB entry is in use
|
||||
if not vacb_array[counter]:
|
||||
continue
|
||||
@@ -1472,7 +1472,7 @@ class SHARED_CACHE_MAP(objects.StructType):
|
||||
|
||||
if not section_size > self.VACB_SIZE_OF_FIRST_LEVEL:
|
||||
array_head = vacb_obj
|
||||
for counter in range(0, full_blocks):
|
||||
for counter in range(full_blocks):
|
||||
vacb_entry = self._context.object(
|
||||
symbol_table_name + constants.BANG + "pointer",
|
||||
layer_name=self.vol.layer_name,
|
||||
@@ -1531,7 +1531,7 @@ class SHARED_CACHE_MAP(objects.StructType):
|
||||
|
||||
# Walk the array and if any entry points to the shared cache map object then we extract it.
|
||||
# Otherwise, if it is non-zero, then traverse to the next level.
|
||||
for counter in range(0, self.VACB_ARRAY):
|
||||
for counter in range(self.VACB_ARRAY):
|
||||
if not vacb_array[counter]:
|
||||
continue
|
||||
|
||||
|
||||
@@ -73,7 +73,7 @@ class ROW(objects.StructType):
|
||||
)
|
||||
for i in range(0, len(char_row), 3)
|
||||
)
|
||||
except Exception as e:
|
||||
except Exception:
|
||||
line = ""
|
||||
|
||||
if truncate:
|
||||
|
||||
@@ -8,12 +8,7 @@ from volatility3.framework import objects
|
||||
class PARTITION_TABLE(objects.StructType):
|
||||
def get_disk_signature(self) -> str:
|
||||
"""Get Disk Signature (GUID)."""
|
||||
return "{0:02x}-{1:02x}-{2:02x}-{3:02x}".format(
|
||||
self.DiskSignature[0],
|
||||
self.DiskSignature[1],
|
||||
self.DiskSignature[2],
|
||||
self.DiskSignature[3],
|
||||
)
|
||||
return f"{self.DiskSignature[0]:02x}-{self.DiskSignature[1]:02x}-{self.DiskSignature[2]:02x}-{self.DiskSignature[3]:02x}"
|
||||
|
||||
|
||||
class PARTITION_ENTRY(objects.StructType):
|
||||
|
||||
@@ -22,7 +22,7 @@ def inet_ntop(address_family: int, packed_ip: Union[List[int], Array]) -> str:
|
||||
raise RuntimeError(
|
||||
"This version of python does not have socket.inet_ntop, please upgrade"
|
||||
)
|
||||
raise socket.error("[Errno 97] Address family not supported by protocol")
|
||||
raise OSError("[Errno 97] Address family not supported by protocol")
|
||||
|
||||
|
||||
# Python's socket.AF_INET6 is 0x1e but Microsoft defines it
|
||||
@@ -167,11 +167,9 @@ class _TCP_LISTENER(objects.StructType):
|
||||
|
||||
def is_valid(self):
|
||||
try:
|
||||
if not self.get_address_family() in (AF_INET, AF_INET6):
|
||||
if self.get_address_family() not in (AF_INET, AF_INET6):
|
||||
vollog.debug(
|
||||
"netw obj 0x{:x} invalid due to invalid address_family {}".format(
|
||||
self.vol.offset, self.get_address_family()
|
||||
)
|
||||
f"netw obj 0x{self.vol.offset:x} invalid due to invalid address_family {self.get_address_family()}"
|
||||
)
|
||||
return False
|
||||
|
||||
|
||||
@@ -101,9 +101,9 @@ class IMAGE_DOS_HEADER(objects.StructType):
|
||||
)
|
||||
except OverflowError:
|
||||
vollog.warning(
|
||||
"Volatility was unable to fix the image base for the PE file at base address {:#x}. "
|
||||
f"Volatility was unable to fix the image base for the PE file at base address {self.vol.offset:#x}. "
|
||||
"This will cause issues with many static analysis tools if you do not inform the "
|
||||
"tool of the in-memory load address.".format(self.vol.offset)
|
||||
"tool of the in-memory load address."
|
||||
)
|
||||
new_pe = raw_data
|
||||
|
||||
|
||||
@@ -217,7 +217,7 @@ class POOL_HEADER(objects.StructType):
|
||||
yield mem_object
|
||||
|
||||
@classmethod
|
||||
@functools.lru_cache()
|
||||
@functools.lru_cache
|
||||
def _calculate_optional_header_lengths(
|
||||
cls, context: interfaces.context.ContextInterface, symbol_table_name: str
|
||||
) -> Tuple[List[str], List[int]]:
|
||||
@@ -430,9 +430,7 @@ class OBJECT_HEADER(objects.StructType):
|
||||
|
||||
if header_offset == 0:
|
||||
raise ValueError(
|
||||
"Could not find _OBJECT_HEADER_NAME_INFO for object at {} of layer {}".format(
|
||||
self.vol.offset, self.vol.layer_name
|
||||
)
|
||||
f"Could not find _OBJECT_HEADER_NAME_INFO for object at {self.vol.offset} of layer {self.vol.layer_name}"
|
||||
)
|
||||
|
||||
header = ntkrnlmp.object(
|
||||
|
||||
@@ -196,9 +196,7 @@ class CM_KEY_NODE(objects.StructType):
|
||||
yield cast("CM_KEY_NODE", node)
|
||||
else:
|
||||
vollog.debug(
|
||||
"Unexpected node type encountered when traversing subkeys: {}, signature: {}".format(
|
||||
node.vol.type_name, signature
|
||||
)
|
||||
f"Unexpected node type encountered when traversing subkeys: {node.vol.type_name}, signature: {signature}"
|
||||
)
|
||||
|
||||
if listjump:
|
||||
|
||||
@@ -263,9 +263,7 @@ class PdbReader:
|
||||
)
|
||||
if header.index_max < header.index_min:
|
||||
raise ValueError(
|
||||
"Maximum {} index is smaller than minimum TPI index, found: {} < {} ".format(
|
||||
stream_name, header.index_max, header.index_min
|
||||
)
|
||||
f"Maximum {stream_name} index is smaller than minimum TPI index, found: {header.index_max} < {header.index_min} "
|
||||
)
|
||||
# Reset the state
|
||||
info_references: Dict[str, int] = {}
|
||||
@@ -976,7 +974,7 @@ class PdbRetreiver:
|
||||
if __name__ == "__main__":
|
||||
import argparse
|
||||
|
||||
class PrintedProgress(object):
|
||||
class PrintedProgress:
|
||||
"""A progress handler that prints the progress value and the
|
||||
description onto the command line."""
|
||||
|
||||
|
||||
@@ -94,7 +94,7 @@ class PDBUtility(interfaces.configuration.VersionableInterface):
|
||||
if not requirements.VersionRequirement.matches_required(
|
||||
(1, 0, 0), symbol_cache.SqliteCache.version
|
||||
):
|
||||
vollog.debug(f"Required version of SQLiteCache not found")
|
||||
vollog.debug("Required version of SQLiteCache not found")
|
||||
return None
|
||||
|
||||
identifiers_path = os.path.join(
|
||||
@@ -291,9 +291,7 @@ class PDBUtility(interfaces.configuration.VersionableInterface):
|
||||
break
|
||||
except PermissionError:
|
||||
vollog.warning(
|
||||
"Cannot write necessary symbol file, please check permissions on {}".format(
|
||||
potential_output_filename
|
||||
)
|
||||
f"Cannot write necessary symbol file, please check permissions on {potential_output_filename}"
|
||||
)
|
||||
continue
|
||||
finally:
|
||||
|
||||
@@ -60,7 +60,7 @@ class Certificates(interfaces.plugins.PluginInterface):
|
||||
open_method: Type[interfaces.plugins.FileHandlerInterface],
|
||||
) -> Optional[interfaces.plugins.FileHandlerInterface]:
|
||||
try:
|
||||
dump_name = "{}-{}-{}.crt".format(hive_offset, reg_section, key_hash)
|
||||
dump_name = f"{hive_offset}-{reg_section}-{key_hash}.crt"
|
||||
file_handle = open_method(dump_name)
|
||||
file_handle.write(certificate_data)
|
||||
return file_handle
|
||||
|
||||
@@ -64,9 +64,7 @@ class Statistics(plugins.PluginInterface):
|
||||
other_invalid += 1
|
||||
page_size = expected_page_size
|
||||
vollog.debug(
|
||||
"A non-page lookup invalid address exception occurred at: {} in layer {}".format(
|
||||
hex(excp.invalid_address), excp.layer_name
|
||||
)
|
||||
f"A non-page lookup invalid address exception occurred at: {hex(excp.invalid_address)} in layer {excp.layer_name}"
|
||||
)
|
||||
|
||||
page_addr += page_size
|
||||
|
||||
@@ -20,7 +20,7 @@ def load_cached_validations() -> Set[str]:
|
||||
to revalidate them."""
|
||||
validhashes: Set = set()
|
||||
if os.path.exists(cached_validation_filepath):
|
||||
with open(cached_validation_filepath, "r") as f:
|
||||
with open(cached_validation_filepath) as f:
|
||||
validhashes.update(json.load(f))
|
||||
return validhashes
|
||||
|
||||
@@ -46,7 +46,7 @@ def validate(input: Dict[str, Any], use_cache: bool = True) -> bool:
|
||||
if not os.path.exists(schema_path):
|
||||
vollog.debug(f"Schema for format not found: {schema_path}")
|
||||
return False
|
||||
with open(schema_path, "r") as s:
|
||||
with open(schema_path) as s:
|
||||
schema = json.load(s)
|
||||
return valid(input, schema, use_cache)
|
||||
|
||||
@@ -66,7 +66,7 @@ def create_json_hash(
|
||||
if not os.path.exists(schema_path):
|
||||
vollog.debug(f"Schema for format not found: {schema_path}")
|
||||
return None
|
||||
with open(schema_path, "r") as s:
|
||||
with open(schema_path) as s:
|
||||
schema = json.load(s)
|
||||
return hashlib.sha1(
|
||||
bytes(json.dumps((input, schema), sort_keys=True), "utf-8")
|
||||
|
||||
Reference in New Issue
Block a user