diff options
| author | André Zwing <nerv@dawncrow.de> | 2025-05-25 18:36:14 +0200 |
|---|---|---|
| committer | André Zwing <nerv@dawncrow.de> | 2025-05-25 21:41:23 +0200 |
| commit | e09adad1b9db271d3f3add3abe6bf1ae3659d0aa (patch) | |
| tree | 4794a386575390268a9a7d9ca19a6e32d9888d12 | |
| parent | b6429edf0975f54c533a4a46a7fe332396a3a781 (diff) | |
| download | box64-e09adad1b9db271d3f3add3abe6bf1ae3659d0aa.tar.gz box64-e09adad1b9db271d3f3add3abe6bf1ae3659d0aa.zip | |
[WOW64] Partially implement BTCpuResetToConsistentState
| -rw-r--r-- | wow64/compiler.h | 1 | ||||
| -rw-r--r-- | wow64/wowbox64.c | 34 |
2 files changed, 34 insertions, 1 deletions
diff --git a/wow64/compiler.h b/wow64/compiler.h index e30691fd..a7bf71a7 100644 --- a/wow64/compiler.h +++ b/wow64/compiler.h @@ -18,6 +18,7 @@ typedef struct _WOW64_CPURESERVED NTSTATUS WINAPI RtlWow64GetCurrentCpuArea(USHORT *, void **, void **); NTSTATUS WINAPI Wow64SystemServiceEx(UINT, UINT*); NTSYSAPI NTSTATUS WINAPI LdrGetDllHandle(LPCWSTR, ULONG, const UNICODE_STRING*, HMODULE*); +NTSYSAPI NTSTATUS WINAPI NtContinue(PCONTEXT, BOOLEAN); NTSYSAPI void* WINAPI RtlFindExportedRoutineByName(HMODULE, const char*); NTSYSAPI void DECLSPEC_NORETURN WINAPI RtlRaiseStatus(NTSTATUS); diff --git a/wow64/wowbox64.c b/wow64/wowbox64.c index 6f7f8b46..67cac41b 100644 --- a/wow64/wowbox64.c +++ b/wow64/wowbox64.c @@ -12,6 +12,7 @@ #include "compiler.h" #include "os.h" #include "custommem.h" +#include "dynablock.h" #include "env.h" #include "emu/x64emu_private.h" #include "emu/x87emu_private.h" @@ -166,9 +167,40 @@ STATIC_ASSERT(offsetof(x64emu_t, win64_teb) == 3120, offset_of_b_must_be_4); return STATUS_SUCCESS; } +static uint8_t box64_is_addr_in_jit(void* addr) +{ + if (!addr) + return FALSE; + return !!FindDynablockFromNativeAddress(addr); +} + NTSTATUS WINAPI BTCpuResetToConsistentState(EXCEPTION_POINTERS* ptrs) { - // NYI + x64emu_t *emu = NtCurrentTeb()->TlsSlots[0]; // FIXME + EXCEPTION_RECORD *rec = ptrs->ExceptionRecord; + CONTEXT *ctx = ptrs->ContextRecord; + + if (rec->ExceptionCode == EXCEPTION_ACCESS_VIOLATION) + { + dynablock_t *db = NULL; + void* addr = NULL; + uint32_t prot; + + if (rec->NumberParameters == 2 && rec->ExceptionInformation[0] == 1) + addr = ULongToPtr(rec->ExceptionInformation[1]); + + if (addr) + { + unprotectDB((uintptr_t)addr, 1, 1); // unprotect 1 byte... But then, the whole page will be unprotected + NtContinue(ctx, FALSE); + } + } + + if (!box64_is_addr_in_jit(ULongToPtr(ctx->Pc))) + return STATUS_SUCCESS; + + /* Replace the host context with one captured before JIT entry so host code can unwind */ + memcpy(ctx, NtCurrentTeb()->TlsSlots[WOW64_TLS_MAX_NUMBER], sizeof(*ctx)); return STATUS_SUCCESS; } |