https://bugs.winehq.org/show_bug.cgi?id=46019
Anastasius Focht focht@gmx.net changed:
What |Removed |Added ---------------------------------------------------------------------------- CC| |focht@gmx.net Keywords| |Installer Component|-unknown |kernel32 Summary|Adobe Digital Editions |Adobe Digital Editions |4.5.9 doesn't install: |4.5.9 installer fails, |claims ``Adobe Digital |reports 'Adobe Digital |Editions 4.5 is already |Editions 4.5 is already |running``, then |running' (invalid module |aborts/crashes |handle passed to | |'FreeLibrary()', causing | |code dll unmapped as data | |dll)
--- Comment #4 from Anastasius Focht focht@gmx.net --- Hello folks,
confirming.
--- snip --- $ wine ./ADE_4.5_Installer.exe wine: Unhandled page fault on read access to 0x00000000 at address 0x10001559 (thread 0009), starting debugger... Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x10001559). Register dump: CS:0023 SS:002b DS:002b ES:002b FS:0063 GS:006b EIP:10001559 ESP:0033fcf8 EBP:004072f0 EFLAGS:00010a06( R- --O I - -P- ) EAX:00000000 EBX:00000000 ECX:0043a020 EDX:00000000 ESI:00149918 EDI:00422ec0 ... Backtrace: =>0 0x10001559 in system (+0x1559) (0x004072f0) 0x10001559: testl %eax,0x0(%eax) Modules: Module Address Debug info Name (109 modules) PE 400000- 43a000 Deferred ade_4.5_installer PE 10000000-10006000 Export system ELF 7ac00000-7ac86000 Deferred riched20<elf> -PE 7ac10000-7ac86000 \ riched20 ELF 7b400000-7b7ed000 Deferred kernel32<elf> -PE 7b420000-7b7ed000 \ kernel32 ELF 7bc00000-7bd00000 Deferred ntdll<elf> -PE 7bc10000-7bd00000 \ ntdll ELF 7c000000-7c004000 Deferred <wine-loader> ... Threads: process tid prio (all id:s are in hex) 00000008 (D) Z:\home\focht\Downloads\ADE_4.5_Installer.exe 00000029 0 00000009 0 <== --- snip ---
The installer is NSIS based, and as Louis already mentioned you can unpack it using 7zip. Listing of content:
--- snip --- $ 7z l ADE_4.5_Installer.exe
7-Zip [64] 16.02 : Copyright (c) 1999-2016 Igor Pavlov : 2016-05-21 p7zip Version 16.02 (locale=en_US.utf8,Utf16=on,HugeFiles=on,64 bits,8 CPUs Intel(R) Core(TM) i7-4700HQ CPU @ 2.40GHz (306C3),ASM,AES-NI)
Scanning the drive for archives: 1 file, 8906168 bytes (8698 KiB)
Listing archive: ADE_4.5_Installer.exe
-- Path = ADE_4.5_Installer.exe Type = PE Physical Size = 8906168 CPU = x86 Characteristics = Executable 32-bit NoRelocs NoLineNums NoLocalSyms Created = 2016-12-11 23:50:45 Headers Size = 1024 Checksum = 8971119 Name = DigitalEditions.exe Image Size = 237568 Section Alignment = 4096 File Alignment = 512 Code Size = 24576 Initialized Data Size = 118784 Uninitialized Data Size = 1024 Linker Version = 6.0 OS Version = 4.0 Image Version = 6.0 Subsystem Version = 4.0 Subsystem = Windows GUI DLL Characteristics = Relocated NX-Compatible NoSEH TerminalServerAware Stack Reserve = 1048576 Stack Commit = 4096 Heap Reserve = 1048576 Heap Commit = 4096 Image Base = 4194304 Comment = FileVersion: 4.5.9.0 FileVersion: 1.0 ProductVersion: 4.5.9.0 CompanyName: Adobe Systems Incorporated Debugger: 0 FileDescription: Adobe Digital Editions 4.5.9 InternalName: Adobe Digital Editions 4.5.9 LegalCopyright: © 2006-2018 Adobe Systems Incorporated and its licensors. All rights reserved. LegalTrademarks: Adobe® Digital Editions OriginalFilename: DigitalEditions.exe ProductName: Adobe Digital Editions 4.5.9 ---- Path = [0] Size = 8826272 Packed Size = 8826272 Virtual Size = 8826272 Offset = 72192 -- Path = [0] Type = Nsis Physical Size = 8826269 Tail Size = 3 Method = LZMA:23 Solid = + Headers Size = 1466291 Embedded Stub Size = 0 SubType = NSIS-3 BadCmd=11
Date Time Attr Size Compressed Name ------------------- ----- ------------ ------------ ------------------------ ..... 11264 8826265 $PLUGINSDIR/System.dll ..... 14848 $PLUGINSDIR/UAC.dll 2018-09-25 08:53:26 ..... 2037784 DigitalEditions.exe 2018-09-25 08:53:20 ..... 220184 ADEAutoUpdater_450.exe 2018-09-25 08:55:18 ..... 10306072 rmsdk_wrapper.dll 2018-09-25 08:54:40 ..... 246296 migration.exe 2018-09-25 08:54:38 ..... 306712 log4net.dll ... 2018-09-25 08:13:58 ..... 95297 $DOCUMENTS/My Digital Editions/welcome.epub 2018-09-25 08:13:58 ..... 902 $DOCUMENTS/My Digital Editions/Manifest/welcome.epub.xml 2018-09-25 08:13:58 ..... 162633 $DOCUMENTS/My Digital Editions/welcome.epub 2018-09-25 08:13:58 ..... $DOCUMENTS/My Digital Editions/Manifest/welcome.epub.xml ------------------- ----- ------------ ------------ ------------------------ 2018-09-25 08:55:48 25075078 8826265 86 files --- snip ---
Trace log:
--- snip --- $ WINEDEBUG=+seh,+relay wine ./ADE_4.5_Installer.exe >>log.txt 2>&1 ... 002a:Call KERNEL32.GetModuleHandleA(00409800 "C:\users\focht\Temp\nso7084.tmp\System.dll") ret=00402030 002a:Ret KERNEL32.GetModuleHandleA() retval=00000000 ret=00402030 002a:Call KERNEL32.LoadLibraryExA(00409800 "C:\users\focht\Temp\nso7084.tmp\System.dll",00000000,00000008) ret=00402040 002a:Call PE DLL (proc=0x1000270b,module=0x10000000 L"System.dll",reason=PROCESS_ATTACH,res=(nil)) 002a:Call KERNEL32.VirtualProtect(1000404c,00000004,00000040,1000403c) ret=1000272f 002a:Ret KERNEL32.VirtualProtect() retval=00000001 ret=1000272f 002a:Ret PE DLL (proc=0x1000270b,module=0x10000000 L"System.dll",reason=PROCESS_ATTACH,res=(nil)) retval=1 002a:Ret KERNEL32.LoadLibraryExA() retval=10000000 ret=00402040 002a:Call KERNEL32.GetProcAddress(10000000,00409400 "Call") ret=0040204f 002a:Ret KERNEL32.GetProcAddress() retval=100016bd ret=0040204f ... 002a:Call KERNEL32.FreeLibrary(100016bd) ret=004020ba 002a:Ret KERNEL32.FreeLibrary() retval=00000001 ret=004020ba ... 002a:Call KERNEL32.GetModuleHandleA(00409800 "C:\users\focht\Temp\nso7084.tmp\UAC.dll") ret=00402030 002a:Ret KERNEL32.GetModuleHandleA() retval=00000000 ret=00402030 002a:Call KERNEL32.LoadLibraryExA(00409800 "C:\users\focht\Temp\nso7084.tmp\UAC.dll",00000000,00000008) ret=00402040 002a:Call PE DLL (proc=0x10002854,module=0x10000000 L"UAC.dll",reason=PROCESS_ATTACH,res=(nil)) 002a:Ret PE DLL (proc=0x10002854,module=0x10000000 L"UAC.dll",reason=PROCESS_ATTACH,res=(nil)) retval=1 002a:Ret KERNEL32.LoadLibraryExA() retval=10000000 ret=00402040 002a:Call KERNEL32.GetProcAddress(10000000,00409400 "_") ret=0040204f 002a:Ret KERNEL32.GetProcAddress() retval=10002017 ret=0040204f ... 002a:Ret PE DLL (proc=0x7d117d20,module=0x7d100000 L"secur32.dll",reason=PROCESS_ATTACH,res=(nil)) retval=1 002a:Ret KERNEL32.LoadLibraryA() retval=7d100000 ret=1000188d 002a:Call KERNEL32.GetProcAddress(7d100000,10001224 "GetUserNameExA") ret=10001895 002a:Ret KERNEL32.GetProcAddress() retval=7d1033e4 ret=10001895 002a:Call KERNEL32.GetProcAddress(7e690000,1000123c "CreateProcessWithLogonW") ret=100018a2 002a:Ret KERNEL32.GetProcAddress() retval=7e6a0534 ret=100018a2 002a:Call KERNEL32.GetProcAddress(7dc60000,10001254 "SHGetValueA") ret=100018af 002a:Ret KERNEL32.GetProcAddress() retval=7dc6c1f8 ret=100018af 002a:Call KERNEL32.CreateEventA(00000000,00000000,00000000,00000000) ret=100020c2 002a:Ret KERNEL32.CreateEventA() retval=00000060 ret=100020c2 002a:Call KERNEL32.CreateEventA(00000000,00000000,00000000,00000000) ret=100020d1 002a:Ret KERNEL32.CreateEventA() retval=00000064 ret=100020d1 002a:Call KERNEL32.CreateFileMappingA(ffffffff,00000000,08000004,00000000,00002804,00000000) ret=100020f1 002a:Ret KERNEL32.CreateFileMappingA() retval=00000068 ret=100020f1 002a:Call KERNEL32.MapViewOfFile(00000068,000f001f,00000000,00000000,00000000) ret=10002109 002a:Ret KERNEL32.MapViewOfFile() retval=00390000 ret=10002109 002a:Call KERNEL32.CreateThread(00000000,00000001,10001cd8,00000000,00000000,00000000) ret=10002137 002a:Ret KERNEL32.CreateThread() retval=0000006c ret=10002137 002a:Call KERNEL32.WaitForSingleObject(00000064,ffffffff) ret=10002156 002a:Call KERNEL32.WaitForSingleObject(00000064,ffffffff) ret=10002156 ... 002b:Call PE DLL (proc=0x1000270b,module=0x10000000 L"System.dll",reason=THREAD_ATTACH,res=(nil)) 002b:Call user32.UnhookWindowsHookEx(00000000) ret=1000271a 002b:Ret user32.UnhookWindowsHookEx() retval=00000000 ret=1000271a 002b:Call KERNEL32.CloseHandle(00000000) ret=100027bf 002b:Ret KERNEL32.CloseHandle() retval=00000000 ret=100027bf 002b:trace:seh:raise_exception code=c0000005 flags=0 addr=0x100027d6 ip=100027d6 tid=002b 002b:trace:seh:raise_exception info[0]=00000000 002b:trace:seh:raise_exception info[1]=00000000 002b:trace:seh:raise_exception eax=1000270b ebx=7bce2000 ecx=00000000 edx=c0000001 esi=00fbeb68 edi=7bce2000 002b:trace:seh:raise_exception ebp=00fbeb68 esp=00fbeb48 cs=0023 ds=002b es=002b fs=0063 gs=006b flags=00010283 002b:trace:seh:call_stack_handlers calling handler at 0x7bca53e0 code=c0000005 flags=0 002b:trace:seh:__regs_RtlUnwind code=c0000005 flags=2 002b:trace:seh:__regs_RtlUnwind eax=00000000 ebx=7bca5270 ecx=00fbeaf0 edx=00fbebec esi=00fbebec edi=7bca5270 002b:trace:seh:__regs_RtlUnwind ebp=00fbe6a8 esp=00fbe688 eip=7bca52cd cs=0023 ds=002b fs=0063 gs=006b flags=00000206 002b:trace:seh:__regs_RtlUnwind calling handler at 0x7bc816b0 code=c0000005 flags=2 002b:trace:seh:__regs_RtlUnwind handler at 0x7bc816b0 returned 1 002b:exception c0000005 in PE entry point (proc=0x1000270b,module=0x10000000,reason=THREAD_ATTACH,res=(nil)) ... 002a:Call KERNEL32.GetModuleHandleA(00409800 "C:\users\focht\Temp\nso7084.tmp\System.dll") ret=00402030 002a:Ret KERNEL32.GetModuleHandleA() retval=10000000 ret=00402030 002a:Call KERNEL32.GetProcAddress(10000000,00409400 "Call") ret=0040204f 002a:Ret KERNEL32.GetProcAddress() retval=00000000 ret=0040204f ... 002a:Call KERNEL32.lstrcpynA(0040a000,004226c0 "Adobe Digital Editions 4.5 is already running. Please close Adobe Digital Editions 4.5 and try again.",00000400) ret=00405f0a 002a:Ret KERNEL32.lstrcpynA() retval=0040a000 ret=00405f0a 002a:Call user32.MessageBoxIndirectA(00409230) ret=0040574e --- snip ---
Another example of Adobe living up to its standards, producing garbage code. Disassembly of installer app code:
--- snip --- 00402029 PUSH ESI 0040202A CALL DWORD PTR DS:[<&KERNEL32.GetModuleHandleA>] 00402030 MOV EDI,EAX 00402032 CMP EDI,EBX 00402034 JNE SHORT 00402046 00402036 PUSH 8 00402038 PUSH EBX 00402039 PUSH ESI 0040203A CALL DWORD PTR DS:[<&KERNEL32.LoadLibraryExA>] 00402040 MOV EDI,EAX 00402042 CMP EDI,EBX 00402044 JE SHORT 004020BF 00402046 PUSH DWORD PTR SS:[EBP+8] 00402049 PUSH EDI 0040204A CALL <JMP.&KERNEL32.GetProcAddress> ; get API entry 0040204F MOV ESI,EAX 00402051 CMP ESI,EBX 00402053 JE SHORT 00402092 00402055 CMP DWORD PTR SS:[EBP-20],EBX 00402058 MOV DWORD PTR SS:[EBP-4],EBX 0040205B JE SHORT 00402074 0040205D PUSH DWORD PTR SS:[EBP-20] 00402060 CALL 00401423 00402065 CALL ESI 00402067 TEST EAX,EAX 00402069 JZ SHORT 0040209C 0040206B MOV DWORD PTR SS:[EBP-4],1 00402072 JMP SHORT 0040209C 00402074 PUSH OFFSET 00409000 ; callback1 00402079 PUSH OFFSET 0040A804 ; callback2 0040207E PUSH OFFSET 00424000 ; callback3 00402083 PUSH 400 00402088 PUSH DWORD PTR SS:[EBP-8] 0040208B CALL ESI ; call API entry 0040208D ADD ESP,14 00402090 JMP SHORT 0040209C 00402092 PUSH DWORD PTR SS:[EBP+8] 00402095 PUSH -9 00402097 CALL 00405110 0040209C CMP DWORD PTR SS:[EBP-1C],EBX 0040209F JNE 0040295E 004020A5 PUSH EDI 004020A6 CALL 00403817 004020AB TEST EAX,EAX 004020AD JZ 0040295E 004020B3 PUSH EDI ; function clobbered EDI lowbits 004020B4 CALL DWORD PTR DS:[<&KERNEL32.FreeLibrary>] 004020BA JMP 0040295E --- snip ---
The helper library clobbers EDI in the API entry point. Register EDI is supposed to hold the module handle but neither caller nor callee saves it across the entry point call.
--- snip --- 002a:Call KERNEL32.FreeLibrary(100016bd) ret=004020ba 002a:Ret KERNEL32.FreeLibrary() retval=00000001 ret=004020ba --- snip ---
Wine happily unmaps the library because it thinks it's a data dll (low bits set due to clobber). Later, the app loads another helper lib 'UAC.dll' which gets mapped to 0x10000000 (re-occupies the same load address as former 'system.dll'). 'UAC.dll' creates a thread, causing OS loader notifications to be sent to all dll entry points, including the one that was mistakenly unmapped as data dll. Since the module data from 'system.dll' is still in loader module list, the old dll entry point from 'system.dll' is called. 'UAC.dll' code is now mapped in this place, causing exception.
Wine's FreeLibrary() code should be more robust to handle the case of braindamaged/broken apps better.
https://source.winehq.org/git/wine.git/blob/HEAD:/dlls/kernel32/module.c#l10...
--- snip --- 1080 /*********************************************************************** 1081 * FreeLibrary (KERNEL32.@) 1082 * 1083 * Free a dll loaded into the process address space. 1084 * 1085 * PARAMS 1086 * hLibModule [I] Handle to the dll returned by LoadLibraryA(). 1087 * 1088 * RETURNS 1089 * Success: TRUE. The dll is removed if it is not still in use. 1090 * Failure: FALSE. Use GetLastError() to determine the cause. 1091 */ 1092 BOOL WINAPI DECLSPEC_HOTPATCH FreeLibrary(HINSTANCE hLibModule) 1093 { 1094 BOOL retv = FALSE; 1095 NTSTATUS nts; 1096 1097 if (!hLibModule) 1098 { 1099 SetLastError( ERROR_INVALID_HANDLE ); 1100 return FALSE; 1101 } 1102 1103 if ((ULONG_PTR)hLibModule & 3) /* this is a datafile module */ 1104 { 1105 if ((ULONG_PTR)hLibModule & 1) 1106 { 1107 struct exclusive_datafile *file; 1108 ULONG_PTR magic; 1109 1110 LdrLockLoaderLock( 0, NULL, &magic ); 1111 LIST_FOR_EACH_ENTRY( file, &exclusive_datafile_list, struct exclusive_datafile, entry ) 1112 { 1113 if (file->module != hLibModule) continue; 1114 TRACE( "closing %p for module %p\n", file->file, file->module ); 1115 CloseHandle( file->file ); 1116 list_remove( &file->entry ); 1117 HeapFree( GetProcessHeap(), 0, file ); 1118 break; 1119 } 1120 LdrUnlockLoaderLock( 0, magic ); 1121 } 1122 return UnmapViewOfFile( (void *)((ULONG_PTR)hLibModule & ~3) ); 1123 } 1124 1125 if ((nts = LdrUnloadDll( hLibModule )) == STATUS_SUCCESS) retv = TRUE; 1126 else SetLastError( RtlNtStatusToDosError( nts ) ); 1127 1128 return retv; 1129 } --- snip ---
Before trying to unmap a dll as datafile you should check if there is a PE header present, i.e.:
--- snip --- if( !RtlImageNtHeader((PVOID)((ULONG_PTR)hLibModule & ~3))) -> error out ... --- snip ---
Even dlls, loaded via 'LoadLibraryEx( ... LOAD_LIBRARY_AS_DATAFILE)' still need a PE header - although with only very few members required valid. Most of the PE structure would be useless anyway since data dlls are handled completely differently.
$ sha1sum ADE_4.5_Installer.exe cf271d4f749bdf0b6cfc6114f5536dfb6381fe70 ADE_4.5_Installer.exe
$ du -sh ADE_4.5_Installer.exe 8.5M ADE_4.5_Installer.exe
$ wine --version wine-3.18-114-g417e94f199
Regards