[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