Skip to content

Commit 6cf51ec

Browse files
committed
Support WoW64 for Windows Builds < 14393
1 parent 213ed21 commit 6cf51ec

File tree

1 file changed

+30
-12
lines changed

1 file changed

+30
-12
lines changed

src/dumpulator/dumpulator.py

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -455,8 +455,34 @@ def _setup_memory(self):
455455

456456
def _setup_pebteb(self, thread):
457457
self.teb = thread.Teb & 0xFFFFFFFFFFFFF000
458-
self.wow64 = self.modules["ntdll.dll"].find_export("Wow64Transition") is not None
459458

459+
# Handle WoW64 support
460+
def patch_wow64(patch_addr):
461+
# See: https://opcode0x90.wordpress.com/2007/05/18/kifastsystemcall-hook/
462+
# mov edx, esp; sysenter; ret
463+
KiFastSystemCall = b"\x8B\xD4\x0F\x34\x90\x90\xC3"
464+
self.write(patch_addr, KiFastSystemCall)
465+
self.wow64 = True
466+
467+
ntdll = self.modules["ntdll.dll"]
468+
Wow64Transition = ntdll.find_export("Wow64Transition")
469+
ZwWow64ReadVirtualMemory64 = ntdll.find_export("ZwWow64ReadVirtualMemory64")
470+
if Wow64Transition:
471+
# This exists from Windows 10 1607 (Build: 14393)
472+
patch_addr = self.read_ptr(Wow64Transition.address)
473+
self.info(f"Patching Wow64Transition: [{hex(Wow64Transition.address)}] -> {hex(patch_addr)}")
474+
patch_wow64(patch_addr)
475+
elif ZwWow64ReadVirtualMemory64:
476+
# This function exists since Windows XP
477+
# TODO: Implement by finding EA ???????? 3300 in wow64cpu.dll instead
478+
# Reference: https://github.com/x64dbg/ScyllaHide/blob/a727ac39/InjectorCLI/RemoteHook.cpp#L354-L434
479+
patch_addr = self.read_ptr(self.teb + 0xC0)
480+
self.error(f"Unsupported WoW64 OS version detected, trampoline: {hex(patch_addr)}")
481+
patch_wow64(patch_addr)
482+
else:
483+
self.wow64 = False
484+
485+
# Get thread information
460486
for i in range(0, len(self._minidump.threads.threads)):
461487
thread = self._minidump.threads.threads[i]
462488
teb = thread.Teb & 0xFFFFFFFFFFFFF000
@@ -800,21 +826,13 @@ def _setup_modules(self):
800826
def _setup_syscalls(self):
801827
# Load the ntdll module from memory
802828
ntdll = self.modules["ntdll.dll"]
829+
self.KiUserExceptionDispatcher = ntdll.find_export("KiUserExceptionDispatcher").address
830+
self.LdrLoadDll = ntdll.find_export("LdrLoadDll").address
831+
803832
nt_syscalls = []
804833
for export in ntdll.exports:
805834
if export.name and export.name.startswith("Zw"):
806835
nt_syscalls.append((export.address, export.name))
807-
elif export.name == "Wow64Transition":
808-
patch_addr = self.read_ptr(export.address)
809-
self.info(f"Patching Wow64Transition: {hex(export.address)} -> {hex(patch_addr)}")
810-
# See: https://opcode0x90.wordpress.com/2007/05/18/kifastsystemcall-hook/
811-
# mov edx, esp; sysenter; ret
812-
KiFastSystemCall = b"\x8B\xD4\x0F\x34\x90\x90\xC3"
813-
self.write(patch_addr, KiFastSystemCall)
814-
elif export.name == "KiUserExceptionDispatcher":
815-
self.KiUserExceptionDispatcher = export.address
816-
elif export.name == "LdrLoadDll":
817-
self.LdrLoadDll = export.address
818836

819837
def add_syscalls(syscalls, table):
820838
# The index when sorting by RVA is the syscall index

0 commit comments

Comments
 (0)