[Bug 36934] C&C Red Alert 2 installer reports "A debugger has been detected. Unload the debugger and try again." when run in Win9x mode (SafeDisc v2.05.030)

wine-bugs at winehq.org wine-bugs at winehq.org
Tue Sep 9 19:11:26 CDT 2014


https://bugs.winehq.org/show_bug.cgi?id=36934

Anastasius Focht <focht at gmx.net> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |Installer, obfuscation
             Status|UNCONFIRMED                 |RESOLVED
                 CC|                            |focht at gmx.net
         Resolution|---                         |WONTFIX
            Summary|Command and Conquer: Red    |C&C Red Alert 2 installer
                   |Alert 2 - Installation      |reports "A debugger has
                   |won't start and complains   |been detected. Unload the
                   |about debugger              |debugger and try again."
                   |                            |when run in Win9x mode
                   |                            |(SafeDisc v2.05.030)

--- Comment #2 from Anastasius Focht <focht at gmx.net> ---
Hello folks,

confirming.

The game is protected by Safedisc v2.05.030 which uses different code paths
when detecting it is being run on Win9X systems.

Setting 'WinVer' to Win9X is usually a _bad_ choice when it comes to emulating
copy protection/DRM schemes. Certain stuff that works on Win9X can't be
properly supported by design.

You are better off leaving the WINEPREFIX Windows version at *default* setting
unless you know what it really means/implies.

Unfortunately in NT/2K/XP+ mode, Safedisc v2.05.030 runs into bug 30155 which
is still valid.

