[Bug 27349] New: SafeDisc v2.x API entry analyzer flags Wine's user32.dll as "bad" (too many exports with PIC loads in prolog code) (SimCity 4, ...)

wine-bugs at winehq.org wine-bugs at winehq.org
Tue May 31 17:22:20 CDT 2011


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 at winehq.org
        ReportedBy: focht at 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

-- 
Configure bugmail: http://bugs.winehq.org/userprefs.cgi?tab=email
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