https://bugs.winehq.org/show_bug.cgi?id=42716
Anastasius Focht focht@gmx.net changed:
What |Removed |Added ---------------------------------------------------------------------------- CC| |focht@gmx.net Summary|MetaTrader5 64-bit refuses |64-bit MetaTrader5 refuses |to start when |to start, reports 'A |IsDebuggerPresent returns |debugger has been found |true |running in your system' | |(Denuvo Anti-Tamper x64) URL| |https://download.mql5.com/c | |dn/web/metaquotes.software. | |corp/mt5/mt5setup.exe?utm_c | |ampaign=www.metaquotes.net Status|UNCONFIRMED |NEW Keywords| |download, obfuscation Ever confirmed|0 |1 Component|kernel32 |-unknown
--- Comment #9 from Anastasius Focht focht@gmx.net --- Hello folks,
the conclusion is wrong, correcting summary.
The app is wrapped with Denuvo "Anti-Tamper" x64 software protection.
ProtectionID scan:
--- snip --- -=[ ProtectionID v0.6.8.5 DECEMBER]=- (c) 2003-2017 CDKiLLER & TippeX Build 24/12/16-13:09:21 Ready... Scanning -> Z:\home\focht\Downloads\MetaTrader 5\terminal64.exe File Type : 64-Bit Exe (Subsystem : Win GUI / 2), Size : 16390320 (0FA18B0h) Byte(s) | Machine: 0x8664 (AMD64) [!] Warning -> File needs higher OS (Current OS : 05.01, Requires OS: 06.00) [!] Warning : File is 64 Bit, this os is NOT Compilation TimeStamp : 0x00F30400 -> Sat 04th Jul 1970 07:57:52 (GMT) [TimeStamp] 0x00F30400 -> Sat 04th Jul 1970 07:57:52 (GMT) | PE Header | - | Offset: 0x00000000:00000150 | VA: 0x00000001:40000150 | - [TimeStamp] 0x59009228 -> Wed 26th Apr 2017 12:27:20 (GMT) | DebugDirectory | - | Offset: 0x00000000:00CCA664 | VA: 0x00000001:41F49E64 | - [TimeStamp] 0x59009228 -> Wed 26th Apr 2017 12:27:20 (GMT) | DebugDirectory | - | Offset: 0x00000000:00CCA680 | VA: 0x00000001:41F49E80 | - [TimeStamp] 0x59009228 -> Wed 26th Apr 2017 12:27:20 (GMT) | DebugDirectory | - | Offset: 0x00000000:00CCA69C | VA: 0x00000001:41F49E9C | - -> File Appears to be Digitally Signed @ Offset 0F9FFA8h, size : 01908h / 06408 byte(s) -> File has 457640 (06FBA8h) bytes of appended data starting at offset 0F30400h [!] Executable uses TLS callbacks (3 total... 0 invalid addresses) [File Heuristics] -> Flag #1 : 00000100000001001101001000000101 (0x0404D205) [Entrypoint Section Entropy] : 7.99 (section #8) ".cod1 " | Size : 0xD3142C (13833260) byte(s) [DllCharacteristics] -> Flag : (0x8160) -> HEVA | ASLR | DEP | TSA [SectionCount] 11 (0xB) | ImageSize 0x2E15000 (48320512) byte(s) [VersionInfo] Company Name : MetaQuotes Software Corp. [VersionInfo] Product Name : MetaTrader 5 Client Terminal [VersionInfo] Product Version : 5.0.0.1596 [VersionInfo] File Description : MetaTrader 5 Client Terminal [VersionInfo] File Version : 5.0.0.1596 [VersionInfo] Original FileName : terminal.exe [VersionInfo] Internal Name : terminal.exe [VersionInfo] Version Comments : http://www.metaquotes.net [VersionInfo] Legal Trademarks : MetaTrader [VersionInfo] Legal Copyrights : © 2001-2017. MetaQuotes Software Corp. [ModuleReport] [IAT] Modules -> CRYPT32.dll | WINMM.dll | VERSION.dll | NETAPI32.dll | WINHTTP.dll | gdiplus.dll | UxTheme.dll | KERNEL32.dll | USER32.dll | GDI32.dll | MSIMG32.dll | WINSPOOL.DRV | ADVAPI32.dll | SHELL32.dll | COMCTL32.dll | SHLWAPI.dll | ole32.dll | OLEAUT32.dll | oledlg.dll | urlmon.dll | IPHLPAPI.DLL | dbghelp.dll | WS2_32.dll | Secur32.dll | OLEACC.dll | IMM32.dll | WTSAPI32.dll | KERNEL32.dll | USER32.dll | ADVAPI32.dll | KERNEL32.dll | ADVAPI32.dll [Debug Info] (record 1 of 3) (file offset 0xCCA660) Characteristics : 0x0 | TimeDateStamp : 0x59009228 (Wed 26th Apr 2017 12:27:20 (GMT)) | MajorVer : 0 / MinorVer : 0 -> (0.0) Type : 2 (0x2) -> CodeView | Size : 0x5B (91) AddressOfRawData : 0x1F499C0 | PointerToRawData : 0xCCA1C0 CvSig : 0x53445352 | SigGuid 5D5F75E6-83B5-4F0F-B56BB8527C4A0449 Age : 0x1 (1) | Pdb : E:\MetaTrader5\Client\MetaTrader5Terminal\Release64\terminal64.pdb [Debug Info] (record 2 of 3) (file offset 0xCCA67C) Characteristics : 0x0 | TimeDateStamp : 0x59009228 (Wed 26th Apr 2017 12:27:20 (GMT)) | MajorVer : 0 / MinorVer : 0 -> (0.0) Type : 12 (0xC) -> Undocumented | Size : 0x14 (20) AddressOfRawData : 0x1F49A20 | PointerToRawData : 0xCCA220 [Debug Info] (record 3 of 3) (file offset 0xCCA698) Characteristics : 0x0 | TimeDateStamp : 0x59009228 (Wed 26th Apr 2017 12:27:20 (GMT)) | MajorVer : 0 / MinorVer : 0 -> (0.0) Type : 13 (0xD) -> Undocumented | Size : 0x418 (1048) AddressOfRawData : 0x1F49A40 | PointerToRawData : 0xCCA240 [?] Possibly Denuvo "Anti-Tamper" x64 [CompilerDetect] -> Borland Delphi (unknown version) - 20% probability - Scan Took : 2.322 Second(s) [000000A76h (2678) tick(s)] [234 of 580 scan(s) done] --- snip ---
Some info:
https://steamcommunity.com/app/379720/discussions/0/357286119113278148/
https://www.reddit.com/r/CrackStatus/comments/43dgej/how_denuvo_works_and_wh...
Relevant trace log:
--- snip --- $ WINEDEBUG=+tid,+seh,+relay wine64 ./terminal64.exe >>log.txt 2>&1 ... 0037:Call TLS callback (proc=0x1416b3b84,module=0x140000000,reason=PROCESS_ATTACH,reserved=0) ... 0037:Call KERNEL32.GetModuleHandleA(0023f430 "kernel32.dll") ret=1416629fb 0037:Ret KERNEL32.GetModuleHandleA() retval=7b460000 ret=1416629fb 0037:Call KERNEL32.GetModuleHandleA(0023f430 "ntdll.dll") ret=1416629fb 0037:Ret KERNEL32.GetModuleHandleA() retval=7bc80000 ret=1416629fb 0037:Call KERNEL32.IsDebuggerPresent() ret=1416b988d 0037:Ret KERNEL32.IsDebuggerPresent() retval=00000000 ret=1416b988d 0037:Call KERNEL32.CheckRemoteDebuggerPresent(ffffffffffffffff,0023f68c) ret=1416b988d 0037:Ret KERNEL32.CheckRemoteDebuggerPresent() retval=00000001 ret=1416b988d 0037:Call ntdll.NtQueryInformationProcess(ffffffffffffffff,0000001e,0023f7f0,00000008,00000000) ret=1416b988d 0037:Ret ntdll.NtQueryInformationProcess() retval=c0000353 ret=1416b988d 0037:Call ntdll.NtSetInformationThread(fffffffffffffffe,00000011,00000000,00000000) ret=1416b988d 0037:Ret ntdll.NtSetInformationThread() retval=00000000 ret=1416b988d 0037:Call ntdll.NtQuerySystemInformation(00000023,0023fb20,00000002,00000000) ret=1416b988d 0037:Ret ntdll.NtQuerySystemInformation() retval=00000000 ret=1416b988d 0037:Call ntdll.NtQuerySystemInformation(0000000b,0023f5f8,00000000,0023fb38) ret=1416b988d 0037:Ret ntdll.NtQuerySystemInformation() retval=c0000004 ret=1416b988d 0037:Call KERNEL32.LocalAlloc(00000000,00005348) ret=1416b988d 0037:Ret KERNEL32.LocalAlloc() retval=00072080 ret=1416b988d 0037:Call ntdll.NtQuerySystemInformation(0000000b,00072080,00005348,00000000) ret=1416b988d 0037:Ret ntdll.NtQuerySystemInformation() retval=00000000 ret=1416b988d 0037:Call KERNEL32.LocalFree(00072080) ret=1416b988d 0037:Ret KERNEL32.LocalFree() retval=00000000 ret=1416b988d 0037:Call KERNEL32.VirtualProtect(140c7d000,0060201c,00000040,0023f670) ret=1416b988d 0037:Ret KERNEL32.VirtualProtect() retval=00000001 ret=1416b988d 0037:Call KERNEL32.VirtualProtect(1408b6000,0026ce26,00000004,0023f670) ret=1416b988d 0037:Ret KERNEL32.VirtualProtect() retval=00000001 ret=1416b988d 0037:Call KERNEL32.VirtualProtect(140001000,008b4744,00000040,0023f670) ret=1416b988d 0037:Ret KERNEL32.VirtualProtect() retval=00000001 ret=1416b988d 0037:Call KERNEL32.VirtualProtect(140bfb000,00063b70,00000004,0023f670) ret=1416b988d 0037:Ret KERNEL32.VirtualProtect() retval=00000001 ret=1416b988d 0037:Call KERNEL32.VirtualProtect(140c5f000,0001bcb8,00000004,0023f670) ret=1416b988d 0037:Ret KERNEL32.VirtualProtect() retval=00000001 ret=1416b988d 0037:Call KERNEL32.VirtualProtect(140c7b000,00000010,00000004,0023f670) ret=1416b988d 0037:Ret KERNEL32.VirtualProtect() retval=00000001 ret=1416b988d 0037:Call KERNEL32.VirtualProtect(140cae000,00005c58,00000004,0023f670) ret=1416b988d 0037:Ret KERNEL32.VirtualProtect() retval=00000001 ret=1416b988d 0037:Call KERNEL32.VirtualProtect(141fb3000,00e61674,00000004,0023f670) ret=1416b988d 0037:Ret KERNEL32.VirtualProtect() retval=00000001 ret=1416b988d ... 0037:Call KERNEL32.CloseHandle(deadc0de) ret=1416b988d 0037:Ret KERNEL32.CloseHandle() retval=00000000 ret=1416b988d 0037:trace:seh:raise_exception code=80000004 flags=0 addr=0x141f49833 ip=141f49833 tid=0037 0037:trace:seh:raise_exception rax=00000000e9b2b85c rbx=0000000141685350 rcx=00000000deadc0de rdx=00000000000055d1 0037:trace:seh:raise_exception rsi=0000000000000000 rdi=aaaaaaaaaaaaaaab rbp=000000000023f5a0 rsp=000000000023f550 0037:trace:seh:raise_exception r8=0000000000267148 r9=000000000000a388 r10=00000000c5fb301a r11=0000000000000038 0037:trace:seh:raise_exception r12=0000000141669385 r13=0000000000000048 r14=0000000000000004 r15=000000014166898c 0037:trace:seh:RtlVirtualUnwind type 1 rip 141f49833 rsp 23f550 0037:trace:seh:dump_unwind_info **** func 1f49767-1f498fa 0037:trace:seh:dump_unwind_info unwind info at 0x14164c650 flags 1 prolog 0x19 bytes function 0x141f49767-0x141f498fa ... 0037:trace:seh:call_handler calling handler 0x140c97ee0 (rec=0x23f410, frame=0x23f550 context=0x23e790, dispatch=0x23ec60) ... 0037:trace:seh:RtlRestoreContext returning to 141f4983e stack 23f550 0037:Call KERNEL32.GetModuleFileNameW(140000000,0023eb00,00000104) ret=141f496ef 0037:Ret KERNEL32.GetModuleFileNameW() retval=00000033 ret=141f496ef 0037:Call advapi32.OpenSCManagerW(00000000,00000000,00000004) ret=1416b988d ... 0037:Ret advapi32.OpenSCManagerW() retval=000725c0 ret=1416b988d 0037:Call advapi32.EnumServicesStatusExW(000725c0,00000000,00000030,00000001,00000000,00000000,0023f568,0023eae0,0023eae4,00000000) ret=141f496f9 ... 0037:Ret advapi32.EnumServicesStatusExW() retval=00000000 ret=141f496f9 0037:Call KERNEL32.GetLastError() ret=1416b988d 0037:Ret KERNEL32.GetLastError() retval=000000ea ret=1416b988d 0037:Call KERNEL32.LocalAlloc(00000000,0000021c) ret=1416b988d 0037:Ret KERNEL32.LocalAlloc() retval=00072740 ret=1416b988d 0037:Call advapi32.EnumServicesStatusExW(000725c0,00000000,00000030,00000001,00072740,0000021c,0023f568,0023eae0,0023eae4,00000000) ret=141f49703 ... 0037:Ret advapi32.EnumServicesStatusExW() retval=00000001 ret=141f49703 ... 0037:Call advapi32.CloseServiceHandle(000725c0) ret=1416b988d ... 0037:Ret advapi32.CloseServiceHandle() retval=00000001 ret=1416b988d 0037:Call KERNEL32.LoadLibraryA(0023e970 "user32.dll") ret=141653449 0037:Ret KERNEL32.LoadLibraryA() retval=7fccac340000 ret=141653449 0037:Call user32.MessageBoxW(00000000,0023ed10 L"A debugger has been found running in your system.\nPlease, unload it from memory and restart your program.",0023eb4a L"terminal64.exe",00000010) ret=1416b988d ... --- snip ---
Those anti-debugging tricks as seen from trace log seem to work fine with 64-bit:
* IsDebuggerPresent * CheckRemoteDebuggerPresent * NtQueryInformationProcess( ProcessDebugObjectHandle) * NtSetInformationThread( ThreadHideFromDebugger) * NtQuerySystemInformation( SystemKernelDebuggerInformation) * NtQuerySystemInformation( SystemModuleInformation) * CloseHandle( invalid handle/EXCEPTION_INVALID_HANDLE)
There is a lot of 64-bit virtual machine code which makes this kinda hard to debug/analyse.
The single step trap from trace log looks suspicious though.
--- snip --- 0037:trace:seh:raise_exception code=80000004 flags=0 addr=0x141f49833 ip=141f49833 tid=0037 --- snip ---
--- snip --- ... 0x0000000141f49802: call 0x000000014128b557 0x0000000141f49807: pushq $0xd92eb714 0x0000000141f4980c: call 0x000000014128b557 0x0000000141f49811: pushq $0x18ff4951 0x0000000141f49816: call 0x000000014128b557 0x0000000141f4981b: pushq $0xd8d940e7 0x0000000141f49820: call 0x000000014128b557 0x0000000141f49825: testb %ch,0xffffffffffffffae(%rax) 0x0000000141f49828: aad $0xd8 0x0000000141f4982a: popq %rax 0x0000000141f4982b: call 0x000000014128b557 0x0000000141f49830: popfl 0x0000000141f49831: rdtsc 0x0000000141f49833: nop 0x0000000141f49834: pushq $0x592872dc 0x0000000141f49839: call 0x000000014128b557 0x0000000141f4983e: pushq $0x58d88e4f 0x0000000141f49843: call 0x000000014128b557 0x0000000141f49848: popfl 0x0000000141f49849: rdtsc 0x0000000141f4984b: nop 0x0000000141f4984c: pushq $0x98d8fed4 0x0000000141f49851: call 0x000000014128b557 ...
Wine-dbg>b *0x0000000141f49830 Breakpoint 1 at 0x0000000141f49830 Wine-dbg>b *0x0000000141f49831 Breakpoint 2 at 0x0000000141f49831 Wine-dbg>c Stopped on breakpoint 1 at 0x0000000141f49830
Wine-dbg>info reg Register dump: rip:0000000141f49830 rsp:000000000023f538 rbp:000000000023f590 eflags:00000246 ( - -- I Z- -P- ) rax:0000000000000346 rbx:0000000141685350 rcx:00000000deadc0de rdx:00000000000787c0 rsi:0000000000000000 rdi:aaaaaaaaaaaaaaab r8:0000000000267148 r9:000000000000a400 r10:00000000c5fb2fee r11:0000000000000038 r12:0000000141669385 r13:0000000000000048 r14:0000000000000004 r15:000000014166898c
Wine-dbg>si Stopped on breakpoint 2 at 0x0000000141f49831 0x0000000141f49831: rdtsc
Wine-dbg>info reg Register dump: rip:0000000141f49831 rsp:000000000023f540 rbp:000000000023f590 eflags:00000346 ( - -- IT Z- -P- ) rax:0000000000000346 rbx:0000000141685350 rcx:00000000deadc0de rdx:00000000000787c0 rsi:0000000000000000 rdi:aaaaaaaaaaaaaaab r8:0000000000267148 r9:000000000000a400 r10:00000000c5fb2fee r11:0000000000000038 r12:0000000141669385 r13:0000000000000048 r14:0000000000000004 r15:000000014166898c --- snip ---
Normally 'rdtsc' sequences are used for timing analysis, that is VM/emulation detection, single stepping detection under debugger etc. I'm not sure why Denuvo sets the trap flag (TF) before execution (popfl -> eflags), if the trap sequence is intended at all. Maybe the exception handler has some state machine/logic for timing analysis. I didn't look very hard though.
The remaining sequence, that is querying the SCM for services state is always done when something bad happened. You can simulate it by having one of the anti-debug checks intentionally fail.
$ sha1sum mt5setup.exe fe34784ab570f051ed81c6409d07becdae12aafd mt5setup.exe
$ du -sh mt5setup.exe 640K mt5setup.exe
$ wine --version wine-2.12
Regards