https://bugs.winehq.org/show_bug.cgi?id=36491
Bug ID: 36491 Summary: Theatre of War 3: Korea Demo hangs on start Product: Wine Version: 1.7.19 Hardware: x86 URL: http://www.gamershell.com/news_115056.html OS: Linux Status: NEW Keywords: download Severity: normal Priority: P2 Component: -unknown Assignee: wine-bugs@winehq.org Reporter: austinenglish@gmail.com Blocks: 26827
Created attachment 48567 --> https://bugs.winehq.org/attachment.cgi?id=48567 protection id log
Split from bug 26827. It's a regression, but not sure in what (wine/userland/kernel), as this bug didn't happen before with 1.3.15 and does now in a modern OS.
Anywho, the program installs fine, but hangs on startup.
ProtectionID says it has Gameshield, not sure if the original demo did (no sha1sum).
Scanning -> C:\Program Files\Battlefront\1C Company\Theatre of War 3 Korea - Trial Version\Korea.exe File Type : 32-Bit Exe (Subsystem : Win GUI / 2), Size : 2219832 (021DF38h) Byte(s) -> File Appears to be Digitally Signed @ Offset 021C528h, size : 01A10h / 06672 byte(s) -> File has 6 (06h) bytes of appended data starting at offset 021C522h [File Heuristics] -> Flag : 00000000000001001100000000100110 (0x0004C026) [Entrypoint Section Entropy] : 6.37 [!] Yummy Interactive GameShield/Software Shield Protection detected ! - Scan Took : 0.350 Second(s) [00000015Eh tick(s)] [533 scan(s) done]
[austin@localhost Theatre of War 3 Korea - Trial Version]$ sha1sum Korea.exe d5dc9dfd9b4a2100df53b85b25ff0c5668deeb3e Korea.exe
[austin@localhost 26827]$ sha1sum Theatre-of-War3_Korea_Trial_Version.exe 954a1704fd61a8971548af5c8ac218583ffe9d6c Theatre-of-War3_Korea_Trial_Version.exe [austin@localhost 26827]$ du -h Theatre-of-War3_Korea_Trial_Version.exe 1.7G Theatre-of-War3_Korea_Trial_Version.exe
https://bugs.winehq.org/show_bug.cgi?id=36491
--- Comment #1 from Austin English austinenglish@gmail.com --- +relay is tiny:
[austin@localhost Theatre of War 3 Korea - Trial Version]$ WINEDEBUG=relay,set,tid wine Korea.exe 0023:trace:relay:load_list L"RelayExclude" = L"ntdll.RtlEnterCriticalSection;ntdll.RtlLeaveCriticalSection;kernel32.48;kernel32.49;kernel32.94;kernel32.95;kernel32.96;kernel32.97;kernel32.98;kernel32.TlsGetValue;kernel32.TlsSetValue;kernel32.FlsGetValue;kernel32.FlsSetValue;kernel32.SetLastError" 0023:trace:relay:load_list L"RelayFromExclude" = L"winex11.drv;winemac.drv;user32;gdi32;advapi32;kernel32" 0023:Call KERNEL32.__wine_kernel_init() ret=7bc5a7b3 0023:Call PE DLL (proc=0x7bc966c0,module=0x7bc10000 L"ntdll.dll",reason=PROCESS_ATTACH,res=0x1) 0023:Ret PE DLL (proc=0x7bc966c0,module=0x7bc10000 L"ntdll.dll",reason=PROCESS_ATTACH,res=0x1) retval=1 0023:Call PE DLL (proc=0x7b8843c0,module=0x7b810000 L"KERNEL32.dll",reason=PROCESS_ATTACH,res=0x1) 0023:Ret PE DLL (proc=0x7b8843c0,module=0x7b810000 L"KERNEL32.dll",reason=PROCESS_ATTACH,res=0x1) retval=1 0023:Starting process L"C:\Program Files\Battlefront\1C Company\Theatre of War 3 Korea - Trial Version\Korea.exe" (entryproc=0x4025c8) 0023:Call KERNEL32.GetVersionExA(0032fda4) ret=0040246f 0023:Ret KERNEL32.GetVersionExA() retval=00000001 ret=0040246f 0023:Call KERNEL32.GetModuleHandleA(00000000) ret=004024c7 0023:Ret KERNEL32.GetModuleHandleA() retval=00400000 ret=004024c7
https://bugs.winehq.org/show_bug.cgi?id=36491
--- Comment #2 from Austin English austinenglish@gmail.com --- Linux localhost.localdomain 3.14.4-200.fc20.x86_64 #1 SMP Tue May 13 13:51:08 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux
[austin@localhost Theatre of War 3 Korea - Trial Version]$ gcc -v Using built-in specs. COLLECT_GCC=/usr/bin/gcc COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-redhat-linux/4.8.2/lto-wrapper Target: x86_64-redhat-linux Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-bootstrap --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --with-linker-hash-style=gnu --enable-languages=c,c++,objc,obj-c++,java,fortran,ada,go,lto --enable-plugin --enable-initfini-array --enable-java-awt=gtk --disable-dssi --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-1.5.0.0/jre --enable-libgcj-multifile --enable-java-maintainer-mode --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --disable-libjava-multilib --with-isl=/builddir/build/BUILD/gcc-4.8.2-20131212/obj-x86_64-redhat-linux/isl-install --with-cloog=/builddir/build/BUILD/gcc-4.8.2-20131212/obj-x86_64-redhat-linux/cloog-install --with-tune=generic --with-arch_32=i686 --build=x86_64-redhat-linux Thread model: posix gcc version 4.8.2 20131212 (Red Hat 4.8.2-7) (GCC)
http://bugs.winehq.org/show_bug.cgi?id=36491
Anastasius Focht focht@gmx.net changed:
What |Removed |Added ---------------------------------------------------------------------------- CC| |focht@gmx.net
--- Comment #3 from Anastasius Focht focht@gmx.net --- Hello Austin,
I can't reproduce this.
'korea.exe' is a launcher which displays some HTML window with buttons. Clicking 'play' results in 'korea.bin' being launched.
There is a crash later, still during startup (after 1 minute of loading) but it's an entirely different issue.
--- snip --- ... Available Texture Memory: 687Mb WWThreadPool.create(): Thread pool is created. Threads count = 0 Load gui skin from: Data/Settings/gui.ini #RTS: Unable to handle an exception.\n#RTS: Unable to handle an exception.\n#RTS: Unable to handle an exception.\n#RTS: Unable to handle an exception.\nfixme:dbghelp:elf_search_auxv can't find symbol in module wine: Unhandled exception 0xe06d7363 in thread 47 at address 0x7b83ac57 (thread 0047), starting debugger... --- snip ---
I'm using Fedora 19 x86 which has same base kernel:
--- snip --- $ uname -a Linux nexus4 3.14.4-100.fc19.x86_64 #1 SMP Tue May 13 15:00:26 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux --- snip ---
I guess something on your host is broken (Linux Kernel/libs, Wine, WINEPREFIX). Check with earlier kernel versions etc.
$ sha1sum Theatre-of-War3_Korea_Trial_Version.exe 954a1704fd61a8971548af5c8ac218583ffe9d6c Theatre-of-War3_Korea_Trial_Version.exe
$ du -sh Theatre-of-War3_Korea_Trial_Version.exe 1.7G Theatre-of-War3_Korea_Trial_Version.exe
$ wine --version wine-1.7.19-56-gee13e10
Regards
https://bugs.winehq.org/show_bug.cgi?id=36491
--- Comment #4 from Nikolay Sivov bunglehead@gmail.com --- I see exactly same output as in comment 1. I'm on Debian Testing, kernel 3.13.x.
https://bugs.winehq.org/show_bug.cgi?id=36491
--- Comment #5 from Anastasius Focht focht@gmx.net --- Hello Nikolay,
I switched to earlier Linux 3.13.x kernel version and it still works for me.
Please attach a +server,+relay log as follows:
Make sure there is no background process running prior: 'wineserver -k'
--- snip --- $ pwd /home/focht/.wine/drive_c/Program Files/Battlefront/1C Company/Theatre of War 3 Korea - Trial Version
$ WINEDEBUG=+tid,+seh,+relay,+server wine ./Korea.exe >>log.txt 2>&1 --- snip ---
At the point of hang: 'wineserver -k' from another terminal.
Regards
http://bugs.winehq.org/show_bug.cgi?id=36491
--- Comment #6 from Nikolay Sivov bunglehead@gmail.com --- Created attachment 48599 --> http://bugs.winehq.org/attachment.cgi?id=48599 +server,+relay,+seh,+tid
During a hang game process gets 100% on one core.
http://bugs.winehq.org/show_bug.cgi?id=36491
--- Comment #7 from Anastasius Focht focht@gmx.net --- Hello Nikolay,
--- quote --- During a hang game process gets 100% on one core. --- quote ---
This reminds me of bug 35041 (live-lock in libX11). Can you run with the processes pinned to one core -> 'taskset -c 0'?
Additionally can you generate a dump of all threads without 'taskset' ('winedbg' -> 'bt all') and attach the result. Thanks.
Regards
http://bugs.winehq.org/show_bug.cgi?id=36491
--- Comment #8 from Nikolay Sivov bunglehead@gmail.com --- (In reply to Anastasius Focht from comment #7)
Hello Nikolay,
--- quote --- During a hang game process gets 100% on one core. --- quote ---
This reminds me of bug 35041 (live-lock in libX11). Can you run with the processes pinned to one core -> 'taskset -c 0'?
It makes no difference. I did 'taskset -c 0 ~/devel/wine32/wine Korea.exe', not sure if it's a totally correct way to do that.
Additionally can you generate a dump of all threads without 'taskset' ('winedbg' -> 'bt all') and attach the result.
Sure, how to do that? I mean I'll need to 'attach' and 'bt', so I need to see winedbg output same time it needs to be logged. It might be basic shell usage question but still, I don't know how to redirect it that way.
Thanks.
Regards
http://bugs.winehq.org/show_bug.cgi?id=36491
--- Comment #9 from Anastasius Focht focht@gmx.net --- Hello Nikolay,
--- quote --- Sure, how to do that? I mean I'll need to 'attach' and 'bt', so I need to see winedbg output same time it needs to be logged. It might be basic shell usage question but still, I don't know how to redirect it that way. --- quote ---
there is no need to manually attach to a specific process. You can instruct 'winedbg' to backtrace every thread in every process using 'bt all'. There is a limitation though, this doesn't work for processes that are under control of another debugger (protection/DRM stuff).
The following command line should automate the task of dumping everything:
--- snip --- $ echo -e "info process\n info thread\n bt all\n" | winedbg &> log.txt --- snip ---
Regards
http://bugs.winehq.org/show_bug.cgi?id=36491
--- Comment #10 from Nikolay Sivov bunglehead@gmail.com --- Created attachment 48602 --> http://bugs.winehq.org/attachment.cgi?id=48602 bt all output
Thanks for guiding, log attached.
http://bugs.winehq.org/show_bug.cgi?id=36491
Anastasius Focht focht@gmx.net changed:
What |Removed |Added ---------------------------------------------------------------------------- Keywords| |obfuscation
--- Comment #11 from Anastasius Focht focht@gmx.net --- Hello folks,
I think I know where the problem is -> 'GameShield' brain damage (buggy protection code). Since I can't reproduce this here I need more data from you to prove my analysis :)
Please start the launcher with 'winedbg' and do the following after entry has been reached (debugger prompt shown):
--- snip --- $ winedbg ./Korea.exe
$ Wine-dbg>x/20x &ldr.InLoadOrderModuleList --- snip ---
Paste the output (memory dump), it should be pretty small.
Regards
http://bugs.winehq.org/show_bug.cgi?id=36491
--- Comment #12 from Nikolay Sivov bunglehead@gmail.com --- Here you go:
--- Wine-dbg>x/20x &ldr.InLoadOrderModuleList 0x7bce044c ldr+0xc: 00110800 00110200 00110808 00110160 0x7bce045c ldr+0x1c: 00110168 00110810 7ffdf000 00000000 0x7bce046c compl_port: 00000000 00000000 00000000 00000000 0x7bce047c num_workers: 00000000 00000000 00000000 00000000 0x7bce048c cached_tzi+0xc: 00000000 00000000 00000000 00000000 ---
http://bugs.winehq.org/show_bug.cgi?id=36491
--- Comment #13 from Anastasius Focht focht@gmx.net --- Hello folks,
after unwrapping in entry point, the protection code proceeds to do some harmless debugger checks and then starts bringing up the custom imports resolver.
It walks the OS loader internal InLoadOrderModuleList list, examines the entries, checking the dll base addresses for zero and a magic value 0xABABABAB. Unfortunately the protection code is buggy - it got the "last" entry condition wrong when doing list walking. Pretty stupid for such simple thing as walking a (double) linked list.
The last module entry 'FLink' points to 'ldr.InLoadOrderModuleList.FLink' (cyclic). The iterator code doesn't compare the pointer to list start but interprets the address as 'next' LDR_MODULE entry, looking at 'LDR_MODULE.BaseAddress':
--- snip --- typedef struct _PEB_LDR_DATA { ULONG Length; BOOLEAN Initialized; PVOID SsHandle; LIST_ENTRY InLoadOrderModuleList; LIST_ENTRY InMemoryOrderModuleList; LIST_ENTRY InInitializationOrderModuleList; } PEB_LDR_DATA, *PPEB_LDR_DATA;
...
typedef struct _LDR_MODULE { LIST_ENTRY InLoadOrderModuleList; LIST_ENTRY InMemoryOrderModuleList; LIST_ENTRY InInitializationOrderModuleList; void* BaseAddress; void* EntryPoint; ULONG SizeOfImage; UNICODE_STRING FullDllName; UNICODE_STRING BaseDllName; ULONG Flags; SHORT LoadCount; SHORT TlsIndex; HANDLE SectionHandle; ULONG CheckSum; ULONG TimeDateStamp; HANDLE ActivationContext; } LDR_MODULE, *PLDR_MODULE; --- snip ---
LDR_MODULE.BaseAddress lives at offset 0x18 (24 bytes for 3 LIST_ENTRY)
How Nikolay's memory dump looks rewritten:
sizeof(PEB_LDR_DATA) = 0x24
--- snip --- ldr+0x00 = PEB_LDR_DATA ... ldr+0x0c (+0x00): 00110800 ; InLoadOrderModuleList.FLink ldr+0x10 (+0x04): 00110200 ; InLoadOrderModuleList.BLink ldr+0x14 (+0x08): 00110808 ; InMemoryOrderModuleList.FLink ldr+0x18 (+0x0C): 00110160 ; InMemoryOrderModuleList.BLink ldr+0x1c (+0x10): 00110168 ; InInitializationOrderModuleList.FLink ldr+0x20 (+0x14): 00110810 ; InInitializationOrderModuleList.BLink <--- PEB_LDR_DATA ends here ---> ldr+0x24 (+0x18): 7ffdf000 ; *problem* ldr+0x28 (+0x1C): 00000000 ... --- snip ---
'ldr' is declared as 'static' module local variable (goes to '.bss' section). Placement/alignment with neighbouring objects matters.
In my case, the area following 'PEB_LDR_DATA' serves as alignment to next 16-byte boundary (zeroed at runtime) hence the protection code sees the exit condition 'LDR_MODULE.BaseAddress == 0' and proceeds further.
One can find 'PEB_LDR_DATA' definitions which carry an additional field:
http://www.nirsoft.net/kernel_struct/vista/PEB_LDR_DATA.html
--- quote --- typedef struct _PEB_LDR_DATA { ULONG Length; UCHAR Initialized; PVOID SsHandle; LIST_ENTRY InLoadOrderModuleList; LIST_ENTRY InMemoryOrderModuleList; LIST_ENTRY InInitializationOrderModuleList; PVOID EntryInProgress; } PEB_LDR_DATA, *PPEB_LDR_DATA; --- quote ---
It shouldn't harm if Wine adds this 'EntryInProgress' field - even if it's not going to be used. This field reserves/keeps the memory location which should work around the broken protection code.
@Nikolay / Austin:
Can you add this additional field and check if it helps?
Regards
http://bugs.winehq.org/show_bug.cgi?id=36491
--- Comment #14 from Nikolay Sivov bunglehead@gmail.com --- Yes, it helps. Thanks! It brings up a launcher window with embedded browser.
https://bugs.winehq.org/show_bug.cgi?id=36491
--- Comment #15 from Austin English austinenglish@gmail.com --- Works here as well, thanks. I'll send a patch.
http://bugs.winehq.org/show_bug.cgi?id=36491
Anastasius Focht focht@gmx.net changed:
What |Removed |Added ---------------------------------------------------------------------------- Fixed by SHA1| |e63f0bf4b8656c73a26870005cd | |8694e50c4834a Status|NEW |RESOLVED Resolution|--- |FIXED
--- Comment #16 from Anastasius Focht focht@gmx.net --- Hello folks,
this is fixed by commit http://source.winehq.org/git/wine.git/commitdiff/e63f0bf4b8656c73a26870005cd...
Thanks Austin
Regards
https://bugs.winehq.org/show_bug.cgi?id=36491
Alexandre Julliard julliard@winehq.org changed:
What |Removed |Added ---------------------------------------------------------------------------- Status|RESOLVED |CLOSED
--- Comment #17 from Alexandre Julliard julliard@winehq.org --- Closing bugs fixed in 1.7.20.