[Bug 24374] Driller crashes in process PE entry point due to Wine's mis-align workaround for 32-bit entry point asm wrapper (MoleBox Ultra v4.x)

wine-bugs at winehq.org wine-bugs at winehq.org
Fri Aug 8 17:35:03 CDT 2014


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

Anastasius Focht <focht at gmx.net> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |obfuscation
             Status|UNCONFIRMED                 |NEW
                 CC|                            |focht at gmx.net
          Component|-unknown                    |kernel32
            Summary|Driller fails to start      |Driller crashes in process
                   |                            |PE entry point due to
                   |                            |Wine's mis-align workaround
                   |                            |for 32-bit entry point asm
                   |                            |wrapper (MoleBox Ultra
                   |                            |v4.x)
     Ever confirmed|0                           |1

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

confirming. The app is protected by 'MoleBox Ultra v4.x'

Wine implements a workaround for broken apps when setting up the stack for the
process entry point (misaligns the stack).
This harms the protection code because it expects specific values/layout on the
process entry stack.

A trace log with +relay is not really useful here since it influences stack
layout/values and the crash is at entry point anyway.

The protection code at PE entry point:

--- snip ---
10001004  6A 28            PUSH 28
10001006  68 70204000      PUSH 402070
1000100B  E8 74020000      CALL Driller.10001284 ; see next chunk
10001010  33FF             XOR EDI,EDI
10001012  57               PUSH EDI
10001013  FF15 00D02910    CALL DWORD PTR DS:[<&kernel32.GetModuleHandleA>
10001019  66:8138 4D5A     CMP WORD PTR DS:[EAX],5A4D
...
10001284  68 D0124000      PUSH 4012D0
10001289  64:A1 00000000   MOV EAX,DWORD PTR FS:[0]
1000128F  50               PUSH EAX
10001290  8B4424 10        MOV EAX,DWORD PTR SS:[ESP+10]
10001294  896C24 10        MOV DWORD PTR SS:[ESP+10],EBP
10001298  8D6C24 10        LEA EBP,DWORD PTR SS:[ESP+10]
1000129C  2BE0             SUB ESP,EAX
1000129E  53               PUSH EBX
1000129F  56               PUSH ESI
100012A0  57               PUSH EDI
100012A1  8B45 F8          MOV EAX,DWORD PTR SS:[EBP-8]
100012A4  8965 E8          MOV DWORD PTR SS:[EBP-18],ESP
100012A7  50               PUSH EAX
100012A8  8B45 FC          MOV EAX,DWORD PTR SS:[EBP-4]
100012AB  C745 FC FFFFFFFF MOV DWORD PTR SS:[EBP-4],-1
100012B2  8945 F8          MOV DWORD PTR SS:[EBP-8],EAX
100012B5  8D45 F0          LEA EAX,DWORD PTR SS:[EBP-10] ; 0x0033FE10
100012B8  8B70 C8          MOV ESI,DWORD PTR DS:[EAX-38]
100012BB  8B40 20          MOV EAX,DWORD PTR DS:[EAX+20] ; [0x0033FE30] -> 0x23
100012BE  8D40 04          LEA EAX,DWORD PTR DS:[EAX+4]  ; -> 0x27
100012C1  50               PUSH EAX
100012C2  8B76 05          MOV ESI,DWORD PTR DS:[ESI+5]
100012C5  FF16             CALL DWORD PTR DS:[ESI] ; kernel32.GetModuleHandleA
--- snip ---

'kernel32.GetModuleHandleA(0x27)' -> *boom*

Callstack at PE entry point, annotated:

--- snip ---
0033FE24  7B8642D4 ; return from asm wrapper 'CALL DWORD PTR SS:[EBP+C]'
0033FE28  7FFDF000 ; PEB *peb
0033FE2C  7B8642CB ; mis-align workaround, offset to 'call_process_entry'
0033FE30  00000023 ; mis-align workaround, garbage ---> *problem*
0033FE34  00000302 ; mis-align workaround, garbage
0033FE38  0033FE98 ; saved EBP
0033FE3C  7B864421 ; return from KERNEL32.call_process_entry
0033FE40  7FFDF000 ; PEB *peb
0033FE44  10001004 ; LPTHREAD_START_ROUTINE entry
--- snip ---

Source:
http://source.winehq.org/git/wine.git/blob/fd6c5490dfe8818b1f9fa19e6502e22ae1736e05:/dlls/kernel32/process.c#l1048

--- snip ---
1048 #ifdef __i386__
1049 extern DWORD call_process_entry( PEB *peb, LPTHREAD_START_ROUTINE entry );
1050 __ASM_GLOBAL_FUNC( call_process_entry,
1051                     "pushl %ebp\n\t"
1052                     __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
1053                     __ASM_CFI(".cfi_rel_offset %ebp,0\n\t")
1054                     "movl %esp,%ebp\n\t"
1055                     __ASM_CFI(".cfi_def_cfa_register %ebp\n\t")
1056                     "subl $12,%esp\n\t" /* deliberately mis-align the
stack by 8, Doom 3 needs this */
1057                     "pushl 8(%ebp)\n\t"
1058                     "call *12(%ebp)\n\t"
1059                     "leave\n\t"
1060                     __ASM_CFI(".cfi_def_cfa %esp,4\n\t")
1061                     __ASM_CFI(".cfi_same_value %ebp\n\t")
1062                     "ret" )
1063 #else
1064 static inline DWORD call_process_entry( PEB *peb, LPTHREAD_START_ROUTINE
entry )
1065 {
1066     return entry( peb );
1067 }
1068 #endif
--- snip ---

The mis-align workaround moves potentially garbage values into view from PE
entry point perspective when it examines the caller stack.

The protection code ought to read 'call_process_entry' caller return address
from stack, adding four(?) and passing this address as module name to
'kernel32.GetModuleHandleA' (see previous entry point disassembly).

This (garbage) module name is not really useful at all - but it has an
important property: it points into mapped 'kernel32 .text' section (four bytes
after 'call_process_entry' caller return address) - hence the "string" is
readable.
The API call is expected to fail (returning NULL).

If you really need to mis-align the stack in the 32-bit asm wrapper you need to
put valid/mapped addresses as stack value(s) into misalignment area.

Protection scan:

--- snip ---
-=[ ProtectionID v0.6.5.5 OCTOBER]=-
(c) 2003-2013 CDKiLLER & TippeX
Build 31/10/13-21:09:09
Ready...
Scanning -> Z:\home\focht\Downloads\Driller.exe
File Type : 32-Bit Exe (Subsystem : Win GUI / 2), Size : 23620456 (01686B68h)
Byte(s)
-> File has 22539112 (0157EB68h) bytes of appended data starting at offset
0108000h
[File Heuristics] -> Flag : 00000000000000000000000000000100 (0x00000004)
[Entrypoint Section Entropy] : 7.73
[!] MoleBox Ultra v4.x detected !
[i] relinked sections: yes
- Scan Took : 0.639 Second(s) [00000027Fh tick(s)] [533 scan(s) done]
--- snip ---

$ sha1sum install-driller.zip 
bd737b9bbd3c8fcb3000e532db987a505876af2a  install-driller.zip

$ du -sh install-driller.zip 
23M    install-driller.zip

$ wine --version
wine-1.7.23-90-gbdeb761

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