https://bugs.winehq.org/show_bug.cgi?id=47170
Bug ID: 47170 Summary: nProtect GameGuard Personal/Anti-Virus/Spyware 3.x/4.x kernel drivers crash due to 'winedevice' PE module having no export table Product: Wine Version: 4.8 Hardware: x86-64 OS: Linux Status: NEW Severity: normal Priority: P2 Component: ntoskrnl Assignee: wine-bugs@winehq.org Reporter: focht@gmx.net Distribution: ---
Hello folks,
as it says.
Stable download link which is a web-installer for nProtect GameGuard Personal 3.x (bundles nProtect Anti-Virus/Spyware 3.0 which fetches 4.0):
http://fs2.download82.com/software/bbd8ff9dba17080c0c121804efbd61d5/nprotect...
The AVS 4.0 installer works, although one can already see multiple crashing kernel drivers in console which cause additional zombie service processes (Windows userspace side).
--- snip --- ... 002d:trace:ntoskrnl:load_driver loading driver L"C:\windows\system32\TKPcFtHk.sys" ... 002d:Call driver init 0x350005 (obj=0x121ba0,str=L"\Registry\Machine\System\CurrentControlSet\Services\TKPcFt") ... 002d:trace:ntoskrnl:IoCreateDevice (0x121ba0, 0, L"\Device\TKPcFt", 34, 0, 0, 0x348104) ... 002d:trace:ntoskrnl:IoCreateSymbolicLink L"\DosDevices\TKPcFt" -> L"\Device\TKPcFt" ... 002d:Call ntoskrnl.exe.ExAllocatePoolWithTag(00000000,00001000,34314c53) ret=00342f27 002d:Call ntdll.RtlAllocateHeap(00110000,00000000,00001000) ret=7e8789fa 002d:Ret ntdll.RtlAllocateHeap() retval=00121ea0 ret=7e8789fa 002d:trace:ntoskrnl:ExAllocatePoolWithTag 4096 pool 0 -> 0x121ea0 002d:Ret ntoskrnl.exe.ExAllocatePoolWithTag() retval=00121ea0 ret=00342f27 002d:Call ntoskrnl.exe.memset(00121ea0,00000000,00001000) ret=00342f41 002d:Ret ntoskrnl.exe.memset() retval=00121ea0 ret=00342f41 002d:Call ntoskrnl.exe.ZwQuerySystemInformation(0000000b,00121ea0,00001000,0082f864) ret=0034392d 002d:Call ntdll.NtQuerySystemInformation(0000000b,00121ea0,00001000,0082f864) ret=7bc8e964 002d:Ret ntdll.NtQuerySystemInformation() retval=00000000 ret=7bc8e964 002d:Ret ntoskrnl.exe.ZwQuerySystemInformation() retval=00000000 ret=0034392d 002d:Call ntoskrnl.exe.ExAllocatePoolWithTag(00000000,00000104,35314c53) ret=00342f27 002d:Call ntdll.RtlAllocateHeap(00110000,00000000,00000104) ret=7e8789fa 002d:Ret ntdll.RtlAllocateHeap() retval=00122ea8 ret=7e8789fa 002d:trace:ntoskrnl:ExAllocatePoolWithTag 260 pool 0 -> 0x122ea8 002d:Ret ntoskrnl.exe.ExAllocatePoolWithTag() retval=00122ea8 ret=00342f27 002d:Call ntoskrnl.exe.memset(00122ea8,00000000,00000104) ret=00342f41 002d:Ret ntoskrnl.exe.memset() retval=00122ea8 ret=00342f41 002d:trace:seh:raise_exception code=c0000005 flags=0 addr=0x343c13 ip=00343c13 tid=002d 002d:trace:seh:raise_exception info[0]=00000000 002d:trace:seh:raise_exception info[1]=00d05a4d 002d:trace:seh:raise_exception eax=00345390 ebx=00121ba0 ecx=00d05a4f edx=00d05a4d esi=00350005 edi=00121c54 002d:trace:seh:raise_exception ebp=0082f8d4 esp=0082f888 cs=0023 ds=002b es=002b fs=0063 gs=006b flags=00010206 002d:trace:seh:call_vectored_handlers calling handler at 0x7e877f10 code=c0000005 flags=0 002d:trace:seh:call_vectored_handlers handler at 0x7e877f10 returned 0 002d:trace:seh:call_stack_handlers calling handler at 0x7bcc3660 code=c0000005 flags=0 002d:Call msvcrt.signal(0000000b,00000000) ret=00403789 002d:trace:seh:MSVCRT_signal (11, (nil)) 002d:Ret msvcrt.signal() retval=00000000 ret=00403789 002d:trace:seh:start_debugger Starting debugger "winedbg --auto 42 56" 002d:trace:seh:call_stack_handlers handler at 0x7bcc3660 returned 1 --- snip ---
The reason of the crash is not visible by tracing, one has to debug the garbage.
Disassembly of sub-routine where the "custom" resolver magic happens, annotated where needed ...
--- snip --- 005539C0 MOV EDI,EDI 005539C2 PUSH EBP 005539C3 MOV EBP,ESP 005539C5 SUB ESP,4C 005539C8 MOV DWORD PTR SS:[LOCAL.9],0 005539CF MOV DWORD PTR SS:[LOCAL.10],0 005539D6 MOV DWORD PTR SS:[LOCAL.11],0 005539DD MOV DWORD PTR SS:[LOCAL.13],0 005539E4 MOV DWORD PTR SS:[LOCAL.7],0 005539EB MOV DWORD PTR SS:[LOCAL.4],0 005539F2 MOV DWORD PTR SS:[LOCAL.8],0 005539F9 MOV DWORD PTR SS:[LOCAL.6],0 00553A00 MOV DWORD PTR SS:[LOCAL.12],0 00553A07 MOV DWORD PTR SS:[LOCAL.1],0 00553A0E MOV DWORD PTR SS:[LOCAL.3],0 00553A15 MOV DWORD PTR SS:[LOCAL.5],0 00553A1C MOV DWORD PTR SS:[LOCAL.14],0 00553A23 MOV DWORD PTR SS:[LOCAL.2],0 00553A2A CALL DWORD PTR DS:[<&HAL.KeGetCurrentIrql>] 00553A30 MOVZX EAX,AL 00553A33 TEST EAX,EAX 00553A35 JZ SHORT 00553A3C 00553A37 JMP 00553C72 00553A3C LEA ECX,[LOCAL.10] 00553A3F PUSH ECX 00553A40 PUSH 0B ; SystemModuleInformation 00553A42 CALL 005538C0 ; ZwQuerySystemInformation 00553A47 MOV DWORD PTR SS:[LOCAL.11],EAX 00553A4A CMP DWORD PTR SS:[LOCAL.11],0 00553A4E JNE SHORT 00553A55 00553A50 JMP 00553C72 00553A55 PUSH 35314C53 00553A5A PUSH 104 00553A5F PUSH 0 00553A61 CALL 00552F00 ; ExAllocatePoolWithTag 00553A66 MOV DWORD PTR SS:[LOCAL.8],EAX 00553A69 CMP DWORD PTR SS:[LOCAL.8],0 00553A6D JNE SHORT 00553A74 00553A6F JMP 00553C72 00553A74 MOV EDX,DWORD PTR SS:[LOCAL.11] ; _RTL_PROCESS_MODULE_INFORMATION --- snip ---
--- snip --- 00553A74 ; typedef struct _RTL_PROCESS_MODULE_INFORMATION 00553A74 ; { 00553A74 ; HANDLE Section; 00553A74 ; PVOID MappedBase; 00553A74 ; PVOID ImageBase; 00553A74 ; ULONG ImageSize; 00553A74 ; ULONG Flags; 00553A74 ; USHORT LoadOrderIndex; 00553A74 ; USHORT InitOrderIndex; 00553A74 ; USHORT LoadCount; 00553A74 ; USHORT OffsetToFileName; 00553A74 ; UCHAR FullPathName[256]; 00553A74 ; } RTL_PROCESS_MODULE_INFORMATION, *PRTL_PROCESS_MODULE_INFORMATION; 00553A74 ; 00553A74 ; $ ==> 00000000 00553A74 ; $+4 00000000 00553A74 ; $+8 7EFF0000 ; OFFSET winedevice.<STRUCT IMAGE_DOS_HEADER> 00553A74 ; $+C 00010000 00553A74 ; $+10 80080000 00553A74 ; $+14 00000000 00553A74 ; $+18 00140000 00553A74 ; $+1C 775C3A43 C:\w 00553A74 ; $+20 6F646E69 indo 00553A74 ; $+24 735C7377 ws\s 00553A74 ; $+28 65747379 yste 00553A74 ; $+2C 5C32336D m32\ 00553A74 ; $+30 656E6977 wine 00553A74 ; $+34 69766564 devi 00553A74 ; $+38 652E6563 ce.e 00553A74 ; $+3C 00006578 xe 00553A74 ; $+40 00000000 --- snip ---
--- snip --- 00553A77 ADD EDX,4 00553A7A MOV DWORD PTR SS:[LOCAL.13],EDX ; ModuleInfo 00553A7D MOV DWORD PTR SS:[LOCAL.4],0 ; mod_count 00553A84 JMP SHORT 00553A8F 00553A86 MOV EAX,DWORD PTR SS:[EBP-10] ; loop_mod_count 00553A89 ADD EAX,1 00553A8C MOV DWORD PTR SS:[EBP-10],EAX ; loop_mod_count 00553A8F MOV ECX,DWORD PTR SS:[EBP-2C] ; ModuleInfo 00553A92 MOV EDX,DWORD PTR SS:[EBP-10] 00553A95 CMP EDX,DWORD PTR DS:[ECX] 00553A97 JAE 00553B5C 00553A9D CMP DWORD PTR SS:[EBP+8],0 00553AA1 JNE SHORT 00553AD8 00553AA3 MOV EAX,DWORD PTR SS:[EBP-34] ; ModuleInfo 00553AA6 MOV ECX,DWORD PTR DS:[EAX+8] ; ImageBase 00553AA9 MOV DWORD PTR SS:[EBP-18],ECX 00553AAC MOV EDX,DWORD PTR SS:[EBP-34] 00553AAF MOVZX EAX,WORD PTR DS:[EDX+1A] ; OffsetToFileName 00553AB3 MOV ECX,DWORD PTR SS:[EBP-34]
00553AB6 LEA EDX,[EAX+ECX+1C] ; ModuleInfo->Modules[i].FullPathName+ModuleInfo->Modules[i].OffsetToFileName
00553ABA PUSH EDX 00553ABB PUSH 00555520 ; ASCII "%s" 00553AC0 PUSH 104 00553AC5 MOV EAX,DWORD PTR SS:[EBP-20] 00553AC8 PUSH EAX 00553AC9 CALL 00553CA0 ; copy_to_buffer 00553ACE ADD ESP,10 00553AD1 JMP 00553B5C 00553AD6 JMP SHORT 00553B57 00553AD8 MOV ECX,DWORD PTR SS:[EBP+8] 00553ADB PUSH ECX 00553ADC MOV EDX,DWORD PTR SS:[EBP-10] ; mod_count 00553ADF IMUL EDX,EDX,11C 00553AE5 ADD EDX,DWORD PTR SS:[EBP-34] ; ModuleInfo 00553AE8 MOV EAX,DWORD PTR SS:[EBP-10] 00553AEB IMUL EAX,EAX,11C 00553AF1 MOV ECX,DWORD PTR SS:[EBP-34] 00553AF4 MOVZX EAX,WORD PTR DS:[EAX+ECX+1A] 00553AF9 LEA ECX,[EAX+EDX+1C] 00553AFD PUSH ECX 00553AFE CALL <JMP.&ntoskrnl_exe._stricmp> 00553B03 ADD ESP,8 00553B06 TEST EAX,EAX 00553B08 JNZ SHORT 00553B57 00553B0A MOV EDX,DWORD PTR SS:[EBP-10] 00553B0D IMUL EDX,EDX,11C 00553B13 MOV EAX,DWORD PTR SS:[EBP-34] 00553B16 MOV ECX,DWORD PTR DS:[EDX+EAX+8] 00553B1A MOV DWORD PTR SS:[EBP-18],ECX 00553B1D MOV EDX,DWORD PTR SS:[EBP-10] 00553B20 IMUL EDX,EDX,11C 00553B26 ADD EDX,DWORD PTR SS:[EBP-34] 00553B29 MOV EAX,DWORD PTR SS:[EBP-10] 00553B2C IMUL EAX,EAX,11C 00553B32 MOV ECX,DWORD PTR SS:[EBP-34] 00553B35 MOVZX EAX,WORD PTR DS:[EAX+ECX+1A] 00553B3A LEA ECX,[EAX+EDX+1C] 00553B3E PUSH ECX 00553B3F PUSH 00555520 ; ASCII "%s" 00553B44 PUSH 104 00553B49 MOV EDX,DWORD PTR SS:[EBP-20] 00553B4C PUSH EDX 00553B4D CALL 00553CA0 ; copy_to_buffer 00553B52 ADD ESP,10 00553B55 JMP SHORT 00553B5C 00553B57 JMP 00553A86 00553B5C CMP DWORD PTR SS:[EBP-18],0 ; ImageBase 00553B60 JNE SHORT 00553B67 00553B62 JMP 00553C72 00553B67 MOV EAX,DWORD PTR SS:[EBP-18] 00553B6A MOV DWORD PTR SS:[EBP-30],EAX 00553B6D MOV ECX,DWORD PTR SS:[EBP-30] 00553B70 MOVZX EDX,WORD PTR DS:[ECX] 00553B73 CMP EDX,5A4D ; DOS HEADER 00553B79 JE SHORT 00553B80 00553B7B JMP 00553C72 00553B80 MOV EAX,DWORD PTR SS:[EBP-30] ; ImageBase 00553B83 MOV ECX,DWORD PTR SS:[EBP-18] 00553B86 ADD ECX,DWORD PTR DS:[EAX+3C] ; file offset to the PE signature 00553B89 MOV DWORD PTR SS:[EBP-4],ECX 00553B8C MOV EDX,DWORD PTR SS:[EBP-4] 00553B8F MOV EAX,DWORD PTR SS:[EBP-18] 00553B92 ADD EAX,DWORD PTR DS:[EDX+78] ; RVA of the export table 00553B95 MOV DWORD PTR SS:[EBP-0C],EAX ; Wine: NULL -> image_base 00553B98 MOV ECX,DWORD PTR SS:[EBP-0C] 00553B9B MOV EDX,DWORD PTR SS:[EBP-18] 00553B9E ADD EDX,DWORD PTR DS:[ECX+20] ; offset(names table) 00553BA1 MOV DWORD PTR SS:[EBP-14],EDX 00553BA4 MOV EAX,DWORD PTR SS:[EBP-0C] 00553BA7 MOV ECX,DWORD PTR SS:[EBP-18] 00553BAA ADD ECX,DWORD PTR DS:[EAX+1C] ; offset(address table) 00553BAD MOV DWORD PTR SS:[EBP-38],ECX 00553BB0 MOV EDX,DWORD PTR SS:[EBP-0C] 00553BB3 MOV EAX,DWORD PTR SS:[EBP-18] 00553BB6 ADD EAX,DWORD PTR DS:[EDX+24] ; offset(ordinals table) 00553BB9 MOV DWORD PTR SS:[EBP-8],EAX 00553BBC MOV DWORD PTR SS:[EBP-10],0 00553BC3 JMP SHORT 00553BE0 00553BC5 MOV ECX,DWORD PTR SS:[EBP-10] 00553BC8 ADD ECX,1 00553BCB MOV DWORD PTR SS:[EBP-10],ECX 00553BCE MOV EDX,DWORD PTR SS:[EBP-14] ; export_names 00553BD1 ADD EDX,4 00553BD4 MOV DWORD PTR SS:[EBP-14],EDX 00553BD7 MOV EAX,DWORD PTR SS:[EBP-8] ; EAT ordinals_addr 00553BDA ADD EAX,2 00553BDD MOV DWORD PTR SS:[EBP-8],EAX 00553BE0 MOV ECX,DWORD PTR SS:[EBP-0C] ; export_table_addr 00553BE3 MOV EDX,DWORD PTR SS:[EBP-10] 00553BE6 CMP EDX,DWORD PTR DS:[ECX+18] ; table numberOfNamePointers 00553BE9 JAE 00553C72 00553BEF CMP DWORD PTR SS:[EBP+0C],0 ; func_name 00553BF3 JNE SHORT 00553BF7 00553BF5 JMP SHORT 00553C6D 00553BF7 MOV EAX,DWORD PTR SS:[EBP-14] ; export_names 00553BFA MOV ECX,DWORD PTR SS:[EBP-18] ; ImageBase 00553BFD ADD ECX,DWORD PTR DS:[EAX] 00553BFF MOV DWORD PTR SS:[EBP-3C],ECX 00553C02 MOV EDX,DWORD PTR SS:[EBP+0C] 00553C05 MOV DWORD PTR SS:[EBP-40],EDX 00553C08 MOV EAX,DWORD PTR SS:[EBP-40] 00553C0B MOV CL,BYTE PTR DS:[EAX] 00553C0D MOV BYTE PTR SS:[EBP-41],CL 00553C10 MOV EDX,DWORD PTR SS:[EBP-3C] ; name_ptr_rva 00553C13 CMP CL,BYTE PTR DS:[EDX] ; *boom* 00553C15 JNE SHORT 00553C45 00553C17 CMP BYTE PTR SS:[EBP-41],0 00553C1B JE SHORT 00553C3C 00553C1D MOV EAX,DWORD PTR SS:[EBP-40] 00553C20 MOV CL,BYTE PTR DS:[EAX+1] 00553C23 MOV BYTE PTR SS:[EBP-42],CL 00553C26 MOV EDX,DWORD PTR SS:[EBP-3C] 00553C29 CMP CL,BYTE PTR DS:[EDX+1] 00553C2C JNE SHORT 00553C45 00553C2E ADD DWORD PTR SS:[EBP-40],2 00553C32 ADD DWORD PTR SS:[EBP-3C],2 00553C36 CMP BYTE PTR SS:[EBP-42],0 00553C3A JNE SHORT 00553C08 00553C3C MOV DWORD PTR SS:[EBP-48],0 00553C43 JMP SHORT 00553C4D 00553C45 SBB EAX,EAX 00553C47 SBB EAX,-1 00553C4A MOV DWORD PTR SS:[EBP-48],EAX 00553C4D MOV ECX,DWORD PTR SS:[EBP-48] 00553C50 MOV DWORD PTR SS:[EBP-4C],ECX 00553C53 CMP DWORD PTR SS:[EBP-4C],0 00553C57 JNE SHORT 00553C6D 00553C59 MOV EDX,DWORD PTR SS:[EBP-8] ; eat_ordinals_addr 00553C5C MOVSX EAX,WORD PTR DS:[EDX] 00553C5F MOV ECX,DWORD PTR SS:[EBP-38] ; export_address_table 00553C62 MOV EDX,DWORD PTR SS:[EBP-18] ; ImageBase 00553C65 ADD EDX,DWORD PTR DS:[EAX*4+ECX] 00553C68 MOV DWORD PTR SS:[EBP-24],EDX 00553C6B JMP SHORT 00553C72 00553C6D JMP 00553BC5 00553C72 CMP DWORD PTR SS:[EBP-2C],0 ; ModuleInfo 00553C76 JE SHORT 00553C81 00553C78 MOV EAX,DWORD PTR SS:[EBP-2C] 00553C7B PUSH EAX 00553C7C CALL 00552F60 00553C81 CMP DWORD PTR SS:[EBP-20],0 00553C85 JE SHORT 00553C90 00553C87 MOV ECX,DWORD PTR SS:[EBP-20] 00553C8A PUSH ECX 00553C8B CALL 00552F60 00553C90 MOV EAX,DWORD PTR SS:[EBP-24] 00553C93 MOV ESP,EBP 00553C95 POP EBP 00553C96 RETN 8 --- snip ---
To cut it short: The driver(s) populate the list of loaded modules. Wine runs kernel drivers by design using a helper 'winedevice' hosting process. 'winedevice' is part of the system modules list (first entry). Unfortunately it doesn't export anything hence the drivers choke on an empty export address table.
$ sha1sum ggp3d.exe 5c1b2cca00da683b047c5a429bee540cc585b53e ggp3d.exe
$ du -sh ggp3d.exe 392K ggp3d.exe
$ wine --version wine-4.8
Regards