From 55cd4d9759931036e94d781795ec99e46049423c Mon Sep 17 00:00:00 2001 From: Abyss Watcher Date: Fri, 6 Mar 2026 14:24:48 +0100 Subject: [PATCH] adjust dummy page table check --- volatility3/framework/automagic/windows.py | 38 +++++++++++++++------- 1 file changed, 26 insertions(+), 12 deletions(-) diff --git a/volatility3/framework/automagic/windows.py b/volatility3/framework/automagic/windows.py index bed2a4376..f627043db 100644 --- a/volatility3/framework/automagic/windows.py +++ b/volatility3/framework/automagic/windows.py @@ -287,22 +287,38 @@ class WindowsIntelStacker(interfaces.automagic.StackerLayerInterface): """Key used to sort by tests""" return tests.index(x[0]), x[1] - def get_max_pointer(page_table, test, ptr_size: int): - """Determines a pointer from a page_table""" - max_ptr = 0 + def get_valid_page_table_pointers(page_table, ptr_size: int): + """Yields valid pointers from a page table""" for index in range(0, len(page_table), ptr_size): pointer = struct.unpack( test.ptr_struct, page_table[index : index + ptr_size] )[0] # Make sure the pointer is valid, ignore large pages which would require more calculation if pointer & 0x1 and not pointer & 0x80: - max_ptr = max( - max_ptr, - (pointer ^ (pointer & 0xFFF)) - % test.layer_type.maximum_address, - ) + yield pointer + + def get_max_pointer(page_table, test, ptr_size: int): + """Determines a pointer from a page_table""" + max_ptr = 0 + for pointer in get_valid_page_table_pointers(page_table, ptr_size): + max_ptr = max( + max_ptr, + (pointer ^ (pointer & 0xFFF)) % test.layer_type.maximum_address, + ) return max_ptr + def page_table_is_dummy(page_table, ptr_size: int): + """Verify that a page table has at least 12 valid pointers""" + valid_pointers = 0 + for _ in get_valid_page_table_pointers(page_table, ptr_size): + valid_pointers += 1 + # 12 is an arbitrary constant + if valid_pointers >= 12: + # Do not consume the entire generator to enhance performance + return False + + return True + hits = sorted(list(hits), key=sort_by_tests) vollog.debug(f"WindowsIntelStacker hits: {hits}") @@ -310,16 +326,14 @@ class WindowsIntelStacker(interfaces.automagic.StackerLayerInterface): for test, page_map_offset in hits: # Turn the page tables into integers and find the largest one page_table = base_layer.read(page_map_offset, 0x1000) - + ptr_size = struct.calcsize(test.ptr_struct) # Modern windows can have a dummy page table with only about 2 entries, so sanity check - null_count = sum([1 if page_table[x] else 0 for x in page_table]) - if null_count > 0xFA0: + if page_table_is_dummy(page_table, ptr_size): vollog.debug( f"DTB {page_map_offset:x} contains less than 12 valid pointers, ignoring" ) continue - ptr_size = struct.calcsize(test.ptr_struct) max_pointer = get_max_pointer(page_table, test, ptr_size) if max_pointer <= base_layer.maximum_address: