WineHQ
Bug Tracking Database – Bug 28001

 Bugzilla

 

Last modified: 2013-12-20 12:43:21 UTC  

ExeCryptor protected apps/games complain with 'Clock manipulation detected!' (World War One Gold demo, Universal Mechanic)

Bug 28001 - ExeCryptor protected apps/games complain with 'Clock manipulation detected!' (World War One Gold demo, Universal Mechanic)
ExeCryptor protected apps/games complain with 'Clock manipulation detected!' ...
Status: CLOSED FIXED
AppDB: Show Apps affected by this bug
Product: Wine
Classification: Unclassified
Component: wineserver
1.3.26
x86 Linux
: P2 normal
: ---
Assigned To: Mr. Bugs
http://www.fileplanet.com/212341/2100...
: download, obfuscation
Depends on:
Blocks:
  Show dependency tree
 
Reported: 2011-08-06 10:10 UTC by Béla Gyebrószki
Modified: 2013-12-20 12:43 UTC (History)
3 users (show)

See Also:
Regression SHA1:
Fixed by SHA1: d506e59dabc985be0a24c47112102af409a25b39
Distribution: ---
Staged patchset:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Béla Gyebrószki 2011-08-06 10:10:43 UTC
After starting the trial version of the game I'm getting the following error message:
'Clock manipulation detected!'
Afterwards the game simply quits.
Not a single line appears in the terminal during the game execution.

Normally (under Windows), a trial reminder should appear, showing something like
'You have xx days left'.

The problem is probably due to the fact that the game executable is protected by ExeCryptor. Protection Id tells us the facts:

Scanning -> C:\Program Files\World War One Gold\WW1.exe
File Type : 32-Bit Exe (Subsystem : Win GUI / 2), Size : 9533952 (0917A00h) Byte(s)
[File Heuristics] -> Flag : 00000000000000011100000000100011 (0x0001C023)
[!] EXE Cryptor v2.20 - v2.40 detected !
[!] Possible CD/DVD-Key or Serial Check -> trial period
[CompilerDetect] -> Visual C++ 8.0 (Visual Studio 2005)
- Scan Took : 1.459 Second(s)

Note: the size of the demo for WWI Gold is huge (1.4 GB). One can easily reproduce the reported problem by starting the trial version of Universal Mechanic (uses the same protection method, only 88 MB):
http://www.umlab.ru/download/60/eng/um60.exe
(after installation launch either UMInput.exe or UmSimul.exe to get the same error message).

Fedora 15 x86
Comment 1 Béla Gyebrószki 2011-08-06 10:11:10 UTC
Added some keywords.
Comment 2 Bruno Jesus 2011-08-06 18:05:33 UTC
I tested the Universal Mechanic and could reproduce the bug but it seems to be closely related to timing because when I tried a WINEDEBUG=+all redirecting the output to a file the application started correctly. I guess it was due to the delays introduced by the file writing (?).
Comment 3 Anastasius Focht 2012-01-25 18:02:06 UTC
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
Comment 4 Anastasius Focht 2013-12-18 12:28:36 UTC
Hello folks,

revisiting, still present.

--- snip ---
$ pwd
/home/focht/.wine/drive_c/Program Files/UM Software Lab/UM 6.0.0/bin

$ wineserver -k ; WINEDEBUG=+msgbox wine ./UMInput.exe 
trace:msgbox:MSGBOX_OnInit L"Clock manipulation detected!"
--- snip ---

Setting process start time in 'init_process_done' still fixes this (as proposed in my previous comment #3).

Source: http://source.winehq.org/git/wine.git/blob/1e78c99388c61d353cf60787eac6415328f54560:/server/process.c#l1046

$ sha1sum um60.exe 
e39442618f0d8afc7289ff455ecdd939d4c01bcd  um60.exe

$ du -sh um60.exe 
87M	um60.exe

$ wine --version
wine-1.7.8-248-g8dd9c61

Regards
Comment 5 Anastasius Focht 2013-12-20 11:31:31 UTC
Hello folks,

this is fixed by commit http://source.winehq.org/git/wine.git/commitdiff/d506e59dabc985be0a24c47112102af409a25b39

Thanks Austin

Regards
Comment 6 Alexandre Julliard 2013-12-20 12:43:21 UTC
Closing bugs fixed in 1.7.9.


Privacy Policy
If you have a privacy inquiry regarding this site, please write to [email protected]

Hosted By CodeWeavers