https://bugs.winehq.org/show_bug.cgi?id=45335
Anastasius Focht focht@gmx.net changed:
What |Removed |Added ---------------------------------------------------------------------------- Status|UNCONFIRMED |RESOLVED CC| |focht@gmx.net Resolution|--- |INVALID Summary|OneVolumeViewer: crash when |Morita i-Dixel CT imaging |opens |software 'OneVolumeViewer' | |crashes when opening volume | |files (broken application, | |working directory must be | |short path)
--- Comment #7 from Anastasius Focht focht@gmx.net --- Hello folks,
confirming.
The app is MFC-based and is broken in several aspects. It just works by chance on Windows due to the conditions it ought to be run.
I'm pretty sure you ripped that directory including the whole content 1:1 from a CD media (given by some CT/MRT lab) or generated the content with some app to be written to an external media while preserving the directory structure 1:1
Pointless to provide trace logs as the problems can only be figured out by debugging this mess.
The viewer app tries to copy an image object from an internal object to some newly allocated buffer. Depending on earlier (sub)heap usage this object is located near the end of the heap.
Heap layout in non-working case:
--- snip --- Address Size Owner Section Type Access ... 00400000 00001000 (4096.) OneVolumeViewer Img R 00401000 00291000 (2691072.) OneVolumeViewer .text Img R E 00692000 0009E000 (647168.) OneVolumeViewer .rdata Img R 00730000 00010000 (65536.) OneVolumeViewer .data Img RW Co 00740000 00186000 (1597440.) OneVolumeViewer .rsrc Img R 008D0000 00110000 (1114112.) Priv RW 009E0000 00010000 (65536.) Priv RW 00AF0000 00010000 (65536.) Priv RW 00C00000 00010000 (65536.) Priv RW 00D10000 00010000 (65536.) Priv RW 00E20000 00010000 (65536.) Priv RW 00F30000 00110000 (1114112.) Priv RW 01040000 00220000 (2228224.) Priv RW 01260000 00001000 (4096.) Priv RW 01270000 00001000 (4096.) Priv RW 01280000 00472000 (4661248.) Map R 01700000 00001000 (4096.) JMoritaSkins_cjs Img R 01701000 00235000 (2314240.) JMoritaSkins_cjs .rsrc Img R 01936000 00001000 (4096.) JMoritaSkins_cjs .reloc Img R ... --- snip ---
The sub-heap located at 0x01040000 is of interest here.
The source image object address has a fixed offset within another heap block, suggesting it might be some contained member.
As already mentioned, the source object is located within sub-heap 0x00F30000, near the end.
--- snip --- 1004F8B1 LEA EDX,[EAX*8] 1004F8B8 SUB EDX,EAX 1004F8BA MOV EAX,DWORD PTR SS:[ESP+14] ; 0x010BB7B0 (object) 1004F8BE LEA EDX,[EDX*8+EAX+2C38] ; 0x010BE3E8 1004F8C5 MOV EAX,DWORD PTR SS:[ESP+18] 1004F8C9 MOV EDI,DWORD PTR DS:[EAX+478] 1004F8CF MOV EBX,DWORD PTR DS:[EAX+47C] 1004F8D5 INC ECX 1004F8D6 MOV DWORD PTR SS:[ESP+2C],EDX ; src image object 1004F8DA MOV DWORD PTR SS:[ESP+20],EDI ; width 1004F8DE MOV DWORD PTR SS:[ESP+1C],EBX ; height ... 1004F953 ADD ESP,24 1004F956 MOV ESI,EBX 1004F958 IMUL ESI,EDI ; width*height 1004F95B ADD ESI,ESI ; *2 1004F95D ADD ESI,ESI ; *2 1004F95F PUSH ESI ; object size 1004F960 CALL <JMP.&mfc90.#265> ; -> operator new() 1004F965 MOV EDX,DWORD PTR SS:[ESP+30] 1004F969 ADD ESP,4 1004F96C PUSH ESI ; object size 1004F96D PUSH EDX ; src (0x010BE3E8) 1004F96E PUSH EAX ; dst 1004F96F MOV DWORD PTR SS:[ESP+1C],EAX 1004F973 CALL <JMP.&MSVCR90.memcpy> ; *boom* 1004F978 ADD ESP,0C 1004F97B PUSH OFFSET 100AFCC0 ; ASCII "dwSaveImage" ... --- snip ---
--- snip --- Address Value ASCII Comments 010BB7A8 00002FC0 block size 010BB7AC 00455355 USE (heap magic) 010BB7B0 100B4D3C vtable 010BB7B4 000000F4 member1 010BB7B8 000000F8 ... 010BB7BC 00000100 010BB7C0 0021DFC0 010BB7C4 FFFFFFFF ... 010BE3E4 3F800000 010BE3E8 100B4DB4 vtable 010BE3EC 00000001 member1 010BE3F0 03364250 ... --- snip ---
0x010BB7B0 -> 0x010BE3E8 (object + member offset)
image object size: 0x001C8E40 source copy end addr: 0x1287228 (0x010BE3E8+0x001C8E40)
The memcpy() will trigger a page fault at 0x01261000 as nothing is mapped there. The memory chunk at 0x01260000 was already a "no-go" area but it was mapped adjacent to the end of the sub-heap and readable while the next block has a hole.
The "working" case, heap layout:
--- snip --- Address Size Owner Section Type Access ... 00400000 00001000 (4096.) OneVolumeViewer Img R 00401000 00291000 (2691072.) OneVolumeViewer .text Img R E 00692000 0009E000 (647168.) OneVolumeViewer .rdata Img R 00730000 00010000 (65536.) OneVolumeViewer .data Img RW 00740000 00186000 (1597440.) OneVolumeViewer .rsrc Img R 008D0000 00110000 (1114112.) Priv RW 009E0000 00010000 (65536.) Priv RW 00AF0000 00010000 (65536.) Priv RW 00C00000 00010000 (65536.) Priv RW 00D10000 00010000 (65536.) Priv RW 00E20000 00010000 (65536.) Priv RW 00F30000 00110000 (1114112.) Priv RW 01040000 00220000 (2228224.) Priv RW 01260000 00001000 (4096.) Priv RW 01270000 00001000 (4096.) Priv RW 01280000 00472000 (4661248.) Map R 01700000 00001000 (4096.) JMoritaSkins_cjs Img R 01701000 00235000 (2314240.) JMoritaSkins_cjs .rsrc Img R 01936000 00001000 (4096.) JMoritaSkins_cjs .reloc Img R ... 10000000 00001000 (4096.) VolRE Img R 10001000 000A8000 (688128.) VolRE .text Img R E 100A9000 00020000 (131072.) VolRE .rdata Img R 100C9000 00004000 (16384.) VolRE .data Img RW 100CD000 00027000 (159744.) VolRE .rsrc Img R 100F4000 0000E000 (57344.) VolRE .reloc Img R ... --- snip ---
source image object address: 0x1030BB0
NOTE: the object is now located on the preceding sub-heap (0x00F30000), near the end.
image object size: 0x001C8E40 source copy end addr: 0x011F99F0 (0x1030BB0+0x001C8E40)
The end address exceeds the sub-heap allocation range but since there is another adjacent sub-heap, any read will succeed.
The one-trick pony here is the length of the working directory. Normally these "standalone" viewer apps are distributed on CD/USB stick media from the CT/MRT lab.
The directory layout:
--- snip --- $ tree --charset=ANSI . |-- bin | `-- x86 | |-- GdiPlus.dll | |-- JMFilterLib.dll | |-- mfc90.dll | |-- MFC90JPN.dll | |-- mfc90u.dll | |-- mfcm90.dll | |-- mfcm90u.dll | |-- Microsoft.VC90.CRT | | |-- Microsoft.VC90.CRT.manifest | | |-- msvcm90.dll | | |-- msvcp90.dll | | `-- msvcr90.dll | |-- Microsoft.VC90.MFC | | |-- mfc90.dll | | |-- mfc90u.dll | | |-- mfcm90.dll | | |-- mfcm90u.dll | | `-- Microsoft.VC90.MFC.manifest | |-- Microsoft.VC90.MFCLOC | | |-- MFC90JPN.dll | | `-- Microsoft.VC90.MFCLOC.manifest | |-- Microsoft.VC90.OPENMP | | |-- Microsoft.VC90.OpenMP.manifest | | `-- vcomp90.dll | |-- msvcm90.dll | |-- msvcp90.dll | |-- msvcr90.dll | |-- ODViewer.exe | |-- ODViewer.pdf | |-- OneVolumeViewer.exe | |-- OneVolumeViewer.pdf | |-- tbb.dll | |-- tbbmalloc.dll | |-- Theme | | |-- DarkGreen | | | |-- DarkGreen.dll | | | `-- DarkGreen.ini | | `-- JMoritaSkins.cjstyles | |-- ToolkitPro1521vc90.dll | |-- ToolkitPro.ResourceDe.dll | |-- ToolkitPro.ResourceEl.dll | |-- ToolkitPro.ResourceEn.dll | |-- ToolkitPro.ResourceEs.dll | |-- ToolkitPro.ResourceFi.dll | |-- ToolkitPro.ResourceFr.dll | |-- ToolkitPro.ResourceHe.dll | |-- ToolkitPro.ResourceHu.dll | |-- ToolkitPro.ResourceIt.dll | |-- ToolkitPro.ResourceJa.dll | |-- ToolkitPro.ResourceNl.dll | |-- ToolkitPro.ResourcePl.dll | |-- ToolkitPro.ResourceRo.dll | |-- ToolkitPro.ResourceRu.dll | |-- ToolkitPro.ResourceSk.dll | |-- ToolkitPro.ResourceSv.dll | |-- ToolkitPro.ResourceTh.dll | |-- ToolkitPro.ResourceTr.dll | |-- ToolkitPro.ResourceZhCn.dll | |-- ToolkitPro.ResourceZhTw.dll | |-- vcomp90.dll | `-- VolRE.dll |-- comment.dat |-- CT_20180115171449 | |-- Constants1100.xml | |-- Constants.csv | |-- CT_0.vol | |-- CtStatus.csv | |-- CtTaskId.jmd | `-- VolumeId.xml |-- ODViewer.exe |-- OneVolumeViewer.exe |-- photo_proc | `-- proc.pak |-- photo_proc.txt |-- Series_01 | `-- CT_01_20180115171528716.pak |-- series.dat `-- ver_ctrl.txt
11 directories, 69 files --- snip ---
When one inserts the media, the longest path is something like:
'd:\OneVolumeViewer.exe' -> double click in 'explorer' which cause the bootstrapper to spawn a sub-process in 'd:\bin\x86\OneVolumeViewer.exe' with working directory set to root. This works.
Now with Wine if you put the whole directory somewhere you already end up with:
'z:\<long path>\OneVolumeViewer.exe'
which causes the crash due to different heap usage patterns (corruption is likely involved too).
You can work around by creating a drive-mapping to shorten the path, for example map 'z:\home\foobar\long path\' to 'd:\' (winecfg)
Alternatively you can put the whole directory into the WINEPREFIX. This should also work:
--- snip --- $ pwd /home/focht/.wine/drive_c/Program Files (x86)/OneVolumeViewer --- snip ---
This one will not:
--- snip --- 0000002d (D) C:\Program Files (x86)\a-very-long-path-1111-2222-3333-4444-5555-6666-7777-8888-9999\OneVolumeViewer\bin\x86\OneVolumeViewer.exe 0000003e 0 <== 0000003b -2 --- snip ---
Anyway, the app will crash the same way on Windows if you put it into a long path. It's simply broken.
ProtectionID scan for documentation:
--- snip --- -=[ ProtectionID v0.6.9.0 DECEMBER]=- (c) 2003-2017 CDKiLLER & TippeX Build 24/12/17-21:05:42 Ready... Scanning -> C:\Program Files (x86)\OneVolumeViewer\OneVolumeViewer.exe File Type : 32-Bit Exe (Subsystem : Win GUI / 2), Size : 79360 (013600h) Byte(s) | Machine: 0x14C (I386) Compilation TimeStamp : 0x522D30CB -> Mon 09th Sep 2013 02:22:03 (GMT) [TimeStamp] 0x522D30CB -> Mon 09th Sep 2013 02:22:03 (GMT) | PE Header | - | Offset: 0x000000E8 | VA: 0x004000E8 | - [TimeStamp] 0x522D30CB -> Mon 09th Sep 2013 02:22:03 (GMT) | DebugDirectory | - | Offset: 0x0000C3A4 | VA: 0x0040D1A4 | - [LoadConfig] Struct determined as v8 (Expected size 140 | Actual size 64) [!] Executable uses SEH Tables (/SAFESEH) (10 calculated 10 recorded... 0 invalid addresses) [LoadConfig] CodeIntegrity -> Flags 0x1 | Catalog 0x0 (0) | Catalog Offset 0x545C3A65 | Reserved 0x4C636172 [LoadConfig] GuardAddressTakenIatEntryTable 0x74686769 | Count 0x6F72705C (1869770844) [LoadConfig] GuardLongJumpTargetTable 0x7463656A | Count 0x75685C73 (1969773683) [LoadConfig] HybridMetadataPointer 0x6E6F7364 | DynamicValueRelocTable 0x75682E5C [LoadConfig] FailFastIndirectProc 0x6E6F7364 | FailFastPointer 0x626F6A5C [LoadConfig] UnknownZero1 0x444F5C73 [File Heuristics] -> Flag #1 : 00000100000001001101000000000000 (0x0404D000) [Entrypoint Section Entropy] : 6.54 (section #0) ".text " | Size : 0xBD67 (48487) byte(s) [DllCharacteristics] -> Flag : (0x8140) -> ASLR | DEP | TSA [SectionCount] 5 (0x5) | ImageSize 0x17000 (94208) byte(s) [ModuleReport] [IAT] Modules -> KERNEL32.dll | SHLWAPI.dll [Debug Info] (record 1 of 1) (file offset 0xC3A0) Characteristics : 0x0 | TimeDateStamp : 0x522D30CB (Mon 09th Sep 2013 02:22:03 (GMT)) | MajorVer : 0 / MinorVer : 0 -> (0.0) Type : 2 (0x2) -> CodeView | Size : 0x93 (147) AddressOfRawData : 0xEC80 | PointerToRawData : 0xDE80 CvSig : 0x53445352 | SigGuid 4E5D2626-92EC-42ED-BDA19DC284BB4A18 Age : 0x1 (1) | Pdb : e:\TracLight\projects\hudson.hudson\jobs\ODV_Creator_1_6\workspace\ODV\ODV\bin\Win32\Launcher\OneVolumeViewerLauncher.pdb [CompilerDetect] -> Visual C++ 9.0 (Visual Studio 2008) [!] File appears to have no protection or is using an unknown protection - Scan Took : 0.226 Second(s) [0000000E2h (226) tick(s)] [506 of 580 scan(s) done]
Scanning -> C:\Program Files (x86)\OneVolumeViewer\bin\x86\OneVolumeViewer.exe File Type : 32-Bit Exe (Subsystem : Win GUI / 2), Size : 4963368 (04BBC28h) Byte(s) | Machine: 0x14C (I386) Compilation TimeStamp : 0x522D2ACB -> Mon 09th Sep 2013 01:56:27 (GMT) [TimeStamp] 0x522D2ACB -> Mon 09th Sep 2013 01:56:27 (GMT) | PE Header | - | Offset: 0x00000110 | VA: 0x00400110 | - [TimeStamp] 0x522D2ACA -> Mon 09th Sep 2013 01:56:26 (GMT) | Export | - | Offset: 0x0032DD94 | VA: 0x0072EF94 | - [TimeStamp] 0x522D2ACB -> Mon 09th Sep 2013 01:56:27 (GMT) | DebugDirectory | - | Offset: 0x002948E4 | VA: 0x00695AE4 | - -> File has 552 (0228h) bytes of appended data starting at offset 04BBA00h [LoadConfig] Struct determined as v8 (Expected size 140 | Actual size 64) [!] Executable uses SEH Tables (/SAFESEH) (1441 calculated 1441 recorded... 0 invalid addresses) [LoadConfig] CodeIntegrity -> Flags 0x1 | Catalog 0x0 (0) | Catalog Offset 0x545C3A65 | Reserved 0x4C636172 [LoadConfig] GuardAddressTakenIatEntryTable 0x74686769 | Count 0x6F72705C (1869770844) [LoadConfig] GuardLongJumpTargetTable 0x7463656A | Count 0x75685C73 (1969773683) [LoadConfig] HybridMetadataPointer 0x6E6F7364 | DynamicValueRelocTable 0x75682E5C [LoadConfig] FailFastIndirectProc 0x6E6F7364 | FailFastPointer 0x626F6A5C [LoadConfig] UnknownZero1 0x444F5C73 [File Heuristics] -> Flag #1 : 00000100000001001100000100000100 (0x0404C104) [Entrypoint Section Entropy] : 6.52 (section #0) ".text " | Size : 0x29094B (2689355) byte(s) [DllCharacteristics] -> Flag : (0x8000) -> TSA [SectionCount] 4 (0x4) | ImageSize 0x4C6000 (5005312) byte(s) [Export] 100% of function(s) (36 of 36) are in file | 0 are forwarded | 32 code | 4 data | 0 uninit data | 0 unknown | [VersionInfo] Company Name : J. MORITA MFG. CORP. [VersionInfo] Product Name : 3D viewer [VersionInfo] Product Version : 2. 813. 20. 3946 [VersionInfo] File Description : 3D viewer application [VersionInfo] File Version : 2. 813. 20. 3946 [VersionInfo] Original FileName : CTViewer.exe [VersionInfo] Internal Name : CTViewer [VersionInfo] Version Comments : Compiled with Codejock Toolkit 15.2.1.0 [VersionInfo] Legal Copyrights : Copyright (C) 2010-2013 [ModuleReport] [IAT] Modules -> VERSION.dll | SHLWAPI.dll | mfc90.dll | MSVCR90.dll | KERNEL32.dll | USER32.dll | GDI32.dll | MSIMG32.dll | ADVAPI32.dll | SHELL32.dll | COMCTL32.dll | ole32.dll | OLEAUT32.dll | gdiplus.dll | ToolkitPro1521vc90.dll | MSVCP90.dll | imagehlp.dll | OPENGL32.dll | GLU32.dll | AVIFIL32.dll | MSVFW32.dll | WS2_32.dll [Debug Info] (record 1 of 1) (file offset 0x2948E0) Characteristics : 0x0 | TimeDateStamp : 0x522D2ACB (Mon 09th Sep 2013 01:56:27 (GMT)) | MajorVer : 0 / MinorVer : 0 -> (0.0) Type : 2 (0x2) -> CodeView | Size : 0x77 (119) AddressOfRawData : 0x2ED818 | PointerToRawData : 0x2EC618 CvSig : 0x53445352 | SigGuid 5E24CE0C-534B-48DF-81E60BD604319772 Age : 0x1 (1) | Pdb : e:\TracLight\projects\hudson.hudson\jobs\ODV_Creator_1_6\workspace\OVV\bin\Win32\CTViewer.pdb [CdKeySerial] found "Invalid code" @ VA: 0x002C8618 / Offset: 0x002C7418 [CdKeySerial] found "Invalid code" @ VA: 0x002C8638 / Offset: 0x002C7438 [CdKeySerial] found "Invalid code" @ VA: 0x002CE580 / Offset: 0x002CD380 [!] File appears to have no protection or is using an unknown protection - Scan Took : 1.927 Second(s) [000000431h (1073) tick(s)] [566 of 580 scan(s) done]
Scanning -> C:\Program Files (x86)\OneVolumeViewer\bin\x86\VolRE.dll File Type : 32-Bit Dll (Subsystem : Win GUI / 2), Size : 1042432 (0FE800h) Byte(s) | Machine: 0x14C (I386) Compilation TimeStamp : 0x522D2E49 -> Mon 09th Sep 2013 02:11:21 (GMT) [TimeStamp] 0x522D2E49 -> Mon 09th Sep 2013 02:11:21 (GMT) | PE Header | - | Offset: 0x00000110 | VA: 0x10000110 | - [TimeStamp] 0x522D2E3C -> Mon 09th Sep 2013 02:11:08 (GMT) | Export | - | Offset: 0x000C7664 | VA: 0x100C8664 | - [TimeStamp] 0x522D2E49 -> Mon 09th Sep 2013 02:11:21 (GMT) | DebugDirectory | - | Offset: 0x000A8994 | VA: 0x100A9994 | - [LoadConfig] Struct determined as v8 (Expected size 140 | Actual size 64) [!] Executable uses SEH Tables (/SAFESEH) (447 calculated 447 recorded... 0 invalid addresses) [LoadConfig] CodeIntegrity -> Flags 0x1 | Catalog 0x0 (0) | Catalog Offset 0x545C3A65 | Reserved 0x4C636172 [LoadConfig] GuardAddressTakenIatEntryTable 0x74686769 | Count 0x6F72705C (1869770844) [LoadConfig] GuardLongJumpTargetTable 0x7463656A | Count 0x75685C73 (1969773683) [LoadConfig] HybridMetadataPointer 0x6E6F7364 | DynamicValueRelocTable 0x75682E5C [LoadConfig] FailFastIndirectProc 0x6E6F7364 | FailFastPointer 0x626F6A5C [LoadConfig] UnknownZero1 0x444F5C73 [File Heuristics] -> Flag #1 : 00000100000001001101000100000000 (0x0404D100) [Entrypoint Section Entropy] : 6.47 (section #0) ".text " | Size : 0xA7B85 (686981) byte(s) [DllCharacteristics] -> Flag : (0x0140) -> ASLR | DEP [SectionCount] 5 (0x5) | ImageSize 0x102000 (1056768) byte(s) [Export] 100% of function(s) (1 of 1) are in file | 0 are forwarded | 1 code | 0 data | 0 uninit data | 0 unknown | [VersionInfo] Company Name : J. MORITA MFG. Corp. [VersionInfo] Product Name : VolRE [VersionInfo] Product Version : 2. 714. 0. 2686 [VersionInfo] File Description : Volume Rendering Engine. [VersionInfo] File Version : 2. 714. 0. 2686 [VersionInfo] Original FileName : VolRE.dll [VersionInfo] Internal Name : VolRE.dll [VersionInfo] Version Comments : Joint venture with Nagoya university. [VersionInfo] Legal Copyrights : (C) 2009-2013 J. MORITA MFG. Corp. All rights reserved. [ModuleReport] [IAT] Modules -> tbb.dll | mfc90.dll | MSVCR90.dll | KERNEL32.dll | USER32.dll | GDI32.dll | ADVAPI32.dll | SHELL32.dll | SHLWAPI.dll | OLEAUT32.dll | MSVCP90.dll | AVIFIL32.dll | VCOMP90.DLL | VERSION.dll | WINMM.dll | imagehlp.dll | OPENGL32.dll | GLU32.dll | RPCRT4.dll [Debug Info] (record 1 of 1) (file offset 0xA8990) Characteristics : 0x0 | TimeDateStamp : 0x522D2E49 (Mon 09th Sep 2013 02:11:21 (GMT)) | MajorVer : 0 / MinorVer : 0 -> (0.0) Type : 2 (0x2) -> CodeView | Size : 0x76 (118) AddressOfRawData : 0xB5580 | PointerToRawData : 0xB4580 CvSig : 0x53445352 | SigGuid 12257628-B807-40A6-9135D921CF5237EB Age : 0x1 (1) | Pdb : e:\TracLight\projects\hudson.hudson\jobs\ODV_Creator_1_6\workspace\VolRE\bin\Win32\VolRE.pdb [!] File appears to have no protection or is using an unknown protection - Scan Took : 0.573 Second(s) [00000023Dh (573) tick(s)] [246 of 580 scan(s) done] --- snip ---
$ wine --version wine-3.10-89-gb6c7b2d322
Regards