[Bug 38950] New: Creo Elements/Direct Modeling Express 6.0 .NET based licensing tool crashes on startup (Xenocode VM, 'load_native_dll' must also allow imports resolving for 'EXECUTABLE_IMAGE')

wine-bugs at winehq.org wine-bugs at winehq.org
Sun Jul 19 08:36:56 CDT 2015


https://bugs.winehq.org/show_bug.cgi?id=38950

            Bug ID: 38950
           Summary: Creo Elements/Direct Modeling Express 6.0 .NET based
                    licensing tool crashes on startup (Xenocode VM,
                    'load_native_dll' must also allow imports resolving
                    for 'EXECUTABLE_IMAGE')
           Product: Wine
           Version: 1.7.47
          Hardware: x86-64
                OS: Linux
            Status: NEW
          Severity: normal
          Priority: P2
         Component: ntdll
          Assignee: wine-bugs at winehq.org
          Reporter: focht at gmx.net
      Distribution: ---

Hello folks,

while revisiting bug 27827 I found another interesting one...

Starting the main app with workaround
https://bugs.winehq.org/show_bug.cgi?id=27827#c9, another process is spawned
which seems to be some .NET Framework based licensing tool.

That helper tool crashes on startup, preventing the main app from working.

--- snip ---
$ pwd
/home/focht/.wine/drive_c/Program Files/PTC/Creo Elements/Direct Modeling
Express 6.0/binNT/OLAPE

