http://bugs.winehq.org/show_bug.cgi?id=28768
Anastasius Focht focht@gmx.net changed:
What |Removed |Added ---------------------------------------------------------------------------- Keywords| |obfuscation Status|RESOLVED |UNCONFIRMED Component|-unknown |tools Resolution|DUPLICATE |--- Summary|Kane & Lynch: Dead Men |Multiple GFWL (Games For |crashes on launch |Windows Live) 1.x games | |crash on startup (Kane & | |Lynch: Dead Men)
--- Comment #9 from Anastasius Focht focht@gmx.net --- Hello folks,
reopening.
I found a distributed "backup" of the game to play with - thanks to the guys still seeding ;-)
The game installer bundles an old 1.x version of GFWL (no .NET Framework dependencies).
$ sha1sum XLiveRedist.msi 6c670f4e16fa801978fe1ba7cd4d13bc64792e0e XLiveRedist.msi
$ du -sh XLiveRedist.msi 20M XLiveRedist.msi
'xlive.dll' version info:
--- snip ---- Microsoft Corporation Games for Windows LIVE 1.2.0238.0 11/11/2007 --- snip ---
The crash 'wine: Unhandled exception 0x80000003 ...' is a builtin assert() triggered from the game engine due to initialization failure of XLive.
This older version implements some tampering/consistency checks differently than GFWL 3.x (.NET 3.5 based version).
--- snip --- $ pwd /home/focht/.wine/drive_c/Program Files/Eidos/Kane and Lynch Dead Men
$ WINEDEBUG=+tid,+seh,+relay,+snoop,+msvcrt wine ./kaneandlynch.exe >>log.txt 2>&1 ... 0042:CALL xlive.5001(<unknown, check return>) ret=00485a37 0042:RET xlive.5001(0114e944) retval=80070057 ret=00485a37 ... 0042:CALL xlive.5001(0114d444) ret=00485a37 0042:Call KERNEL32.GetModuleHandleA(0114d408 "ntdll.dll") ret=011d93dd 0042:Ret KERNEL32.GetModuleHandleA() retval=7bc10000 ret=011d93dd 0042:Call KERNEL32.GetProcAddress(7bc10000,0114d408 "ZwQueryInformationProcess") ret=011d9422 0042:Ret KERNEL32.GetProcAddress() retval=7bc2545c ret=011d9422 0042:Call ntdll.ZwQueryInformationProcess(ffffffff,00000007,0114d3e0,00000004,00000000) ret=011d9443 0042:Ret ntdll.ZwQueryInformationProcess() retval=00000000 ret=011d9443 0042:RET xlive.5001() retval=00000000 ret=00485a37 ... 0042:CALL xlive.5000(<unknown, check return>) ret=0079235b ... 0042:Call KERNEL32.CreateEventW(00000000,00000000,00000000,0cb58390 L"Global\XLive-S-1-5-21-0-0-0-1000") ret=003d0dd9 0042:Ret KERNEL32.CreateEventW() retval=000000ec ret=003d0dd9 ... 0042:Call KERNEL32.CreateFileW(0114eb48 L"C:\windows\system32\xlive.dll.CAT",80000000,00000001,00000000,00000003,00000080,00000000) ret=012296e5 0042:Ret KERNEL32.CreateFileW() retval=000000f0 ret=012296e5 ... 0042:Call KERNEL32.CreateFileW(0114e940 L"C:\windows\system32\xlive.dll",80000000,00000001,00000000,00000003,00000080,00000000) ret=012291e9 0042:Ret KERNEL32.CreateFileW() retval=000000f0 ret=012291e9 ... 0042:Call KERNEL32.LoadLibraryW(0114e69c L"C:\windows\system32\xlive.dll") ret=0122abd2 0042:Ret KERNEL32.LoadLibraryW() retval=01150000 ret=0122abd2 0042:Call KERNEL32.lstrcmpiW(0cb99c3c L"xlive.dll",01156474 L"shimeng.dll") ret=0122a513 0042:Ret KERNEL32.lstrcmpiW() retval=00000001 ret=0122a513 ... 0042:Call KERNEL32.K32EnumProcessModules(ffffffff,0114e520,000003fc,0114e92c) ret=003f037d 0042:Ret KERNEL32.K32EnumProcessModules() retval=00000001 ret=003f037d ... 0042:Call KERNEL32.CreateFileW(0114e944 L"C:\Program Files\Eidos\Kane and Lynch Dead Men\kaneandlynch.exe.CAT",80000000,00000001,00000000,00000003,00000080,00000000) ret=012296e5 0042:Ret KERNEL32.CreateFileW() retval=000000f0 ret=012296e5 ... 0042:Call KERNEL32.CreateFileW(0114eb4c L"C:\Program Files\Eidos\Kane and Lynch Dead Men\kaneandlynch.exe.CFG",80000000,00000001,00000000,00000003,00000080,00000000) ret=011f9e26 0042:Ret KERNEL32.CreateFileW() retval=000000f0 ret=011f9e26 ... 0042:Call oleaut32.SysAllocString(0cbbbfd8 L"<?xml version=\"1.0\" encoding=\"utf-8\" ?>\r\n<Liveconfig xmlns="http://schemas.microsoft.com/XBOX/LIVE/LIVECONFIG/2007/01%5C%22%3E%5Cr%5Cn%5...<titleid>534307EB</titleid>\r\n\t<lankey>xxxx</lankey>\r\n\t<enableCrossPlatformSystemLink>false</enableCrossPlatformSystemLink>\r\n\t<title"...) ret=011fd712 ... 0042:Call KERNEL32.LoadLibraryExW(0114de2e L"C:\windows\system32\msxml3.dll",00000000,00000008) ret=7e985853 ... 0042:Call KERNEL32.CreateFileW(0114e27c L"C:\Program Files\Eidos\Kane and Lynch Dead Men\kaneandlynch.exe",80000000,00000005,00000000,00000003,08000000,00000000) ret=0122c0d5 0042:Ret KERNEL32.CreateFileW() retval=000000f0 ret=0122c0d5 ... 0042:Call KERNEL32.LoadLibraryW(0114e27c L"C:\Program Files\Eidos\Kane and Lynch Dead Men\kaneandlynch.exe") ret=0122abd2 0042:Ret KERNEL32.LoadLibraryW() retval=00400000 ret=0122abd2 ... 0042:Call KERNEL32.K32GetModuleInformation(ffffffff,00400000,0114e264,0000000c) ret=0122943d 0042:Ret KERNEL32.K32GetModuleInformation() retval=00000001 ret=0122943d ... --- snip ---
xlive.5000 = XLiveInitialize()
The issue from bug 33034 which prevents GFWL 3.x from working is also present here (loader module structure for the main executable doesn't have the entry point member set).
After fixing that it still fails:
--- snip --- ... 0042:Call KERNEL32.GetModuleFileNameW(7bc10000,0114eb4c,00000104) ret=003f0407 0042:Ret KERNEL32.GetModuleFileNameW() retval=0000001d ret=003f0407 ... 0042:Call KERNEL32.CreateFileW(0114eb4c L"C:\windows\system32\KERNEL32.dll",80000000,00000001,00000000,00000003,00000080,00000000) ret=012291e9 0042:Ret KERNEL32.CreateFileW() retval=000000f0 ret=012291e9 0042:Call KERNEL32.GetFileSize(000000f0,0114e488) ret=012591c0 0042:Ret KERNEL32.GetFileSize() retval=001985f4 ret=012591c0 0042:Call KERNEL32.CreateFileMappingW(000000f0,00000000,00000002,00000000,00000000,00000000) ret=012591e5 0042:Ret KERNEL32.CreateFileMappingW() retval=0000011c ret=012591e5 0042:Call KERNEL32.MapViewOfFile(0000011c,00000004,00000000,00000000,00000000) ret=012591f7 0042:Ret KERNEL32.MapViewOfFile() retval=0e090000 ret=012591f7 0042:Call KERNEL32.CloseHandle(0000011c) ret=01259201 0042:Ret KERNEL32.CloseHandle() retval=00000001 ret=01259201 0042:Call msvcr80.memset(0114e334,00000000,00000038) ret=015b024a 0042:Ret msvcr80.memset() retval=0114e334 ret=015b024a 0042:Call KERNEL32.UnmapViewOfFile(0e090000) ret=01257fcf 0042:Ret KERNEL32.UnmapViewOfFile() retval=00000001 ret=01257fcf 0042:Call KERNEL32.CloseHandle(000000f0) ret=011f780d 0042:Ret KERNEL32.CloseHandle() retval=00000001 ret=011f780d ... 0042:Call KERNEL32.GetModuleHandleA(0114ed8c "kernel32.dll") ret=003e0ef3 0042:Ret KERNEL32.GetModuleHandleA() retval=7b810000 ret=003e0ef3 ... 0042:Call KERNEL32.GetProcAddress(7b810000,0114ed8c "ReadFile") ret=003e051b 0042:Ret KERNEL32.GetProcAddress() retval=7b824c7c ret=003e051b ... 0042:Call advapi32.RegisterEventSourceW(00000000,01154c9c) ret=011fbb57 0042:fixme:advapi:RegisterEventSourceW ((null),L"XLive"): stub 0042:Ret advapi32.RegisterEventSourceW() retval=cafe4242 ret=011fbb57 0042:Call advapi32.ReportEventW(cafe4242,00000002,00000000,80000002,00000000,00000004,00000000,0114dcec,00000000) ret=011fbb82 0042:fixme:advapi:ReportEventW (0xcafe4242,0x0002,0x0000,0x80000002,(nil),0x0004,0x00000000,0x114dcec,(nil)): stub 0042:Ret advapi32.ReportEventW() retval=00000001 ret=011fbb82 0042:Call advapi32.DeregisterEventSource(cafe4242) ret=011fbba6 0042:fixme:advapi:DeregisterEventSource (0xcafe4242) stub 0042:Ret advapi32.DeregisterEventSource() retval=00000001 ret=011fbba6 ... 0042:RET xlive.5000(0114f278) retval=80004005 ret=0079235b 0042:trace:seh:raise_exception code=80000003 flags=0 addr=0x792371 ip=00792372 tid=0042 0042:trace:seh:raise_exception eax=80004005 ebx=00000000 ecx=5c4276b0 edx=00110064 esi=00188c34 edi=00c8f8fc 0042:trace:seh:raise_exception ebp=0c866c80 esp=0114f254 cs=0023 ds=002b es=002b fs=0063 gs=006b flags=00000287 0042:trace:seh:call_stack_handlers calling handler at 0x90f154 code=80000003 flags=0 0042:trace:seh:call_stack_handlers handler at 0x90f154 returned 1 ... wine: Unhandled exception 0x80000003 in thread 42 at address 0x792371 (thread 0042), starting debugger... --- snip ---
Unfortunately it does some things in an area where Wine is very weak - placeholders/fake dll validation.
The DRM scheme maps the builtin 'kernel32.dll' and 'ntdll.dll' placeholders into memory and validates PE header structures/attributes.
I dumped the 'kernel32.dll' placeholder PE NT optional header (= adjusted for offset 0) from memory to show the problem:
--- snip --- ... $ 50 45 00 00 ASCII "PE" ; PE signature (PE) $+4 4C01 DW 014C ; Machine = IMAGE_FILE_MACHINE_I386 $+6 0300 DW 0003 ; NumberOfSections = 3 $+8 00000000 DD 00000000 ; TimeDateStamp = 0 $+C 00000000 DD 00000000 ; PointerToSymbolTable = 0 $+10 00000000 DD 00000000 ; NumberOfSymbols = 0 $+14 E000 DW 00E0 ; SizeOfOptionalHeader = E0 (224.) $+16 2220 DW 2022 ; Characteristics = DLL|EXECUTABLE_IMAGE|20 $+18 0B01 DW 010B ; MagicNumber = PE32 $+1A 00 DB 00 ; MajorLinkerVersion = 0 $+1B 00 DB 00 ; MinorLinkerVersion = 0 $+1C 05000000 DD 00000005 ; SizeOfCode = 5 $+20 00000000 DD 00000000 ; SizeOfInitializedData = 0 $+24 00000000 DD 00000000 ; SizeOfUninitializedData = 0 $+28 00100000 DD 00001000 ; AddressOfEntryPoint = 1000 $+2C 00100000 DD 00001000 ; BaseOfCode = 1000 $+30 00000000 DD 00000000 ; BaseOfData = 0 $+34 00000010 DD 10000000 ; ImageBase = 10000000 $+38 00100000 DD 00001000 ; SectionAlignment = 1000 $+3C 00020000 DD 00000200 ; FileAlignment = 200 ... --- snip ---
There is one check that does really harm here.
--- snip --- ... 015B0329 807F 1A 03 CMP BYTE PTR DS:[EDI+1A],3 ; MajorLinkerVersion 015B032D 73 0A JNB SHORT xlive.015B0339 015B032F 807F 1B 05 CMP BYTE PTR DS:[EDI+1B],5 ; MinorLinkerVersion 015B0333 0F82 5FFFFFFF JB xlive.015B0298 015B0339 0FB74F 18 MOVZX ECX,WORD PTR DS:[EDI+18] ; MagicNumber 015B033D 66:81F9 0B01 CMP CX,10B 015B0342 74 12 JE SHORT xlive.015B0356 015B0344 66:81F9 0B02 CMP CX,20B 015B0349 0F85 49FFFFFF JNZ xlive.015B0298 015B034F 66:81F9 0B01 CMP CX,10B ... 015B0298 B8 7B0000C0 MOV EAX,C000007B 015B029D 5F POP EDI 015B029E 5E POP ESI 015B029F 5B POP EBX 015B02A0 5D POP EBP 015B02A1 C2 2800 RETN 28 --- snip ---
PE linker version needs to be at least 2.5, or better 'MajorLinkerVersion' should match something that modern Windows XP+ has.
Source: http://source.winehq.org/git/wine.git/blob/4e4acd5f705c770b7c361605e11d9d7c0...
--- snip --- 636 void output_fake_module( DLLSPEC *spec ) 637 { ... 644 static const char fakedll_signature[] = "Wine placeholder DLL"; ... 709 put_word( spec->characteristics ); /* Characteristics */ 710 put_word( get_ptr_size() == 8 ? 711 IMAGE_NT_OPTIONAL_HDR64_MAGIC : 712 IMAGE_NT_OPTIONAL_HDR32_MAGIC ); /* Magic */ 713 put_byte( 0 ); /* MajorLinkerVersion */ 714 put_byte( 0 ); /* MinorLinkerVersion */ 715 put_dword( text_size ); /* SizeOfCode */ ... --- snip ---
Surprisingly many other nonsense header values survived the initial validation phase.
If you fix that it goes further - only to run into bug 6194
--- snip --- ... 0028:Call wintrust.CryptCATAdminAcquireContext(0114cc20,0114e2b0,00000000) ret=01259320 0028:Call ntdll.RtlAllocateHeap(00110000,00000000,00000210) ret=7d89217b 0028:Ret ntdll.RtlAllocateHeap() retval=0a85dab8 ret=7d89217b 0028:Call KERNEL32.GetSystemDirectoryW(0114c940,00000104) ret=7d8921b7 0028:Ret KERNEL32.GetSystemDirectoryW() retval=00000013 ret=7d8921b7 0028:Call KERNEL32.CreateDirectoryW(0114c940 L"C:\windows\system32\catroot",00000000) ret=7d8921e8 0028:Ret KERNEL32.CreateDirectoryW() retval=00000000 ret=7d8921e8 0028:Call KERNEL32.CreateDirectoryW(0a85dabc L"C:\windows\system32\catroot\{f750e6c3-38ee-11d1-85e5-00c04fc295ee}",00000000) ret=7d892333 0028:Ret KERNEL32.CreateDirectoryW() retval=00000000 ret=7d892333 0028:Ret wintrust.CryptCATAdminAcquireContext() retval=00000001 ret=01259320 0028:Call wintrust.CryptCATAdminEnumCatalogFromHash(0a85dab8,0114ed54,00000014,00000000,0114cc1c) ret=0125936e 0028:Call advapi32.CryptAcquireContextW(0114c83c,00000000,0114ca92 L"Microsoft Base Cryptographic Provider v1.0",00000001,f0000000) ret=7d892c46 ... 0028:Call KERNEL32.FindFirstFileW(0a85e348 L"C:\windows\system32\catroot\{f750e6c3-38ee-11d1-85e5-00c04fc295ee}\*.cat",0114c840) ret=7d892d34 0028:Ret KERNEL32.FindFirstFileW() retval=ffffffff ret=7d892d34 ... 0028:Ret wintrust.CryptCATAdminEnumCatalogFromHash() retval=00000000 ret=0125936e 0028:Call wintrust.CryptCATAdminReleaseContext(0a85dab8,00000000) ret=012594d6 0028:Call ntdll.RtlFreeHeap(00110000,00000000,0a85dab8) ret=7d8933d7 0028:Ret ntdll.RtlFreeHeap() retval=00000001 ret=7d8933d7 0028:Ret wintrust.CryptCATAdminReleaseContext() retval=00000001 ret=012594d6 ... --- snip ---
Unfortunately there is more nasty stuff following hence I doubt this is going to work in near future.
There is a "workaround" though.
When bug 33034 gets fixed you can upgrade the older GFWL v1.x clients to 3.x which carries the cost of .NET Framework 3.5 SP1 dependency.
I already tested this. The game will work with GFWL v3.x - only to run into other Wine bugs (not GFWL related anymore).
$ wine --version wine-1.7.19-71-g94ccd61
Regards