[Bug 35986] New: Multiple DRM-enabled apps and games crash when being relay traced (game overlay renderer enabled Stream games)

wine-bugs at winehq.org wine-bugs at winehq.org
Sun Apr 13 10:24:29 CDT 2014


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

            Bug ID: 35986
           Summary: Multiple DRM-enabled apps and games crash when being
                    relay traced (game overlay renderer enabled Stream
                    games)
           Product: Wine
           Version: 1.7.16
          Hardware: x86
                OS: Linux
            Status: NEW
          Severity: normal
          Priority: P2
         Component: tools
          Assignee: wine-bugs at winehq.org
          Reporter: focht at gmx.net

Hello folks,

this is more an experts request but it should also help getting better
diagnosis (logs) from users.

There are apps and games that crash when being relay traced because they employ
intrusive API hooking schemes that can't cope with Wine's relay thunks.

Example of a Steam game crashing with game overlay renderer enabled when relay
trace is turned on:

--- snip ---
$ pwd
/home/focht/.wine/drive_c/Program Files/Steam

$ WINEDEBUG=+tid,+seh,+relay wine ./steam.exe -no-dwrite -applaunch 238430
-windowed >>log.txt 2>&1
...
Unhandled exception: page fault on read access to 0x0a55527c in 32-bit code
(0xf6ea4243).
Register dump:
 CS:0023 SS:002b DS:002b ES:002b FS:0063 GS:006b
 EIP:f6ea4243 ESP:0033e438 EBP:0a548150 EFLAGS:00010246(  R- --  I  Z- -P- )
 EAX:0a555278 EBX:00000000 ECX:0a548150 EDX:00020234
 ESI:0a548150 EDI:0033e6d8
...
Backtrace:
=>0 0xf6ea4243 in winmm (+0x4243) (0x0a548150)
  1 0x0a532919 in inputsystem (+0x2918) (0x0a548150)
  2 0x00000001 (0x0a5422ac)
  3 0x0a531990 in inputsystem (+0x198f) (0x0a531760)
  4 0xf18b5608 (0x24448b51)
0xf6ea4243: call    *0x4(%eax)
Modules:
Module    Address            Debug info    Name (132 modules)
PE      380000-  3b0000    Deferred        launcher
PE      400000-  46f000    Deferred        contagion
PE     1a80000- 1ae7000    Deferred        tier0
PE     1af0000- 1b52000    Deferred        vstdlib
PE     9590000- 95e6000    Deferred        filesystem_stdio
PE     99f0000- a0cc000    Deferred        engine
PE     a530000- a551000    Export          inputsystem
PE     a560000- a68d000    Deferred        materialsystem
PE     b690000- b6d6000    Deferred        datacache
PE     b6e0000- bb0e000    Deferred        studiorender
PE     bb10000- bcb1000    Deferred        vphysics
PE     bcf0000- bd63000    Deferred        vscript
PE     bd70000- bd93000    Deferred        valve_avi
PE     bda0000- bf03000    Deferred        vguimatsurface
PE     bf10000- bf6f000    Deferred        vgui2
PE     bf90000- c086000    Deferred        shaderapidx9
PE     c090000- c28f000    Deferred        d3dx9_43
PE     e4d0000- e584000    Deferred        crashhandler
PE     e6a0000- e6b4000    Deferred        xinput1_3
PE    10000000-100bb000    Deferred        gameoverlayrenderer
PE    18000000-1803b000    Deferred        binkw32
PE    38000000-38893000    Deferred        steamclient
PE    3b400000-3b41e000    Deferred        steam_api
PE    3f000000-3f0ac000    Deferred        tier0_s
PE    3f600000-3f64b000    Deferred        vstdlib_s
ELF    7b800000-7ba60000    Deferred        kernel32<elf>
  \-PE    7b810000-7ba60000    \               kernel32
ELF    7bc00000-7bcee000    Deferred        ntdll<elf>
  \-PE    7bc10000-7bcee000    \               ntdll
ELF    7bf00000-7bf04000    Deferred        <wine-loader>
...
ELF    f6e90000-f6f4e000    Dwarf           winmm<elf>
  \-PE    f6ea0000-f6f4e000    \               winmm
...
Threads:
process  tid      prio (all id:s are in hex)
...
00000031 (D) C:\Program Files\Steam\SteamApps\common\Contagion\contagion.exe
    00000063    0
    00000064    0
    00000067    0
    00000065    0
    00000030    0 <==
--- snip ---

Caller code:

--- snip ---
0A532900   81EC CC010000    SUB ESP,1CC
0A532906   53               PUSH EBX
0A532907   55               PUSH EBP
0A532908   8BE9             MOV EBP,ECX
0A53290A   33DB             XOR EBX,EBX
0A53290C   56               PUSH ESI
0A53290D   899D 8C150000    MOV DWORD PTR SS:[EBP+158C],EBX
0A532913   FF15 5821540A    CALL DWORD PTR DS:[<&WINMM.joyGetNumDevs>]
0A532919   8BF0             MOV ESI,EAX
0A53291B   83FE 04          CMP ESI,4
0A53291E   897424 0C        MOV DWORD PTR SS:[ESP+C],ESI
0A532922   0F8E 80010000    JLE inputsys.0A532AA8
--- snip ---

The game dll calls 'WINMM.joyGetNumDevs'.

Original relay thunk emitted for that API:

--- snip ---
F6F38234   push    esp
F6F38235   push    1Dh
F6F38237   call    __wine_spec_get_pc_thunk_eax
F6F3823C   lea     eax, [eax+35270h] ; descriptor lookup
F6F38242   push    eax
F6F38243   call    dword ptr [eax+4]
F6F38246   retn    0
--- snip --- 

The hook engine copies all opcodes that are potentially overwritten by the
5-byte long jump to an intermediate thunk.
Hence the call to '__wine_spec_get_pc_thunk_eax' is copied too - leading to the
actual problem.

A long jump is written to the relay thunk entry which jumps to another
trampoline, located at the intermediate thunk area.

'WINMM.joyGetNumDevs' relay thunk hooked by Steam's gameoverlayrenderer:

--- snip ---
F6F38234   E9 D47D5E13      JMP 0A52000D
F6F38239   1300             ADC EAX,DWORD PTR DS:[EAX]
F6F3823B   008D 80705203    ADD BYTE PTR SS:[EBP+3527080],CL
F6F38241   0050 FF          ADD BYTE PTR DS:[EAX-1],DL
F6F38244   50               PUSH EAX
F6F38245   04 C2            ADD AL,0C2
F6F38247   0000             ADD BYTE PTR DS:[EAX],AL
--- snip ---

Intermediate jump trampoline to actual hook code:

--- snip --- 
0A52000D   E9 DE27B305      JMP gameover.100527F0
--- snip --- 

'gameoverlayrenderer' module info:

--- snip ---
 Base=10000000
 Size=000BB000 (765952.)
 Entry=1005798F gameover.<ModuleEntryPoint>
 Name=gameover
 File version=02.13.04.49
 Path=C:\Program Files\Steam\gameoverlayrenderer.dll
--- snip ---

'gameoverlayrenderer' code:

--- snip ---
100527F0   833D 2C7A0910 00 CMP DWORD PTR DS:[10097A2C],0
100527F7   7F 06            JG SHORT gameover.100527FF
100527F9   FF25 1C8F0910    JMP DWORD PTR DS:[10098F1C]
100527FF   B8 04000000      MOV EAX,4
10052804   C3               RETN
10052805   CC               INT3
--- snip ---

Memory refs:

--- snip ---
10097A2C   00000000  ....
...
10098F1C   0A520000  ..R.
--- snip ---

Original copy Wine relay thunk entry + continuation + hook jump

--- snip ---
0A520000   54               PUSH ESP
0A520001   6A 1D            PUSH 1D
0A520003   E8 5095A1EC      CALL winmm.__wine_spec_get_pc_thunk_eax
0A520008   E9 2F82A1EC      JMP winmm.F6F3823C ; org. relay thunk code (cont)
0A52000D   E9 DE27B305      JMP gameover.100527F0
--- snip --- 

__wine_spec_get_pc_thunk_eax:

--- snip ---
F6F39558   8B0424           MOV EAX,DWORD PTR SS:[ESP]
F6F3955B   C3               RETN
--- snip ---

'WINMM.joyGetNumDevs' original Wine relay thunk code (continuation):

--- snip ---
F6F3823C   8D80 70520300    LEA EAX,DWORD PTR DS:[EAX+35270]
F6F38242   50               PUSH EAX
F6F38243   FF50 04          CALL DWORD PTR DS:[EAX+4]
F6F38246   C2 0000          RETN 0
--- snip ---

This obviously can't work because '__wine_spec_get_pc_thunk_eax' relies on
being called from original relay thunk code.

Because Steam game overlay renderer hook engine relocated this essential part
of relay thunk code, the returned address will always be wrong.

You can fix this problem by padding the relay thunk entry with enough 'no-op'
opcodes to not have '__wine_spec_get_pc_thunk_eax' relocated by hook engines.

Wine:
http://source.winehq.org/git/wine.git/blob/4e4acd5f705c770b7c361605e11d9d7c044ca0e8:/tools/winebuild/spec32.c#l100

The method works and AFAIK has no side-effects.
I used a patch in my repo for some time now to cope with such stubborn
apps/games (mostly DRM related).

$ wine --version
wine-1.7.16-133-gd8ca8c2

Regards

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