[Bug 46019] Adobe Digital Editions 4.5.9 installer fails, reports ' Adobe Digital Editions 4.5 is already running' ( invalid module handle passed to 'FreeLibrary()', causing code dll unmapped as data dll)
wine-bugs at winehq.org
wine-bugs at winehq.org
Sat Oct 20 06:28:17 CDT 2018
https://bugs.winehq.org/show_bug.cgi?id=46019
Anastasius Focht <focht at gmx.net> changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |focht at 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 at 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#l1080
--- 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
--
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