[Bug 25243] Microsoft Viva Pinata fails on startup (Wine-Gecko "SetThreadName" MSVC exception 0x406d1388 breaks SafeDisc debugger)

wine-bugs at winehq.org wine-bugs at winehq.org
Fri Apr 20 19:05:17 CDT 2012


http://bugs.winehq.org/show_bug.cgi?id=25243

Anastasius Focht <focht at gmx.net> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
            Summary|Viva Pinata fails           |Microsoft Viva Pinata fails
                   |installation and startup    |on startup (Wine-Gecko
                   |                            |"SetThreadName" MSVC
                   |                            |exception 0x406d1388 breaks
                   |                            |SafeDisc debugger)

--- Comment #21 from Anastasius Focht <focht at gmx.net> 2012-04-20 19:05:17 CDT ---
Hello,

I had the right feeling about this one ... bought the game for a few bugs and
it was delivered today :)

Two-disc version, installs fine (CD changes: 1-2-1) so the first part of this
bug is actually "fixed".

ProtectionID tool gives:

--- snip ---
-=[ ProtectionID v0.6.4.0 JULY]=-
(c) 2003-2010 CDKiLLER & TippeX
Build 07/08/10-17:57:05
Ready...

Scanning -> Z:\home\focht\.wine\drive_c\Program Files (x86)\Microsoft
Games\Viva Pinata\Startup.exe
File Type : 32-Bit Exe (Subsystem : Win GUI / 2), Size : 2010304 (01EACC0h)
Byte(s)
-> File Appears to be Digitally Signed @ Offset 01E88C0h, size : 02400h / 09216
byte(s)
-> File has 1444032 (01608C0h) bytes of appended data starting at offset
088000h
[File Heuristics] -> Flag : 00000000000000001100000000000111 (0x0000C007)
[!] Safedisc v4.81.000 detected !
[i] Appended data contents....
   [.] o: 0x00088028  / t: <0xA8726B03> <0xEF01996C> <0x00000001> / s: 00303952
byte(s) -> ~de02a3.tmp
   [.] o: 0x000D239F  / t: <0xA8726B03> <0xEF01996C> <0x0000044C> / s: 00015887
byte(s) -> clcd32.dll
   [.] o: 0x000D61D5  / t: <0xA8726B03> <0xEF01996C> <0x0000044C> / s: 00004123
byte(s) -> clcd16.dll
   [.] o: 0x000D7214  / t: <0xA8726B03> <0xEF01996C> <0x0000044D> / s: 00037971
byte(s) -> mcp.dll
   [.] o: 0x000E0690  / t: <0xA8726B03> <0xEF01996C> <0x0000000B> / s: 00005446
byte(s) -> SecDrv04.VxD
   [.] o: 0x000E1BFB  / t: <0xA8726B03> <0xEF01996C> <0x00000000> / s: 00072192
byte(s) -> ~e5.0001
   [.] o: 0x000F3622  / t: <0xA8726B03> <0xEF01996C> <0x00000000> / s: 00045056
byte(s) -> PfdRun.pfd
   [.] o: 0x000FE64A  / t: <0xA8726B03> <0xEF01996C> <0x00000000> / s: 00959004
byte(s) -> ~df394b.tmp
[CompilerDetect] -> Visual C++ 8.0 (Visual Studio 2005)
- Scan Took : 0.470 Second(s)

Scanning -> Z:\home\focht\.wine\drive_c\Program Files (x86)\Microsoft
Games\Viva Pinata\Viva Pinata.exe
File Type : 32-Bit Exe (Subsystem : Win GUI / 2), Size : 11056128 (0A8B400h)
Byte(s)
-> File Appears to be Digitally Signed @ Offset 0A89000h, size : 02400h / 09216
byte(s)
[File Heuristics] -> Flag : 00000000000000000000000000000100 (0x00000004)
[!] Games For Windows Live detected !
[CompilerDetect] -> Visual C++ 8.0 (Visual Studio 2005)
- Scan Took : 0.175 Second(s)
--- snip ---

The game exits on startup.

The reason is an unfortunate combination of SafeDisc's design (debugger +
debuggee) and Wine-Gecko engine being overly "helpful" with debugging hints.

When the game is started using the launcher it creates a second process by
design which acts as debugger to the first one (parent):

