[Bug 37785] New: dBASE Plus 9.x demo crashes on startup (custom DRM scheme translates API entry points to dynamic thunks, calling PIC code outside of original code section)
wine-bugs at winehq.org
wine-bugs at winehq.org
Fri Dec 26 16:21:19 CST 2014
https://bugs.winehq.org/show_bug.cgi?id=37785
Bug ID: 37785
Summary: dBASE Plus 9.x demo crashes on startup (custom DRM
scheme translates API entry points to dynamic thunks,
calling PIC code outside of original code section)
Product: Wine
Version: 1.7.33
Hardware: x86
OS: Linux
Status: NEW
Severity: normal
Priority: P2
Component: kernel32
Assignee: wine-bugs at winehq.org
Reporter: focht at gmx.net
Distribution: ---
Hello folks,
reported by a user in #winehq
The app seems to be protected by a custom DRM scheme which causes some grief.
I couldn't find a known signature using protection scanners ... but that
doesn't matter in the end :)
Another protection that tries to be uberclever, rewriting/translating API entry
points.
Unlike other protection schemes which only target the prolog code, this one
processes *all* entry point opcodes.
It disassembles them and partially replaces opcodes with alternatives which
preserves the original semantics of the code sequence. The "new" sequence is
written out to a dynamic thunk on heap and referred via trampolines from its
own code.
Example API entry, original 'GetStartupInfoW':
--- snip ---
.text:7B83ADE7 push ebp
.text:7B83ADE8 mov ebp, esp
.text:7B83ADEA push edi
.text:7B83ADEB push esi
.text:7B83ADEC push ebx
.text:7B83ADED call __x86_get_pc_thunk_bx
.text:7B83ADF2 add ebx, 8420Eh
.text:7B83ADF8 mov eax, [ebp+8]
.text:7B83ADFB mov edx, eax
.text:7B83ADFD lea esi, (startup_infoW.cb - 7B8BF000h)[ebx]
.text:7B83AE03 mov eax, 11h
.text:7B83AE08 mov edi, edx
.text:7B83AE0A mov ecx, eax
.text:7B83AE0C rep movsd
.text:7B83AE0E pop ebx
.text:7B83AE0F pop esi
.text:7B83AE10 pop edi
.text:7B83AE11 pop ebp
.text:7B83AE12 retn 4
--- snip ---
The protection scheme translates the entry point to a dynamic thunk:
--- snip ---
003E3208 52 PUSH EDX
003E3209 892C24 MOV DWORD PTR SS:[ESP],EBP
003E320C 89E5 MOV EBP,ESP
003E320E 52 PUSH EDX
003E320F 893C24 MOV DWORD PTR SS:[ESP],EDI
003E3212 50 PUSH EAX
003E3213 893424 MOV DWORD PTR SS:[ESP],ESI
003E3216 EB 03 JMP SHORT 003E321B
...
003E321B 50 PUSH EAX
003E321C 891C24 MOV DWORD PTR SS:[ESP],EBX
003E321F 87E4 XCHG ESP,ESP
003E3221 E8 AAC6437B CALL 7B81F8D0 ; __x86_get_pc_thunk_bx
003E3226 81C3 0E420800 ADD EBX,8420E
003E322C 3E:8B45 08 MOV EAX,DWORD PTR DS:[EBP+8]
003E3230 8D10 LEA EDX,[EAX]
003E3232 8DB3 005B1A00 LEA ESI,[EBX+1A5B00]
003E3238 B8 11000000 MOV EAX,11
003E323D 3E:8D3A LEA EDI,DS:[EDX]
003E3240 3E:8D08 LEA ECX,DS:[EAX]
003E3243 F3:A5 REP MOVS DWORD PTR ES:[EDI],DWORD PTR DS:[ESI]
003E3245 5B POP EBX
003E3246 8B3424 MOV ESI,DWORD PTR SS:[ESP]
003E3249 8D6424 04 LEA ESP,[ESP+4]
003E324D 8B3C24 MOV EDI,DWORD PTR SS:[ESP]
003E3250 8D6424 04 LEA ESP,[ESP+4]
003E3254 8B2C24 MOV EBP,DWORD PTR SS:[ESP]
003E3257 8D6424 04 LEA ESP,[ESP+4]
003E325B C2 0400 RETN 4
...
__x86_get_pc_thunk_bx:
7B81F8D0 8B1C24 MOV EBX,DWORD PTR SS:[ESP]
7B81F8D3 C3 RETN
--- snip ---
This of course can't work with Wine's PIC code.
'__x86_get_pc_thunk_bx' must be called from within the original code section
otherwise the PC relative offset will be always wrong.
I started placing wrapper functions in between to preserve the PIC semantics
(which works) but gave up after seeing that almost every API call is affected.
I don't think it's worth to waste more time with this unless someone writes a
code generator to wrap every entry point containing PIC code in automated way.
$ sha1sum Plus951b2426Full20141124.exe
997a7411a0c7b8c1e0598142d1b3c3da9005147b Plus951b2426Full20141124.exe
$ du -sh Plus951b2426Full20141124.exe
182M Plus951b2426Full20141124.exe
$ wine --version
wine-1.7.33-84-gfecbc88
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