From 1cc9bcbfa7675f1c6ef0f41e20eab9d899d9e5b4 Mon Sep 17 00:00:00 2001 From: Willi Ballenthin Date: Mon, 9 Mar 2026 19:39:05 +0100 Subject: [PATCH] fix: use memory-mapped image for API module decoy PEs The ApiModuleLoader was writing raw PE file bytes into emulated memory, but PE sections have different file offsets vs virtual addresses. Shellcode that walks the PEB InInitializationOrderModuleList to find kernel32 and then parses its export directory would read garbage because the .edata section data was at its file offset rather than its virtual address. Use pefile's get_memory_mapped_image() so sections are placed at their correct virtual addresses, matching how Windows loads DLLs. Also fixes Process.ldr_entries being a shared class-level mutable default instead of a per-instance list, and corrects the test config module order to list ntdll before kernel32 (matching the default config). Closes #45 remove unnecessary test file --- speakeasy/windows/objman.py | 1 + tests/test.json | 10 +++++----- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/speakeasy/windows/objman.py b/speakeasy/windows/objman.py index b58b92c3..bba128a2 100644 --- a/speakeasy/windows/objman.py +++ b/speakeasy/windows/objman.py @@ -477,6 +477,7 @@ def __init__(self, emu, pe=None, user_modules=None, name="", path="", cmdline="" list_entry = self.address + 0x188 self.emu.mem_write(list_entry, list_entry.to_bytes(8, "little")) self.emu.mem_write(list_entry + 8, list_entry.to_bytes(8, "little")) + self.ldr_entries: list[LdrDataTableEntry] = [] self.name: str = name self.base: int = base self.pid: int = self.id diff --git a/tests/test.json b/tests/test.json index 024b9b67..bc242a05 100644 --- a/tests/test.json +++ b/tests/test.json @@ -296,16 +296,16 @@ ], "user_modules": [ - { - "name": "kernel32", - "base_addr": "0x77000000", - "path": "C:\\Windows\\system32\\kernel32.dll" - }, { "name": "ntdll", "base_addr": "0x7C000000", "path": "C:\\Windows\\system32\\ntdll.dll" }, + { + "name": "kernel32", + "base_addr": "0x77000000", + "path": "C:\\Windows\\system32\\kernel32.dll" + }, { "name": "ws2_32",