--- snip ---
0024:trace:process:__wine_kernel_init starting process name=L"C:\\Program Files
(x86)\\Microsoft Games\\Viva Pinata\\Startup.exe" argv[0]=L"C:\\Program Files
(x86)\\Microsoft Games\\Viva Pinata\\Startup.exe" 
...
0024:Call KERNEL32.CreateProcessA(0032f4a8
"C:\\users\\focht\\Temp\\~e5.0001",0032f5b0
"\"C:\\users\\focht\\Temp\\~e5.0001\" 35
\"C:\\users\\focht\\Temp\\\"\"~e5.0001.dir.0000\"",00000000,00000000,00000000,00000030,00000000,0032fc08
"C:\\users\\focht\\Temp\\",0032f460,0032f450) ret=00489eb9
0024:trace:process:create_process_impl app L"C:\\users\\focht\\Temp\\~e5.0001"
cmdline L"\"C:\\users\\focht\\Temp\\~e5.0001\" 35
\"C:\\users\\focht\\Temp\\\"\"~e5.0001.dir.0000\""
0024:trace:process:open_exe_file looking for
L"C:\\users\\focht\\Temp\\~e5.0001"
0024:trace:process:create_process_impl starting
L"C:\\users\\focht\\Temp\\~e5.0001" as Win32 binary (0x400000-0x416000)
...
0026:trace:loaddll:load_builtin_dll Loaded L"KERNEL32.dll" at 0x7b810000:
builtin
0026:Call KERNEL32.__wine_kernel_init() ret=7bc530d2
0026:trace:process:init_current_directory starting in
L"C:\\users\\focht\\Temp\\" 0x10
0026:trace:process:__wine_kernel_init starting process
name=L"C:\\users\\focht\\Temp\\~e5.0001"
argv[0]=L"C:\\users\\focht\\Temp\\~e5.0001"
0026:trace:loaddll:load_native_dll Loaded L"C:\\users\\focht\\Temp\\~e5.0001"
at 0x400000: native
0024:trace:process:create_process_impl started process pid 0025 tid 0026
0024:Ret  KERNEL32.CreateProcessA() retval=00000001 ret=00489eb9 
...
0026:Ret  KERNEL32.CreateThread() retval=0000003c ret=00402dbd 
...
0027:Starting thread proc 0x402cc2 (arg=0x416ee8)
...
0027:Call KERNEL32.DebugActiveProcess(00000023) ret=667ad4da
0027:Ret  KERNEL32.DebugActiveProcess() retval=00000001 ret=667ad4da 
...
0027:Call KERNEL32.WaitForDebugEvent(0062e3dc,ffffffff) ret=667ad513
0027:Ret  KERNEL32.WaitForDebugEvent() retval=00000001 ret=667ad513 
--- snip ---

The debugger expects events/exceptions from child as part of the software
protection.

For example when an int 3 (safedisc nanomite) is seen by debugger it checks
where exception occurred.
The debugger decides if the opcode is to be emulated or decrypted by using
WriteProcessMemory (writing the original opcode back to child address space and
re-executing code).