--- snip ---
$ pwd
/home/focht/.wine/drive_c/Westwood/RA2
...
0009:Call KERNEL32.LoadLibraryA(0033f9c0
"C:\\users\\focht\\Temp\\~ef87a1\\~df394b.tmp") ret=0041cf4b
0009:trace:loaddll:load_native_dll Loaded
L"C:\\users\\focht\\Temp\\~ef87a1\\~df394b.tmp" at 0x10000000: native
0009:Call PE DLL (proc=0x1002ce40,module=0x10000000
L"~df394b.tmp",reason=PROCESS_ATTACH,res=(nil)) 
...
0009:Ret  PE DLL (proc=0x1002ce40,module=0x10000000
L"~df394b.tmp",reason=PROCESS_ATTACH,res=(nil)) retval=1
0009:Ret  KERNEL32.LoadLibraryA() retval=10000000 ret=0041cf4b
...
0009:Call KERNEL32.GetProcAddress(10000000,00148e70 "Ox12121212") ret=0041ccd8
0009:Ret  KERNEL32.GetProcAddress() retval=1000520c ret=0041ccd8
...
0009:Call KERNEL32.GetModuleHandleA(00641180 "Kernel32") ret=1001ea98
0009:Ret  KERNEL32.GetModuleHandleA() retval=7b810000 ret=1001ea98
0009:Call KERNEL32.LoadLibraryA(00641280 "Kernel32.dll") ret=10025692
0009:Ret  KERNEL32.LoadLibraryA() retval=7b810000 ret=10025692
0009:Call KERNEL32.GetProcAddress(7b810000,00641290 "ReadProcessMemory")
ret=10025758
0009:Ret  KERNEL32.GetProcAddress() retval=7b824c7c ret=10025758
0009:Call KERNEL32.GetProcAddress(7b810000,006412b0 "WriteProcessMemory")
ret=10025758
0009:Ret  KERNEL32.GetProcAddress() retval=7b825f54 ret=10025758
0009:Call KERNEL32.GetProcAddress(7b810000,006412d0 "VirtualProtect")
ret=10025758
0009:Ret  KERNEL32.GetProcAddress() retval=7b825b64 ret=10025758
0009:Call KERNEL32.VirtualProtect(10001000,000155e6,00000004,0033fad0)
ret=10006831
0009:Ret  KERNEL32.VirtualProtect() retval=00000001 ret=10006831
0009:Call KERNEL32.VirtualProtect(10017000,000041e7,00000004,0033fad0)
ret=10006831
0009:Ret  KERNEL32.VirtualProtect() retval=00000001 ret=10006831
0009:Call KERNEL32.VirtualProtect(1001c000,0001ba4a,00000004,0033fad0)
ret=10006831
0009:Ret  KERNEL32.VirtualProtect() retval=00000001 ret=10006831
0009:Call KERNEL32.GetVersionExA(0033fa10) ret=1000804b
0009:Ret  KERNEL32.GetVersionExA() retval=00000001 ret=1000804b
0009:trace:seh:raise_exception code=c0000005 flags=0 addr=0x10008218
ip=10008218 tid=0009
0009:trace:seh:raise_exception  info[0]=00000000
0009:trace:seh:raise_exception  info[1]=ff569028
0009:trace:seh:raise_exception  eax=0033fa00 ebx=ff569028 ecx=00000028
edx=0033faa4 esi=ff569028 edi=0033fa00
0009:trace:seh:raise_exception  ebp=0033fad0 esp=0033f9c8 cs=0023 ds=002b
es=002b fs=0063 gs=006b flags=00010286
0009:trace:seh:call_vectored_handlers calling handler at 0x7ea21bd4
code=c0000005 flags=0
0009:trace:seh:call_vectored_handlers handler at 0x7ea21bd4 returned 0
0009:trace:seh:call_vectored_handlers calling handler at 0x7ea1707b
code=c0000005 flags=0
0009:trace:seh:call_vectored_handlers handler at 0x7ea1707b returned 0
0009:trace:seh:call_stack_handlers calling handler at 0x1002d1d8 code=c0000005
flags=0
0009:Call ntdll.RtlUnwind(0033fac0,1002d0f8,00000000,00000000) ret=1002d0f8
0009:  eax=00000001 ebx=0033fac0 ecx=00000000 edx=7bc814fd esi=00000000
edi=100381e0 ebp=0033f484 esp=0033f474 ds=002b es=002b fs=0063 gs=006b
flags=00000202
0009:trace:seh:__regs_RtlUnwind code=c0000027 flags=2
0009:trace:seh:__regs_RtlUnwind calling handler at 0x7bc814fd code=c0000027
flags=2
0009:trace:seh:__regs_RtlUnwind handler at 0x7bc814fd returned 1
0009:Ret  ntdll.RtlUnwind() retval=00000000 ret=1002d0f8
0009:  eax=00000000 ebx=0033fac0 ecx=00000000 edx=7bc814fd esi=00000000
edi=100381e0 ebp=0033f484 esp=0033f474 ds=002b es=002b fs=0063 gs=006b
flags=00000202
0009:Call KERNEL32.VirtualProtect(100204f6,00000020,00000004,0033f994)
ret=1001c6b0
0009:Ret  KERNEL32.VirtualProtect() retval=00000001 ret=1001c6b0 
...
0009:Call KERNEL32.LoadLibraryA(1004f198
"C:\\users\\focht\\Temp\\~ef87a1\\~de50cd.tmp") ret=100019cd
0009:trace:loaddll:load_native_dll Loaded
L"C:\\users\\focht\\Temp\\~ef87a1\\~de50cd.tmp" at 0x340000: native 
...
0009:Call KERNEL32.GetProfileIntA(0036a158 "C-DILLA",0036a160
"TESTMESSAGES",00000000) ret=0034e4b7
0009:Ret  KERNEL32.GetProfileIntA() retval=00000000 ret=0034e4b7
0009:Call KERNEL32.GetVersionExA(0033f8c4) ret=0034e58e
0009:Ret  KERNEL32.GetVersionExA() retval=00000001 ret=0034e58e
0009:Call KERNEL32.GetProfileIntA(0036a158 "C-DILLA",0036a14c
"INTERACTIVE",00000000) ret=0034e60b
0009:Ret  KERNEL32.GetProfileIntA() retval=00000000 ret=0034e60b
0009:Call KERNEL32.GetModuleHandleA(1004b048 "~de50cd.tmp") ret=0034e020
0009:Ret  KERNEL32.GetModuleHandleA() retval=00340000 ret=0034e020
0009:Call KERNEL32.LoadLibraryA(00b51220
"C:\\users\\focht\\Temp\\~ef87a1\\~df394b.tmp") ret=00362ef0
0009:Ret  KERNEL32.LoadLibraryA() retval=10000000 ret=00362ef0
0009:Call KERNEL32.GetProcAddress(10000000,00370d70 "Ox12345678") ret=00362f2b
0009:Ret  KERNEL32.GetProcAddress() retval=10023900 ret=00362f2b 
...
0009:Call KERNEL32.OpenFileMappingA(00000002,00000000,0033ed14
"SAFEDISC_ERROR_00000008") ret=00354032
0009:Ret  KERNEL32.OpenFileMappingA() retval=00000000 ret=00354032
...
0009:Call user32.MessageBoxA(00010020,00b51d90 "Unload the debugger and try
again",00b51cb0 "A debugger has been detected",00040010) ret=00353217 
...
--- snip ---

Code sequence in question, in between obfuscated code.

--- snip ---
...
100081FA    C745 FC 00000000     MOV DWORD PTR SS:[EBP-4],0
10008201    60                   PUSHAD
10008202    9C                   PUSHFD
10008203    0F014D DC            SIDT FWORD PTR SS:[EBP-24]
10008207    8B5D DE              MOV EBX,DWORD PTR SS:[EBP-22] ; IDTR+2
1000820A    039D 38FFFFFF        ADD EBX,DWORD PTR SS:[EBP-0C8] ; +0x28 = INT 5
10008210    8BBD 2CFFFFFF        MOV EDI,DWORD PTR SS:[EBP-0D4] ; saved gate
10008216    8BF3                 MOV ESI,EBX
10008218    A5                   MOVS DWORD PTR ES:[EDI],DWORD PTR DS:[ESI]
10008219    A5                   MOVS DWORD PTR ES:[EDI],DWORD PTR DS:[ESI]
1000821A    FA                   CLI
1000821B    8BFB                 MOV EDI,EBX                    ; new gate
1000821D    8B75 E4              MOV ESI,DWORD PTR SS:[EBP-1C]
10008220    A5                   MOVS DWORD PTR ES:[EDI],DWORD PTR DS:[ESI]
10008221    A5                   MOVS DWORD PTR ES:[EDI],DWORD PTR DS:[ESI]
10008222    FB                   STI
10008223    FA                   CLI
10008224    8BFB                 MOV EDI,EBX
10008226    8BB5 2CFFFFFF        MOV ESI,DWORD PTR SS:[EBP-0D4] ; old gate
1000822C    A5                   MOVS DWORD PTR ES:[EDI],DWORD PTR DS:[ESI]
1000822D    A5                   MOVS DWORD PTR ES:[EDI],DWORD PTR DS:[ESI]
1000822E    FB                   STI
1000822F    9D                   POPFD
10008230    61                   POPAD
10008231    C745 FC FFFFFFFF     MOV DWORD PTR SS:[EBP-4],-1
10008238    E9 9E000000          JMP 100082DB
1000823D    B8 01000000          MOV EAX,1
10008242    C3                   RETN
...
--- snip ---

At first glance it looks like the "old" way of getting/testing ring0 privileges
by using software interrupt.
Basically an IDT entry is patched with a handler containing custom code that
ought to be run in ring0. An 'INT' instruction with selected interrupt number
is executed to trigger the handler.
The IDT entry needs to have DPL3 to allow execution of 'INT' from ring3.
Usually INT 1,3,4,5... are suitable for that task (here 'INT 5' is chosen).

But ... the actual 'INT' instruction is missing in between.
Also the "handler" misses the 'IRETD' hence it's never meant to be executed.
It just restores the IDT entry (gate) again.

IDTR base = 0xff569000

--- snip IDTR ---
Address   16-bit hex dump
$ ==>     0FFF    9000    FF56
--- snip IDTR ---

I think the idea was to check if the installed userspace SEH gets triggered on
NT-based systems in case someone tried to fake Win9X by lying in
GetVersionInfo().

Resolving 'WONTFIX'.

--- snip ---
-=[ ProtectionID v0.6.5.5 OCTOBER]=-
(c) 2003-2013 CDKiLLER & TippeX
Build 31/10/13-21:09:09
Ready...

Scanning -> E:\Setup\drvmgt.dll
File Type : 32-Bit Dll (Subsystem : Win GUI / 2), Size : 34304 (08600h) Byte(s)
[File Heuristics] -> Flag : 00000000000001001100000000000000 (0x0004C000)
[Entrypoint Section Entropy] : 6.45
[!] Safedisc driver managment dll (drvmgt.dll) detected!
[CompilerDetect] -> Visual C++ 5.1
- Scan Took : 0.278 Second(s) [000000116h tick(s)] [229 scan(s) done]

Scanning -> E:\Setup\secdrv.sys
File Type : 32-Bit Driver (good checksum) (Subsystem : Native / 1), Size :
18768 (04950h) Byte(s)
-> File has 592 (0250h) bytes of appended data starting at offset 04700h
[File Heuristics] -> Flag : 00000100000000000000000000000111 (0x04000007)
[Entrypoint Section Entropy] : 6.13
[Debug Info]
Characteristics : 0x0 | TimeDateStamp : 0x398E144A | MajorVer : 0 / MinorVer :
0 -> (0.0)
Type : 4 -> Misc | Size : 0x110 (272)
AddressOfRawData : 0x0 | PointerToRawData : 0x4700
[!] Safedisc protection driver (secdrv.sys) detected!
- Scan Took : 0.289 Second(s) [000000121h tick(s)] [128 scan(s) done]

Scanning -> E:\Setup\Setup.exe
File Type : 32-Bit Exe (Subsystem : Win GUI / 2), Size : 1308863 (013F8BFh)
Byte(s)
-> File has 733375 (0B30BFh) bytes of appended data starting at offset 08C800h
[File Heuristics] -> Flag : 00000000000000000100000000100111 (0x00004027)
[Entrypoint Section Entropy] : 6.26
[!] Safedisc v2.05.030 detected !
[i] Appended data contents....
   [.] o: 0x0008C828  / t: <0x00000001> <0x00000000> <0x00000001> / s: 00194947
byte(s) -> ~de7bc4.tmp
   [.] o: 0x000BC1D2  / t: <0x00000001> <0x00000000> <0x0000044C> / s: 00030208
byte(s) -> clcd32.dll
   [.] o: 0x000C37F9  / t: <0x00000001> <0x00000000> <0x0000044C> / s: 00006784
byte(s) -> clcd16.dll
   [.] o: 0x000C529D  / t: <0x00000001> <0x00000000> <0x0000044D> / s: 00067584
byte(s) -> mcp.dll
   [.] o: 0x000D5AC5  / t: <0x00000001> <0x00000000> <0x00000000> / s: 00327220
byte(s) -> ~df394b.tmp
   [.] o: 0x00125920  / t: <0x00000001> <0x00000000> <0x00000002> / s: 00034304
byte(s) -> drvmgt.dll
   [.] o: 0x0012DF47  / t: <0x00000001> <0x00000000> <0x00000002> / s: 00018768
byte(s) -> secdrv.sys
   [.] o: 0x001328BF  / t: <0x00000001> <0x00000000> <0x00000000> / s: 00053248
byte(s) -> ~ef7194.tmp
[CompilerDetect] -> Visual C++ 6.0
- Scan Took : 0.425 Second(s) [0000001A9h tick(s)] [533 scan(s) done]
--- snip ---

$ wine --version
wine-1.7.26-21-g45c1d7c

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