[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