--- snip ---
...
0024:trace:seh:raise_exception code=80000003 flags=0 addr=0x404ca1 ip=00404ca2
tid=0024
0024:trace:seh:raise_exception  eax=00000001 ebx=00000001 ecx=00000000
edx=00000000 esi=0047e2ac edi=0043f4e0
0024:trace:seh:raise_exception  ebp=0032fd94 esp=0032fd68 cs=0023 ds=002b
es=002b fs=0063 gs=006b flags=00000206
0027:Ret  KERNEL32.WaitForDebugEvent() retval=00000001 ret=667ad5b4
0027:Call ntdll.RtlAllocateHeap(00630000,00000000,000002ec) ret=6678eca6
0027:Ret  ntdll.RtlAllocateHeap() retval=006499b0 ret=6678eca6
0027:Call KERNEL32.GetVersionExA(0062e330) ret=667ae700
0027:Ret  KERNEL32.GetVersionExA() retval=00000001 ret=667ae700
0027:Call KERNEL32.GetThreadContext(00000078,006499c0) ret=667ae2cf
0027:Ret  KERNEL32.GetThreadContext() retval=00000001 ret=667ae2cf
0027:Call ntdll.RtlAllocateHeap(00630000,00000000,00000008) ret=6678eca6
0027:Ret  ntdll.RtlAllocateHeap() retval=0064ac08 ret=6678eca6
0027:Call ntdll.RtlAllocateHeap(00630000,00000000,00000008) ret=6678eca6
0027:Ret  ntdll.RtlAllocateHeap() retval=0064ac80 ret=6678eca6
0027:Call
KERNEL32.ReadProcessMemory(00000074,00404ca0,0062de40,00000010,0062dab0)
ret=667adf40
0027:Ret  KERNEL32.ReadProcessMemory() retval=00000001 ret=667adf40
0027:Call
KERNEL32.WriteProcessMemory(00000074,00404ca1,0062dea4,00000002,0062dab0)
ret=667adefb
0027:Ret  KERNEL32.WriteProcessMemory() retval=00000001 ret=667adefb
...
0027:Call KERNEL32.FlushInstructionCache(00000074,00404ca1,00000008)
ret=667ae4f5
0027:Ret  KERNEL32.FlushInstructionCache() retval=00000001 ret=667ae4f5
0027:Call KERNEL32.SetThreadContext(00000078,006499c0) ret=667ae29d
0027:Ret  KERNEL32.SetThreadContext() retval=00000001 ret=667ae29d
0027:Call ntdll.RtlAllocateHeap(00630000,00000000,00000080) ret=6678eca6
0027:Ret  ntdll.RtlAllocateHeap() retval=0064acb8 ret=6678eca6
0027:Call KERNEL32.GetModuleHandleA(0064acb8 "Kernel32") ret=6674f76d
0027:Ret  KERNEL32.GetModuleHandleA() retval=7b810000 ret=6674f76d
0027:Call ntdll.RtlFreeHeap(00630000,00000000,0064acb8) ret=6678ea06
0027:Ret  ntdll.RtlFreeHeap() retval=00000001 ret=6678ea06
0027:Call ntdll.RtlAllocateHeap(00630000,00000000,00000080) ret=6678eca6
0027:Ret  ntdll.RtlAllocateHeap() retval=0064acb8 ret=6678eca6
0027:Call ntdll.RtlFreeHeap(00630000,00000000,0064acb8) ret=6678ea06
0027:Ret  ntdll.RtlFreeHeap() retval=00000001 ret=6678ea06
0027:Call KERNEL32.ContinueDebugEvent(00000023,00000024,00010002) ret=6675f9eb
0027:Ret  KERNEL32.ContinueDebugEvent() retval=00000001 ret=6675f9eb
0027:Call ntdll.RtlFreeHeap(00630000,00000000,006499b0) ret=6678ea06
0027:Ret  ntdll.RtlFreeHeap() retval=00000001 ret=6678ea06
0027:Call KERNEL32.WaitForDebugEvent(0062e3dc,ffffffff) ret=667ad5b4 
--- snip ---

This works as designed.

Consider the following snippet when the Wine-Gecko engine is loaded:

--- snip ---
0024:Call mshtml.DllGetClassObject(0032ca08,7e5ea4ec,0032c8bc) ret=7e50ac12
0024:trace:mshtml:DllGetClassObject (CLSID_HTMLDocument
{00000001-0000-0000-c000-000000000046} 0x32c8bc)
...
0024:trace:mshtml:load_gecko ()
...
0024:trace:mshtml:check_version "Wine Gecko 1.5"
0024:trace:mshtml:load_xul
(L"C:\\windows\\syswow64\\gecko\\1.5\\wine_gecko\\\\xul.dll") 
...
0024:Call KERNEL32.LoadLibraryExW(0032c284
L"C:\\windows\\syswow64\\gecko\\1.5\\wine_gecko\\\\xul.dll",00000000,00000008)
ret=7d2e1b86
0027:Ret  KERNEL32.WaitForDebugEvent() retval=00000001 ret=667ad5b4 
...
0027:Call KERNEL32.ContinueDebugEvent(00000023,00000024,00010002) ret=6675f9eb
0027:Ret  KERNEL32.ContinueDebugEvent() retval=00000001 ret=6675f9eb
0027:Call ntdll.RtlFreeHeap(00630000,00000000,0064ac08) ret=6678ea06
0027:Ret  ntdll.RtlFreeHeap() retval=00000001 ret=6678ea06
0027:Call KERNEL32.WaitForDebugEvent(0062e3dc,ffffffff) ret=667ad5b4
0024:trace:loaddll:load_builtin_dll Loaded L"C:\\windows\\system32\\msvcrt.dll"
at 0x7d1c0000: builtin
0027:Ret  KERNEL32.WaitForDebugEvent() retval=00000001 ret=667ad5b4 
...
002d:Call KERNEL32.IsDebuggerPresent() ret=6a89b761
002d:Ret  KERNEL32.IsDebuggerPresent() retval=00000001 ret=6a89b761
002d:Call KERNEL32.GetCurrentThreadId() ret=6a89b723
002d:Ret  KERNEL32.GetCurrentThreadId() retval=0000002d ret=6a89b723
002d:Call KERNEL32.RaiseException(406d1388,00000000,00000004,00f2e8e0)
ret=6a89b7ab
002d:trace:seh:raise_exception code=406d1388 flags=0 addr=0x7b839357
ip=7b839357 tid=002d
002d:trace:seh:raise_exception  info[0]=00001000
002d:trace:seh:raise_exception  info[1]=00160584
002d:trace:seh:raise_exception  info[2]=0000002d
002d:trace:seh:raise_exception  info[3]=00000000
002d:trace:seh:raise_exception  eax=7b826381 ebx=7b8aa728 ecx=00000000
edx=00f2e814 esi=00f2e8e0 edi=00f2e860
002d:trace:seh:raise_exception  ebp=00f2e848 esp=00f2e7e4 cs=0023 ds=002b
es=002b fs=0063 gs=006b flags=00000283
--- snip ---

Gecko checks if a debugger is present/active and issues a special
"SetThreadName" msvc exception (code 0x406d1388) because it assumes there is
someone who debugs the process.
Unfortunately it's not the user but SafeDisc itself which acts as debugger by
design.

--- snip ---
0027:Ret  KERNEL32.WaitForDebugEvent() retval=00000001 ret=667ad5b4 
...
0027:Call KERNEL32.ContinueDebugEvent(00000023,0000002d,80010001) ret=6675f9eb
0027:Ret  KERNEL32.ContinueDebugEvent() retval=00000001 ret=6675f9eb
0027:Call ntdll.RtlFreeHeap(00630000,00000000,0064b3f8) ret=6678ea06
0027:Ret  ntdll.RtlFreeHeap() retval=00000001 ret=6678ea06
0027:Call KERNEL32.WaitForDebugEvent(0062e3dc,ffffffff) ret=667ad5b4
002d:trace:seh:call_stack_handlers calling handler at 0x7bc91b99 code=406d1388
flags=0
002d:Call KERNEL32.UnhandledExceptionFilter(00f2e2b4) ret=7bc91bd3
002d:Ret  KERNEL32.UnhandledExceptionFilter() retval=00000000 ret=7bc91bd3
002d:trace:seh:call_stack_handlers handler at 0x7bc91b99 returned 1
0027:Ret  KERNEL32.WaitForDebugEvent() retval=00000001 ret=667ad5b4 
...
0027:Call KERNEL32.WaitForDebugEvent(0062e3dc,ffffffff) ret=667ad5b4
002d:err:seh:raise_exception Unhandled exception code 406d1388 flags 0 addr
0x7b839357
0027:Ret  KERNEL32.WaitForDebugEvent() retval=00000001 ret=667ad5b4 
--- snip ---

The SafeDisc debugger doesn't expect this legacy exception and can't handle it
-> processes get terminated.

For testing I modified the code (ntdll) to swallow this exception and it helps:
the game launcher runs further and shows html-based GUI.

One approach could be to modify Wine-Gecko to not issue this exception either
by disabling this feature in Wine-Gecko builds or providing config option to
turn it off.
Actually I don't see much benefit in having some named threads when debugging
applications that load Gecko engine.

$ wine --version
wine-1.5.2-191-gd080774

Regards

-- 
Configure bugmail: http://bugs.winehq.org/userprefs.cgi?tab=email
Do not reply to this email, post in Bugzilla using the
above URL to reply.
------- You are receiving this mail because: -------
You are watching all bug changes.



More information about the wine-bugs mailing list