International Rally Championship executes cli on startup and sti on exit, this currently crashes as an exception is thrown and isn't handled by the game.
The ntdll:exception tests show that an exception is thrown on x86_64, i386 and WOW64 mode, however the game also runs fine when executed in a Windows 10 64bit VM (with 640x480 16bpp compatibility mode). It crashes when run in a Windows 8 32bit VM, so possibly something WOW64 related swallows the exception.
From: Rémi Bernon rbernon@codeweavers.com
International Rally Championship executes cli on startup and sti on exit, this currently crashes as an exception is thrown and isn't handled by the game.
The ntdll:exception tests show that an exception is thrown on x86_64, i386 and WOW64 mode, however the game also runs fine when executed in a Windows 10 64bit VM (with 640x480 16bpp compatibility mode). It crashes when run in a Windows 8 32bit VM, so possibly something WOW64 related swallows the exception.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=57381 --- dlls/kernelbase/debug.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+)
diff --git a/dlls/kernelbase/debug.c b/dlls/kernelbase/debug.c index cbefc0c8733..e49fa3dcb6e 100644 --- a/dlls/kernelbase/debug.c +++ b/dlls/kernelbase/debug.c @@ -761,6 +761,42 @@ LONG WINAPI UnhandledExceptionFilter( EXCEPTION_POINTERS *epointers ) if (ret != EXCEPTION_CONTINUE_SEARCH) return ret; }
+#ifndef _WIN64 + if (rec->ExceptionCode == EXCEPTION_PRIV_INSTRUCTION && is_wow64) + { + BYTE *instr = rec->ExceptionAddress, prefix_len = 0; + CONTEXT *ctx = epointers->ContextRecord; + + for (;;) switch (*instr++) + { + /* instruction prefixes */ + case 0x2e: /* %cs: */ + case 0x36: /* %ss: */ + case 0x3e: /* %ds: */ + case 0x26: /* %es: */ + case 0x64: /* %fs: */ + case 0x65: /* %gs: */ + case 0x66: /* opcode size */ + case 0x67: /* addr size */ + case 0xf0: /* lock */ + case 0xf2: /* repne */ + case 0xf3: /* repe */ + if (++prefix_len >= 15) break; + continue; + case 0x0f: /* extended instruction */ + break; + + case 0xfa: /* cli */ + case 0xfb: /* sti */ + WARN( "Ignoring privileged instruction exception\n" ); + ctx->Eip += prefix_len + 1; + return EXCEPTION_CONTINUE_EXECUTION; + default: + break; + } + } +#endif + if ((GetErrorMode() & SEM_NOGPFAULTERRORBOX) || !start_debugger_atomic( epointers ) || !NtCurrentTeb()->Peb->BeingDebugged) return EXCEPTION_EXECUTE_HANDLER;
Shouldn't this code be guarded behind a i386 define (because it deals directly with that architecture)?
This merge request was closed by Rémi Bernon.
This is incorrect, a simple application that does `cli` crashes right away with an error on Windows. Still, somehow, that game just works...
I encountered the same with Slave Zero game lately. The behaviour to catch cli / sti (and maybe other subset of privileged instructions, I tested only these) is trigered on modern Windows by setting Win98 compat. In that game it was achieved by setting `<fulldirpath>\SlaveZero.exe" string value to "WIN98 RUNASADMIN HIGHDPIAWARE"" to registry key `HKEY_CURRENT_USER\Software\Microsoft\WindowsNT\CurrentVersion\AppCompatFlags\Layers`. It is Win98 part which matters here. That works for 32 bit code only. For that game setting this registry was done by Steam during game setup. It should probably also be possible to achieve with Compatibility Tool Administrator. I guess that for this game either something in its installer does that or it is in the shim database.
With some testing around (adding various exception handlers) it works through PE side vectored exception handler. That is probably installed by one of generic shim dlls Windows loads when compat options are used.
For International Rally Championship, it works without setting WIN98 compat. Only the 640x480 16bpp compat flags are required. In addition, setting the same flags on a test executable that simply executes `cli` is not enough and it crashes with an unhandled exception, so it's not something that's triggered by those flags but something else here.
Yes, those compat flags are not related, then more likely it has some other way to trigger it (something in exe or else, some game-installed compat profile??).
Yes I was thinking something in the EXE header but I haven't spent much time looking into it, or perhaps some of the DLLs the game is using. There is no real installation procedure for that game.