Merge branch 'volatilityfoundation:develop' into feature/vadwalk

This commit is contained in:
Donghyun Kim
2022-06-10 00:24:01 +09:00
committed by GitHub
13 changed files with 77 additions and 31 deletions
+1 -1
View File
@@ -26,7 +26,7 @@ except ImportError:
# Volatility must be findable in sys.path in order for collect_submodules to work
# This adds the current working directory, which should usually do the trick
sys.path.append(os.getcwd())
sys.path.append(os.path.dirname(os.path.abspath(SPEC)))
vol_analysis = Analysis(['vol.py'],
pathex = [],
+3 -3
View File
@@ -37,9 +37,9 @@ class WarningFindSpec(abc.MetaPathFinder):
first."""
if fullname.startswith("volatility3.framework.plugins."):
warning = "Please do not use the volatility3.framework.plugins namespace directly, only use volatility3.plugins"
# Pyinstaller uses walk_packages to import, but needs to read the modules to figure out dependencies
# As such, we only print the warning when directly imported rather than from within walk_packages
if inspect.stack()[-2].function != 'walk_packages':
# Pyinstaller uses walk_packages/_collect_submodules to import, but needs to read the modules to figure out dependencies
# As such, we only print the warning when directly imported rather than from within walk_packages/_collect_submodules
if inspect.stack()[-2].function in ['walk_packages', '_collect_submodules']:
raise Warning(warning)
+1 -1
View File
@@ -63,7 +63,7 @@ class ObjectTemplate(interfaces.objects.Template):
object_info: interfaces.objects.ObjectInformation) -> interfaces.objects.ObjectInterface:
"""Constructs the object.
Returns: an object adhereing to the :class:`~volatility3.framework.interfaces.objects.ObjectInterface`
Returns: an object adhering to the :class:`~volatility3.framework.interfaces.objects.ObjectInterface`
"""
arguments: Dict[str, Any] = {}
for arg in self.vol:
@@ -80,7 +80,7 @@ class Check_syscall(plugins.PluginInterface):
def _get_table_info_disassembly(self, ptr_sz, vmlinux):
"""Find the size of the system call table by disassembling functions
that immediately reference it in their first isntruction This is in the
that immediately reference it in their first instruction This is in the
form 'cmp reg,NR_syscalls'."""
table_size = 0
@@ -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
#
# Author: Gustavo Moreira
import logging
from collections import namedtuple
+1 -1
View File
@@ -40,7 +40,7 @@ class PsAux(plugins.PluginInterface):
name: string name of the process (from task.comm)
"""
# kernel theads never have an mm as they do not have userland mappings
# kernel threads never have an mm as they do not have userland mappings
try:
mm = task.mm
except exceptions.InvalidAddressException:
@@ -19,7 +19,7 @@ class PsTree(pslist.PsList):
"""Finds how deep the PID is in the tasks hierarchy.
Args:
pid: PID to find the level in the hierachy
pid: PID to find the level in the hierarchy
"""
seen = set([pid])
level = 0
@@ -1,4 +1,4 @@
# This file is opyright 2020 Volatility Foundation and licensed under the Volatility Software License 1.0
# This file is Copyright 2020 Volatility Foundation and licensed under the Volatility Software License 1.0
# which is available at https://www.volatilityfoundation.org/license/vsl-v1.0
#
+3 -3
View File
@@ -101,7 +101,7 @@ class Timeliner(interfaces.plugins.PluginInterface):
return [sortable(timestamp) for timestamp in data[2:]]
def _generator(self, runable_plugins: List[TimeLinerInterface]) -> Optional[Iterable[Tuple[int, Tuple]]]:
def _generator(self, runnable_plugins: List[TimeLinerInterface]) -> Optional[Iterable[Tuple[int, Tuple]]]:
"""Takes a timeline, sorts it and output the data from each relevant
row from each plugin."""
# Generate the results for each plugin
@@ -115,9 +115,9 @@ class Timeliner(interfaces.plugins.PluginInterface):
file_data = None
fp = None
for plugin in runable_plugins:
for plugin in runnable_plugins:
plugin_name = plugin.__class__.__name__
self._progress_callback((runable_plugins.index(plugin) * 100) // len(runable_plugins),
self._progress_callback((runnable_plugins.index(plugin) * 100) // len(runnable_plugins),
f"Running plugin {plugin_name}...")
try:
vollog.log(logging.INFO, f"Running {plugin_name}")
@@ -9,7 +9,7 @@
# For a thorough walkthrough on how the R&D was performed to develop this plugin,
# please see our blogpost here:
#
# <insert blog URL once published>
# https://volatility-labs.blogspot.com/2021/10/memory-forensics-r-illustrated.html
import io
import logging
@@ -95,10 +95,10 @@ class SSDT(plugins.PluginInterface):
if is_kernel_64:
array_subtype = "long"
def kvo_calulator(func: int) -> int:
def kvo_calculator(func: int) -> int:
return kvo + service_table_address + (func >> 4)
find_address = kvo_calulator
find_address = kvo_calculator
else:
array_subtype = "unsigned long"
+1 -1
View File
@@ -38,4 +38,4 @@ class WindowsMetadata(interfaces.symbols.MetadataInterface):
class LinuxMetadata(interfaces.symbols.MetadataInterface):
"""Class to handle the etadata from a Linux symbol table."""
"""Class to handle the metadata from a Linux symbol table."""
@@ -10,10 +10,10 @@ import os
import re
import struct
from typing import Any, Dict, Generator, List, Optional, Tuple, Union
from urllib import request, parse
from urllib import parse, request
from volatility3 import symbols
from volatility3.framework import constants, interfaces, exceptions
from volatility3.framework import constants, contexts, exceptions, interfaces
from volatility3.framework.configuration.requirements import SymbolTableRequirement
from volatility3.framework.symbols import intermed
from volatility3.framework.symbols.windows import pdbconv
@@ -24,7 +24,7 @@ vollog = logging.getLogger(__name__)
class PDBUtility(interfaces.configuration.VersionableInterface):
"""Class to handle and manage all getting symbols based on MZ header"""
_version = (1, 0, 0)
_version = (1, 0, 1)
_required_framework_version = (2, 0, 0)
@classmethod
@@ -131,14 +131,14 @@ class PDBUtility(interfaces.configuration.VersionableInterface):
# Check it is actually the MZ header
if mz_sig != b"MZ":
return None
nt_header_start, = struct.unpack("<I", layer.read(offset + 0x3C, 4))
pe_sig = layer.read(offset + nt_header_start, 2)
# Check it is actually the Nt Headers
if pe_sig != b"PE":
return None
optional_header_size, = struct.unpack('<H', layer.read(offset + nt_header_start + 0x14, 2))
# Just enough to tell us the max size
pe_header = layer.read(offset, nt_header_start + 0x16 + optional_header_size)
@@ -146,7 +146,7 @@ class PDBUtility(interfaces.configuration.VersionableInterface):
max_size = pe_data.OPTIONAL_HEADER.SizeOfImage
# Proper data
virtual_data = layer.read(offset, max_size, pad=True)
virtual_data = layer.read(offset, max_size, pad = True)
pe_data = pefile.PE(data = virtual_data)
# De-virtualize the memory
@@ -291,7 +291,7 @@ class PDBUtility(interfaces.configuration.VersionableInterface):
@classmethod
def symbol_table_from_pdb(cls, context: interfaces.context.ContextInterface, config_path: str, layer_name: str,
pdb_name: str, module_offset: int, module_size: int) -> str:
pdb_name: str, module_offset: int = None, module_size: int = None) -> str:
"""Creates symbol table for a module in the specified layer_name.
Searches the memory section of the loaded module for its PDB GUID
@@ -307,6 +307,19 @@ class PDBUtility(interfaces.configuration.VersionableInterface):
Returns:
The name of the constructed and loaded symbol table
"""
_, symbol_table_name = cls._modtable_from_pdb(context, config_path, layer_name, pdb_name, module_offset,
module_size)
return symbol_table_name
@classmethod
def _modtable_from_pdb(cls, context: interfaces.context.ContextInterface, config_path: str, layer_name: str,
pdb_name: str, module_offset: int = None, module_size: int = None,
create_module: bool = False) -> Tuple[Optional[str], Optional[str]]:
if module_offset is None:
module_offset = context.layers[layer_name].minimum_address
if module_size is None:
module_size = context.layers[layer_name].maximum_address - module_offset
guids = list(
cls.pdbname_scan(context,
@@ -323,12 +336,46 @@ class PDBUtility(interfaces.configuration.VersionableInterface):
vollog.debug(f"Found {guid['pdb_name']}: {guid['GUID']}-{guid['age']}")
return cls.load_windows_symbol_table(context,
guid["GUID"],
guid["age"],
guid["pdb_name"],
"volatility3.framework.symbols.intermed.IntermediateSymbolTable",
config_path = config_path)
module_name = guid["pdb_name"].strip('.pdb')
symbol_table_name = cls.load_windows_symbol_table(context,
guid["GUID"],
guid["age"],
guid["pdb_name"],
"volatility3.framework.symbols.intermed.IntermediateSymbolTable",
config_path = config_path)
new_module_name = None
if create_module:
new_module = contexts.Module.create(context, module_name, layer_name, offset = guid['mz_offset'],
symbol_table_name = symbol_table_name)
new_module_name = new_module.name
return new_module_name, symbol_table_name
@classmethod
def module_from_pdb(cls, context: interfaces.context.ContextInterface, config_path: str, layer_name: str,
pdb_name: str, module_offset: int = None, module_size: int = None) -> str:
"""Creates a module in the specified layer_name based on a pdb name.
Searches the memory section of the loaded module for its PDB GUID
and loads the associated symbol table into the symbol space.
Args:
context: The context to retrieve required elements (layers, symbol tables) from
config_path: The config path where to find symbol files
layer_name: The name of the layer on which to operate
module_offset: This memory dump's module image offset
module_size: The size of the module for this dump
Returns:
The name of the constructed and loaded symbol table
"""
module_name, _ = cls._modtable_from_pdb(context, config_path, layer_name, pdb_name, module_offset,
module_size, create_module = True)
return module_name
class PdbSignatureScanner(interfaces.layers.ScannerInterface):