mirror of
https://github.com/volatilityfoundation/volatility3.git
synced 2026-09-29 13:04:58 +02:00
Address feedback
This commit is contained in:
@@ -13,7 +13,7 @@
|
||||
|
||||
import logging
|
||||
|
||||
from volatility3.framework import symbols
|
||||
from volatility3.framework import symbols, interfaces
|
||||
from volatility3.framework.configuration import requirements
|
||||
from volatility3.plugins.windows import svclist, svcscan
|
||||
from volatility3.framework.symbols.windows import versions
|
||||
@@ -26,6 +26,10 @@ class SvcDiff(svcscan.SvcScan):
|
||||
|
||||
_required_framework_version = (2, 4, 0)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self._enumeration_method = self.service_diff
|
||||
|
||||
@classmethod
|
||||
def get_requirements(cls):
|
||||
# Since we're calling the plugin, make sure we have the plugin's requirements
|
||||
@@ -43,19 +47,24 @@ class SvcDiff(svcscan.SvcScan):
|
||||
),
|
||||
]
|
||||
|
||||
def _generator(self):
|
||||
@classmethod
|
||||
def service_diff(
|
||||
cls,
|
||||
context: interfaces.context.ContextInterface,
|
||||
layer_name: str,
|
||||
symbol_table: str,
|
||||
service_table_name: str,
|
||||
service_binary_dll_map,
|
||||
filter_func,
|
||||
):
|
||||
"""
|
||||
On Windows 10 version 15063+ 64bit Windows memory samples, walk the services list
|
||||
and scan for services then report differences
|
||||
"""
|
||||
kernel, service_table_name, service_binary_dll_map, filter_func = (
|
||||
self.get_prereq_info()
|
||||
)
|
||||
|
||||
if not symbols.symbol_table_is_64bit(
|
||||
self.context, kernel.symbol_table_name
|
||||
context, symbol_table
|
||||
) or not versions.is_win10_15063_or_later(
|
||||
context=self.context, symbol_table=kernel.symbol_table_name
|
||||
context=context, symbol_table=symbol_table
|
||||
):
|
||||
vollog.warning(
|
||||
"This plugin only supports Windows 10 version 15063+ 64bit Windows memory samples"
|
||||
@@ -68,8 +77,9 @@ class SvcDiff(svcscan.SvcScan):
|
||||
|
||||
# collect unique service names from scanning
|
||||
for service in svcscan.SvcScan.service_scan(
|
||||
self.context,
|
||||
kernel,
|
||||
context,
|
||||
layer_name,
|
||||
symbol_table,
|
||||
service_table_name,
|
||||
service_binary_dll_map,
|
||||
filter_func,
|
||||
@@ -79,8 +89,9 @@ class SvcDiff(svcscan.SvcScan):
|
||||
|
||||
# collect services from listing walking
|
||||
for service in svclist.SvcList.service_list(
|
||||
self.context,
|
||||
kernel,
|
||||
context,
|
||||
layer_name,
|
||||
symbol_table,
|
||||
service_table_name,
|
||||
service_binary_dll_map,
|
||||
filter_func,
|
||||
@@ -89,4 +100,4 @@ class SvcDiff(svcscan.SvcScan):
|
||||
|
||||
# report services found from scanning but not list walking
|
||||
for hidden_service in from_scan - from_list:
|
||||
yield (0, records[hidden_service])
|
||||
yield records[hidden_service]
|
||||
|
||||
@@ -59,15 +59,16 @@ class SvcList(svcscan.SvcScan):
|
||||
def service_list(
|
||||
cls,
|
||||
context: interfaces.context.ContextInterface,
|
||||
kernel,
|
||||
layer_name: str,
|
||||
symbol_table: str,
|
||||
service_table_name: str,
|
||||
service_binary_dll_map,
|
||||
filter_func,
|
||||
):
|
||||
if not symbols.symbol_table_is_64bit(
|
||||
context, kernel.symbol_table_name
|
||||
context, symbol_table
|
||||
) or not versions.is_win10_15063_or_later(
|
||||
context=context, symbol_table=kernel.symbol_table_name
|
||||
context=context, symbol_table=symbol_table
|
||||
):
|
||||
vollog.warning(
|
||||
"This plugin only supports Windows 10 version 15063+ 64bit Windows memory samples"
|
||||
@@ -76,8 +77,8 @@ class SvcList(svcscan.SvcScan):
|
||||
|
||||
for proc in pslist.PsList.list_processes(
|
||||
context=context,
|
||||
layer_name=kernel.layer_name,
|
||||
symbol_table=kernel.symbol_table_name,
|
||||
layer_name=layer_name,
|
||||
symbol_table=symbol_table,
|
||||
filter_func=filter_func,
|
||||
):
|
||||
try:
|
||||
|
||||
@@ -148,14 +148,17 @@ class SvcScan(interfaces.plugins.PluginInterface):
|
||||
native_types=native_types,
|
||||
)
|
||||
|
||||
def _get_service_key(self, kernel) -> Optional[objects.StructType]:
|
||||
@classmethod
|
||||
def _get_service_key(
|
||||
cls, context, config_path: str, layer_name: str, symbol_table: str
|
||||
) -> Optional[objects.StructType]:
|
||||
for hive in hivelist.HiveList.list_hives(
|
||||
context=self.context,
|
||||
context=context,
|
||||
base_config_path=interfaces.configuration.path_join(
|
||||
self.config_path, "hivelist"
|
||||
config_path, "hivelist"
|
||||
),
|
||||
layer_name=kernel.layer_name,
|
||||
symbol_table=kernel.symbol_table_name,
|
||||
layer_name=layer_name,
|
||||
symbol_table=symbol_table,
|
||||
filter_string="machine\\system",
|
||||
):
|
||||
# Get ControlSet\Services.
|
||||
@@ -273,7 +276,8 @@ class SvcScan(interfaces.plugins.PluginInterface):
|
||||
def service_scan(
|
||||
cls,
|
||||
context: interfaces.context.ContextInterface,
|
||||
kernel,
|
||||
layer_name: str,
|
||||
symbol_table: str,
|
||||
service_table_name: str,
|
||||
service_binary_dll_map,
|
||||
filter_func,
|
||||
@@ -283,7 +287,7 @@ class SvcScan(interfaces.plugins.PluginInterface):
|
||||
).relative_child_offset("Tag")
|
||||
|
||||
is_vista_or_later = versions.is_vista_or_later(
|
||||
context=context, symbol_table=kernel.symbol_table_name
|
||||
context=context, symbol_table=symbol_table
|
||||
)
|
||||
|
||||
if is_vista_or_later:
|
||||
@@ -295,8 +299,8 @@ class SvcScan(interfaces.plugins.PluginInterface):
|
||||
|
||||
for task in pslist.PsList.list_processes(
|
||||
context=context,
|
||||
layer_name=kernel.layer_name,
|
||||
symbol_table=kernel.symbol_table_name,
|
||||
layer_name=layer_name,
|
||||
symbol_table=symbol_table,
|
||||
filter_func=filter_func,
|
||||
):
|
||||
proc_id = "Unknown"
|
||||
@@ -348,36 +352,41 @@ class SvcScan(interfaces.plugins.PluginInterface):
|
||||
seen.append(service_record)
|
||||
yield service_record
|
||||
|
||||
def get_prereq_info(self):
|
||||
@classmethod
|
||||
def get_prereq_info(cls, context, config_path, layer_name: str, symbol_table: str):
|
||||
"""
|
||||
Data structures and information needed to analyze service information
|
||||
"""
|
||||
kernel = self.context.modules[self.config["kernel"]]
|
||||
|
||||
service_table_name = self.create_service_table(
|
||||
self.context, kernel.symbol_table_name, self.config_path
|
||||
service_table_name = cls.create_service_table(
|
||||
context, symbol_table, config_path
|
||||
)
|
||||
|
||||
services_key = self._get_service_key(kernel)
|
||||
services_key = cls._get_service_key(
|
||||
context, config_path, layer_name, symbol_table
|
||||
)
|
||||
|
||||
service_binary_dll_map = (
|
||||
self._get_service_binary_map(services_key)
|
||||
cls._get_service_binary_map(services_key)
|
||||
if services_key is not None
|
||||
else {}
|
||||
)
|
||||
|
||||
filter_func = pslist.PsList.create_name_filter(["services.exe"])
|
||||
|
||||
return kernel, service_table_name, service_binary_dll_map, filter_func
|
||||
return service_table_name, service_binary_dll_map, filter_func
|
||||
|
||||
def _generator(self):
|
||||
kernel, service_table_name, service_binary_dll_map, filter_func = (
|
||||
self.get_prereq_info()
|
||||
kernel = self.context.modules[self.config["kernel"]]
|
||||
|
||||
service_table_name, service_binary_dll_map, filter_func = self.get_prereq_info(
|
||||
self.context, self.config_path, kernel.layer_name, kernel.symbol_table_name
|
||||
)
|
||||
|
||||
for record in self._enumeration_method(
|
||||
self.context,
|
||||
kernel,
|
||||
kernel.layer_name,
|
||||
kernel.symbol_table_name,
|
||||
service_table_name,
|
||||
service_binary_dll_map,
|
||||
filter_func,
|
||||
|
||||
Reference in New Issue
Block a user