https://bugs.winehq.org/show_bug.cgi?id=39093
Bug ID: 39093 Summary: Bermuda (indie game) crashes on start Product: Wine Version: 1.7.49 Hardware: x86 URL: http://store.steampowered.com/app/337640/ OS: Linux Status: NEW Keywords: download Severity: normal Priority: P2 Component: -unknown Assignee: wine-bugs@winehq.org Reporter: gyebro69@gmail.com Distribution: ---
Created attachment 52086 --> https://bugs.winehq.org/attachment.cgi?id=52086 terminal output
The game crashes immediately on start. Can be reproduced with the demo version too. The game can be launched directly, without Steam running. Beside the Bermuda game, I have 2 more games on Steam that crash with the same backtrace. Maybe it's only a coincidence that all these games require msscript.ocx to start.The crash reported here occurs sooner, so it's doesn't matter whether msscript.ocx is installed or not.
I remembered that those games used to start properly in previous Wine versions (provided msccript.ocx was installed). The result of the regression test is probably not the cause of the crash, but it could have surfaced a different bug in Wine. I talked about it on irc with Nikolay and he also has doubts that this commit has anything with the crash. However, I verified that those games don't crash prior to commit 50ad765cd604630214d87f9e696d7da216c0f814 kernel32: Added a message for WSAECONNRESET.
Fedora 22 32-bit wine-1.7.49-41-g36a39ce
https://bugs.winehq.org/show_bug.cgi?id=39093
--- Comment #1 from Béla Gyebrószki gyebro69@gmail.com --- Created attachment 52087 --> https://bugs.winehq.org/attachment.cgi?id=52087 +relay,+seh,+tid log (uncompressed 2.4 MB)
https://bugs.winehq.org/show_bug.cgi?id=39093
Michael Müller michael@fds-team.de changed:
What |Removed |Added ---------------------------------------------------------------------------- CC| |michael@fds-team.de
--- Comment #2 from Michael Müller michael@fds-team.de --- Created attachment 52091 --> https://bugs.winehq.org/attachment.cgi?id=52091 Hack to increase size of fake dlls
I am not 100% sure why the program does this, but it seems like the game calculates some offset in the mapped kernel32 module and then maps the dll manually:
------- 003d:Call KERNEL32.GetModuleFileNameW(7b810000,00168978,00000104) ret=009716e0 003d:Ret KERNEL32.GetModuleFileNameW() retval=00000020 ret=009716e0 003d:Call KERNEL32.CreateFileW(00168978 L"C:\windows\system32\KERNEL32.dll",80000000,00000001,00000000,00000003,00000000,00000000) ret=009716f5 003d:Ret KERNEL32.CreateFileW() retval=00000080 ret=009716f5 [...] KERNEL32.CreateFileMappingW(00000080,00000000,00000002,00000000,00000000,00000000) ret=00971751 003d:Ret KERNEL32.CreateFileMappingW() retval=00000084 ret=00971751 003d:Call KERNEL32.MapViewOfFile(00000084,00000004,00000000,00000000,00000000) ret=00971779 003d:Ret KERNEL32.MapViewOfFile() retval=02ec0000 ret=00971779 -------
Now it tries to access the same offset in the mapped memory area (which somehow points into the resource section in the ELF-PE kernel32 module). This causes an access violation since Wine mapped the fake kernel32.dll which is about 1MB smaller then the ELF-PE version. I am not sure what the program is searching for or if it is a bug that it tries to access this memory address. The mentioned commit changed the size of the resource section and had some influence on the offset the program is looking for.
I attached a hack which increases the size of the fake dlls about 1MB and therefore prevents the access violations. The game starts fine using this hack (+ msscript override).
https://bugs.winehq.org/show_bug.cgi?id=39093
--- Comment #3 from Dmitry Timoshkov dmitry@baikal.ru --- (In reply to Michael Müller from comment #2)
I am not 100% sure why the program does this, but it seems like the game calculates some offset in the mapped kernel32 module and then maps the dll manually:
Sounds similar to the bug 29688.
https://bugs.winehq.org/show_bug.cgi?id=39093
--- Comment #4 from Béla Gyebrószki gyebro69@gmail.com --- (In reply to Michael Müller from comment #2)
Created attachment 52091 [details] Hack to increase size of fake dlls
I am not 100% sure why the program does this, but it seems like the game calculates some offset in the mapped kernel32 module and then maps the dll manually:
The affected games start properly with this hack, thanks Michael for analyzing the problem.
https://bugs.winehq.org/show_bug.cgi?id=39093
Qian Hong fracting@gmail.com changed:
What |Removed |Added ---------------------------------------------------------------------------- CC| |fracting@gmail.com
https://bugs.winehq.org/show_bug.cgi?id=39093
Anastasius Focht focht@gmx.net changed:
What |Removed |Added ---------------------------------------------------------------------------- CC| |focht@gmx.net Status|NEW |RESOLVED Keywords| |obfuscation Resolution|--- |DUPLICATE Summary|Bermuda (indie game) |Bermuda (Steam, Indie game) |crashes on start |crashes on start | |(madCodeHook tries to | |resolve kernel32.dll API | |exports via mapped Wine | |placeholder)
--- Comment #5 from Anastasius Focht focht@gmx.net --- Hello folks,
the hack from comment #2 that ought to extend Wine's placeholder (fake) dlls just works by chance.
Michael was a bit unspecific about the nature of the offset in comment #2 Dmitry correctly recognized the relation to bug 29688 in comment #3 (which is not fixable without redesigning the Wine's placeholder dll structure).
It's actually bug 15437 which can be worked around by removing the affected placeholder.
Protection ID scan (after manual unpack of UPX compressed PE):
--- snip --- Scanning -> Z:\home\focht\Downloads\bermuda_demo.exe File Type : 32-Bit Exe (Subsystem : Win GUI / 2), Size : 42101246 (028269FEh) Byte(s) | Machine: 0x14C (I386) Compilation TimeStamp : 0x52E770AC -> Tue 28th Jan 2014 08:56:12 (GMT) [TimeStamp] 0x52E770AC -> Tue 28th Jan 2014 08:56:12 (GMT) | PE Header | - | Offset: 0x00000128 | VA: 0x00400128 | - [TimeStamp] 0x52E77079 -> Tue 28th Jan 2014 08:55:21 (GMT) | Export | - | Offset: 0x0084FD64 | VA: 0x00C51564 | - -> File has 14622718 (0DF1FFEh) bytes of appended data starting at offset 01A34A00h [LoadConfig] CodeIntegrity -> Flags 0xA3F0 | Catalog 0x46 (70) | Catalog Offset 0x2000001 | Reserved 0x46A4A0 [LoadConfig] GuardAddressTakenIatEntryTable 0x8000011 | Count 0x46A558 (4629848) [LoadConfig] GuardLongJumpTargetTable 0x8000001 | Count 0x46A5F8 (4630008) [LoadConfig] HybridMetadataPointer 0x8000011 | DynamicValueRelocTable 0x46A66C [LoadConfig] FailFastIndirectProc 0x8000011 | FailFastPointer 0x46C360 [LoadConfig] UnknownZero1 0x8000011 [File Heuristics] -> Flag #1 : 00000000000000001101000100000100 (0x0000D104) [Entrypoint Section Entropy] : 6.62 (section #0) ".text " | Size : 0x56A72A (5678890) byte(s) [DllCharacteristics] -> Flag : (0x8140) -> ASLR | DEP | TSA [SectionCount] 9 (0x9) | ImageSize 0x1A70000 (27721728) byte(s) [Export] 100% of function(s) (56 of 56) are in file | 0 are forwarded | 56 code | 0 data | 0 uninit data | 0 unknown | [VersionInfo] Company Name : InvertMouse [VersionInfo] Product Name : Bermuda [VersionInfo] Product Version : 1.0.0.0 [VersionInfo] File Description : Bermuda [VersionInfo] File Version : 1.0.0.0 [VersionInfo] Original FileName : bermuda_demo [VersionInfo] Internal Name : Bermuda [VersionInfo] Legal Trademarks : (C) InvertMouse 2014 [VersionInfo] Legal Copyrights : InvertMouse [ModuleReport] [IAT] Modules -> KERNEL32.DLL | ADVAPI32.dll | COMCTL32.dll | COMDLG32.dll | d3d9.dll | DDRAW.dll | GDI32.dll | IPHLPAPI.DLL | ole32.dll | OLEAUT32.dll | RPCRT4.dll | SHELL32.dll | urlmon.dll | USER32.dll | WINHTTP.dll | WININET.dll | WINMM.dll | WINSPOOL.DRV | WS2_32.dll [Raw/Hidden Debug Record] (File Offset 0x8030E0) CvSig : 0x53445352 | SigGuid 4FEF8324-6666-44FA-8AC0480E4C9EB645 Age : 0x3 (3) | Pdb : c:\MDM\Zinc4\projector\Release\projector.pdb [Raw/Hidden Debug Record] (File Offset 0x9AF690) CvSig : 0x53445352 | SigGuid BB516622-27E5-4E5A-BAC8FFD4BCB875DD Age : 0x1 (1) | Pdb : D:\MDM\Zinc4\vista_sound_volume\Release\vista_sound_volume.pdb [Raw/Hidden Debug Record] (File Offset 0x184AB50) CvSig : 0x53445352 | SigGuid 69BE659A-D4F2-492C-A40CAAA6E9F4F685 Age : 0x1 (1) | Pdb : NPSWF32.pdb [CdKeySerial] found "Invalid code" @ VA: 0x0057464F / Offset: 0x0057324F [CdKeySerial] found "Serial Number" @ VA: 0x005FA7A7 / Offset: 0x005F8FA7 [CdKeySerial] found "Serial Number" @ VA: 0x005FA88C / Offset: 0x005F908C [CdKeySerial] found "Serial Number" @ VA: 0x005FA89F / Offset: 0x005F909F [CdKeySerial] found "Serial Number" @ VA: 0x00600359 / Offset: 0x005FEB59 [CdKeySerial] found "SerialNumber" @ VA: 0x00600BD8 / Offset: 0x005FF3D8 [CdKeySerial] found "SerialNumber" @ VA: 0x006228F7 / Offset: 0x006210F7 [CdKeySerial] found "SerialNumber" @ VA: 0x006229A9 / Offset: 0x006211A9 [CdKeySerial] found "Invalid code" @ VA: 0x006303D4 / Offset: 0x0062EBD4 [CdKeySerial] found "Invalid code" @ VA: 0x00630420 / Offset: 0x0062EC20 [CdKeySerial] found "SerialNumber" @ VA: 0x006331C4 / Offset: 0x006319C4 [CdKeySerial] found "SerialNumber" @ VA: 0x006342CC / Offset: 0x00632ACC [CdKeySerial] found "SerialNumber" @ VA: 0x0063438C / Offset: 0x00632B8C [CdKeySerial] found "SerialNumber" @ VA: 0x00688E36 / Offset: 0x00687636 [CdKeySerial] found "Invalid code" @ VA: 0x006CBBF7 / Offset: 0x006CA3F7 [CdKeySerial] found "Invalid code" @ VA: 0x006CBC27 / Offset: 0x006CA427 [CdKeySerial] found "Invalid code" @ VA: 0x006CBCF3 / Offset: 0x006CA4F3 [CdKeySerial] found "SerialNumber" @ VA: 0x01620787 / Offset: 0x015E6187 [CdKeySerial] found "Unregistered" @ VA: 0x016901D3 / Offset: 0x01655BD3 [CdKeySerial] found "Unregistered" @ VA: 0x01690203 / Offset: 0x01655C03 [CdKeySerial] found "Invalid code" @ VA: 0x016C0080 / Offset: 0x01685A80 [CdKeySerial] found "Invalid code" @ VA: 0x016C00C4 / Offset: 0x01685AC4 [CdKeySerial] found "SerialNumber" @ VA: 0x01717BE4 / Offset: 0x016DD5E4 [CdKeySerial] found "SerialNumber" @ VA: 0x01877B1B / Offset: 0x0183D51B [CdKeySerial] found "SerialNumber" @ VA: 0x01877BCD / Offset: 0x0183D5CD [CompilerDetect] -> Visual C++ 9.0 (Visual Studio 2008) [!] File appears to have no protection or is using an unknown protection - Scan Took : 4.283 Second(s) [00000126Dh (4717) tick(s)] [566 of 580 scan(s) done] --- snip ---
Relevant part of trace log (although all the magic can't be seen here):
--- snip --- $ pwd /home/focht/wine-games/wineprefix64-steam/drive_c/Program Files (x86)/Steam
$ WINEDEBUG=+seh,+loaddll,+process,+debugstr,+relay wine ./steam.exe -applaunch 337640 -no-cef-sandbox -nominidumps -nobreakpad -noassert -nocrashdialog -windowed >>log.txt 2>&1 ... 006a:Call KERNEL32.lstrcmpA(7b644bdf "CreateFileMappingW",04220050 "CreateFileW") ret=00971821 006a:Ret KERNEL32.lstrcmpA() retval=ffffffff ret=00971821 006a:Call KERNEL32.lstrcmpA(7b644bf2 "CreateFileW",04220050 "CreateFileW") ret=00971821 006a:Ret KERNEL32.lstrcmpA() retval=00000000 ret=00971821 006a:Call KERNEL32.GetVersion() ret=009716bf 006a:Ret KERNEL32.GetVersion() retval=0ece0205 ret=009716bf 006a:Call KERNEL32.LocalAlloc(00000040,0000020a) ret=009716d2 006a:Ret KERNEL32.LocalAlloc() retval=0021e170 ret=009716d2 006a:Call KERNEL32.GetModuleFileNameW(7b420000,0021e170,00000104) ret=009716e0 006a:Ret KERNEL32.GetModuleFileNameW() retval=00000020 ret=009716e0 006a:Call KERNEL32.CreateFileW(0021e170 L"C:\windows\system32\KERNEL32.dll",80000000,00000001,00000000,00000003,00000000,00000000) ret=009716f5 006a:Ret KERNEL32.CreateFileW() retval=000000fc ret=009716f5 006a:Call KERNEL32.LocalFree(0021e170) ret=00971730 006a:Ret KERNEL32.LocalFree() retval=00000000 ret=00971730 006a:Call KERNEL32.GetVersion() ret=0097173a 006a:Ret KERNEL32.GetVersion() retval=0ece0205 ret=0097173a 006a:Call KERNEL32.CreateFileMappingW(000000fc,00000000,00000002,00000000,00000000,00000000) ret=00971751 006a:Ret KERNEL32.CreateFileMappingW() retval=00000100 ret=00971751 006a:Call KERNEL32.MapViewOfFile(00000100,00000004,00000000,00000000,00000000) ret=00971779 006a:Ret KERNEL32.MapViewOfFile() retval=04320000 ret=00971779 006a:Call KERNEL32.CloseHandle(00000100) ret=00971781 006a:Ret KERNEL32.CloseHandle() retval=00000001 ret=00971781 006a:Call KERNEL32.CloseHandle(000000fc) ret=00971787 006a:Ret KERNEL32.CloseHandle() retval=00000001 ret=00971787 006a:trace:seh:raise_exception code=c0000005 flags=0 addr=0x9718c5 ip=009718c5 tid=006a 006a:trace:seh:raise_exception info[0]=00000000 006a:trace:seh:raise_exception info[1]=04541134 006a:trace:seh:raise_exception eax=04541118 ebx=7b420000 ecx=00000001 edx=00221118 esi=7b420040 edi=04320000 006a:trace:seh:raise_exception ebp=04541118 esp=0033fbac cs=0023 ds=002b es=002b fs=0063 gs=006b flags=00210206 006a:trace:seh:call_stack_handlers calling handler at 0x97ddf4 code=c0000005 flags=0 006a:trace:seh:call_stack_handlers handler at 0x97ddf4 returned 1 006a:trace:seh:call_stack_handlers calling handler at 0x950818 code=c0000005 flags=0 ... --- snip ---
The exception context register information, annotated by debugging the code/trace log:
ebx = 0x7b420000 ; load (base) address of 'kernel32.dll' esi = 0x7b420040 ; PE signature (PE header) edi = 0x04320000 ; mapping of placeholder 'kernel32.dll' via 'MapViewOfFile' edx = 0x00221118 ; RVA export table address eax = ebp = 0x04541118 ; VA export table
fault addr 0x4541134 ; export table: AddressOfFunctions
In-memory dump of 'kernel32.dll' PE header, annotated:
--- snip --- $ ==> 7B420000 ASCII "MZ" ; DOS EXE Signature ... ... $+3C 7B42003C DD 00000040 ; Offset to PE signature $+40 7B420040 ASCII "PE" ; PE signature (PE) $+44 7B420044 DW 014C ; Machine = IMAGE_FILE_MACHINE_I386 $+46 7B420046 DW 0002 ; NumberOfSections = 2 $+48 7B420048 DD 00000000 ; TimeDateStamp = 0 $+4C 7B42004C DD 00000000 ; PointerToSymbolTable = 0 $+50 7B420050 0DD 00000000 ; NumberOfSymbols = 0 $+54 7B420054 DW 00E0 ; SizeOfOptionalHeader = E0 (224.) $+56 7B420056 DW 2022 ; Characteristics = DLL|EXECUTABLE_IMAGE| $+58 7B420058 DW 010B ; MagicNumber = PE32 $+5A 7B42005A DB 07 ; MajorLinkerVersion = 7 $+5B 7B42005B DB 0A ; MinorLinkerVersion = A (10.) $+5C 7B42005C DD 00220000 ; SizeOfCode = 220000 (2228224.) $+60 7B420060 DD 001B1000 ; SizeOfInitializedData = 1B1000 $+64 7B420064 DD 00000000 ; SizeOfUninitializedData = 0 $+68 7B420068 DD 0006EEF2 ; AddressOfEntryPoint = 6EEF2 $+6C 7B42006C DD 00001000 ; BaseOfCode = 1000 $+70 7B420070 DD 00221000 ; BaseOfData = 221000 $+74 7B420074 DD 7B420000 ; ImageBase = 7B420000 $+78 7B420078 DD 00001000 ; SectionAlignment = 1000 $+7C 7B42007C DD 00001000 ; FileAlignment = 1000 $+80 7B420080 DW 0001 ; MajorOSVersion = 1 $+82 7B420082 DW 0000 ; MinorOSVersion = 0 $+84 7B420084 DW 0000 ; MajorImageVersion = 0 $+86 7B420086 DW 0000 ; MinorImageVersion = 0 $+88 7B420088 DW 0004 ; MajorSubsystemVersion = 4 $+8A 7B42008A DW 0000 ; MinorSubsystemVersion = 0 $+8C 7B42008C DD 00000000 ; Reserved $+90 7B420090 DD 003D2000 ; SizeOfImage = 3D2000 (4005888.) $+94 7B420094 DD 00001000 ; SizeOfHeaders = 1000 (4096.) $+98 7B420098 DD 00000000 ; CheckSum = 0 $+9C 7B42009C DW 0000 ; Subsystem = IMAGE_SUBSYSTEM_UNKNOWN $+9E 7B42009E DW 0100 ; DLLCharacteristics = 100 $+A0 7B4200A0 DD 00100000 ; SizeOfStackReserve = 100000 $+A4 7B4200A4 DD 00001000 ; SizeOfStackCommit = 1000 $+A8 7B4200A8 DD 00100000 ; SizeOfHeapReserve = 100000 $+AC 7B4200AC DD 00001000 ; SizeOfHeapCommit = 1000 $+B0 7B4200B0 DD 00000000 ; LoaderFlags = 0 $+B4 7B4200B4 DD 00000010 ; NumberOfRvaAndSizes = 10 $+B8 7B4200B8 DD 00221118 ; Export Table address = 221118 $+BC 7B4200BC DD 0000AB3C ; Export Table size = AB3C --- snip ---
Mapping of placeholder 'kernel32.dll' : 0x4320000-0x44C3FFF
Crash location:
--- snip --- ... 009718C1 03C7 ADD EAX,EDI ; 0x4320000 += 0x221118 (RVA export table) 009718C3 89C5 MOV EBP,EAX 009718C5 8B55 1C MOV EDX,DWORD PTR SS:[EBP+1C] ; 0x4541134 = *boom* 009718C8 8BC6 MOV EAX,ESI 009718CA E8 68FDFFFF CALL 00971637 ; validate EAT entry 009718CF 03C7 ADD EAX,EDI 009718D1 0FB75424 0C MOVZX EDX,WORD PTR SS:[ESP+C] ; EAT AoF lookup index 009718D6 8B2C90 MOV EBP,DWORD PTR DS:[EAX+EDX*4] ; VA API entry ... --- snip ---
The hack to the placeholder just makes the memory range accessible which the game thinks is an export table (but it's not). The code that tries to resolve/validate the API entries fortunately checks memory ranges/access before accessing/dereference VA's. It's the initial access to the export address table that goes unchecked, causing a page fault because game code would never assume this to fail on Windows.
Fortunately you can work around without the hack by removing/renaming the placeholder 'kernel32.dll' and the game is still happy.
--- snip --- ... 0068:Call KERNEL32.GetModuleFileNameW(7b420000,0021e190,00000104) ret=009716e0 0068:Ret KERNEL32.GetModuleFileNameW() retval=00000020 ret=009716e0 0068:Call KERNEL32.CreateFileW(0021e190 L"C:\windows\system32\KERNEL32.dll",80000000,00000001,00000000,00000003,00000000,00000000) ret=009716f5 0068:Ret KERNEL32.CreateFileW() retval=ffffffff ret=009716f5 ... 0068:Call KERNEL32.IsBadReadPtr(7b420000,00000002) ret=009714f1 0068:Ret KERNEL32.IsBadReadPtr() retval=00000000 ret=009714f1 ... 0068:Call KERNEL32.OpenFileMappingW(000f001f,00000000,04220268 L"Global\NamedBuffer, mix, Process $00000067, API $7b420000") ret=00977958 0068:Ret KERNEL32.OpenFileMappingW() retval=00000000 ret=00977958 0068:Call KERNEL32.OpenFileMappingW(000f001f,00000000,0422032c L"NamedBuffer, mix, Process $00000067, API $7b420000") ret=00977981 0068:Ret KERNEL32.OpenFileMappingW() retval=00000000 ret=00977981 ... 0068:Call KERNEL32.OpenFileMappingW(00000004,00000000,04220268 L"Global\NamedBuffer, mAH, Process $00000067, API $7b420000") ret=00977958 0068:Ret KERNEL32.OpenFileMappingW() retval=00000000 ret=00977958 0068:Call KERNEL32.OpenFileMappingW(00000004,00000000,0422032c L"NamedBuffer, mAH, Process $00000067, API $7b420000") ret=00977981 0068:Ret KERNEL32.OpenFileMappingW() retval=00000000 ret=00977981 0068:Call KERNEL32.VirtualQuery(7b420000,0033fa7c,0000001c) ret=009748e2 0068:Ret KERNEL32.VirtualQuery() retval=0000001c ret=009748e2 0068:Call KERNEL32.GetModuleFileNameA(7b420000,0033fa98,00000104) ret=0097490c 0068:Ret KERNEL32.GetModuleFileNameA() retval=00000020 ret=0097490c 0068:Call KERNEL32.IsBadReadPtr(7b420000,00000002) ret=009714f1 0068:Ret KERNEL32.IsBadReadPtr() retval=00000000 ret=009714f1 0068:Call KERNEL32.GetLastError() ret=0097e5c3 0068:Ret KERNEL32.GetLastError() retval=00000000 ret=0097e5c3 0068:Call KERNEL32.IsBadReadPtr(0033fba0,00000460) ret=00976eb4 0068:Ret KERNEL32.IsBadReadPtr() retval=00000000 ret=00976eb4 ... --- snip ---
The 'NamedBuffer, mAH ...' messages reveal this is indeed MadCodeHook at work here.
http://forum.madshi.net/viewtopic.php?f=7&t=27969
Resolving as dupe of bug 15437
$ wine --version wine-3.3
Regards
*** This bug has been marked as a duplicate of bug 15437 ***
https://bugs.winehq.org/show_bug.cgi?id=39093
--- Comment #6 from Anastasius Focht focht@gmx.net --- Hello folks,
since this was mentioned in comment #2
--- quote --- The game starts fine using this hack (+ msscript override). --- quote ---
I've created bug 44717 for the msscript problem.
Regards
https://bugs.winehq.org/show_bug.cgi?id=39093
Alistair Leslie-Hughes leslie_alistair@hotmail.com changed:
What |Removed |Added ---------------------------------------------------------------------------- Status|RESOLVED |CLOSED
--- Comment #7 from Alistair Leslie-Hughes leslie_alistair@hotmail.com --- Closing Duplicates