mirror of
https://github.com/volatilityfoundation/volatility3.git
synced 2026-09-07 10:17:38 +02:00
Windows Shimcachemem: Updates req's, new major version
This updates the ShimcacheMem plugins with the version bumps on the modules and pslist requirements, updates the corresponding method calls, and does a major version bump of its own due to a required breaking method signature change. Co-authored-by: Andrew Case <andrew@dfir.org>
This commit is contained in:
co-authored by
Andrew Case
parent
ae6ced5888
commit
886faec474
@@ -65,13 +65,13 @@ class ShimcacheMem(interfaces.plugins.PluginInterface, timeliner.TimeLinerInterf
|
||||
architectures=["Intel32", "Intel64"],
|
||||
),
|
||||
requirements.PluginRequirement(
|
||||
name="pslist", plugin=pslist.PsList, version=(2, 0, 0)
|
||||
name="pslist", plugin=pslist.PsList, version=(3, 0, 0)
|
||||
),
|
||||
requirements.VersionRequirement(
|
||||
name="vadinfo", component=vadinfo.VadInfo, version=(2, 0, 0)
|
||||
),
|
||||
requirements.VersionRequirement(
|
||||
name="modules", component=modules.Modules, version=(2, 0, 0)
|
||||
name="modules", component=modules.Modules, version=(3, 0, 0)
|
||||
),
|
||||
]
|
||||
|
||||
@@ -79,7 +79,7 @@ class ShimcacheMem(interfaces.plugins.PluginInterface, timeliner.TimeLinerInterf
|
||||
def create_shimcache_table(
|
||||
cls,
|
||||
context: interfaces.context.ContextInterface,
|
||||
symbol_table: str,
|
||||
symbol_table_name: str,
|
||||
config_path: str,
|
||||
) -> str:
|
||||
"""Creates a shimcache symbol table
|
||||
@@ -92,16 +92,16 @@ class ShimcacheMem(interfaces.plugins.PluginInterface, timeliner.TimeLinerInterf
|
||||
Returns:
|
||||
The name of the constructed shimcache table
|
||||
"""
|
||||
native_types = context.symbol_space[symbol_table].natives
|
||||
is_64bit = symbols.symbol_table_is_64bit(context, symbol_table)
|
||||
table_mapping = {"nt_symbols": symbol_table}
|
||||
native_types = context.symbol_space[symbol_table_name].natives
|
||||
is_64bit = symbols.symbol_table_is_64bit(context, symbol_table_name)
|
||||
table_mapping = {"nt_symbols": symbol_table_name}
|
||||
|
||||
try:
|
||||
symbol_filename = next(
|
||||
filename
|
||||
for version_check, for_64bit, filename in ShimcacheMem._win_version_file_map
|
||||
if is_64bit == for_64bit
|
||||
and version_check(context=context, symbol_table=symbol_table)
|
||||
and version_check(context=context, symbol_table=symbol_table_name)
|
||||
)
|
||||
except StopIteration:
|
||||
raise NotImplementedError("This version of Windows is not supported!")
|
||||
@@ -122,8 +122,7 @@ class ShimcacheMem(interfaces.plugins.PluginInterface, timeliner.TimeLinerInterf
|
||||
def find_shimcache_win_xp(
|
||||
cls,
|
||||
context: interfaces.context.ContextInterface,
|
||||
layer_name: str,
|
||||
kernel_symbol_table: str,
|
||||
kernel_module_name: str,
|
||||
shimcache_symbol_table: str,
|
||||
) -> Iterator[shimcache.SHIM_CACHE_ENTRY]:
|
||||
"""Attempts to find the shimcache in a Windows XP memory image
|
||||
@@ -142,9 +141,7 @@ class ShimcacheMem(interfaces.plugins.PluginInterface, timeliner.TimeLinerInterf
|
||||
|
||||
seen = set()
|
||||
|
||||
for process in pslist.PsList.list_processes(
|
||||
context, layer_name, kernel_symbol_table
|
||||
):
|
||||
for process in pslist.PsList.list_processes(context, kernel_module_name):
|
||||
pid = process.UniqueProcessId
|
||||
vollog.debug("checking process %d", pid)
|
||||
for vad in vadinfo.VadInfo.list_vads(
|
||||
@@ -219,8 +216,7 @@ class ShimcacheMem(interfaces.plugins.PluginInterface, timeliner.TimeLinerInterf
|
||||
cls,
|
||||
context: interfaces.context.ContextInterface,
|
||||
config_path: str,
|
||||
kernel_layer_name: str,
|
||||
nt_symbol_table: str,
|
||||
kernel_module_name: str,
|
||||
shimcache_symbol_table: str,
|
||||
) -> Iterator[shimcache.SHIM_CACHE_ENTRY]:
|
||||
"""Implements the algorithm to search for the shim cache on Windows 2000
|
||||
@@ -239,31 +235,33 @@ class ShimcacheMem(interfaces.plugins.PluginInterface, timeliner.TimeLinerInterf
|
||||
:param shimcache_symbol_table: The name of a symbol table containing the hand-crafted shimcache symbols
|
||||
"""
|
||||
|
||||
kernel = context.modules[kernel_module_name]
|
||||
|
||||
data_sec = cls.get_module_section_range(
|
||||
context,
|
||||
config_path,
|
||||
kernel_layer_name,
|
||||
nt_symbol_table,
|
||||
kernel_module_name,
|
||||
cls.NT_KRNL_MODS,
|
||||
".data",
|
||||
)
|
||||
mod_page = cls.get_module_section_range(
|
||||
context,
|
||||
config_path,
|
||||
kernel_layer_name,
|
||||
nt_symbol_table,
|
||||
kernel_module_name,
|
||||
cls.NT_KRNL_MODS,
|
||||
"PAGE",
|
||||
)
|
||||
|
||||
# We require both in order to accurately handle AVL table
|
||||
if not (data_sec and mod_page):
|
||||
return None
|
||||
return
|
||||
|
||||
data_sec_offset, data_sec_size = data_sec
|
||||
mod_page_offset, mod_page_size = mod_page
|
||||
|
||||
addr_size = 8 if symbols.symbol_table_is_64bit(context, nt_symbol_table) else 4
|
||||
addr_size = (
|
||||
8 if symbols.symbol_table_is_64bit(context, kernel.symbol_table_name) else 4
|
||||
)
|
||||
|
||||
shim_head = None
|
||||
for offset in range(
|
||||
@@ -272,8 +270,7 @@ class ShimcacheMem(interfaces.plugins.PluginInterface, timeliner.TimeLinerInterf
|
||||
shim_head = cls.try_get_shim_head_at_offset(
|
||||
context,
|
||||
shimcache_symbol_table,
|
||||
nt_symbol_table,
|
||||
kernel_layer_name,
|
||||
kernel_module_name,
|
||||
mod_page_offset,
|
||||
mod_page_offset + mod_page_size,
|
||||
offset,
|
||||
@@ -293,9 +290,8 @@ class ShimcacheMem(interfaces.plugins.PluginInterface, timeliner.TimeLinerInterf
|
||||
def try_get_shim_head_at_offset(
|
||||
cls,
|
||||
context: interfaces.context.ContextInterface,
|
||||
symbol_table: str,
|
||||
kernel_symbol_table: str,
|
||||
layer_name: str,
|
||||
shimcache_symbol_table: str,
|
||||
kernel_module_name: str,
|
||||
mod_page_start: int,
|
||||
mod_page_end: int,
|
||||
offset: int,
|
||||
@@ -307,9 +303,14 @@ class ShimcacheMem(interfaces.plugins.PluginInterface, timeliner.TimeLinerInterf
|
||||
If a number of validity checks are passed, this method will return the `SHIM_CACHE_HEAD`
|
||||
object. Otherwise, `None` is returned.
|
||||
"""
|
||||
|
||||
kernel = context.modules[kernel_module_name]
|
||||
|
||||
# Check RTL_AVL_TABLE at offset
|
||||
rtl_avl_table = context.object(
|
||||
symbol_table + constants.BANG + "_RTL_AVL_TABLE", layer_name, offset
|
||||
shimcache_symbol_table + constants.BANG + "_RTL_AVL_TABLE",
|
||||
kernel.layer_name,
|
||||
offset,
|
||||
)
|
||||
if not rtl_avl_table.is_valid(mod_page_start, mod_page_end):
|
||||
return None
|
||||
@@ -317,11 +318,11 @@ class ShimcacheMem(interfaces.plugins.PluginInterface, timeliner.TimeLinerInterf
|
||||
vollog.debug(f"Candidate RTL_AVL_TABLE found at offset {offset:#x}")
|
||||
|
||||
ersrc_size = context.symbol_space.get_type(
|
||||
kernel_symbol_table + constants.BANG + "_ERESOURCE"
|
||||
kernel.symbol_table_name + constants.BANG + "_ERESOURCE"
|
||||
).size
|
||||
ersrc_alignment = (
|
||||
0x20
|
||||
if symbols.symbol_table_is_64bit(context, kernel_symbol_table)
|
||||
if symbols.symbol_table_is_64bit(context, kernel.symbol_table_name)
|
||||
else 0x10
|
||||
# 0x20 if context.symbol_space.get_type("pointer").size == 8 else 0x10
|
||||
)
|
||||
@@ -334,8 +335,8 @@ class ShimcacheMem(interfaces.plugins.PluginInterface, timeliner.TimeLinerInterf
|
||||
|
||||
vollog.debug(f"Constructing ERESOURCE at {eresource_offset:#x}")
|
||||
eresource = context.object(
|
||||
kernel_symbol_table + constants.BANG + "_ERESOURCE",
|
||||
layer_name,
|
||||
kernel.symbol_table_name + constants.BANG + "_ERESOURCE",
|
||||
kernel.layer_name,
|
||||
eresource_offset,
|
||||
)
|
||||
if not eresource.is_valid():
|
||||
@@ -344,12 +345,12 @@ class ShimcacheMem(interfaces.plugins.PluginInterface, timeliner.TimeLinerInterf
|
||||
|
||||
shim_head_offset = offset + rtl_avl_table.vol.size
|
||||
|
||||
if not context.layers[layer_name].is_valid(shim_head_offset):
|
||||
if not context.layers[kernel.layer_name].is_valid(shim_head_offset):
|
||||
return None
|
||||
|
||||
shim_head = context.object(
|
||||
symbol_table + constants.BANG + "SHIM_CACHE_ENTRY",
|
||||
layer_name,
|
||||
shimcache_symbol_table + constants.BANG + "SHIM_CACHE_ENTRY",
|
||||
kernel.layer_name,
|
||||
shim_head_offset,
|
||||
)
|
||||
|
||||
@@ -365,8 +366,7 @@ class ShimcacheMem(interfaces.plugins.PluginInterface, timeliner.TimeLinerInterf
|
||||
cls,
|
||||
context: interfaces.context.ContextInterface,
|
||||
config_path: str,
|
||||
kernel_layer_name: str,
|
||||
nt_symbol_table: str,
|
||||
kernel_module_name: str,
|
||||
shimcache_symbol_table: str,
|
||||
) -> Iterator[shimcache.SHIM_CACHE_ENTRY]:
|
||||
"""Attempts to locate and yield shimcache entries from a Windows 8 or later memory image.
|
||||
@@ -376,10 +376,11 @@ class ShimcacheMem(interfaces.plugins.PluginInterface, timeliner.TimeLinerInterf
|
||||
:param kernel_symbol_table: The name of an existing symbol table containing the kernel symbols
|
||||
:param shimcache_symbol_table: The name of a symbol table containing the hand-crafted shimcache symbols
|
||||
"""
|
||||
kernel = context.modules[kernel_module_name]
|
||||
|
||||
is_8_1_or_later = versions.is_windows_8_1_or_later(
|
||||
context, nt_symbol_table
|
||||
) or versions.is_win10(context, nt_symbol_table)
|
||||
context, kernel.symbol_table_name
|
||||
) or versions.is_win10(context, kernel.symbol_table_name)
|
||||
|
||||
module_names = ["ahcache.sys"] if is_8_1_or_later else cls.NT_KRNL_MODS
|
||||
vollog.debug(f"Searching for modules {module_names}")
|
||||
@@ -387,16 +388,14 @@ class ShimcacheMem(interfaces.plugins.PluginInterface, timeliner.TimeLinerInterf
|
||||
data_sec = cls.get_module_section_range(
|
||||
context,
|
||||
config_path,
|
||||
kernel_layer_name,
|
||||
nt_symbol_table,
|
||||
kernel_module_name,
|
||||
module_names,
|
||||
".data",
|
||||
)
|
||||
mod_page = cls.get_module_section_range(
|
||||
context,
|
||||
config_path,
|
||||
kernel_layer_name,
|
||||
nt_symbol_table,
|
||||
kernel_module_name,
|
||||
module_names,
|
||||
"PAGE",
|
||||
)
|
||||
@@ -419,12 +418,16 @@ class ShimcacheMem(interfaces.plugins.PluginInterface, timeliner.TimeLinerInterf
|
||||
for offset in range(
|
||||
data_sec_offset,
|
||||
data_sec_offset + data_sec_size,
|
||||
8 if symbols.symbol_table_is_64bit(context, nt_symbol_table) else 4,
|
||||
(
|
||||
8
|
||||
if symbols.symbol_table_is_64bit(context, kernel.symbol_table_name)
|
||||
else 4
|
||||
),
|
||||
):
|
||||
vollog.debug(f"Building shim handle pointer at {offset:#x}")
|
||||
shim_handle = context.object(
|
||||
object_type=shimcache_symbol_table + constants.BANG + "pointer",
|
||||
layer_name=kernel_layer_name,
|
||||
layer_name=kernel.layer_name,
|
||||
subtype=handle_type,
|
||||
offset=offset,
|
||||
)
|
||||
@@ -445,7 +448,7 @@ class ShimcacheMem(interfaces.plugins.PluginInterface, timeliner.TimeLinerInterf
|
||||
# On Windows 8 x64, the first cache contains the shim cache.
|
||||
# On Windows 8 x86, 8.1 x86/x64, and 10, the second cache contains the shim cache.
|
||||
if (
|
||||
not symbols.symbol_table_is_64bit(context, nt_symbol_table)
|
||||
not symbols.symbol_table_is_64bit(context, kernel.symbol_table_name)
|
||||
and not is_8_1_or_later
|
||||
):
|
||||
valid_head = shim_heads[1]
|
||||
@@ -474,8 +477,7 @@ class ShimcacheMem(interfaces.plugins.PluginInterface, timeliner.TimeLinerInterf
|
||||
entries = self.find_shimcache_win_8_or_later(
|
||||
self.context,
|
||||
self.config_path,
|
||||
kernel.layer_name,
|
||||
kernel.symbol_table_name,
|
||||
self.config["kernel"],
|
||||
shimcache_table_name,
|
||||
)
|
||||
|
||||
@@ -488,8 +490,7 @@ class ShimcacheMem(interfaces.plugins.PluginInterface, timeliner.TimeLinerInterf
|
||||
entries = self.find_shimcache_win_2k3_to_7(
|
||||
self.context,
|
||||
self.config_path,
|
||||
kernel.layer_name,
|
||||
kernel.symbol_table_name,
|
||||
self.config["kernel"],
|
||||
shimcache_table_name,
|
||||
)
|
||||
|
||||
@@ -499,8 +500,7 @@ class ShimcacheMem(interfaces.plugins.PluginInterface, timeliner.TimeLinerInterf
|
||||
vollog.info("Finding shimcache entries for WinXP")
|
||||
entries = self.find_shimcache_win_xp(
|
||||
self._context,
|
||||
kernel.layer_name,
|
||||
kernel.symbol_table_name,
|
||||
self.config["kernel"],
|
||||
shimcache_table_name,
|
||||
)
|
||||
else:
|
||||
@@ -547,8 +547,7 @@ class ShimcacheMem(interfaces.plugins.PluginInterface, timeliner.TimeLinerInterf
|
||||
cls,
|
||||
context: interfaces.context.ContextInterface,
|
||||
config_path: str,
|
||||
layer_name: str,
|
||||
symbol_table: str,
|
||||
kernel_module_name: str,
|
||||
module_list: List[str],
|
||||
section_name: str,
|
||||
) -> Optional[Tuple[int, int]]:
|
||||
@@ -566,14 +565,14 @@ class ShimcacheMem(interfaces.plugins.PluginInterface, timeliner.TimeLinerInterf
|
||||
try:
|
||||
krnl_mod = next(
|
||||
module
|
||||
for module in modules.Modules.list_modules(
|
||||
context, layer_name, symbol_table
|
||||
)
|
||||
for module in modules.Modules.list_modules(context, kernel_module_name)
|
||||
if module.BaseDllName.String in module_list
|
||||
)
|
||||
except StopIteration:
|
||||
return None
|
||||
|
||||
kernel = context.modules[kernel_module_name]
|
||||
|
||||
pe_table_name = intermed.IntermediateSymbolTable.create(
|
||||
context,
|
||||
interfaces.configuration.path_join(config_path, "pe"),
|
||||
@@ -585,7 +584,7 @@ class ShimcacheMem(interfaces.plugins.PluginInterface, timeliner.TimeLinerInterf
|
||||
# code taken from Win32KBase._section_chunks (win32_core.py)
|
||||
dos_header = context.object(
|
||||
pe_table_name + constants.BANG + "_IMAGE_DOS_HEADER",
|
||||
layer_name,
|
||||
kernel.layer_name,
|
||||
offset=krnl_mod.DllBase,
|
||||
)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user