https://bugs.winehq.org/show_bug.cgi?id=39454
--- Comment #18 from Anastasius Focht focht@gmx.net --- Hello folks,
although the patch prevents the crash in Wine code, allowing the launcher to run much further, it still fails - at the login procedure.
--- snip --- ... 0029:Ret PE DLL (proc=0x3cd0a8c0,module=0x3c910000 L"Battle.net-64.dll",reason=PROCESS_ATTACH,res=(nil)) retval=1 0029:Ret KERNEL32.LoadLibraryW() retval=3c910000 ret=141603362 0029:Call msvcr100.memset(0381b2b0,00000000,00000024) ret=140007960 0029:Ret msvcr100.memset() retval=0381b2b0 ret=140007960 0029:Call KERNEL32.GetProcAddress(3c910000,00000001) ret=1415ffb86 0029:Ret KERNEL32.GetProcAddress() retval=3c9868b0 ret=1415ffb86 0029:Call KERNEL32.GetProcAddress(3c910000,00000002) ret=1415ffba4 0029:Ret KERNEL32.GetProcAddress() retval=3c9869e0 ret=1415ffba4 0029:Call KERNEL32.GetProcAddress(3c910000,00000003) ret=1415ffbc2 0029:Ret KERNEL32.GetProcAddress() retval=3c986ad0 ret=1415ffbc2 0029:Call KERNEL32.GetProcAddress(3c910000,00000004) ret=1415ffbe0 0029:Ret KERNEL32.GetProcAddress() retval=3c9868d0 ret=1415ffbe0 0029:Call KERNEL32.IsDebuggerPresent() ret=3ccae65a 0029:Ret KERNEL32.IsDebuggerPresent() retval=00000000 ret=3ccae65a 0029:Call KERNEL32.LoadLibraryA(01f29ba0 "ntdll.dll") ret=3d9e2d08 0029:Ret KERNEL32.LoadLibraryA() retval=7fae1d280000 ret=3d9e2d08 0029:Call KERNEL32.GetProcAddress(7fae1d280000,01f29ba0 "NtQueryInformationProcess") ret=3d505c73 0029:Ret KERNEL32.GetProcAddress() retval=7fae1d284acc ret=3d505c73 0029:Call ntdll.NtQueryInformationProcess(ffffffffffffffff,0000001e,01f29c88,00000008,01f29cb4) ret=3d4ac0d3 0029:Ret ntdll.NtQueryInformationProcess() retval=c0000353 ret=3d4ac0d3 0029:Call KERNEL32.FreeLibrary(7fae1d280000) ret=3ca418ac 0029:Ret KERNEL32.FreeLibrary() retval=00000001 ret=3ca418ac 0029:Call KERNEL32.SetThreadContext(fffffffffffffffe,01f29980) ret=3ca7254b 0029: set_thread_context( handle=fffffffe, suspend=1, context={cpu=x86_64,dr0=3c9abbc0,dr1=3ca94610,dr2=3ca2e920,dr3=3ca2ec00,dr6=00000000,dr7=00000155} ) 0029: *signal* signal=19 0029: set_thread_context() = 0 { self=1 } 0029:fixme:seh:set_cpu_context setting debug registers not supported 0029:Ret KERNEL32.SetThreadContext() retval=00000001 ret=3ca7254b ... 0029:Call KERNEL32.GetThreadContext(fffffffffffffffe,01f27310) ret=3ca7289a 0029:Ret KERNEL32.GetThreadContext() retval=00000001 ret=3ca7289a 0029:Call msvcr100.memset(12387870,00000000,00000014) ret=140007960 0029:Ret msvcr100.memset() retval=12387870 ret=140007960 0029:Call msvcr100.memset(17357530,00000000,00000014) ret=140007960 0029:Ret msvcr100.memset() retval=17357530 ret=140007960 0029:Call msvcr100.memset(1228e9e0,00000000,00000014) ret=140007960 0029:Ret msvcr100.memset() retval=1228e9e0 ret=140007960 0029:Call msvcr100._beginthreadex(00000000,00004000,3ccb3010,1228e9e0,100000000,17357538) ret=3ccb312e 0029:Call KERNEL32.CreateThread(00000000,00004000,3ccb3010,1228e9e0,00000000,17357538) ret=7fae14e0695b 0029: *fd* 236 <- 279 0029: new_thread( access=001fffff, attributes=00000000, suspend=1, request_fd=236 ) 0029: new_thread() = 0 { tid=0052, handle=04a0 } 0029: resume_thread( handle=04a0 ) 0029: resume_thread() = 0 { count=1 } 0029:Ret KERNEL32.CreateThread() retval=000004a0 ret=7fae14e0695b 0052: *fd* 238 <- 283 0029:Ret msvcr100._beginthreadex() retval=000004a0 ret=3ccb312e 0052: *fd* 240 <- 284 0029:Call KERNEL32.WaitForSingleObject(000004a0,ffffffff) ret=3ccb319f 0052: init_thread( unix_pid=21794, unix_tid=22318, debug_level=1, teb=7ffffe028000, entry=3ccb3010, reply_fd=238, wait_fd=240, cpu=x86_64 ) 0052: init_thread() = 0 { pid=0028, tid=0052, server_start=1d134194f75f0e8 (-633.4852040), info_size=0, version=490, all_cpus=00000003 } 0029: select( flags=2, cookie=01f26cb4, timeout=infinite, prev_apc=0000, result={}, data={WAIT,handles={04a0}} ) 0029: select() = PENDING { timeout=infinite, call={APC_NONE}, apc_handle=0000 } 0052:Call PE DLL (proc=0x7fae16665fa1,module=0x7fae16570000 L"user32.dll",reason=THREAD_ATTACH,res=(nil)) ... 0052:Call PE DLL (proc=0x7fae114c11b8,module=0x7fae11460000 L"wininet.dll",reason=THREAD_ATTACH,res=(nil)) 0052:Ret PE DLL (proc=0x7fae114c11b8,module=0x7fae11460000 L"wininet.dll",reason=THREAD_ATTACH,res=(nil)) retval=1 0052:Starting thread proc 0x3ccb3010 (arg=0x1228e9e0) 0052:Call msvcr100.memset(0dbe32b0,00000000,00000034) ret=140007960 0052:Ret msvcr100.memset() retval=0dbe32b0 ret=140007960 0052:Call msvcr100.memset(0dd475a0,00000000,00020004) ret=140007960 0052:Ret msvcr100.memset() retval=0dd475a0 ret=140007960 0052:Call msvcr100.memset(0de59390,00000000,00005024) ret=140007960 0052:Ret msvcr100.memset() retval=0de59390 ret=140007960 0052:Call msvcr100.memset(0dbe32f0,00000000,00000024) ret=140007960 0052:Ret msvcr100.memset() retval=0dbe32f0 ret=140007960 0052:trace:seh:raise_exception code=c0000005 flags=0 addr=0xffffffffb3037b9b ip=ffffffffb3037b9b tid=0052 0052:trace:seh:raise_exception info[0]=0000000000000000 0052:trace:seh:raise_exception info[1]=ffffffffb3037b9b 0052:trace:seh:raise_exception rax=00000000de393e54 rbx=0000000012387870 rcx=0000000012387870 rdx=ffffffffb3037b9b 0052:trace:seh:raise_exception rsi=000000001228e9e0 rdi=000000003ca727d0 rbp=00000000051ee6b0 rsp=00000000051ee508 0052:trace:seh:raise_exception r8=0000000000000020 r9=0000000000000010 r10=0000000001190010 r11=00000000051ee4d8 0052:trace:seh:raise_exception r12=0000000001f26b3f r13=00000000051ef700 r14=0000000000000000 r15=0000000000000001 0052:trace:seh:call_vectored_handlers calling handler at 0x3ca730d0 code=c0000005 flags=0 ... 0052:trace:seh:call_stack_handlers found wine frame 0x51ee5b0 rsp 51ee6c0 handler 0x7fae1d340137 0052:trace:seh:call_teb_handler calling TEB handler 0x7fae1d340137 (rec=0x51ee3d0, frame=0x51ee5b0 context=0x51ed760, dispatcher=0x51ed228) 0052:Call KERNEL32.UnhandledExceptionFilter(051ed1d0) ret=7fae1d340191 ... --- snip ---
The code in 'Battle.net-64.dll' is highly obfuscated so it's hard to debug this garbage but it seems it relies on debug register values preserved and retrieved again (multiple times).
I cached the 64-bit context debug register Dr0-3, Dr6, Dr7 values on the client side (spare TEB area) to allow later 'GetThreadContext' calls to retain the values. Interestingly the actual 'on execute' hardware breakpoints are not hit after login so a real setting seems not needed here.
With that hack in place, further crashes are prevented and I successfully played some tutorial mission.
Regards