$ WINEDEBUG=+tid,+seh,+relay wine ./OLAPEP.exe >>log.txt 2>&1
...
0034:Starting process L"C:\\Program Files\\PTC\\Creo Elements\\Direct Modeling
Express 6.0\\binNT\\OLAPE\\OLAPEP.exe" (entryproc=0x2131a000) 
...
0034:Call ntdll.RtlInitUnicodeString(2142fd38,0015d8a8 L"C:\\Program
Files\\PTC\\Creo Elements\\Direct Modeling Express
6.0\\binNT\\OLAPE\\OLAPEPP.exe") ret=212e03aa
0034:Ret  ntdll.RtlInitUnicodeString() retval=2142fd38 ret=212e03aa
0034:Call ntdll.LdrLoadDll(00000000,00000000,2142fd38,2142fd14) ret=212e03be
0034:Ret  ntdll.LdrLoadDll() retval=00000000 ret=212e03be
0034:Call user32.EnumThreadWindows(00000034,212e2ad0,2142fda0) ret=212e2fbb
0034:Call PE DLL (proc=0x7e324070,module=0x7e2c0000
L"winex11.drv",reason=PROCESS_ATTACH,res=(nil))
0034:Ret  PE DLL (proc=0x7e324070,module=0x7e2c0000
L"winex11.drv",reason=PROCESS_ATTACH,res=(nil)) retval=1
0034:Call winex11.drv.wine_get_gdi_driver(0000002e) ret=7eb23c42
0034:Ret  winex11.drv.wine_get_gdi_driver() retval=7e3287e0 ret=7eb23c42
0034:Call winex11.drv.CreateDesktopWindow(00010020) ret=7ec571f6
0034:Ret  winex11.drv.CreateDesktopWindow() retval=00000001 ret=7ec571f6
0034:Ret  user32.EnumThreadWindows() retval=00000001 ret=212e2fbb
0034:Call KERNEL32.GetTickCount() ret=212e2fca
0034:Ret  KERNEL32.GetTickCount() retval=00d4485c ret=212e2fca
0034:Call
KERNEL32.CreateThread(00000000,00000000,212e2f70,21318bf4,00000000,00000000)
ret=212e2fe7
0034:Ret  KERNEL32.CreateThread() retval=00000240 ret=212e2fe7
0034:trace:seh:raise_exception code=c0000005 flags=0 addr=0x7f12327e
ip=7f12327e tid=0034
0034:trace:seh:raise_exception  info[0]=00000000
0034:trace:seh:raise_exception  info[1]=00402000
0034:trace:seh:raise_exception  eax=7f12327e ebx=00000000 ecx=2142fe24
edx=21317fe8 esi=21317fec edi=00000002
0034:trace:seh:raise_exception  ebp=2142fe30 esp=2142fde8 cs=0023 ds=002b
es=002b fs=0063 gs=006b flags=00010206 
--- snip ---

The import and usage of large number of native API makes this already
suspicious.

'ProtectionID' tool doesn't reveal much:

--- snip ---
-=[ ProtectionID v0.6.6.7 DECEMBER]=-
(c) 2003-2015 CDKiLLER & TippeX
Build 24/12/14-22:48:13
Ready...
Scanning -> C:\Program Files\PTC\Creo Elements\Direct Modeling Express
6.0\binNT\OLAPE\OLAPEP.exe
File Type : 32-Bit Exe (Subsystem : Win GUI / 2), Size : 17768448 (010F2000h)
Byte(s)
Compilation TimeStamp : 0x00000026 -> Thu 01st Jan 1970 00:00:38 (GMT)
[TimeStamp] 0x00000026 -> Thu 01st Jan 1970 00:00:38 (GMT) | PE Header | - |
Offset: 0x00000088 | VA: 0x00100088 | -
[File Heuristics] -> Flag #1 : 00000000000000001000001000000001 (0x00008201)
[Entrypoint Section Entropy] : 2.32 (section #5) ".textxc " | Size : 0x5 (5)
byte(s)
[DllCharacteristics] -> Flag : (0x0000) -> NONE
[SectionCount] 9 (0x9) | ImageSize 0x210F4000 (554647552) byte(s)
[VersionInfo] Company Name : Parametric Technology GmbH
[VersionInfo] Product Name : Modeling Express
[VersionInfo] Product Version : 4.0.0.1
[VersionInfo] File Description : OLAPEPP
[VersionInfo] File Version : 4.0.0.1
[VersionInfo] Original FileName : OLAPEPP.exe
[VersionInfo] Internal Name : OLAPEPP.exe
[VersionInfo] Version Comments : Online Activation Modeling Express PTC Plain
[VersionInfo] Legal Copyrights : Copyright © 2011
[CdKeySerial] found "Invalid code" @ VA: 0x210DB100 / Offset: 0x010DB100
[CompilerDetect] -> Visual C++ 6.0
[!] File appears to have no protection or is using an unknown protection
- Scan Took : 4.965 Second(s) [000000FC3h (4035) tick(s)] [499 of 573 scan(s)
done]
--- snip ---

The layout of the entry point and debugging a bit past reveals:

--- snip ---
4241A000  E9 1BC8FCFF    JMP OLAPEP.423E6820
4241A005  0000           ADD BYTE PTR DS:[EAX],AL
...
423E6820  E9 3BFEFFFF    JMP OLAPEP.423E6660
423E6825  CC             INT3
...
423E6660  55             PUSH EBP
423E6661  8BEC           MOV EBP,ESP
...
423E6740  68 182C4042    PUSH OLAPEP.42402C18   ; UNICODE ".\dllmain.cpp"
423E6745  68 342C4042    PUSH OLAPEP.42402C34   ; UNICODE "DoEmbeddedVM"
...
423E67F0  E8 DB5DFDFF    CALL OLAPEP.423BC5D0
423E67F5  83C4 0C        ADD ESP,0C
423E67F8  6A 10          PUSH 10   ; Style = MB_OK|MB_ICONHAND|MB_APPLMODAL
423E67FA  68 B02F4042    PUSH OLAPEP.42402FB0 ; Title = "Xenocode Virtual
Appliance Runtime"
423E67FF  8B55 E4        MOV EDX,DWORD PTR SS:[EBP-1C]
423E6802  52             PUSH EDX             ; Text
423E6803  6A 00          PUSH 0               ; hOwner = NULL
423E6805  FF15 28B24142  CALL DWORD PTR DS:[<&USER32.MessageBoxW>]
423E680B  E8 00FEFFFF    CALL OLAPEP.423E6610
423E6810  6A FF          PUSH -1              ; ExitCode = FFFFFFFF
423E6812  F15 08B04142   CALL DWORD PTR DS:[<&KERNEL32.ExitProcess>]
423E6818  CC             INT3
--- snip ---

Oh well ... Xenocode ;-)

The crash location:

--- snip ---
...
423E6708  A1 CC8B4142      MOV EAX,DWORD PTR DS:[42418BCC]
423E670D  3BC3             CMP EAX,EBX
423E670F  74 02            JE SHORT 423E6713
423E6711  FFD0             CALL EAX         ; call 0x00415857
423E6713  8B4D F4          MOV ECX,DWORD PTR SS:[EBP-C]
423E6716  64:890D 00000000 MOV DWORD PTR FS:[0],ECX
423E671D  5F               POP EDI
423E671E  5E               POP ESI
423E671F  5B               POP EBX
423E6720  8BE5             MOV ESP,EBP
423E6722  5D               POP EBP
423E6723  C3               RETN
...
00415857  FF25 00604100    JMP DWORD PTR DS:[416000] ; *boom*
0041585D  0000             ADD BYTE PTR DS:[EAX],AL
0041585F  0000             ADD BYTE PTR DS:[EAX],AL
00415861  0000             ADD BYTE PTR DS:[EAX],AL
--- snip ---

Dump of memory reference:

--- snip ---
00416000  00016044
00416004  00000000
00416008  00016030
0041600C  00000000
00416010  00000000
00416014  00016038
00416018  00016000
0041601C  00000000
...
00416030  00016044
00416034  00000000
00416038  6F63736D  msco
0041603C  2E656572  ree.
00416040  006C6C64  dll.
00416044  435F0000  .._C
00416048  7845726F  orEx
0041604C  69614D65  eMai
00416050  0000006E  n...
--- snip ---

As seen in trace log, the Xenocode VM loader calls 'ntdll.LdrLoadDll' which in
turn boils down to:

-> ntdll.load_dll -> ntdll.load_native_dll -> load/map images

XenoCode hooks the relevant native API to override the NT loader.

* NtCreateSection
* NtMapViewOfSection
* <many more but not relevant in this special situation>

Since Wine's loader also calls those native API in sequence, correctly
following native NT loader behaviour, those hooked functions get called.

Xenocode unpacks the main executable and all dependencies in memory from PE
resources and injects those images as part of loader sequence.

That's also the reason for the high initial load address for the original
executable.
The Xenocode VM must keep the standard load address ranges, such as 0x400000,
0x10000000+ in process address space free to allow its custom loader to map all
internal executable images there.

Wine gets it almost right ... but fails at resolving the imports for the main
executable. See the dump earlier: 0x416000 -> address of IAT which is still
unprocessed.

Source:
https://source.winehq.org/git/wine.git/blob/21c37248135f6379e6af7aa3ec29997314e5c52d:/dlls/ntdll/loader.c#l1608

--- snip ---
1608 static NTSTATUS load_native_dll( LPCWSTR load_path, LPCWSTR name, HANDLE
file,
1609                                  DWORD flags, WINE_MODREF** pwm )
1610 {
1611     void *module;
1612     HANDLE mapping;
1613     LARGE_INTEGER size;
1614     IMAGE_NT_HEADERS *nt;
1615     SIZE_T len = 0;
1616     WINE_MODREF *wm;
1617     NTSTATUS status;
1618 
1619     TRACE("Trying native dll %s\n", debugstr_w(name));
1620 
1621     size.QuadPart = 0;
1622     status = NtCreateSection( &mapping, STANDARD_RIGHTS_REQUIRED |
SECTION_QUERY | SECTION_MAP_READ,
1623                               NULL, &size, PAGE_EXECUTE_READ, SEC_IMAGE,
file );
1624     if (status != STATUS_SUCCESS) return status;
1625 
1626     module = NULL;
1627     status = NtMapViewOfSection( mapping, NtCurrentProcess(),
1628                                  &module, 0, 0, &size, &len, ViewShare, 0,
PAGE_EXECUTE_READ );
1629     if (status < 0) goto done;
1630 
1631     /* create the MODREF */
1632 
1633     if (!(wm = alloc_module( module, name )))
1634     {
1635         status = STATUS_NO_MEMORY;
1636         goto done;
1637     }
1638 
1639     /* fixup imports */
1640 
1641     nt = RtlImageNtHeader( module );
1642 
1643     if (!(flags & DONT_RESOLVE_DLL_REFERENCES) &&
1644         ((nt->FileHeader.Characteristics & IMAGE_FILE_DLL) ||
1645          nt->OptionalHeader.Subsystem == IMAGE_SUBSYSTEM_NATIVE))
1646     {
1647         if ((status = fixup_imports( wm, load_path )) != STATUS_SUCCESS)
1648         {
...
--- snip ---

Dump of the in-memory PE image header for the main executable which gets
"injected" through Xenocode:

--- snip ---
...
00400080   50 45 00 0>ASCII "PE"      ; PE signature (PE)
00400084   4C01       DW 014C         ; Machine = IMAGE_FILE_MACHINE_I386
00400086   0400       DW 0004         ;  NumberOfSections = 4
00400088   1B000000   DD 0000001B     ;  TimeDateStamp = 1B
0040008C   00000000   DD 00000000     ;  PointerToSymbolTable = 0
00400090   00000000   DD 00000000     ;  NumberOfSymbols = 0
00400094   E000       DW 00E0         ;  SizeOfOptionalHeader = E0 (224.)
00400096   0E01       DW 010E         ;  Characteristics =
EXECUTABLE_IMAGE|32BIT_MACHINE|LINE_NUMS_STRIPPED|LOCAL_SYMS_STRIPPED
00400098   0B01       DW 010B         ; MagicNumber = PE32
0040009A   08         DB 08           ;  MajorLinkerVersion = 8
0040009B   00         DB 00           ;  MinorLinkerVersion = 0
0040009C   00400100   DD 00014000     ;  SizeOfCode = 14000 (81920.)
004000A0   00600000   DD 00006000     ;  SizeOfInitializedData = 6000 (24576.)
004000A4   00000000   DD 00000000     ;  SizeOfUninitializedData = 0
004000A8   57580100   DD 00015857     ;  AddressOfEntryPoint = 15857
004000AC   00200000   DD 00002000     ;  BaseOfCode = 2000
004000B0   00600100   DD 00016000     ;  BaseOfData = 16000
004000B4   00004000   DD 00400000     ; ImageBase = 400000
004000B8   00200000   DD 00002000     ;  SectionAlignment = 2000
004000BC   00020000   DD 00000200     ;  FileAlignment = 200
004000C0   0400       DW 0004         ;  MajorOSVersion = 4
004000C2   0000       DW 0000         ;  MinorOSVersion = 0
004000C4   0000       DW 0000         ;  MajorImageVersion = 0
004000C6   0000       DW 0000         ;  MinorImageVersion = 0
004000C8   0400       DW 0004         ;  MajorSubsystemVersion = 4
004000CA   0000       DW 0000         ;  MinorSubsystemVersion = 0
004000CC   00000000   DD 00000000     ;  Reserved
004000D0   00C00100   DD 0001C000     ;  SizeOfImage = 1C000 (114688.)
004000D4   00040000   DD 00000400     ;  SizeOfHeaders = 400 (1024.)
004000D8   00000000   DD 00000000     ;  CheckSum = 0
004000DC   0200       DW 0002         ;  Subsystem =
IMAGE_SUBSYSTEM_WINDOWS_GUI
004000DE   4085       DW 8540         ;  DLLCharacteristics = 8540
004000E0   00001000   DD 00100000     ;  SizeOfStackReserve = 100000 (1048576.)
004000E4   00100000   DD 00001000     ;  SizeOfStackCommit = 1000 (4096.)
004000E8   00001000   DD 00100000     ;  SizeOfHeapReserve = 100000 (1048576.)
004000EC   00100000   DD 00001000     ;  SizeOfHeapCommit = 1000 (4096.)
004000F0   00000000   DD 00000000     ;  LoaderFlags = 0
004000F4   10000000   DD 00000010     ;  NumberOfRvaAndSizes = 10 (16.)
004000F8   00000000   DD 00000000     ;  Export Table address = 0
004000FC   00000000   DD 00000000     ;  Export Table size = 0
00400100   08600100   DD 00016008     ;  Import Table address = 16008
00400104   28000000   DD 00000028     ;  Import Table size = 28 (40.)
00400108   00A00100   DD 0001A000     ;  Resource Table address = 1A000
0040010C   0A060000   DD 0000060A     ;  Resource Table size = 60A (1546.)
00400110   00000000   DD 00000000     ;  Exception Table address = 0
00400114   00000000   DD 00000000     ;  Exception Table size = 0
00400118   00000000   DD 00000000     ;  Certificate File pointer = 0
0040011C   00000000   DD 00000000     ;  Certificate Table size = 0
00400120   00800100   DD 00018000     ;  Relocation Table address = 18000
00400124   0C000000   DD 0000000C     ;  Relocation Table size = C (12.)
00400128   00000000   DD 00000000     ;  Debug Data address = 0
0040012C   00000000   DD 00000000     ;  Debug Data size = 0
00400130   00000000   DD 00000000     ;  Architecture Data address = 0
00400134   00000000   DD 00000000     ;  Architecture Data size = 0
00400138   00000000   DD 00000000     ;  Global Ptr address = 0
0040013C   00000000   DD 00000000     ;  Must be 0
00400140   00000000   DD 00000000     ;  TLS Table address = 0
00400144   00000000   DD 00000000     ;  TLS Table size = 0
00400148   00000000   DD 00000000     ;  Load Config Table address = 0
0040014C   00000000   DD 00000000     ;  Load Config Table size = 0
00400150   00000000   DD 00000000     ;  Bound Import Table address = 0
00400154   00000000   DD 00000000     ;  Bound Import Table size = 0
00400158   00600100   DD 00016000     ;  Import Address Table address = 16000
0040015C   08000000   DD 00000008     ;  Import Address Table size = 8
00400160   00000000   DD 00000000     ;  Delay Import Descriptor address = 0
00400164   00000000   DD 00000000     ;  Delay Import Descriptor size = 0
00400168   00200000   DD 00002000     ;  COM+ Runtime Header address = 2000
0040016C   48000000   DD 00000048     ;  Import Address Table size = 48 (72.)
00400170   00000000   DD 00000000     ;  Reserved
00400174   00000000   DD 00000000     ;  Reserved
00400178   2E 74 65 7>ASCII ".textxc" ; SECTION
00400180   5D380100   DD 0001385D     ;  VirtualSize = 1385D (79965.)
00400184   00200000   DD 00002000     ;  VirtualAddress = 2000
00400188   003A0100   DD 00013A00     ;  SizeOfRawData = 13A00 (80384.)
0040018C   00040000   DD 00000400     ;  PointerToRawData = 400
00400190   00000000   DD 00000000     ;  PointerToRelocations = 0
00400194   00000000   DD 00000000     ;  PointerToLineNumbers = 0
00400198   0000       DW 0000         ;  NumberOfRelocations = 0
0040019A   0000       DW 0000         ;  NumberOfLineNumbers = 0
0040019C   20000060   DD 60000020     ;  Characteristics = CODE|EXECUTE|READ
004001A0   2E 69 64 6>ASCII ".idata"  ; SECTION
004001A8   56000000   DD 00000056     ;  VirtualSize = 56 (86.)
004001AC   00600100   DD 00016000     ;  VirtualAddress = 16000
004001B0   00020000   DD 00000200     ;  SizeOfRawData = 200 (512.)
004001B4   003E0100   DD 00013E00     ;  PointerToRawData = 13E00
004001B8   00000000   DD 00000000     ;  PointerToRelocations = 0
004001BC   00000000   DD 00000000     ;  PointerToLineNumbers = 0
004001C0   0000       DW 0000         ;  NumberOfRelocations = 0
004001C2   0000       DW 0000         ;  NumberOfLineNumbers = 0
004001C4   40000040   DD 40000040     ;  Characteristics =
INITIALIZED_DATA|READ
004001C8   2E 72 65 6>ASCII ".reloc"  ; SECTION
004001D0   0C000000   DD 0000000C     ;  VirtualSize = C (12.)
004001D4   00800100   DD 00018000     ;  VirtualAddress = 18000
004001D8   00020000   DD 00000200     ;  SizeOfRawData = 200 (512.)
004001DC   00400100   DD 00014000     ;  PointerToRawData = 14000
004001E0   00000000   DD 00000000     ;  PointerToRelocations = 0
004001E4   00000000   DD 00000000     ;  PointerToLineNumbers = 0
004001E8   0000       DW 0000         ;  NumberOfRelocations = 0
004001EA   0000       DW 0000         ;  NumberOfLineNumbers = 0
004001EC   40000042   DD 42000040     ;  Characteristics =
INITIALIZED_DATA|DISCARDABLE|READ
004001F0   2E 72 73 7>ASCII ".rsrc"   ; SECTION
004001F8   0A060000   DD 0000060A     ;  VirtualSize = 60A (1546.)
004001FC   00A00100   DD 0001A000     ;  VirtualAddress = 1A000
00400200   00080000   DD 00000800     ;  SizeOfRawData = 800 (2048.)
00400204   00420100   DD 00014200     ;  PointerToRawData = 14200
00400208   00000000   DD 00000000     ;  PointerToRelocations = 0
0040020C   00000000   DD 00000000     ;  PointerToLineNumbers = 0
00400210   0000       DW 0000         ;  NumberOfRelocations = 0
00400212   0000       DW 0000         ;  NumberOfLineNumbers = 0
00400214   40000040   DD 40000040     ;  Characteristics =
INITIALIZED_DATA|READ
00400218   00         DB 00
--- snip ---

Characteristics =
EXECUTABLE_IMAGE|32BIT_MACHINE|LINE_NUMS_STRIPPED|LOCAL_SYMS_STRIPPED

The check must include 'EXECUTABLE_IMAGE'.

With that part fixed, there is another problem with Xenocode VM bootstrapping
full .NET Framework from its own resources (no .NET physically present in
WINEPREFIX) but that can be worked around with 'winetricks -q dotnet20'.
With that stuff in place the tool presents a license dialog.

$ sha1sum ModelingPE__setup_EN.exe 
333736c553c2eb985436e63f20bfcbb59932b6fb  ModelingPE__setup_EN.exe

$ du -sh ModelingPE__setup_EN.exe 
207M    ModelingPE__setup_EN.exe

$ wine --version
wine-1.7.47-118-ga90592c

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