[Bug 47097] Multiple Steam games crash on startup ( Steam Game Overlay Renderer hook engine engine can't cope with GOT/ PIC register load code)(Counter-Strike, Black Mesa, The Superlatives: Shattered Worlds)

wine-bugs at winehq.org wine-bugs at winehq.org
Tue Apr 30 19:22:03 CDT 2019


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

Anastasius Focht <focht at gmx.net> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
         Resolution|---                         |FIXED
          Component|user32                      |build-env
             Status|NEW                         |RESOLVED
            Summary|Multiple Steam games crash  |Multiple Steam games crash
                   |on startup (Steam Game      |on startup (Steam Game
                   |Overlay Renderer hook       |Overlay Renderer hook
                   |engine needs                |engine engine can't cope
                   |DECLSPEC_HOTPATCH for       |with GOT/ PIC register load
                   |user32.RegisterDeviceNotifi |code)(Counter-Strike, Black
                   |cationA/W)(Counter-Strike,  |Mesa, The Superlatives:
                   |Black Mesa, The             |Shattered Worlds)
                   |Superlatives: Shattered     |
                   |Worlds)                     |
      Fixed by SHA1|                            |8f732c66ab37b54c30d63c74f78
                   |                            |22ba1d4f04996

--- Comment #4 from Anastasius Focht <focht at gmx.net> ---
Hello folks,

technically all the DECLSPEC_HOTPATCH bug reports/patches related to crashes
with Steam Game Overlay Renderer are not needed anymore. Like other hook
engines, it can cope with various opcode sequences in prologue code as well,
except GOT/PIC register load sequence which is gone now.

*
https://source.winehq.org/git/wine.git/commitdiff/8f732c66ab37b54c30d63c74f7822ba1d4f04996
("makefiles: Build with -fno-PIC on i386.")

*
https://source.winehq.org/git/wine.git/commitdiff/8039941c52758113955d376bd7b6b6e1e5b5f76c
("makefiles: Also pass -fPIC flag when linking.")

Thanks Zebediah and Alexandre.

Explanation:

wine-4.7 release ('-fPIC' default for i386):

--- snip ---
$ objdump -d
/home/focht/projects/wine/mainline-install-4.7-x86_64/lib/wine/user32.dll.so |
awk -F"\n" -v RS="\n\n" '$1 ~ /RegisterDeviceNotificationW/'

00088060 <RegisterDeviceNotificationW>:
   88060:    e8 dc 29 fa ff           call   2aa41 <__x86.get_pc_thunk.ax>
   88065:    05 9b bf 08 00           add    $0x8bf9b,%eax
   8806a:    8d 4c 24 04              lea    0x4(%esp),%ecx
   8806e:    83 e4 f0                 and    $0xfffffff0,%esp
   88071:    ff 71 fc                 pushl  -0x4(%ecx)
   88074:    55                       push   %ebp
   88075:    89 e5                    mov    %esp,%ebp
   88077:    53                       push   %ebx
   88078:    51                       push   %ecx
   88079:    8b 11                    mov    (%ecx),%edx
   8807b:    8b 59 04                 mov    0x4(%ecx),%ebx
   8807e:    8b 49 08                 mov    0x8(%ecx),%ecx
   88081:    f6 80 78 b7 0e 00 01     testb  $0x1,0xeb778(%eax)
   88088:    75 16                    jne    880a0
<RegisterDeviceNotificationW+0x40>
   8808a:    8d 65 f8                 lea    -0x8(%ebp),%esp
   8808d:    b8 fe af fe ca           mov    $0xcafeaffe,%eax
   88092:    59                       pop    %ecx
   88093:    5b                       pop    %ebx
   88094:    5d                       pop    %ebp
   88095:    8d 61 fc                 lea    -0x4(%ecx),%esp
   88098:    c2 0c 00                 ret    $0xc
   8809b:    90                       nop
   8809c:    8d 74 26 00              lea    0x0(%esi,%eiz,1),%esi
   880a0:    83 ec 04                 sub    $0x4,%esp
   880a3:    51                       push   %ecx
   880a4:    53                       push   %ebx
   880a5:    52                       push   %edx
   880a6:    8d 90 9c e5 fb ff        lea    -0x41a64(%eax),%edx
   880ac:    52                       push   %edx
   880ad:    8d 90 c8 e8 fb ff        lea    -0x41738(%eax),%edx
   880b3:    8d 80 78 b7 0e 00        lea    0xeb778(%eax),%eax
   880b9:    52                       push   %edx
   880ba:    50                       push   %eax
   880bb:    6a 00                    push   $0x0
   880bd:    e8 ee f4 ff ff           call   875b0 <wine_dbg_log.constprop.3>
   880c2:    83 c4 20                 add    $0x20,%esp
   880c5:    eb c3                    jmp    8808a
<RegisterDeviceNotificationW+0x2a>
--- snip ---

Current Git -> wine-4.7-66-g8039941c52 ('-fno-PIC' default for i386):

--- snip ---
$ objdump -d
/home/focht/projects/wine/mainline-install-x86_64/lib/wine/user32.dll.so | awk
-F"\n" -v RS="\n\n" '$1 ~ /RegisterDeviceNotificationW/'

00096130 <RegisterDeviceNotificationW>:
   96130:    8d 4c 24 04              lea    0x4(%esp),%ecx
   96134:    83 e4 f0                 and    $0xfffffff0,%esp
   96137:    ff 71 fc                 pushl  -0x4(%ecx)
   9613a:    55                       push   %ebp
   9613b:    89 e5                    mov    %esp,%ebp
   9613d:    51                       push   %ecx
   9613e:    83 ec 04                 sub    $0x4,%esp
   96141:    8b 01                    mov    (%ecx),%eax
   96143:    8b 51 04                 mov    0x4(%ecx),%edx
   96146:    8b 49 08                 mov    0x8(%ecx),%ecx
   96149:    f6 05 68 87 20 00 01     testb  $0x1,0x208768
   96150:    75 16                    jne    96168
<RegisterDeviceNotificationW+0x38>
   96152:    8b 4d fc                 mov    -0x4(%ebp),%ecx
   96155:    b8 fe af fe ca           mov    $0xcafeaffe,%eax
   9615a:    c9                       leave  
   9615b:    8d 61 fc                 lea    -0x4(%ecx),%esp
   9615e:    c2 0c 00                 ret    $0xc
   96161:    8d b4 26 00 00 00 00     lea    0x0(%esi,%eiz,1),%esi
   96168:    83 ec 04                 sub    $0x4,%esp
   9616b:    51                       push   %ecx
   9616c:    52                       push   %edx
   9616d:    50                       push   %eax
   9616e:    68 5c c2 0d 00           push   $0xdc25c
   96173:    68 a8 c5 0d 00           push   $0xdc5a8
   96178:    68 68 87 20 00           push   $0x208768
   9617d:    6a 00                    push   $0x0
   9617f:    e8 3c f6 ff ff           call   957c0 <wine_dbg_log.constprop.3>
--- snip ---

-> GOT/PIC register load gone.

How does it look like at runtime:

HANDLE user32.RegisterDeviceNotificationA(hRecipient,pFilter,Flags)

--- snip ---
7E69C0C0  E9 07469600        JMP 7F0006CC              ; to Trampoline1
7E69C0C5  E4 F0              IN AL,0F0
7E69C0C7  FF71 FC            PUSH DWORD PTR DS:[ECX-4] ; continuation
7E69C0CA  55                 PUSH EBP
7E69C0CB  89E5               MOV EBP,ESP
7E69C0CD  51                 PUSH ECX
7E69C0CE  83EC 04            SUB ESP,4
7E69C0D1  8B01               MOV EAX,DWORD PTR DS:[ECX]
7E69C0D3  8B51 04            MOV EDX,DWORD PTR DS:[ECX+4]
7E69C0D6  8B49 08            MOV ECX,DWORD PTR DS:[ECX+8]
7E69C0D9  F605 68E7807E 01   TEST BYTE PTR DS:[7E80E768],01
...
--- snip ---

Trampoline1:

--- snip ---
...
7F0006CC  E9 DF396585     JMP 046540B0           ; Gameoverlayrenderer hook
...
--- snip ---

Gameoverlayrenderer hook:

--- snip ---
046540B0  55              PUSH EBP
046540B1  8BEC            MOV EBP,ESP
046540B3  53              PUSH EBX
046540B4  8B5D 10         MOV EBX,DWORD PTR SS:[EBP+10]
046540B7  56              PUSH ESI
046540B8  8B75 0C         MOV ESI,DWORD PTR SS:[EBP+0C]
046540BB  57              PUSH EDI
046540BC  53              PUSH EBX
046540BD  56              PUSH ESI
046540BE  FF75 08         PUSH DWORD PTR SS:[EBP+8]
; call org Wine impl via Trampoline2
046540C1  FF15 EC1B7004   CALL DWORD PTR DS:[4701BEC]  ; 0x7F0006C0
046540C7  8BF8            MOV EDI,EAX
046540C9  85FF            TEST EDI,EDI
046540CB  74 73           JE SHORT 04654140
--- snip ---

Trampoline2 with original prologue and continuation into original Wine impl

--- snip ---
7F0006C0  8D4C24 04       LEA ECX,[ESP+4]
7F0006C4  83E4 F0         AND ESP,FFFFFFF0
7F0006C7  E9 FBB969FF     JMP 7E69C0C7               ; continue to Wine impl.
--- snip ---

I propose instead of duplicating all issues into a single catch-all-collector
ticket ("Many games / multiple hook engines/DRM schemes: DRM1, DRM2, hook
engine1...") we collect tickets per hook-engine, even the underlying problem is
the same (GOT/PIC loads). Make it easier for end-users who care only about
their favourite content distribution platform (Steam, EA/Origin, ...) and
release notes.

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