From 537efa60e28d0a9ad23c5b0017618c853f338441 Mon Sep 17 00:00:00 2001 From: David McDonald Date: Tue, 15 Apr 2025 13:24:59 -0500 Subject: [PATCH 1/2] Thrdscan: Remove filtering based on VAD count This was preventing enumeration of valid processes (confirmed by disassembly of the start address/Win32 start address). Heuristic-based filtering should probably be left to consumers of the APIs. --- volatility3/framework/plugins/windows/thrdscan.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/volatility3/framework/plugins/windows/thrdscan.py b/volatility3/framework/plugins/windows/thrdscan.py index 0ac3d0c33..8fe13ba64 100644 --- a/volatility3/framework/plugins/windows/thrdscan.py +++ b/volatility3/framework/plugins/windows/thrdscan.py @@ -119,11 +119,6 @@ class ThrdScan(interfaces.plugins.PluginInterface, timeliner.TimeLinerInterface) vads = pe_symbols.PESymbols.get_vads_for_process_cache( vads_cache, owner_proc ) - if not vads or len(vads) < 5: - vollog.debug( - f"Not enough vads for process at {owner_proc.vol.offset:#x}. Skipping thread at {ethread.vol.offset:#x}" - ) - return None start_path = pe_symbols.PESymbols.filepath_for_address( vads, thread_start_addr From b04a498cd755ad511e85c923a00943551b991b41 Mon Sep 17 00:00:00 2001 From: David McDonald Date: Tue, 15 Apr 2025 13:23:41 -0500 Subject: [PATCH 2/2] ThrdScan: Fix process filtering This check was both causing an `InvalidAddressException` due to the member access, while at the same time not being a useful check, since it prevents VADs from being mapped in children of the `System` process. --- .../framework/plugins/windows/thrdscan.py | 27 +++++++++---------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/volatility3/framework/plugins/windows/thrdscan.py b/volatility3/framework/plugins/windows/thrdscan.py index 8fe13ba64..1e7466dc5 100644 --- a/volatility3/framework/plugins/windows/thrdscan.py +++ b/volatility3/framework/plugins/windows/thrdscan.py @@ -111,24 +111,23 @@ class ThrdScan(interfaces.plugins.PluginInterface, timeliner.TimeLinerInterface) return None # don't look for VADs in kernel threads, just let them get reported with empty paths - if ( - owner_proc_pid != 4 - and owner_proc.InheritedFromUniqueProcessId != 4 - and vads_cache is not None - ): + if owner_proc_pid != 4 and vads_cache is not None: vads = pe_symbols.PESymbols.get_vads_for_process_cache( vads_cache, owner_proc ) - - start_path = pe_symbols.PESymbols.filepath_for_address( - vads, thread_start_addr - ) - win32start_path = pe_symbols.PESymbols.filepath_for_address( - vads, thread_win32start_addr - ) else: - start_path = None - win32start_path = None + vads = None + + start_path = ( + pe_symbols.PESymbols.filepath_for_address(vads, thread_start_addr) + if vads + else None + ) + win32start_path = ( + pe_symbols.PESymbols.filepath_for_address(vads, thread_win32start_addr) + if vads + else None + ) return ( format_hints.Hex(thread_offset),