[Bug 28001] ExeCryptor protected apps/games complain with 'Clock manipulation detected!' (World War One Gold demo, Universal Mechanic)
wine-bugs at winehq.org
wine-bugs at winehq.org
Wed Jan 25 18:02:06 CST 2012
http://bugs.winehq.org/show_bug.cgi?id=28001
Anastasius Focht <focht at gmx.net> changed:
What |Removed |Added
----------------------------------------------------------------------------
Status|UNCONFIRMED |NEW
CC| |focht at gmx.net
Component|-unknown |wineserver
Summary|World War One Gold demo |ExeCryptor protected
|fails to start: 'Clock |apps/games complain with
|manipulation detected!' |'Clock manipulation
|[Exe Cryptor protection] |detected!' (World War One
| |Gold demo, Universal
| |Mechanic)
Ever Confirmed|0 |1
--- Comment #3 from Anastasius Focht <focht at gmx.net> 2012-01-25 18:02:06 CST ---
Hello,
lots of anti-debugging trickery.
It seems the author of the protection really hates Ollydbg ;-)
The protection stores the trial/license data encrypted in registry (location
depends on packaged app).
"bad" case = wineserver NOT running, everything gets bootstrapped through app
start (services/winemenubuilder).
"good" case = wineserver and services already running, winemenubuilder
process(es) exited.
--- snip ---
...
0039:Call TLS callback
(proc=0x11b729f,module=0x400000,reason=THREAD_ATTACH,reserved=0)
0039:Ret TLS callback
(proc=0x11b729f,module=0x400000,reason=THREAD_ATTACH,reserved=0)
0039:Starting thread proc 0xa0a450 (arg=0x32fc3c)
0039:Call KERNEL32.GetTickCount() ret=009f13a6
0039:Ret KERNEL32.GetTickCount() retval=00001022 ret=009f13a6
0039:Call KERNEL32.GetCurrentProcess() ret=009d50bc
0039:Ret KERNEL32.GetCurrentProcess() retval=ffffffff ret=009d50bc
0039:Call
KERNEL32.GetProcessTimes(ffffffff,0032fca0,0032fc98,0032fc98,0032fc98)
ret=009d50c2
0039:Ret KERNEL32.GetProcessTimes() retval=00000001 ret=009d50c2
0039:Call TLS callback
(proc=0x11b729f,module=0x400000,reason=THREAD_DETACH,reserved=0)
0039:Ret TLS callback
(proc=0x11b729f,module=0x400000,reason=THREAD_DETACH,reserved=0)
...
0024:Ret KERNEL32.WaitForSingleObject() retval=00000000 ret=009d8d2b
0024:Call KERNEL32.CloseHandle(00000050) ret=009d8d30
0024:Ret KERNEL32.CloseHandle() retval=00000001 ret=009d8d30
0024:Call
KERNEL32.CreateThread(00000000,00000000,00a0a450,0032fc3c,00000000,0032fc38)
ret=00df27fe
0024:Ret KERNEL32.CreateThread() retval=00000050 ret=00df27fe
0024:Call KERNEL32.WaitForSingleObject(00000050,ffffffff) ret=009d8d2b
...
003a:Call TLS callback
(proc=0x11b729f,module=0x400000,reason=THREAD_ATTACH,reserved=0)
003a:Ret TLS callback
(proc=0x11b729f,module=0x400000,reason=THREAD_ATTACH,reserved=0)
003a:Starting thread proc 0xa0a450 (arg=0x32fc3c)
003a:Call KERNEL32.FileTimeToLocalFileTime(0032fc8c,0032fc8c) ret=00df51ac
003a:Ret KERNEL32.FileTimeToLocalFileTime() retval=00000001 ret=00df51ac
003a:Call KERNEL32.FileTimeToDosDateTime(0032fc8c,0032fc76,0032fc74)
ret=009d7b4b
003a:Ret KERNEL32.FileTimeToDosDateTime() retval=00000001 ret=009d7b4b
003a:Call TLS callback
(proc=0x11b729f,module=0x400000,reason=THREAD_DETACH,reserved=0)
003a:Ret TLS callback
(proc=0x11b729f,module=0x400000,reason=THREAD_DETACH,reserved=0)
...
0024:Call advapi32.RegOpenKeyExA(80000001,0032fb90
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Shell
Extensions\\Approved\\{0AACAEAC-62E8-F4E5-C80B-4E70445C5704}",00000000,00000001,0032fca0)
ret=00a03492
0024:Ret advapi32.RegOpenKeyExA() retval=00000000 ret=00a03492
0024:Call advapi32.RegQueryValueExA(00000050,0032fa90
"iaababkngnelnefogn",00000000,0032fc94,00000000,0032fc98) ret=009c776a
0024:Ret advapi32.RegQueryValueExA() retval=00000000 ret=009c776a
0024:Call advapi32.RegQueryValueExA(00000050,0032fa90
"iaababkngnelnefogn",00000000,0032fc94,0032f548,0032fc98) ret=009e222b
0024:Ret advapi32.RegQueryValueExA() retval=00000000 ret=009e222b
...
0024:Call advapi32.RegCreateKeyExA(80000001,0032fb98
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Shell
Extensions\\Approved\\{0AACAEAC-62E8-F4E5-C80B-4E70445C5704}",00000000,00000000,00000000,00000002,00000000,0032fc9c,0032f520)
ret=009e981b
0024:Ret advapi32.RegCreateKeyExA() retval=00000000 ret=009e981b
0024:Call advapi32.RegSetValueExA(00000050,0032fa98
"hacpgngcfdkfdnmm",00000000,00000003,0032f950,00000015) ret=009e3e55
0024:Ret advapi32.RegSetValueExA() retval=00000000 ret=009e3e55
--- snip ---
There are lots of threads created which execute short snippets of code
(anti-debugging tricks/date/timing checks, etc.)
These might not even call any Windows API (through obfuscated thunks).
Most likely the author wanted to prevent easy use of hardware breakpoints (per
thread context).
If the debugger supports break-on-thread-create event (halt in new thread
entry) one can of course circumvent this technique easily (hooking
Create(Remote)Thread and bpx on entry address parameter also works).
The culprit actually lies in the GetProcessTimes() API call, executed in one of
these thread snippets.
I made a +server trace for both cases which gives better info:
"good" (wineserver prestarted):
--- snip ---
...
0039: init_thread( unix_pid=18227, unix_tid=18250, debug_level=1, teb=7ffd4000,
entry=00a0a450, reply_fd=23, wait_fd=25, cpu=x86 )
0039: init_thread() = 0 { pid=0023, tid=0039, server_start=1ccdbb19a715bb0
(-11.0328730), info_size=0, version=430, all_cpus=00000001 }
0024: select( flags=4, cookie=0032f99c, signal=0000, prev_apc=0000,
timeout=infinite, result={}, handles={0050} )
0024: select() = PENDING { timeout=infinite, call={APC_NONE}, apc_handle=0000 }
0039: get_process_info( handle=ffffffff )
0039: get_process_info() = 0 { pid=0023, ppid=0000, affinity=0000000f,
peb=7ffdf000, start_time=1ccdbb1a0bab52a (-0.4873940), end_time=0,
exit_code=259, priority=2, cpu=x86, debugger_present=0 }
...
0039: *killed* exit_code=0
--- snip ---
"bad" (no wineserver prior, full bootstrap with app):
Even in this small snippet I had to filter out interleaving messages from
different threads/processes due to parallel start of services/winemenubuilder.
--- snip ---
...
0037:Call
KERNEL32.GetProcessTimes(ffffffff,0032fca0,0032fc98,0032fc98,0032fc98)
ret=009d50c2
0037: get_process_info( handle=ffffffff )
0037: get_process_info() = 0 { pid=0008, ppid=0000, affinity=0000000f,
peb=7ffdf000, start_time=1ccdbb1f4271956 (-0.8753710), end_time=0,
exit_code=259, priority=2, cpu=x86, debugger_present=0 }
0037:Ret KERNEL32.GetProcessTimes() retval=00000001 ret=009d50c2
0037:Call TLS callback
(proc=0x11b729f,module=0x400000,reason=THREAD_DETACH,reserved=0)
0037:Ret TLS callback
(proc=0x11b729f,module=0x400000,reason=THREAD_DETACH,reserved=0)
...
0037: *killed* exit_code=0
--- snip ---
The culprit is the process' "start_time" field: -0.4873940 vs. -0.8753710
Basically the time between recorded "birth" in wineserver and reaching that
code snippet that retrieves the process start time is too long when fully
bootstrapping (no wineserver running prior).
For testing purpose I moved the "process->start_time" field initialization
(current_time) to "init_process_done" in wineserver (when the process is fully
initialized).
This helped.
Even full bootstrap now displays the registration dialog.
--- snip ---
0037: get_process_info( handle=ffffffff )
0037: get_process_info() = 0 { pid=0008, ppid=0000, affinity=0000000f,
peb=7ffdf000, start_time=1ccdbb9cd1207a6 (-0.3414070), end_time=0,
exit_code=259, priority=2, cpu=x86, debugger_present=0 }
--- snip ---
-> -0.3414070
Maybe Alexandre can comment if such a change, that is setting "birth" time a
bit later in wineserver might be feasible.
This is all Wine internal process initialization hence the child doesn't really
know what happened during "birth" and how long, before the first code in
entry/tls callback is executed.
Otherwise this bug is basically a WONTFIX.
Workaround: start wineserver through other apps prior running the app/game to
get a faster startup phase.
$ sha1sum um60.exe
245ee74f099671b25cdf4d50321d51cc63bea4e4 um60.exe
$ wine --version
wine-1.3.37-413-g5f42f7d
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