[Bug 39093] Bermuda (Steam, Indie game) crashes on start ( madCodeHook tries to resolve kernel32.dll API exports via mapped Wine placeholder )

wine-bugs at winehq.org wine-bugs at winehq.org
Sun Mar 11 14:07:05 CDT 2018


https://bugs.winehq.org/show_bug.cgi?id=39093

Anastasius Focht <focht at gmx.net> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |focht at 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 at 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 ***

-- 
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