https://bugs.winehq.org/show_bug.cgi?id=46626
Anastasius Focht focht@gmx.net changed:
What |Removed |Added ---------------------------------------------------------------------------- Summary|UPlay fails to start : |UPlay fails to start : |"Error at hooking API |"Error at hooking API |LoadStringA" |LoadStringA" (UPlay's | |hooking engine can't handle | |ENDBR32 instruction | |inserted at non-hotpatch | |API entries due to distro | |build environments | |'-fcf-protection') Ever confirmed|0 |1 CC| |focht@gmx.net Status|UNCONFIRMED |NEW URL| |https://web.archive.org/web | |/20190313080907/https://ubi | |static3-a.akamaihd.net/orbi | |t/launcher_installer/UplayI | |nstaller.exe Keywords| |download, obfuscation Distribution|--- |Fedora
--- Comment #6 from Anastasius Focht focht@gmx.net --- Hello folks,
--- quote --- I wonder why locally built wine does not have this problem. compiler version? extra build flags? --- quote ---
Here you go ...
Disassembly of hooked API entry from 'upc.com' process:
--- snip --- Wine-dbg>x/10i LoadStringA
0x000000007e8ad30b LoadStringA in user32: jmp 0x00000000022327b0 EntryPoint+0xffffffffffffffff in upc 0x000000007e8ad310 LoadStringA+0x5 in user32: inb $0xf0,%al 0x000000007e8ad312 LoadStringA+0x7 in user32: pushl 0xfffffffc(%ecx) 0x000000007e8ad315 LoadStringA+0xa in user32: pushl %ebp 0x000000007e8ad316 LoadStringA+0xb in user32: movl %esp,%ebp 0x000000007e8ad318 LoadStringA+0xd in user32: pushl %ebx 0x000000007e8ad319 LoadStringA+0xe in user32: pushl %ecx 0x000000007e8ad31a LoadStringA+0xf in user32: subl $48,%esp 0x000000007e8ad31d LoadStringA+0x12 in user32: movl %ecx,%ebx 0x000000007e8ad31f LoadStringA+0x14 in user32: movl $0x0,0xffffffd4(%ebp)
Wine-dbg>x/10i LoadStringW
0x000000007e8ad0e9 LoadStringW in user32: jmp 0x0000000002232840 EntryPoint+0xffffffffffffffff in upc 0x000000007e8ad0ee LoadStringW+0x5 in user32: inb $0xf0,%al 0x000000007e8ad0f0 LoadStringW+0x7 in user32: pushl 0xfffffffc(%ecx) 0x000000007e8ad0f3 LoadStringW+0xa in user32: pushl %ebp 0x000000007e8ad0f4 LoadStringW+0xb in user32: movl %esp,%ebp 0x000000007e8ad0f6 LoadStringW+0xd in user32: pushl %ebx 0x000000007e8ad0f7 LoadStringW+0xe in user32: pushl %ecx 0x000000007e8ad0f8 LoadStringW+0xf in user32: subl $48,%esp 0x000000007e8ad0fb LoadStringW+0x12 in user32: movl %ecx,%ebx 0x000000007e8ad0fd LoadStringW+0x14 in user32: movl $0x7ea056e0,%eax --- snip ---
Disassembly of same API entry, not hooked yet:
NOTE: This is from a '-fno-PIC' build. I always use no-PIC builds for 32-bit/64-bit for years to avoid all kinds of hooking issues -> bug 37540
--- snip --- 0x000000007e4ac0e9 LoadStringW in user32: leal 0x4(%esp),%ecx 0x000000007e4ac0ed LoadStringW+0x4 in user32: andl $-16,%esp 0x000000007e4ac0f0 LoadStringW+0x7 in user32: pushl 0xfffffffc(%ecx) 0x000000007e4ac0f3 LoadStringW+0xa in user32: pushl %ebp 0x000000007e4ac0f4 LoadStringW+0xb in user32: movl %esp,%ebp 0x000000007e4ac0f6 LoadStringW+0xd in user32: pushl %ebx 0x000000007e4ac0f7 LoadStringW+0xe in user32: pushl %ecx 0x000000007e4ac0f8 LoadStringW+0xf in user32: subl $48,%esp 0x000000007e4ac0fb LoadStringW+0x12 in user32: movl %ecx,%ebx 0x000000007e4ac0fd LoadStringW+0x14 in user32: movl $0x7e6046e0,%eax --- snip ---
Let's look at the package which you reported to be a problem...
https://dl.winehq.org/wine-builds/fedora/29/i686/wine-devel-common-4.1-3.1.i...
Dump the content:
--- snip --- $ rpm2cpio ./wine-devel-common-4.1-3.1.i686.rpm | cpio -idmv --- snip ---
Disassembly of the affected API entry:
--- snip --- $ gdb opt/wine-devel/lib/wine/user32.dll.so -batch -ex 'disassemble LoadStringW' Dump of assembler code for function LoadStringW: 0x0008b860 <+0>: endbr32 0x0008b864 <+4>: lea 0x4(%esp),%ecx 0x0008b868 <+8>: and $0xfffffff0,%esp 0x0008b86b <+11>: pushl -0x4(%ecx) 0x0008b86e <+14>: push %ebp 0x0008b86f <+15>: mov %esp,%ebp 0x0008b871 <+17>: push %edi 0x0008b872 <+18>: push %esi 0x0008b873 <+19>: push %ebx 0x0008b874 <+20>: call 0x202e0 0x0008b879 <+25>: add $0x6b787,%ebx ... --- snip ---
There we go. ENDBR is a special instruction. Intel's CET (Control-Flow Enforcement Technology) introduced a new mechanism called IBT (Indirect Branch Tracking). According to IBT, each indirect branch should land on dedicated ENDBR instruction (end branch).
https://software.intel.com/sites/default/files/managed/4d/2a/control-flow-en...
If the processor does not support Indirect Branch Tracking (IBT), the instruction is a NOP (see [0], pages 15ff. and 130f.)
How does this get in?
https://build.opensuse.org/package/view_file/Emulators:Wine:Fedora/wine-deve...
--- snip --- %build %ifarch x86_64 export CFLAGS="$(echo "%{optflags}" | sed -e 's/-O2//' -e 's/-Wp,-D_FORTIFY_SOURCE=2//') -O2" %else export CFLAGS="$(echo "%{optflags}" | sed -e 's/-Wp,-D_FORTIFY_SOURCE=2//')" %endif --- snip ---
From my local Fedora 28 build host:
--- snip --- $ rpmbuild --showrc | grep ^optflags optflags : %{__global_compiler_flags} -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection --- snip ---
--- snip --- $ gcc -dumpspecs | grep cf-protection --- snip ---
The culprit is '-fcf-protection' which causes the insertion of ENDBR instruction in API entry code. If you use rpmbuild environment then it's active. If you build without rpmbuild using gcc defaults or own CFLAGS then it's not active.
Apparently Uplay hooking engine can't handle/decode this instruction, refusing to hot-patch the entry.
It's unfortunate that https://source.winehq.org/git/wine.git/commit/9b90cfc2817e171e7a9698605deecc... had no corresponding Bugzilla bug report otherwise the issue could have been properly analysed/explained earlier.
I still see many times patches committed that appear to be out of the blue without any background information what they ought to fix. Sometimes it's possible to guess .. many times not. I don't know why it's so hard to create tracking bugs referring to real world apps/games. This lack of traceability causes later additional efforts on figuring out things in case of regressions and/or do really proper fixes.
ProtectionID scan for documentation:
--- snip --- -=[ ProtectionID v0.6.9.0 DECEMBER]=- (c) 2003-2017 CDKiLLER & TippeX Build 24/12/17-21:05:42 Ready... Scanning -> C:\Program Files (x86)\Ubisoft\Ubisoft Game Launcher\upc.exe File Type : 32-Bit Exe (Subsystem : Win GUI / 2), Size : 12171608 (0B9B958h) Byte(s) | Machine: 0x14C (I386) Compilation TimeStamp : 0x5C7FCB72 -> Wed 06th Mar 2019 13:30:26 (GMT) [TimeStamp] 0x5C7FCB72 -> Wed 06th Mar 2019 13:30:26 (GMT) | PE Header | - | Offset: 0x00000170 | VA: 0x00400170 | - [TimeStamp] 0x5C7FCB71 -> Wed 06th Mar 2019 13:30:25 (GMT) | Export | - | Offset: 0x00028CB4 | VA: 0x0259D6B4 | - [TimeStamp] 0x5C7FCB72 -> Wed 06th Mar 2019 13:30:26 (GMT) | DebugDirectory | - | Offset: 0x00AE1AA4 | VA: 0x030564A4 | - [TimeStamp] 0x5C7FCB72 -> Wed 06th Mar 2019 13:30:26 (GMT) | DebugDirectory | - | Offset: 0x00AE1AC0 | VA: 0x030564C0 | - [TimeStamp] 0x5C7FCB72 -> Wed 06th Mar 2019 13:30:26 (GMT) | DebugDirectory | - | Offset: 0x00AE1ADC | VA: 0x030564DC | - -> File Appears to be Digitally Signed @ Offset 0B99E00h, size : 01B58h / 07000 byte(s) [!] Executable uses TLS callbacks (1 total... 0 invalid addresses) [LoadConfig] Struct determined as v8 (Expected size 140 | Actual size 64) [!] Executable uses SEH Tables (/SAFESEH) (42117 calculated 42117 recorded... 0 invalid addresses) [LoadConfig] CodeIntegrity -> Flags 0x5352 | Catalog 0x5344 (21316) | Catalog Offset 0xF26A4B2F | Reserved 0x460D8931 [LoadConfig] GuardAddressTakenIatEntryTable 0x671517AF | Count 0x23EEDC28 (602856488) [LoadConfig] GuardLongJumpTargetTable 0x1 | Count 0x4A5C3A44 (1247558212) [LoadConfig] HybridMetadataPointer 0x696B6E65 | DynamicValueRelocTable 0x6F57736E [LoadConfig] FailFastIndirectProc 0x70736B72 | FailFastPointer 0x5C656361 [LoadConfig] UnknownZero1 0x6B726F77 [File Heuristics] -> Flag #1 : 00000100000001001101001100000111 (0x0404D307) [Entrypoint Section Entropy] : 7.88 (section #6) ".ubx1 " | Size : 0xB0A708 (11577096) byte(s) [DllCharacteristics] -> Flag : (0x8140) -> ASLR | DEP | TSA [SectionCount] 8 (0x8) | ImageSize 0x2D0F000 (47247360) byte(s) [Export] 0% of function(s) (0 of 137) are in file | 0 are forwarded | 136 code | 0 data | 0 uninit data | 0 unknown | [VersionInfo] Company Name : Ubisoft [VersionInfo] Product Name : Uplay [VersionInfo] Product Version : 85.0.6025 [VersionInfo] File Description : Uplay launcher [VersionInfo] File Version : 3.0 [VersionInfo] Original FileName : upc.exe [VersionInfo] Internal Name : Uplay game launcher [VersionInfo] Legal Copyrights : (c) Ubisoft [ModuleReport] [IAT] Modules -> KERNEL32.dll | USER32.dll | SHELL32.dll | ole32.dll | libUbiCustomEvent.dll | libcef.dll | WS2_32.dll | IPHLPAPI.DLL | WINHTTP.dll | RPCRT4.dll | d3d9.dll | gdiplus.dll | dwmapi.dll | GDI32.dll | COMDLG32.dll | ADVAPI32.dll | LIBEAY32.dll | Secur32.dll | CRYPT32.dll | IMM32.dll | KERNEL32.dll | KERNEL32.dll [Debug Info] (record 1 of 3) (file offset 0xAE1AA0) Characteristics : 0x0 | TimeDateStamp : 0x5C7FCB72 (Wed 06th Mar 2019 13:30:26 (GMT)) | MajorVer : 0 / MinorVer : 0 -> (0.0) Type : 2 (0x2) -> CodeView | Size : 0x81 (129) AddressOfRawData : 0x2C56010 | PointerToRawData : 0xAE1610 CvSig : 0x53445352 | SigGuid F26A4B2F-8931-460D-AF17156728DCEE23 Age : 0x1 (1) | Pdb : D:\JenkinsWorkspace\workspace\client_build_release\client\build\working_directory\RelWithDebInfo\upc.pdb [Debug Info] (record 2 of 3) (file offset 0xAE1ABC) Characteristics : 0x0 | TimeDateStamp : 0x5C7FCB72 (Wed 06th Mar 2019 13:30:26 (GMT)) | MajorVer : 0 / MinorVer : 0 -> (0.0) Type : 12 (0xC) -> Undocumented | Size : 0x14 (20) AddressOfRawData : 0x2C56094 | PointerToRawData : 0xAE1694 [Debug Info] (record 3 of 3) (file offset 0xAE1AD8) Characteristics : 0x0 | TimeDateStamp : 0x5C7FCB72 (Wed 06th Mar 2019 13:30:26 (GMT)) | MajorVer : 0 / MinorVer : 0 -> (0.0) Type : 13 (0xD) -> Undocumented | Size : 0x3F8 (1016) AddressOfRawData : 0x2C560A8 | PointerToRawData : 0xAE16A8 [!] Ubisoft UBX detected ! [!] VM Protect detected ! [CompilerDetect] -> Borland Delphi (unknown version) - 20% probability - Scan Took : 2.857 Second(s) [00000085Fh (2143) tick(s)] [506 of 580 scan(s) done] --- snip ---
$ sha1sum UplayInstaller.exe 8ec8e8fc9fab1d1105570a37dd43251c313c380c UplayInstaller.exe
$ du -sh UplayInstaller.exe 86M UplayInstaller.exe
$ wine --version wine-4.4-
Regards