Skip to content

Commit 34dd803

Browse files
henderkesclaude
andcommitted
Merge dev: emulation re-JIT flush, unhook fallthrough, teardown safety (v1.9.0.3)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2 parents 13abd4e + f420bbd commit 34dd803

3 files changed

Lines changed: 18 additions & 1 deletion

File tree

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ endif()
1212
set(VERSION_MAJOR 1)
1313
set(VERSION_MINOR 9)
1414
set(VERSION_PATCH 0)
15-
set(VERSION_TWEAK 2)
15+
set(VERSION_TWEAK 3)
1616

1717
set(VERSION_RC "${CMAKE_CURRENT_BINARY_DIR}/version.rc")
1818
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/version.rc.in" "${VERSION_RC}" @ONLY)

source/D3D9Hooks.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ namespace {
3232
// --- IDirect3D*Texture9 (IUnknown layout) ---------------------------
3333
constexpr int kResource_Release = 2;
3434

35+
// Bytes to flush from a hook target / trampoline so the x86-on-ARM64 emulator re-JITs
36+
// it. Covers MinHook's max prologue patch and its 64-byte trampoline slot.
37+
constexpr SIZE_T kFlushSpan = 64;
38+
3539
void** GetVTable(void* com_object)
3640
{
3741
return *static_cast<void***>(com_object);
@@ -98,6 +102,13 @@ namespace {
98102
Warning("D3D9Hooks: MH_EnableHook failed for %p\n", target);
99103
return false;
100104
}
105+
// Under the x86-on-ARM64 emulator, patched code is only re-translated when its
106+
// instruction cache is flushed. MinHook flushes just the 5 patched bytes, which can
107+
// leave a stale/guarded JIT block and trap; flush the whole prologue and the freshly
108+
// built trampoline so the emulator re-JITs both. No-op on native x86.
109+
const HANDLE proc = GetCurrentProcess();
110+
FlushInstructionCache(proc, target, kFlushSpan);
111+
if (original && *original) FlushInstructionCache(proc, *original, kFlushSpan);
101112
g_hooked_targets.push_back(target);
102113
return true;
103114
}
@@ -361,9 +372,11 @@ void RemoveAllD3D9Hooks()
361372
// Signal first: a detour reached after this (e.g. a surviving patch) falls through.
362373
g_unhooked = true;
363374

375+
const HANDLE proc = GetCurrentProcess();
364376
for (void* target : g_hooked_targets) {
365377
MH_DisableHook(target);
366378
MH_RemoveHook(target);
379+
FlushInstructionCache(proc, target, kFlushSpan); // re-JIT the restored prologue under emulation
367380
}
368381
g_hooked_targets.clear();
369382

source/dll_main.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,10 @@ void InitInstance(HINSTANCE hModule)
252252
if (GetProcAddress_fn) {
253253
MH_CreateHook(GetProcAddress_fn, OnGetProcAddress, (void**)&GetProcAddress_ret);
254254
MH_EnableHook(GetProcAddress_fn);
255+
// Re-JIT the patched prologue + trampoline under the x86-on-ARM64 emulator (no-op native).
256+
const HANDLE proc = GetCurrentProcess();
257+
FlushInstructionCache(proc, (void*)GetProcAddress_fn, 64);
258+
if (GetProcAddress_ret) FlushInstructionCache(proc, (void*)GetProcAddress_ret, 64);
255259
}
256260
}
257261

0 commit comments

Comments
 (0)