https://bugs.winehq.org/show_bug.cgi?id=43656
Anastasius Focht focht@gmx.net changed:
What |Removed |Added ---------------------------------------------------------------------------- CC| |focht@gmx.net Component|-unknown |ntdll Ever confirmed|0 |1 URL| |https://eu.battle.net/accou | |nt/download/ Keywords| |download, obfuscation Status|UNCONFIRMED |NEW Summary|World of Warcraft crash on |64-bit World of Warcraft |startup with stack overflow |client reports 'Game | |Initialization Failed!' or | |crashes on startup with | |stack overflow due to | |improper mapping of | |exception code
--- Comment #13 from Anastasius Focht focht@gmx.net --- Hello folks,
confirming.
Relevant part of trace log:
--- snip --- $ pwd /home/focht/wine-games/wineprefix64-bnet/drive_c/Program Files (x86)/World of Warcraft
$ WINEDEBUG=+seh,+relay,+ntdll wine ./Wow-64.exe >>log2.txt 2>&1 ... 002a:Call TLS callback (proc=0x1400039c0,module=0x140000000,reason=PROCESS_ATTACH,reserved=0) 002a:Call KERNEL32.VirtualProtect(14129b430,00000110,00000004,0023e468,) ret=140004f3e 002a:Ret KERNEL32.VirtualProtect() retval=00000001 ret=140004f3e 002a:Call KERNEL32.VirtualProtect(14129b430,00000110,00000002,0023e480,) ret=1400051da 002a:Ret KERNEL32.VirtualProtect() retval=00000001 ret=1400051da 002a:Ret TLS callback (proc=0x140373710,module=0x140000000,reason=PROCESS_ATTACH,reserved=0) 002a:Call TLS callback (proc=0x14000e530,module=0x140000000,reason=PROCESS_ATTACH,reserved=0) 002a:Call ntdll.RtlAddVectoredExceptionHandler(00000001,14002f870,) ret=14000c52b 002a:Ret ntdll.RtlAddVectoredExceptionHandler() retval=000419c0 ret=14000c52b 002a:trace:seh:NtRaiseException code=c0000005 flags=0 addr=0x14000c5df ip=14000c5df tid=002a 002a:trace:seh:NtRaiseException rax=0000000000000055 rbx=0000000000000000 rcx=000000007bdb321f rdx=000000007bdb31d0 002a:trace:seh:NtRaiseException rsi=000000007bd97758 rdi=0000000000003a68 rbp=000000000023dd70 rsp=000000000023dd20 002a:trace:seh:NtRaiseException r8=0000000000000009 r9=000000014000c52b r10=0000000000000000 r11=0000000000000246 002a:trace:seh:NtRaiseException r12=00000000fd25be65 r13=0000000000000000 r14=000000007bd95170 r15=000000007bd98a4c 002a:trace:seh:call_vectored_handlers calling handler at 0x14002f870 code=c0000005 flags=0 002a:trace:seh:call_vectored_handlers handler at 0x14002f870 returned 0 002a:trace:seh:RtlVirtualUnwind type 1 rip 14000c5df rsp 23dd20 002a:trace:seh:dump_unwind_info **** func c030-e52d 002a:trace:seh:dump_unwind_info unwind info at 0x14150e9bc flags 0 prolog 0xf7 bytes function 0x14000c030-0x14000e52d 002a:trace:seh:dump_unwind_info 0xf7: movq %r15,0x28(%rsp) 002a:trace:seh:dump_unwind_info 0xec: movq %r14,0x30(%rsp) 002a:trace:seh:dump_unwind_info 0xe7: movq %rdi,0x38(%rsp) 002a:trace:seh:dump_unwind_info 0xde: movq %rsi,0x40(%rsp) 002a:trace:seh:dump_unwind_info 0xd9: movq %rbx,0x48(%rsp) 002a:trace:seh:dump_unwind_info 0x16: subq $0x50,%rsp 002a:trace:seh:dump_unwind_info 0xf: pushq %r13 002a:trace:seh:dump_unwind_info 0xd: pushq %r12 002a:trace:seh:dump_unwind_info 0xb: pushq %rbp 002a:trace:seh:RtlVirtualUnwind type 1 rip 14000f2cb rsp 23dd90 002a:trace:seh:dump_unwind_info **** func e5a0-1562d 002a:trace:seh:dump_unwind_info unwind info at 0x14150e9f4 flags 0 prolog 0x30 bytes function 0x14000e5a0-0x14001562d ... 002a:trace:seh:call_stack_handlers found wine frame 0x23e630 rsp 23e790 handler 0x7bd4a517 002a:trace:seh:call_teb_handler calling TEB handler 0x7bd4a517 (rec=0x23dbe0, frame=0x23e630 context=0x23ce90, dispatch=0x23d360) ... 002a:trace:seh:RtlRestoreContext returning to 7bd4a290 stack 23e620 002a:exception in TLS callback (proc=0x14129b438,module=0x140000000,reason=PROCESS_ATTACH,reserved=0) 002a:Starting process L"C:\Program Files (x86)\World of Warcraft\Wow-64.exe" (entryproc=0x1400b4f50) 002a:trace:ntdll:NtQueryInformationProcess (0xffffffffffffffff,0x00000007,0x23fda8,0x00000008,(nil)) 002a: get_process_info( handle=ffffffff ) 002a: get_process_info() = 0 { pid=0029, ppid=0000, affinity=000000ff, peb=7fffffeaf000, start_time=1d3b2efbed2f538 (-0.0964970), end_time=0, exit_code=259, priority=2, cpu=x86_64, debugger_present=0, debug_children=1 } 002a:Call user32.MessageBoxW(00000000,0023fd10 L"Game Initialization Failed!",0023fd00 L"ERROR",00000010,) ret=1400b55ec ... --- snip ---
The actual problem is not visible. One has to debug the code in the TLS callbacks which is another problem as 'winedbg' can't do this (unless one hacks Wine).
This is were 'x64dbg' (https://x64dbg.com/) comes handy which allows to stop in TLS callbacks before the entry point is called. Unfortunately it's also ridden with a number of Wine bugs that have to be worked around to be somewhat usable.
During execution of the second TLS callback, a vectored exception handler is installed which ought to handle privileged instructions and set trap flag to cause single step events.
--- snip --- ... 000000014000C511 48 05 89 .. add rax, FFFFFFFFFFFFF989 000000014000C517 48 89 45 .. mov qword ptr ss:[rbp+30], rax 000000014000C51B 48 8B 05 .. mov rax, qword ptr ds:[141813C50] 000000014000C522 48 8B 55 .. mov rdx, qword ptr ss:[rbp+30] 000000014000C526 49 33 C1 xor rax, r9 000000014000C529 FF D0 call rax ; ntdll.RtlAddVectoredExceptionHandler 000000014000C52B 48 89 05 .. mov qword ptr ds:[1418D6C00], rax 000000014000C532 48 85 C0 test rax, rax 000000014000C535 0F 84 CD .. je wow-64.14000E508 000000014000C53B 48 89 5D .. mov qword ptr ss:[rbp+30], rbx ... 000000014000C5D7 0F B6 45 .. movzx eax, byte ptr ss:[rbp+30] 000000014000C5DB 84 C0 test al, al 000000014000C5DD 74 B4 je wow-64.14000C593 000000014000C5DF F4 hlt ; <---- EXCEPTION_PRIV_INSTRUCTION 000000014000C5E0 4C 8B 5D .. mov r11, qword ptr ss:[rbp+20] ... --- snip ---
Unfortunately Wine's exception handling maps the 'hlt' instruction to EXCEPTION_ACCESS_VIOLATION which leads to a different code path in vectored handler which later leads to things going haywire.
It seems there was a typo introduced by:
https://source.winehq.org/git/wine.git/commitdiff/e1d68b2e169580be8dc6f8927e... ("ntdll: Implement handling of int $0x2d for x86_64.")
https://source.winehq.org/git/wine.git/blob/39c8875ff8aa543eaa50e52db0c54671...
--- snip --- 2750 static void segv_handler( int signal, siginfo_t *siginfo, void *sigcontext ) 2751 { 2752 EXCEPTION_RECORD *rec; 2753 ucontext_t *ucontext = sigcontext; ... 2770 rec = setup_exception( sigcontext, raise_segv_exception ); 2771 if (rec->ExceptionCode == EXCEPTION_STACK_OVERFLOW) return; 2772 2773 switch(TRAP_sig(ucontext)) 2774 { ... 2789 case TRAP_x86_UNKNOWN: /* Unknown fault code */ 2790 { 2791 CONTEXT *win_context = get_exception_context( rec ); 2792 WORD err = ERROR_sig(ucontext); 2793 if ((err & 7) == 2 && handle_interrupt( err >> 3, rec, win_context )) break; 2794 rec->ExceptionCode = err ? EXCEPTION_ACCESS_VIOLATION : EXCEPTION_PRIV_INSTRUCTION; 2795 rec->ExceptionCode = EXCEPTION_ACCESS_VIOLATION; 2796 } 2797 break; --- snip ---
Line 2795 has to be removed.
Fixing this will likely fix a number of apps and games that depend on proper privileged instruction handling (part of DRM schemes -> decrypt, anti-debugging etc.).
NOTE: With this fix applied the entry point is successfully reached and the client runs further but ends up in other bugs I've already documented for Diablo III (bug 44585 , bug 44616 , bug 44617)
$ wine --version wine-3.3
Regards