Merge branch 'fix/netstat-err' of https://github.com/digitalisx/volatility3 into fix/netstat-err

This commit is contained in:
Donghyun Kim
2022-08-25 01:47:30 +09:00
6 changed files with 96 additions and 10 deletions
@@ -171,11 +171,11 @@ class SqliteCache(CacheManagerInterface):
database = sqlite3.connect(path)
database.row_factory = sqlite3.Row
database.cursor().execute(
f'CREATE TABLE IF NOT EXISTS database_info (schema_version INT DEFAULT {constants.CACHE_SQLITE_SCEMA_VERSION})')
f'CREATE TABLE IF NOT EXISTS database_info (schema_version INT DEFAULT {constants.CACHE_SQLITE_SCHEMA_VERSION})')
schema_version = database.cursor().execute('SELECT schema_version FROM database_info').fetchone()
if not schema_version:
database.cursor().execute(f'INSERT INTO database_info VALUES ({constants.CACHE_SQLITE_SCEMA_VERSION})')
elif schema_version['schema_version'] == constants.CACHE_SQLITE_SCEMA_VERSION:
database.cursor().execute(f'INSERT INTO database_info VALUES ({constants.CACHE_SQLITE_SCHEMA_VERSION})')
elif schema_version['schema_version'] == constants.CACHE_SQLITE_SCHEMA_VERSION:
# All good, so pass and move on
pass
else:
@@ -196,7 +196,7 @@ class SqliteCache(CacheManagerInterface):
If multiple locations exist for an identifier, the last found is returned
Args:
identifier: string that uniquely identifies a particular symbolt table
identifier: string that uniquely identifies a particular symbol table
operating_system: optional string to restrict identifiers to just those for a particular operating system
Returns:
@@ -214,6 +214,9 @@ class WindowsIntelStacker(interfaces.automagic.StackerLayerInterface):
context.config[interfaces.configuration.path_join(
config_path, "page_map_offset")] = base_layer.metadata['page_map_offset']
layer = layer_type(context, config_path = config_path, name = new_layer_name, metadata = {'os': 'Windows'})
page_map_offset = context.config[interfaces.configuration.path_join(config_path, "page_map_offset")]
vollog.debug(f"DTB was given to us by base layer: {hex(page_map_offset)}")
return layer
# Self Referential finder
for description, tests, sections in cls.test_sets:
+3 -3
View File
@@ -40,7 +40,7 @@ BANG = "!"
# We use the SemVer 2.0.0 versioning scheme
VERSION_MAJOR = 2 # Number of releases of the library with a breaking change
VERSION_MINOR = 3 # Number of changes that only add to the interface
VERSION_PATCH = 0 # Number of changes that do not change the interface
VERSION_PATCH = 1 # Number of changes that do not change the interface
VERSION_SUFFIX = ""
# TODO: At version 2.0.0, remove the symbol_shift feature
@@ -64,7 +64,7 @@ CACHE_PATH = os.path.join(os.path.expanduser("~"), ".cache", "volatility3")
"""Default path to store cached data"""
if sys.platform == 'win32':
CACHE_PATH = os.path.join(os.environ.get("APPDATA", os.path.expanduser("~")), "volatility3")
CACHE_PATH = os.path.realpath(os.path.join(os.environ.get("APPDATA", os.path.expanduser("~")), "volatility3"))
os.makedirs(CACHE_PATH, exist_ok = True)
LINUX_BANNERS_PATH = os.path.join(CACHE_PATH, "linux_banners.cache")
@@ -76,7 +76,7 @@ MAC_BANNERS_PATH = os.path.join(CACHE_PATH, "mac_banners.cache")
IDENTIFIERS_PATH = os.path.join(CACHE_PATH, "identifiers.cache")
"""Default location to record information about available identifiers"""
CACHE_SQLITE_SCEMA_VERSION = 1
CACHE_SQLITE_SCHEMA_VERSION = 1
"""Version for the sqlite3 cache schema"""
BUG_URL = "https://github.com/volatilityfoundation/volatility3/issues"
@@ -0,0 +1,75 @@
# This file is Copyright 2022 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
from typing import Iterator, List, Tuple
from volatility3.framework import exceptions, interfaces, renderers
from volatility3.framework.configuration import requirements
from volatility3.framework.objects import utility
from volatility3.framework.renderers import format_hints
from volatility3.plugins.windows import pslist
vollog = logging.getLogger(__name__)
class JobLinks(interfaces.plugins.PluginInterface):
"""Print process job link information"""
_required_framework_version = (2, 0, 0)
_version = (1, 0, 0)
@classmethod
def get_requirements(cls) -> List[interfaces.configuration.RequirementInterface]:
return [
requirements.ModuleRequirement(name = 'kernel',
description = 'Windows kernel',
architectures = ["Intel32", "Intel64"]),
requirements.BooleanRequirement(name = 'physical',
description = "Display physical offset instead of virtual",
default = False,
optional = True),
requirements.VersionRequirement(name = 'pslist', component = pslist.PsList, version = (2, 0, 0))
]
def _generator(self) -> Iterator[Tuple]:
kernel = self.context.modules[self.config['kernel']]
memory = self.context.layers[kernel.layer_name]
for proc in pslist.PsList.list_processes(self.context, kernel.layer_name, kernel.symbol_table_name):
try:
if not self.config['physical']:
offset = proc.vol.offset
else:
(_, _, offset, _, _) = list(memory.mapping(offset = proc.vol.offset, length = 0))[0]
job = proc.Job.dereference()
yield (0, (format_hints.Hex(offset), utility.array_to_string(proc.ImageFileName), proc.UniqueProcessId,
proc.InheritedFromUniqueProcessId, proc.get_session_id(), job.SessionId, proc.get_is_wow64(),
job.TotalProcesses, job.ActiveProcesses, job.TotalTerminatedProcesses,
renderers.NotApplicableValue(), "(Original Process)"))
for entry in job.ProcessListHead.to_list(proc.vol.type_name, "JobLinks"):
if not self.config['physical']:
offset = entry.vol.offset
else:
(_, _, offset, _, _) = list(memory.mapping(offset = entry.vol.offset, length = 0))[0]
yield (1, (format_hints.Hex(offset), utility.array_to_string(entry.ImageFileName),
entry.UniqueProcessId, entry.InheritedFromUniqueProcessId, entry.get_session_id(), 0,
entry.get_is_wow64(), 0, 0, 0, "Yes",
entry.get_peb().ProcessParameters.ImagePathName.get_string()))
except (exceptions.InvalidAddressException):
continue
def run(self) -> renderers.TreeGrid:
offsettype = "(V)" if not self.config.get('physical', pslist.PsList.PHYSICAL_DEFAULT) else "(P)"
return renderers.TreeGrid([(f"Offset{offsettype}", format_hints.Hex), ("Name", str),
("PID", int), ("PPID", int), ("Sess", int), ("JobSess", int), ("Wow64", bool),
("Total", int), ("Active", int), ("Term", int), ("JobLink", str), ("Process", str)],
self._generator())
@@ -22,7 +22,7 @@ vollog = logging.getLogger(__name__)
class PsScan(interfaces.plugins.PluginInterface, timeliner.TimeLinerInterface):
"""Scans for processes present in a particular windows memory image."""
_required_framework_version = (2, 0, 0)
_required_framework_version = (2, 3, 1)
_version = (1, 1, 0)
@classmethod
@@ -443,9 +443,17 @@ class KMUTANT(objects.StructType, pool.ExecutiveObject):
class ETHREAD(objects.StructType):
"""A class for executive thread objects."""
def owning_process(self, kernel_layer: str = None) -> interfaces.objects.ObjectInterface:
def owning_process(self) -> interfaces.objects.ObjectInterface:
"""Return the EPROCESS that owns this thread."""
return self.ThreadsProcess.dereference(kernel_layer)
# For Windows XPs
if(self.has_member("ThreadsProcess")):
return self.ThreadsProcess.dereference().cast("_EPROCESS")
# For Windows Vista and later versions
elif(self.has_member("Tcb") and self.Tcb.has_member("Process")):
return self.Tcb.Process.dereference().cast("_EPROCESS")
else:
raise AttributeError("Unable to find the owning process of ethread")
def get_cross_thread_flags(self) -> str:
dictCrossThreadFlags = {