@@ -455,8 +455,34 @@ def _setup_memory(self):
455
455
456
456
def _setup_pebteb (self , thread ):
457
457
self .teb = thread .Teb & 0xFFFFFFFFFFFFF000
458
- self .wow64 = self .modules ["ntdll.dll" ].find_export ("Wow64Transition" ) is not None
459
458
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
460
486
for i in range (0 , len (self ._minidump .threads .threads )):
461
487
thread = self ._minidump .threads .threads [i ]
462
488
teb = thread .Teb & 0xFFFFFFFFFFFFF000
@@ -800,21 +826,13 @@ def _setup_modules(self):
800
826
def _setup_syscalls (self ):
801
827
# Load the ntdll module from memory
802
828
ntdll = self .modules ["ntdll.dll" ]
829
+ self .KiUserExceptionDispatcher = ntdll .find_export ("KiUserExceptionDispatcher" ).address
830
+ self .LdrLoadDll = ntdll .find_export ("LdrLoadDll" ).address
831
+
803
832
nt_syscalls = []
804
833
for export in ntdll .exports :
805
834
if export .name and export .name .startswith ("Zw" ):
806
835
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
818
836
819
837
def add_syscalls (syscalls , table ):
820
838
# The index when sorting by RVA is the syscall index
@@ -1493,6 +1511,8 @@ def _arg_type_string(arg):
1493
1511
return type (arg ).__name__
1494
1512
1495
1513
def _hook_interrupt (uc : Uc , number , dp : Dumpulator ):
1514
+ if dp .trace :
1515
+ dp .trace .flush ()
1496
1516
try :
1497
1517
# Extract exception information
1498
1518
exception = UnicornExceptionInfo ()
@@ -1643,6 +1663,8 @@ def _emulate_unsupported_instruction(dp: Dumpulator, instr: CsInsn):
1643
1663
1644
1664
def _hook_invalid (uc : Uc , dp : Dumpulator ):
1645
1665
address = dp .regs .cip
1666
+ if dp .trace :
1667
+ dp .trace .flush ()
1646
1668
# HACK: unicorn cannot gracefully exit in all contexts
1647
1669
if dp .kill_me :
1648
1670
dp .error (f"terminating emulation..." )
0 commit comments