https://bugs.winehq.org/show_bug.cgi?id=22545
Anastasius Focht focht@gmx.net changed:
What |Removed |Added ---------------------------------------------------------------------------- Summary|WinDVD 2010 won't startup |Multiple applications | |wrapped with | |Themida/WinLicense | |2.0.x/2.1.x software | |protection need | |ntdll.dll.DbgUiRemoteBreaki | |n stub (WinDVD 2010) CC| |focht@gmx.net Component|-unknown |ntdll
--- Comment #10 from Anastasius Focht focht@gmx.net --- Hello folks,
confirming.
--- snip --- $ pwd /home/focht/.wine/drive_c/Program Files (x86)/Corel/CorelWinDVD2010
$ WINEDEBUG=+seh,+module,+ntdll,+relay wine ./WinDVD.exe >>log.txt 2>&1 ... 0035:Call KERNEL32.CreateProcessW(00000000,0032f41c L"C:\windows\system32\rundll32.exe "C:\Program Files (x86)\Corel\CorelWinDVD2010\SQPlus.dll",#235 52",00000000,00000000,00000001,08000004,00000000,00000000,0032f19c,0032f3f0) ret=60102f84 ... 0037:Call KERNEL32.__wine_kernel_init() ret=7bc6c1e8 ... 0035:Ret KERNEL32.CreateProcessW() retval=00000001 ret=60102f84 ... 0037:Call KERNEL32.OpenEventW(00000002,00000000,60127420 L"{4A420D3F-BB93-4F5A-9D0A-59AF4B768F53}") ret=60103078 0037:Ret KERNEL32.OpenEventW() retval=000000ac ret=60103078 0037:Call KERNEL32.GetModuleHandleA(0033f8a8 "ntdll.dll") ret=601033a2 0037:Ret KERNEL32.GetModuleHandleA() retval=7bc30000 ret=601033a2 0037:Call msvcr80.??2@YAPAXI@Z(00000014) ret=6010342f 0037:Call ntdll.RtlAllocateHeap(00360000,00000000,00000014) ret=f787bab6 0037:Ret ntdll.RtlAllocateHeap() retval=00361a98 ret=f787bab6 0037:Ret msvcr80.??2@YAPAXI@Z() retval=00361a98 ret=6010342f 0037:trace:seh:raise_exception code=c0000005 flags=0 addr=0x601026cb ip=601026cb tid=0037 0037:trace:seh:raise_exception info[0]=00000000 0037:trace:seh:raise_exception info[1]=ffffffff 0037:trace:seh:raise_exception eax=00361a98 ebx=00000000 ecx=ffffffff edx=60102fd0 esi=7bc30000 edi=60137368 0037:trace:seh:raise_exception ebp=0033f948 esp=0033f84c cs=0023 ds=002b es=002b fs=0063 gs=006b flags=00010286 0037:trace:seh:call_stack_handlers calling handler at 0x60125a49 code=c0000005 flags=0 0037:trace:seh:call_stack_handlers handler at 0x60125a49 returned 1 0037:trace:seh:call_stack_handlers calling handler at 0x601250e6 code=c0000005 flags=0 0037:Call msvcr80._except_handler4_common(60137190,60102416,0033f7f4,0033f9e0,0033f528,0033f3dc) ret=60125105 0037:trace:seh:_except_handler4_common exception c0000005 flags=0 at 0x601026cb handler=0x601250e6 0x33f528 0x33f3dc cookie=fbddda88 scope table=0x6012a520 cookies=-2/0,-48/0 0037:trace:seh:_except_handler4_common level 1 prev 0 filter 0x601253cc 0037:Call msvcr80.__CppXcptFilter(c0000005,0033f284) ret=601253dd 0037:Ret msvcr80.__CppXcptFilter() retval=00000000 ret=601253dd 0037:trace:seh:_except_handler4_common filter returned CONTINUE_SEARCH 0037:trace:seh:_except_handler4_common level 0 prev -2 filter (nil) ... 0037:exception in PE entry point (proc=0x60282000,module=0x60100000,reason=PROCESS_ATTACH,res=(nil)) 0037:Ret PE DLL (proc=0x60282000,module=0x60100000 L"SQPlus.dll",reason=PROCESS_ATTACH,res=(nil)) retval=0 0037:Call PE DLL (proc=0x60282000,module=0x60100000 L"SQPlus.dll",reason=PROCESS_DETACH,res=(nil)) 0037:Call KERNEL32.GetEnvironmentVariableA(6013f104 "WLNumDLLsProt",6013f114,00000005) ret=6013fb02 0037:Ret KERNEL32.GetEnvironmentVariableA() retval=00000000 ret=6013fb02 --- snip ---
ProtectionID scan:
--- snip --- -=[ ProtectionID v0.6.9.0 DECEMBER]=- (c) 2003-2017 CDKiLLER & TippeX Build 24/12/17-21:05:42 Ready... Scanning -> C:\Program Files (x86)\Corel\CorelWinDVD2010\WinDVD.exe File Type : 32-Bit Exe (Subsystem : Win GUI / 2), Size : 874336 (0D5760h) Byte(s) | Machine: 0x14C (I386) Compilation TimeStamp : 0x4D10FFF2 -> Tue 21st Dec 2010 19:28:50 (GMT) [TimeStamp] 0x4D10FFF2 -> Tue 21st Dec 2010 19:28:50 (GMT) | PE Header | - | Offset: 0x00000108 | VA: 0x00400108 | - [TimeStamp] 0x4D10FFDF -> Tue 21st Dec 2010 19:28:31 (GMT) | Export | - | Offset: 0x0009B784 | VA: 0x0049B784 | - [TimeStamp] 0x4D10FFF2 -> Tue 21st Dec 2010 19:28:50 (GMT) | DebugDirectory | - | Offset: 0x00080AF4 | VA: 0x00480AF4 | - -> File Appears to be Digitally Signed @ Offset 0D4000h, size : 01760h / 05984 byte(s) [LoadConfig] Struct determined as v8 (Expected size 140 | Actual size 64) [!] Executable uses SEH Tables (/SAFESEH) (308 calculated 308 recorded... 0 invalid addresses) [LoadConfig] CodeIntegrity -> Flags 0x1 | Catalog 0x0 (0) | Catalog Offset 0x755C3A45 | Reserved 0x575C7273 [LoadConfig] GuardAddressTakenIatEntryTable 0x56446E69 | Count 0x30315C44 (808541252) [LoadConfig] GuardLongJumpTargetTable 0x315C582E | Count 0x42302E30 (1110453808) [LoadConfig] HybridMetadataPointer 0x2E353030 | DynamicValueRelocTable 0x2E303037 [LoadConfig] FailFastIndirectProc 0x61746552 | FailFastPointer 0x445C6C69 [LoadConfig] UnknownZero1 0x535C4456 [File Heuristics] -> Flag #1 : 00000100000000001000000100000100 (0x04008104) [Entrypoint Section Entropy] : 6.59 (section #0) ".text " | Size : 0x7EE4C (519756) byte(s) [DllCharacteristics] -> Flag : (0x0000) -> NONE [SectionCount] 4 (0x4) | ImageSize 0x1946000 (26501120) byte(s) [Export] 99% of function(s) (1348 of 1349) are in file | 0 are forwarded | 1297 code | 52 data | 0 uninit data | 0 unknown | [VersionInfo] Company Name : Corel Corporation [VersionInfo] Product Name : WinDVD Application [VersionInfo] Product Version : 10.0 [VersionInfo] File Description : WinDVD [VersionInfo] File Version : 10.0.5.713 [VersionInfo] Original FileName : WinDVD.EXE [VersionInfo] Internal Name : WinDVD [ModuleReport] [IAT] Modules -> SQPlus.dll | dbghelp.dll | KERNEL32.dll | USER32.dll | GDI32.dll | COMDLG32.dll | ADVAPI32.dll | SHELL32.dll | ole32.dll | OLEAUT32.dll | SHLWAPI.dll | WINMM.dll | XGUISysMgr.dll | XGUISystem1.2.dll | USERENV.dll | gdiplus.dll | OLEACC.dll | WINSPOOL.DRV [Debug Info] (record 1 of 1) (file offset 0x80AF0) Characteristics : 0x0 | TimeDateStamp : 0x4D10FFF2 (Tue 21st Dec 2010 19:28:50 (GMT)) | MajorVer : 0 / MinorVer : 0 -> (0.0) Type : 2 (0x2) -> CodeView | Size : 0x6A (106) AddressOfRawData : 0x8BEE8 | PointerToRawData : 0x8BEE8 CvSig : 0x53445352 | SigGuid B38C4106-D52C-44AA-A206C28ED7567A59 Age : 0x1 (1) | Pdb : E:\usr\WinDVD\10.X\10.0B005.700.Retail\DVD\Source\WINDVD10\Bin_Release\WinDVD.pdb [CdKeySerial] found "SerialNumber" @ VA: 0x000A4682 / Offset: 0x000A4682 [CompilerDetect] -> Visual C++ 8.0 (Visual Studio 2005) [!] File appears to have no protection or is using an unknown protection - Scan Took : 0.423 Second(s) [0000001A7h (423) tick(s)] [506 of 580 scan(s) done]
Scanning -> C:\Program Files (x86)\Corel\CorelWinDVD2010\SQPlus.dll File Type : 32-Bit Dll (Subsystem : Win GUI / 2), Size : 707936 (0ACD60h) Byte(s) | Machine: 0x14C (I386) Compilation TimeStamp : 0x4C4D7184 -> Mon 26th Jul 2010 11:29:08 (GMT) [TimeStamp] 0x4C4D7184 -> Mon 26th Jul 2010 11:29:08 (GMT) | PE Header | - | Offset: 0x00000100 | VA: 0x60100100 | - [TimeStamp] 0x4C4D7184 -> Mon 26th Jul 2010 11:29:08 (GMT) | Export | - | Offset: 0x000AACF4 | VA: 0x602812F4 | - -> File Appears to be Digitally Signed @ Offset 0AB600h, size : 01760h / 05984 byte(s) [LoadConfig] CodeIntegrity -> Flags 0xA3F0 | Catalog 0x46 (70) | Catalog Offset 0x2000001 | Reserved 0x46A4A0 [LoadConfig] GuardAddressTakenIatEntryTable 0x8000011 | Count 0x46A558 (4629848) [LoadConfig] GuardLongJumpTargetTable 0x8000001 | Count 0x46A5F8 (4630008) [LoadConfig] HybridMetadataPointer 0x8000011 | DynamicValueRelocTable 0x46A66C [LoadConfig] FailFastIndirectProc 0x8000011 | FailFastPointer 0x46C360 [LoadConfig] UnknownZero1 0x8000011 [File Heuristics] -> Flag #1 : 00000000000001001100000100110111 (0x0004C137) [Entrypoint Section Entropy] : 5.19 (section #6) "bctwrsll" | Size : 0x400 (1024) byte(s) [DllCharacteristics] -> Flag : (0x0000) -> NONE [SectionCount] 7 (0x7) | ImageSize 0x183000 (1585152) byte(s) [Export] 0% of function(s) (0 of 235) are in file | 0 are forwarded | 235 code | 0 data | 0 uninit data | 0 unknown | [VersionInfo] Company Name : Corel Corporation [VersionInfo] File Version : 1.0.0.37 [VersionInfo] Original FileName : SQPlus.dll [VersionInfo] Internal Name : SQPlus [VersionInfo] Legal Copyrights : Copyright (c) 2008 Corel Corporation. All rights reserved. [ModuleReport] [IAT] Modules -> kernel32.dll | KERNEL32.dll | USER32.dll | GDI32.dll | ADVAPI32.dll | MSVCP80.dll | MSVCR80.dll [!] Themida/Winlicense detected ! [CompilerDetect] -> Borland Delphi (unknown version) - 20% probability - Scan Took : 0.308 Second(s) [000000134h (308) tick(s)] [246 of 580 scan(s) done] --- snip ---
https://www.virustotal.com/en/file/391b5876ab0b4aa6d3b5682bc8fac2dbb87a2d2b7...
It seems the vendor wiped/hide the exact Themida version so all the tools failed on determining the base version.
Using the "standard" Themida version search recipe, courtesy of:
https://github.com/dubuqingfeng/ollydbg-script/blob/master/Themida/detect%20...
One doesn't need that script, only the essence. Wait for first 'invalid instruction' exception in debugger.
search base = 0x6013A000
#457863657074696F6E20496E666F726D6174696F6E# -> "Exception Information"
search before with pattern #000000000000000000000000000000000000# (pad)
--- snip --- Address Hex dump ASCII 6017BFC6 0D DF 83 E9|9D 0D 42 94|57 27 22 02|3C 90 6A 00| 6017BFD6 53 E8 03 00|00 00 20 5B|C3 5B 89 5C|24 04 81 44| 6017BFE6 24 04 16 00|00 00 43 53|C3 5E 20 AC|8B 8D 8D 16| 6017BFF6 D4 05 80 CA|85 8B 8D 79|2A D4 05 E9|57 FF FF FF| 6017C006 8B 95 09 28|D4 05 40 E9|70 01 00 00|04 00 00 00| 6017C016 00 00 00 00|00 00 00 00|00 00 00 00|00 00 00 00| 6017C026 00 00 00 00|00 00 00 00|00 00 00 00|00 00 00 00| 6017C036 A9 0F 63 A3|92 0E 67 E0|8E B6 71 EB|67 96 CC 91| 6017C046 45 78 63 65|70 74 69 6F|6E 20 49 6E|66 6F 72 6D| Exception I 6017C056 61 74 69 6F|6E 00 50 6C|65 61 73 65|2C 20 63 6F| ation Pleas. --- snip ---
version area around 0x6017C016 is zero-wiped.
The dll was built Tue 21st Dec 2010 and the Oreans Themida copyright string says year 2009.
https://www.oreans.com/ThemidaAllWhatsNew.php
The earliest 2009 release was: Themida [2.0.6.0] (23-Feb-2009) The latest release before the dll build date: Themida [2.1.5.0] (14-Dec-2010)
Anyway, this Themida 2.0.x/2.1.x version can be made to work with Wine.
After some debugging I figured out Wine misses an API export which Themida requires to implement debugger anti-attach mechanism.
Themida uses a custom imports resolver. Any API lookups are not seen in trace logs. One has to debug this brain damage. Fortunately Wine makes it easy to defeat most anti-debugging techniques ;-)
Relevant part of Themida code:
--- snip --- ... 601032EF MOV DWORD PTR SS:[ESP+14],EAX 601032F3 LEA ECX,DWORD PTR SS:[ESP+50] 601032F7 PUSH ECX 601032F8 MOV BYTE PTR SS:[ESP+5A],64 601032FD MOV BYTE PTR SS:[ESP+55],74 60103302 MOV BYTE PTR SS:[ESP+56],64 60103307 MOV BYTE PTR SS:[ESP+5C],6C 6010330C MOV BYTE PTR SS:[ESP+5B],6C 60103311 MOV BYTE PTR SS:[ESP+54],6E 60103316 MOV BYTE PTR SS:[ESP+57],6C 6010331B MOV BYTE PTR SS:[ESP+59],2E 60103320 MOV BYTE PTR SS:[ESP+58],6C 60103325 MOV BYTE PTR SS:[ESP+5D],BL 60103329 MOV BYTE PTR SS:[ESP+7E],65 6010332E MOV BYTE PTR SS:[ESP+76],67 60103333 MOV BYTE PTR SS:[ESP+7C],6F 60103338 MOV BYTE PTR SS:[ESP+74],44 6010333D MOV BYTE PTR SS:[ESP+85],6E 60103345 MOV BYTE PTR SS:[ESP+82],61 6010334D MOV BYTE PTR SS:[ESP+7D],74 60103352 MOV BYTE PTR SS:[ESP+77],55 60103357 MOV BYTE PTR SS:[ESP+83],6B 6010335F MOV BYTE PTR SS:[ESP+80],72 60103367 MOV BYTE PTR SS:[ESP+75],62 6010336C MOV BYTE PTR SS:[ESP+7A],65 60103371 MOV BYTE PTR SS:[ESP+84],69 60103379 MOV BYTE PTR SS:[ESP+78],69 6010337E MOV BYTE PTR SS:[ESP+86],BL 60103385 MOV BYTE PTR SS:[ESP+7B],6D 6010338A MOV BYTE PTR SS:[ESP+7F],42 6010338F MOV BYTE PTR SS:[ESP+79],52 60103394 MOV BYTE PTR SS:[ESP+81],65 ; "DbgUiRemoteBreakin" 6010339C NOP 6010339D CALL 60101188 601033A2 LEA EDX,DWORD PTR SS:[ESP+70] 601033A6 MOV ESI,EAX 601033A8 PUSH EDX 601033A9 PUSH ESI 601033AA CALL 6010D980 ; resolve_ntdll_import() 601033AF MOV DWORD PTR DS:[601371C0],EAX ; ntdll.DbgUiRemoteBreakin 601033B4 LEA EAX,DWORD PTR SS:[ESP+64] 601033B8 PUSH EAX 601033B9 PUSH ESI 601033BA MOV BYTE PTR SS:[ESP+6C],52 601033BF MOV BYTE PTR SS:[ESP+75],65 601033C4 MOV BYTE PTR SS:[ESP+6F],45 601033C9 MOV BYTE PTR SS:[ESP+7C],64 601033CE MOV BYTE PTR SS:[ESP+6D],74 601033D3 MOV BYTE PTR SS:[ESP+7D],BL 601033D7 MOV BYTE PTR SS:[ESP+74],73 601033DC MOV BYTE PTR SS:[ESP+76],72 601033E1 MOV BYTE PTR SS:[ESP+6E],6C 601033E6 MOV BYTE PTR SS:[ESP+71],69 601033EB MOV BYTE PTR SS:[ESP+7A],65 601033F0 MOV BYTE PTR SS:[ESP+73],55 601033F5 MOV BYTE PTR SS:[ESP+70],78 601033FA MOV BYTE PTR SS:[ESP+72],74 601033FF MOV BYTE PTR SS:[ESP+78],68 60103404 MOV BYTE PTR SS:[ESP+7B],61 60103409 MOV BYTE PTR SS:[ESP+77],54 6010340E MOV BYTE PTR SS:[ESP+79],72 ; "RtlExitUserThread" 60103413 CALL 6010D980 ; resolve_ntdll_import() 60103418 ADD ESP,10 6010341B CMP DWORD PTR DS:[601371C0],EBX ; NULL 60103421 MOV DWORD PTR DS:[601371C4],EAX ; ntdll.RtlExitUserThread 60103426 JE SHORT 6010346F ... --- snip ---
Due to the earlier failure to resolve the import it simply crashes when setting up the trampoline (one might blame poor error handling in Themida code here tho).
The anti-attach mechanism used here is rather simple. Themida hooks 'kernel32.dll.DbgUiRemoteBreakin' entry point to prevent breakpoint exception in the debuggee if a debugger attaches using standard mechanism.
Before:
--- snip --- DbgUiRemoteBreakin:
7BC6E902 8D4C24 04 LEA ECX,DWORD PTR SS:[ESP+4] 7BC6E906 83E4 F0 AND ESP,FFFFFFF0 7BC6E909 FF71 FC PUSH DWORD PTR DS:[ECX-4] 7BC6E90C 55 PUSH EBP 7BC6E90D 89E5 MOV EBP,ESP 7BC6E90F 51 PUSH ECX 7BC6E910 83EC 14 SUB ESP,14 7BC6E913 B8 58A8CF7B MOV EAX,7BCFA858 ... --- snip ---
After:
--- snip --- DbgUiRemoteBreakin:
7BC6E902 E9 C94649E4 JMP 60102FD0 ; trampoline 7BC6E907 E4 F0 IN AL,0F0 command 7BC6E909 FF71 FC PUSH DWORD PTR DS:[ECX-4] 7BC6E90C 55 PUSH EBP 7BC6E90D 89E5 MOV EBP,ESP 7BC6E90F 51 PUSH ECX 7BC6E910 83EC 14 SUB ESP,14 7BC6E913 B8 58A8CF7B MOV EAX,7BCFA858 ... --- snip ---
Themida code:
--- snip --- 60102FD0 51 PUSH ECX 60102FD1 C70424 AC721260 MOV DWORD PTR SS:[ESP],601272AC 60102FD8 8D0424 LEA EAX,DWORD PTR SS:[ESP] 60102FDB A1 C4711360 MOV EAX,DWORD PTR DS:[601371C4] 60102FE0 85C0 TEST EAX,EAX 60102FE2 74 04 JE SHORT 60102FE8 60102FE4 6A 00 PUSH 0 60102FE6 FFD0 CALL EAX ; RtlExitUserThread 60102FE8 59 POP ECX 60102FE9 C3 RETN --- snip ---
Normally the code for 'DbgUiRemoteBreakin()' would look like this:
--- snip --- VOID WINAPI DbgUiRemoteBreakin(VOID) { /* breakpoint exception */ if (NtCurrentPeb()->BeingDebugged) DbgBreakPoint();
/* Exit the break-in thread */ RtlExitUserThread(STATUS_SUCCESS); } --- snip ---
For Wine this code wouldn't be useful at all because Wine doesn't implement the sequence like native Windows/Reactos does.
--> DebugActiveProcess --> DbgUiIssueRemoteBreakin --> RtlCreateUserThread( ... DbgUiRemoteBreakin)
On native Windows, the break-in thread would be short-circuit by Themida, causing no breakpoint exception seen by debuggers upon attach.
Wine needs to provide a stub 'DbgUiRemoteBreakin()' to keep Themida 2.0/2.1 happy here.
Sequence shows 'DbgUiRemoteBreakin' trampoline being set up:
--- snip --- ... 0071:Call KERNEL32.OpenEventW(00000002,00000000,60127420 L"{4A420D3F-BB93-4F5A-9D0A-59AF4B768F53}") ret=60103078 0071:Ret KERNEL32.OpenEventW() retval=000000ac ret=60103078 0071:Call KERNEL32.GetModuleHandleA(0033f8a8 "ntdll.dll") ret=601033a2 0071:Ret KERNEL32.GetModuleHandleA() retval=7bc30000 ret=601033a2 0071:Call msvcr80.??2@YAPAXI@Z(00000014) ret=6010342f 0071:Call ntdll.RtlAllocateHeap(00360000,00000000,00000014) ret=f78cbab6 0071:Ret ntdll.RtlAllocateHeap() retval=00361a98 ret=f78cbab6 0071:Ret msvcr80.??2@YAPAXI@Z() retval=00361a98 ret=6010342f 0071:Call KERNEL32.FlushInstructionCache(ffffffff,7bc35dd8,00000005) ret=60102647 0071:Ret KERNEL32.FlushInstructionCache() retval=00000001 ret=60102647 0071:Call KERNEL32.VirtualProtect(7bc35dd8,00000005,00000040,0033f850) ret=6010265d 0071:Ret KERNEL32.VirtualProtect() retval=00000001 ret=6010265d 0071:Call KERNEL32.VirtualProtect(7bc35dd8,00000005,00000020,0033f850) ret=60102689 0071:Ret KERNEL32.VirtualProtect() retval=00000001 ret=60102689 0071:Call KERNEL32.InitializeCriticalSection(6013736c) ret=601034b0 0071:Ret KERNEL32.InitializeCriticalSection() retval=00000001 ret=601034b0 0071:Call user32.SetTimer(00000000,00000010,000007d0,60108470) ret=601034c4 0071:Ret user32.SetTimer() retval=00007fff ret=601034c4 ... --- snip ---
NOTE: The app hangs later due to other ieframe/mshtml shortcomings (different issues).
$ sha1sum WinDVDPro2010-TBYB.exe cad4b6c358f915d79dee4f23de299566ef6af4bf WinDVDPro2010-TBYB.exe
$ du -sh WinDVDPro2010-TBYB.exe 171M WinDVDPro2010-TBYB.exe
$ wine --version wine-3.6-138-ga373054b72
Regards