https://bugs.winehq.org/show_bug.cgi?id=34466
Anastasius Focht focht@gmx.net changed:
What |Removed |Added ---------------------------------------------------------------------------- Status|UNCONFIRMED |RESOLVED CC| |focht@gmx.net Resolution|--- |WONTFIX Summary|Can not start CrossDJ |Cross DJ Free 2.x and 3.x | |fail on startup (app with | |broken Wine workaround)
--- Comment #6 from Anastasius Focht focht@gmx.net --- Hello folks,
I can reproduce the crash too.
Fresh backtrace generated with Cross DJ Free 3.0.1:
--- snip --- Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x00000000). Register dump: CS:0023 SS:002b DS:002b ES:002b FS:0063 GS:006b EIP:00000000 ESP:03c6d520 EBP:03c6d594 EFLAGS:00210212( R- -- I -A- - ) EAX:03c6d554 EBX:11cd1304 ECX:00210065 EDX:03c6d55c ESI:1eca6b10 EDI:00010066 Stack dump: 0x03c6d520: 01745ee1 00010066 00000000 03c6d554 0x03c6d530: 03c6d55c 00210065 03c6d568 00000000 0x03c6d540: 03c6d57c 00000002 00000000 11cd12f8 0x03c6d550: 00000000 000002a8 00000164 00000230 0x03c6d560: 0000015e 00010066 00000000 00000000 0x03c6d570: 03c6d5a0 01991050 ffffffff 01ff0000 000c: sel=0067 base=00000000 limit=00000000 16-bit --x Backtrace: =>0 0x00000000 (0x03c6d594) 1 0x0174ca13 in cross-dj-free (+0x134ca12) (0x03c6f6bc) 2 0x017570c8 in cross-dj-free (+0x13570c7) (0x03c6f758) 3 0x0175994b in cross-dj-free (+0x135994a) (0x03c6f778) 4 0x7ec66506 WINPROC_wrapper+0x19() in user32 (0x03c6f7a8) ... Modules: Module Address Debug info Name (132 modules) PE 400000- 32df000 Export cross-dj-free PE 10000000-10010000 Deferred mvu46mk2 PE 6e300000-6f5c4000 Deferred libmvvideo ... Threads: process tid prio (all id:s are in hex) 00000008 (D) C:\Program Files\MixVibes\Cross DJ Free 3.0.1\Cross-DJ-Free.exe 0000003a 0 00000039 2 00000038 15 00000037 2 00000036 15 00000035 0 00000034 0 00000033 0 00000032 0 00000031 0 00000030 -2 0000002d 0 0000002c -1 0000002b 1 0000002a 0 00000029 0 00000028 0 00000009 0 <== ... --- snip ---
The faulting instruction and memory reference shows a NULL pointer call.
Looking at 'Stack dump' you can see top value 0x01745ee1 which is the caller return address, located in '.text' section of the main executable.
Disassembly gives:
--- snip --- ... 01745EBC 884D EA MOV BYTE PTR SS:[LOCAL.6+2],CL 01745EBF 8B8E 90000000 MOV ECX,DWORD PTR DS:[ESI+90] 01745EC5 51 PUSH ECX 01745EC6 8D55 C8 LEA EDX,[LOCAL.14] 01745EC9 52 PUSH EDX 01745ECA 8D45 C0 LEA EAX,[LOCAL.16] 01745ECD 50 PUSH EAX 01745ECE 6A 00 PUSH 0 01745ED0 57 PUSH EDI 01745ED1 C645 EB 01 MOV BYTE PTR SS:[LOCAL.6+3],1 01745ED5 66:C745 E8 0000 MOV WORD PTR SS:[LOCAL.6],0 01745EDB FF15 908A1403 CALL DWORD PTR DS:[3148A90] ; NULL ptr 01745EE1 5F POP EDI ; <-- return address on stack --- snip ---
The referenced function pointer lives at 0x3148A90
Memory map of executable shows it's located in '.data' section:
--- snip --- Address Size Owner Section Contains Access ... 00400000 00001000 Cross-DJ-Free PE header R 00401000 01623000 Cross-DJ-Free .text Code R E 01A24000 015E2000 Cross-DJ-Free .rdata Imports,exports R 03006000 00147000 Cross-DJ-Free .data Data RW CopyOnWr 0314D000 0001F000 Cross-DJ-Free .rsrc Resources R 0316C000 00173000 Cross-DJ-Free .reloc Relocations R 03C62000 00001000 RW Guarded 03C63000 0000D000 Stack of main thread RW ... --- snip ---
Searching the mapped executable '.text' section for all memory references to '.data:0x3148A90' gives:
--- snip --- 01742210 CMP DWORD PTR DS:[3148A90],0 0174224D MOV DWORD PTR DS:[3148A90],EAX 01742256 CMP DWORD PTR DS:[3148A90],EAX 01745EDB CALL DWORD PTR DS:[3148A90] --- snip ---
Then we find this piece of code here:
--- snip --- ... 01742210 833D 908A1403 00 CMP DWORD PTR DS:[3148A90],0 01742217 75 3B JNE SHORT 01742254 01742219 56 PUSH ESI 0174221A 8B35 F041A201 MOV ESI,DWORD PTR DS:[<&KERNEL32.GetModuleHandleW>] 01742220 57 PUSH EDI 01742221 68 4867C002 PUSH OFFSET 02C06748 ; ModuleName = "ntdll.dll" 01742226 FFD6 CALL ESI ; KERNEL32.GetModuleHandleW 01742228 8B3D C042A201 MOV EDI,DWORD PTR DS:[<&KERNEL32.GetProcAddress>] 0174222E 85C0 TEST EAX,EAX 01742230 74 0C JZ SHORT 0174223E 01742232 68 3467C002 PUSH OFFSET 02C06734 ; Procname = "wine_get_version" 01742237 50 PUSH EAX ; hModule 01742238 FFD7 CALL EDI ; KERNEL32.GetProcAddress 0174223A 85C0 TEST EAX,EAX 0174223C 75 14 JNZ SHORT 01742252 0174223E 68 0468C002 PUSH OFFSET 02C06804 ; UNICODE "user32.dll" 01742243 FFD6 CALL ESI 01742245 68 F067C002 PUSH OFFSET 02C067F0 ; ASCII "UpdateLayeredWindow" 0174224A 50 PUSH EAX 0174224B FFD7 CALL EDI 0174224D A3 908A1403 MOV DWORD PTR DS:[3148A90],EAX 01742252 5F POP EDI 01742253 5E POP ESI 01742254 33C0 XOR EAX,EAX 01742256 3905 908A1403 CMP DWORD PTR DS:[3148A90],EAX 0174225C 0F95C0 SETNE AL 0174225F C3 RETN --- snip ---
The code that ought to call user32.dll.UpdateLayeredWindow entry point is some subroutine within the app WM_PAINT handler.
The parent subroutine allocates many variables on stack (~8K in size). The variable (flag) in question is initialized as byte-sized type and gets later passed as 32-bit type (DWORD, stack). If the upper word is non-zero by chance which happens the case for Wine then the code path to user32.dll.UpdateLayeredWindow will be taken.
The vendor most likely tried to work around older versions of Wine (pre 1.0 era) and messed this up.
$ sha1sum Install_Cross_DJ_Free_3.0.1.exe 98f68e838537789c010d0a1defced4b5eed822c1 Install_Cross_DJ_Free_3.0.1.exe
$ du -sh Install_Cross_DJ_Free_3.0.1.exe 90M Install_Cross_DJ_Free_3.0.1.exe
$ wine --version wine-1.7.18-92-gb01fc1a
Regards