adjust dummy page table check

This commit is contained in:
Abyss Watcher
2026-03-06 14:24:48 +01:00
parent ba466f8064
commit 55cd4d9759
+26 -12
View File
@@ -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: