http://bugs.winehq.org/show_bug.cgi?id=27349
Summary: SafeDisc v2.x API entry analyzer flags Wine's user32.dll as "bad" (too many exports with PIC loads in prolog code) (SimCity 4, ...) Product: Wine Version: 1.3.21 Platform: x86 OS/Version: Linux Status: NEW Severity: normal Priority: P2 Component: user32 AssignedTo: wine-bugs@winehq.org ReportedBy: focht@gmx.net
Hello,
many games (and some apps) have dependency on "meta" bug 219 "Programs refuse to run because of safedisc copy-protection" which just bad (not even targeting specific version).
I bought some games for few bucks just to have a look at some copy protections. Though I will probably never play them ;-)
Collecting/tracking affected games/apps for this _specific_ issue here (applicable appdb entries should have bug 219 dependency removed in favor of this one).
The root cause was already targeted by bug 10273 ("satisfy SafeDisc 2.x heuristic API analyzer by "adjusting" API exports/entry statistics of wine builtins (affects e.g. adobe photoshop)") ... That bug was closed a long time ago because it ought to work for various SD 2.x apps/games (unfortunately also depending on wine build environment/host gcc).
I rejected the idea of reviving that bug and instead created a new one, targeting the affected core dll.
Game: "SimCity 4"
A quick scan with "ProtectionID" reveals:
--- snip --- -=[ ProtectionID v0.6.4.0 JULY]=- (c) 2003-2010 CDKiLLER & TippeX Build 07/08/10-17:57:05 Ready... Scanning -> H:.wine\drive_c\Program Files\Maxis\SimCity 4\Apps\SimCity 4.exe File Type : 32-Bit Exe (Subsystem : Win GUI / 2), Size : 7971630 (079A32Eh) Byte(s) [x] Warning - FileAlignment seems wrong.. no solution calculated (using NULL) -> File has 746286 (0B632Eh) bytes of appended data starting at offset 06E4000h [File Heuristics] -> Flag : 00000000000000000100000100000111 (0x00004107) [!] Safedisc v2/v3/v4 [unknown version] detected ! [i] Appended data contents.... ... [CompilerDetect] -> Visual C++ 6.0 - Scan Took : 0.262 Second(s) --- snip ---
We can do better ... The string "BoG_" is well known for detection of SafeDisc versions.
--- snip --- $:~/.wine/drive_c/Program Files/Maxis/SimCity 4/Apps$ xxd -g 4 SimCity\ 4.exe | grep "BoG_" -A 2 0006fd0: 00000000 426f475f 202a3930 2e302621 ....BoG_ *90.0&! 0006fe0: 21202059 793e0000 00000000 00000000 ! Yy>.......... 0006ff0: 00000000 02000000 50000000 0a000000 ........P....... --- snip ---
0x02000000 -> 2 0x50000000 -> 90 0x0a000000 -> 10
So this is SafeDisc v2.90.10 protection. By debugging this game I came to conclusion there is still a problem with the API entry statistics.
$ wine --version wine-1.3.21-26-ge6ee2c1
$ gcc --version gcc version 4.4.5 (Ubuntu/Linaro 4.4.4-14ubuntu5)
For the meaning of the table just read up some comments in bug 10273
kernel32 user32 gdi32 condition (cx < threshold) -------------------------------------------------------------------- c1: 0x43 0x55 0x50 0x5F c2: 0x23 *0x41 0x39 0x3C c3: 0x00 0x00 0x00 0x5A
* = threshold exceeded -> bad
Basically the majority of exported user32 API entries have PIC register load code within range of first 8 opcode bytes of entry which is treated as trampoline (= high c2 value).
--- snip --- ... .text:0001D847 __i686_get_pc_thunk_bx proc near .text:0001D847 mov ebx, [esp+0] .text:0001D84A retn .text:0001D84A __i686_get_pc_thunk_bx endp ... API entry: .text:0003735C push ebp .text:0003735D mov ebp, esp .text:0003735F push ebx .text:00037360 sub esp, 34h .text:00037363 call __i686_get_pc_thunk_bx .text:00037368 add ebx, 0AEC8Ch ... --- snip ---
Kernel32 gets the good looking stats because it forwards various stuff to ntdll, letting compiler produce different function prolog code (= not having PIC register load in first place). As already mentioned in the other bug, unimpl. stubs also help to improve stats because they have 8 NOPs on entry.
I've tweaked user32 again a bit just to pass the threshold - there are various ugly methods one bad as the other ;-|
A method without adding unimpl. stubs or stack protector code (unreliable because cookie code can be inserted _after_ PIC code) and keeping -fPIC is to convince the compiler to use the 6 byte opcode for reserving stack space, e.g. "subl $xxx, %esp" with a 32-bit immediate (0x81,0xEB,<32 bit immediate>). Good targets are stubs and functions that make use of FIXME/TRACE. There are lots of them that can be tweaked this way (= no performance penalty), improving entry stats.
Result: games work out of the box without the need of No-CD patches.
Regards