[PATCH] mscoree: Implement VTable fixup for x86_64 architecture.
Vincent Povirk
madewokherd at gmail.com
Thu Jan 21 16:32:40 CST 2016
I took a different approach to testing this, and it doesn't seem to be
working quite right.
Instead of building x64 class dll's, I hacked something together based
on wine-staging's related patches, mono's implementation of
_CorValidateImage, and disabling a check in wineserver. I'm attaching
a diff of that.
Instead of working around managed c++ issues, I looked for a way to
use dll fixups more directly from a C# library:
https://sites.google.com/site/robertgiesecke/Home/uploads/unmanagedexports
So I have a C# dll that exports an "add" function, like the example,
and a win32 console exe that calls it via LoadLibrary/GetProcAddress.
On Windows, I can call it multiple times and then exit with no
problems. In Wine with your patch, everything works except that the
result is incorrect the first time add() is called. I suspect
ReallyFixupVTable is changing some registers, and the thunk will have
to preserve them.
Thanks for working on this, by the way. Seeing this *almost* work even
for a simple test case is very cool. :)
-------------- next part --------------
diff --git a/dlls/kernel32/process.c b/dlls/kernel32/process.c
index 7795b47..7e3c918 100644
--- a/dlls/kernel32/process.c
+++ b/dlls/kernel32/process.c
@@ -1082,16 +1082,11 @@ static inline DWORD call_process_entry( PEB *peb, LPTHREAD_START_ROUTINE entry )
*
* Startup routine of a new process. Runs on the new process stack.
*/
-static DWORD WINAPI start_process( PEB *peb )
+static DWORD WINAPI start_process( LPTHREAD_START_ROUTINE entry )
{
- IMAGE_NT_HEADERS *nt;
- LPTHREAD_START_ROUTINE entry;
-
- nt = RtlImageNtHeader( peb->ImageBaseAddress );
- entry = (LPTHREAD_START_ROUTINE)((char *)peb->ImageBaseAddress +
- nt->OptionalHeader.AddressOfEntryPoint);
+ PEB *peb = NtCurrentTeb()->Peb;
- if (!nt->OptionalHeader.AddressOfEntryPoint)
+ if (!entry)
{
ERR( "%s doesn't have an entry point, it cannot be executed\n",
debugstr_w(peb->ProcessParameters->ImagePathName.Buffer) );
diff --git a/dlls/mscoree/mscoree_main.c b/dlls/mscoree/mscoree_main.c
index 8b46fd5..a76dfc9 100644
--- a/dlls/mscoree/mscoree_main.c
+++ b/dlls/mscoree/mscoree_main.c
@@ -21,11 +21,14 @@
#include <stdarg.h>
+#include "ntstatus.h"
+#define WIN32_NO_STATUS
#define COBJMACROS
#include "wine/unicode.h"
#include "wine/library.h"
#include "windef.h"
#include "winbase.h"
+#include "winternl.h"
#include "winuser.h"
#include "winnls.h"
#include "winreg.h"
@@ -257,10 +260,156 @@ VOID WINAPI _CorImageUnloading(PVOID imageBase)
TRACE("(%p): stub\n", imageBase);
}
-HRESULT WINAPI _CorValidateImage(PVOID* imageBase, LPCWSTR imageName)
-{
- TRACE("(%p, %s): stub\n", imageBase, debugstr_w(imageName));
- return E_FAIL;
+STDAPI _CorValidateImage(PVOID *ImageBase, LPCWSTR FileName)
+{
+ IMAGE_DOS_HEADER* DosHeader;
+ IMAGE_NT_HEADERS32* NtHeaders32;
+ IMAGE_DATA_DIRECTORY* CliHeaderDir;
+#ifdef _WIN64
+ IMAGE_NT_HEADERS64* NtHeaders64;
+ IMAGE_COR20_HEADER* CliHeader;
+ DWORD SizeOfHeaders;
+#else
+ DWORD* Address;
+#endif
+ DWORD OldProtect;
+
+ TRACE("(%p, %s)\n", ImageBase, debugstr_w(FileName));
+
+ DosHeader = (IMAGE_DOS_HEADER*)*ImageBase;
+ if (DosHeader->e_magic != IMAGE_DOS_SIGNATURE)
+ return STATUS_INVALID_IMAGE_FORMAT;
+
+ NtHeaders32 = (IMAGE_NT_HEADERS32*)((DWORD_PTR)DosHeader + DosHeader->e_lfanew);
+ if (NtHeaders32->Signature != IMAGE_NT_SIGNATURE)
+ return STATUS_INVALID_IMAGE_FORMAT;
+
+#ifdef _WIN64
+ NtHeaders64 = (IMAGE_NT_HEADERS64*)NtHeaders32;
+ if (NtHeaders64->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC)
+ {
+ if (NtHeaders64->OptionalHeader.NumberOfRvaAndSizes <= IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR)
+ return STATUS_INVALID_IMAGE_FORMAT;
+
+ CliHeaderDir = &NtHeaders64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR];
+ if (!CliHeaderDir->VirtualAddress)
+ return STATUS_INVALID_IMAGE_FORMAT;
+
+ CliHeader = (IMAGE_COR20_HEADER*)((DWORD_PTR)DosHeader + CliHeaderDir->VirtualAddress);
+ if (CliHeader->Flags & COMIMAGE_FLAGS_32BITREQUIRED)
+ return STATUS_INVALID_IMAGE_FORMAT;
+
+ return STATUS_SUCCESS;
+ }
+
+ if (NtHeaders32->OptionalHeader.Magic != IMAGE_NT_OPTIONAL_HDR32_MAGIC)
+ return STATUS_INVALID_IMAGE_FORMAT;
+
+ if (NtHeaders32->OptionalHeader.NumberOfRvaAndSizes <= IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR)
+ return STATUS_INVALID_IMAGE_FORMAT;
+
+ CliHeaderDir = &NtHeaders32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR];
+ if (!CliHeaderDir->VirtualAddress)
+ return STATUS_INVALID_IMAGE_FORMAT;
+
+ CliHeader = (IMAGE_COR20_HEADER*)((DWORD_PTR)DosHeader + CliHeaderDir->VirtualAddress);
+ if (!(CliHeader->Flags & COMIMAGE_FLAGS_ILONLY) || (CliHeader->Flags & COMIMAGE_FLAGS_32BITREQUIRED))
+ return STATUS_INVALID_IMAGE_FORMAT;
+
+ /* Fixup IMAGE_NT_HEADERS32 to IMAGE_NT_HEADERS64. */
+ SizeOfHeaders = NtHeaders32->OptionalHeader.SizeOfHeaders;
+ if (SizeOfHeaders < DosHeader->e_lfanew + sizeof(IMAGE_NT_HEADERS64) + (sizeof(IMAGE_SECTION_HEADER) * NtHeaders32->FileHeader.NumberOfSections))
+ return STATUS_INVALID_IMAGE_FORMAT;
+
+ if (!VirtualProtect(DosHeader, SizeOfHeaders, PAGE_READWRITE, &OldProtect))
+ return E_UNEXPECTED;
+
+ memmove(NtHeaders64 + 1, IMAGE_FIRST_SECTION(NtHeaders32), sizeof(IMAGE_SECTION_HEADER) * NtHeaders32->FileHeader.NumberOfSections);
+
+ NtHeaders64->OptionalHeader.DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES - 1].Size = 0;
+ NtHeaders64->OptionalHeader.DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES - 1].VirtualAddress = 0;
+ NtHeaders64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].Size = NtHeaders32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].Size;
+ NtHeaders64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress = NtHeaders32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress;
+ NtHeaders64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT].Size = 0;
+ NtHeaders64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT].VirtualAddress = 0;
+ NtHeaders64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].Size = 0;
+ NtHeaders64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].VirtualAddress = 0;
+ NtHeaders64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].Size = 0;
+ NtHeaders64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].VirtualAddress = 0;
+ NtHeaders64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG].Size = 0;
+ NtHeaders64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG].VirtualAddress = 0;
+ NtHeaders64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].Size = 0;
+ NtHeaders64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress = 0;
+ NtHeaders64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_GLOBALPTR].Size = 0;
+ NtHeaders64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_GLOBALPTR].VirtualAddress = 0;
+ NtHeaders64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COPYRIGHT].Size = 0;
+ NtHeaders64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COPYRIGHT].VirtualAddress = 0;
+ NtHeaders64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].Size = NtHeaders32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].Size;
+ NtHeaders64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress = NtHeaders32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress;
+ NtHeaders64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size = NtHeaders32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size;
+ NtHeaders64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = NtHeaders32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress;
+ NtHeaders64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY].Size = NtHeaders32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY].Size;
+ NtHeaders64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY].VirtualAddress = NtHeaders32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY].VirtualAddress;
+ NtHeaders64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXCEPTION].Size = 0;
+ NtHeaders64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXCEPTION].VirtualAddress = 0;
+ NtHeaders64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].Size = NtHeaders32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].Size;
+ NtHeaders64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress = NtHeaders32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress;
+ NtHeaders64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size = 0;
+ NtHeaders64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress = 0;
+ NtHeaders64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size = 0;
+ NtHeaders64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress = 0;
+
+ NtHeaders64->OptionalHeader.NumberOfRvaAndSizes = IMAGE_NUMBEROF_DIRECTORY_ENTRIES;
+ NtHeaders64->OptionalHeader.LoaderFlags = NtHeaders32->OptionalHeader.LoaderFlags;
+ NtHeaders64->OptionalHeader.SizeOfHeapCommit = (ULONGLONG)NtHeaders32->OptionalHeader.SizeOfHeapCommit;
+ NtHeaders64->OptionalHeader.SizeOfHeapReserve = (ULONGLONG)NtHeaders32->OptionalHeader.SizeOfHeapReserve;
+ NtHeaders64->OptionalHeader.SizeOfStackCommit = (ULONGLONG)NtHeaders32->OptionalHeader.SizeOfStackCommit;
+ NtHeaders64->OptionalHeader.SizeOfStackReserve = (ULONGLONG)NtHeaders32->OptionalHeader.SizeOfStackReserve;
+ NtHeaders64->OptionalHeader.DllCharacteristics = NtHeaders32->OptionalHeader.DllCharacteristics;
+ NtHeaders64->OptionalHeader.Subsystem = NtHeaders32->OptionalHeader.Subsystem;
+ NtHeaders64->OptionalHeader.CheckSum = NtHeaders32->OptionalHeader.CheckSum;
+ NtHeaders64->OptionalHeader.SizeOfHeaders = NtHeaders32->OptionalHeader.SizeOfHeaders;
+ NtHeaders64->OptionalHeader.SizeOfImage = NtHeaders32->OptionalHeader.SizeOfImage;
+ NtHeaders64->OptionalHeader.Win32VersionValue = NtHeaders32->OptionalHeader.Win32VersionValue;
+ NtHeaders64->OptionalHeader.MinorSubsystemVersion = NtHeaders32->OptionalHeader.MinorSubsystemVersion;
+ NtHeaders64->OptionalHeader.MajorSubsystemVersion = NtHeaders32->OptionalHeader.MajorSubsystemVersion;
+ NtHeaders64->OptionalHeader.MinorImageVersion = NtHeaders32->OptionalHeader.MinorImageVersion;
+ NtHeaders64->OptionalHeader.MajorImageVersion = NtHeaders32->OptionalHeader.MajorImageVersion;
+ NtHeaders64->OptionalHeader.MinorOperatingSystemVersion = NtHeaders32->OptionalHeader.MinorOperatingSystemVersion;
+ NtHeaders64->OptionalHeader.MajorOperatingSystemVersion = NtHeaders32->OptionalHeader.MajorOperatingSystemVersion;
+ NtHeaders64->OptionalHeader.FileAlignment = NtHeaders32->OptionalHeader.FileAlignment;
+ NtHeaders64->OptionalHeader.SectionAlignment = NtHeaders32->OptionalHeader.SectionAlignment;
+ NtHeaders64->OptionalHeader.ImageBase = (ULONGLONG)NtHeaders32->OptionalHeader.ImageBase;
+ /* BaseOfCode is at the same offset. */
+ NtHeaders64->OptionalHeader.AddressOfEntryPoint = 0;
+ NtHeaders64->OptionalHeader.Magic = IMAGE_NT_OPTIONAL_HDR64_MAGIC;
+ NtHeaders64->FileHeader.SizeOfOptionalHeader = sizeof(IMAGE_OPTIONAL_HEADER64);
+
+ if (!VirtualProtect(DosHeader, SizeOfHeaders, OldProtect, &OldProtect))
+ return E_UNEXPECTED;
+#else
+ if (NtHeaders32->OptionalHeader.Magic != IMAGE_NT_OPTIONAL_HDR32_MAGIC)
+ return STATUS_INVALID_IMAGE_FORMAT;
+
+ if (NtHeaders32->OptionalHeader.NumberOfRvaAndSizes <= IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR)
+ return STATUS_INVALID_IMAGE_FORMAT;
+
+ CliHeaderDir = &NtHeaders32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR];
+ if (!CliHeaderDir->VirtualAddress)
+ return STATUS_INVALID_IMAGE_FORMAT;
+
+ Address = &NtHeaders32->OptionalHeader.AddressOfEntryPoint;
+ if (!VirtualProtect(Address, sizeof(DWORD), PAGE_READWRITE, &OldProtect))
+ return E_UNEXPECTED;
+ if (NtHeaders32->FileHeader.Characteristics & IMAGE_FILE_DLL)
+ *Address = (DWORD)((DWORD_PTR)&_CorDllMain - (DWORD_PTR)DosHeader);
+ else
+ *Address = (DWORD)((DWORD_PTR)&_CorExeMain - (DWORD_PTR)DosHeader);
+ if (!VirtualProtect(Address, sizeof(DWORD), OldProtect, &OldProtect))
+ return E_UNEXPECTED;
+#endif
+
+ return STATUS_SUCCESS;
}
HRESULT WINAPI GetCORSystemDirectory(LPWSTR pbuffer, DWORD cchBuffer, DWORD *dwLength)
diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c
index 74feb97..b8d24a2 100644
--- a/dlls/ntdll/loader.c
+++ b/dlls/ntdll/loader.c
@@ -104,6 +104,10 @@ static UINT tls_module_count; /* number of modules with TLS directory */
static IMAGE_TLS_DIRECTORY *tls_dirs; /* array of TLS directories */
LIST_ENTRY tls_links = { &tls_links, &tls_links };
+static HRESULT (WINAPI *p_CorValidateImage)(PVOID* ImageBase, LPCWSTR FileName);
+static __int32 (WINAPI *p_CorExeMain)(void);
+static BOOL (WINAPI *p_CorDllMain)(HINSTANCE hInst, DWORD dwReason, LPVOID lpReserved);
+
static RTL_CRITICAL_SECTION loader_section;
static RTL_CRITICAL_SECTION_DEBUG critsect_debug =
{
@@ -337,6 +341,78 @@ static inline ULONG_PTR allocate_stub( const char *dll, const char *name ) { ret
/*************************************************************************
+ * is_cli_only_image
+ *
+ * Checks if an image is a CLI/.NET image which does not contain any
+ * native code.
+ */
+static BOOL is_cli_only_image( HMODULE image )
+{
+ IMAGE_COR20_HEADER *cliheader;
+ ULONG size;
+
+ cliheader = RtlImageDirectoryEntryToData( image, TRUE, IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR, &size );
+ if (!cliheader || size < sizeof(*cliheader))
+ return FALSE;
+
+ return (cliheader->Flags & COMIMAGE_FLAGS_ILONLY) != 0;
+}
+
+
+/*************************************************************************
+ * load_mscoree
+ *
+ * Load _CorValidateImage and the _Cor{Exe,Dll}Main functions from mscoree.
+ * The loader_section must be locked while calling this function.
+ */
+static BOOL load_mscoree( void )
+{
+ static const WCHAR mscoree_dllW[] = {'m','s','c','o','r','e','e','.','d','l','l',0};
+ UNICODE_STRING unicode_str;
+ ANSI_STRING ansi_str;
+ HMODULE module;
+
+ if (p_CorValidateImage)
+ return TRUE;
+
+ RtlInitUnicodeString( &unicode_str, mscoree_dllW );
+ if (LdrLoadDll( NULL, LOAD_LIBRARY_SEARCH_SYSTEM32, &unicode_str, &module ))
+ {
+ ERR( "Failed to load mscoree.dll\n" );
+ return FALSE;
+ }
+
+ /* Load _CorValidateImage */
+ RtlInitAnsiString( &ansi_str, "_CorValidateImage" );
+ if (LdrGetProcedureAddress( module, &ansi_str, 0, (void **)&p_CorValidateImage) )
+ {
+ ERR( "Failed to get import for _CorValidateImage\n" );
+ LdrUnloadDll( module );
+ return FALSE;
+ }
+
+ /* Load _CorExeMain */
+ RtlInitAnsiString( &ansi_str, "_CorExeMain" );
+ if (LdrGetProcedureAddress( module, &ansi_str, 0, (void **)&p_CorExeMain) )
+ {
+ ERR( "Failed to get import for _CorExeMain\n" );
+ p_CorExeMain = NULL;
+ }
+
+ /* Load _CorDllMain */
+ RtlInitAnsiString( &ansi_str, "_CorDllMain" );
+ if (LdrGetProcedureAddress( module, &ansi_str, 0, (void **)&p_CorDllMain) )
+ {
+ ERR( "Failed to get import for _CorDllMain\n" );
+ p_CorDllMain = NULL;
+ }
+
+ /* FIXME: Unload mscoree again when no longer needed */
+ return TRUE;
+}
+
+
+/*************************************************************************
* get_modref
*
* Looks for the referenced HMODULE in the current process
@@ -875,6 +951,10 @@ static NTSTATUS fixup_imports( WINE_MODREF *wm, LPCWSTR load_path )
if (!(wm->ldr.Flags & LDR_DONT_RESOLVE_REFS)) return STATUS_SUCCESS; /* already done */
wm->ldr.Flags &= ~LDR_DONT_RESOLVE_REFS;
+ /* For a CLI-only image there is nothing to do. Do not allocate a TLS slot
+ * and do not resolve any external dependencies. */
+ if (is_cli_only_image( wm->ldr.BaseAddress )) return STATUS_SUCCESS;
+
wm->ldr.TlsIndex = alloc_tls_slot( &wm->ldr );
if (!(imports = RtlImageDirectoryEntryToData( wm->ldr.BaseAddress, TRUE,
@@ -1082,8 +1162,43 @@ static NTSTATUS MODULE_InitDLL( WINE_MODREF *wm, UINT reason, LPVOID lpReserved
BOOL retv = FALSE;
/* Skip calls for modules loaded with special load flags */
-
if (wm->ldr.Flags & LDR_DONT_RESOLVE_REFS) return STATUS_SUCCESS;
+
+ /* Yes, Windows also has hardcoded exceptions for mscoree in ntdll */
+ if (is_cli_only_image( module ))
+ {
+ #ifndef __x86_64__
+ IMAGE_NT_HEADERS *nt = RtlImageNtHeader( module );
+ #endif
+
+ if (reason == DLL_WINE_PREATTACH)
+ return STATUS_SUCCESS;
+
+ if (reason == DLL_PROCESS_ATTACH)
+ {
+ HRESULT hr;
+
+ if (!load_mscoree())
+ return STATUS_DLL_INIT_FAILED;
+
+ hr = p_CorValidateImage( &module, wm->ldr.FullDllName.Buffer );
+ if (hr)
+ {
+ ERR( "failed to validate CLI image, error 0x%x\n", hr );
+ wm->ldr.EntryPoint = NULL;
+ return STATUS_DLL_INIT_FAILED;
+ }
+
+ #ifdef __x86_64__
+ wm->ldr.EntryPoint = (wm->ldr.Flags & LDR_IMAGE_IS_DLL) ?
+ (void *)p_CorDllMain : (void *)p_CorExeMain;
+ #else
+ wm->ldr.EntryPoint = (char *)module + nt->OptionalHeader.AddressOfEntryPoint;
+ #endif
+ entry = wm->ldr.EntryPoint;
+ }
+ }
+
if (wm->ldr.TlsIndex != -1) call_tls_callbacks( wm->ldr.BaseAddress, reason );
if (!entry || !(wm->ldr.Flags & LDR_IMAGE_IS_DLL)) return STATUS_SUCCESS;
@@ -3037,7 +3152,20 @@ static void load_global_options(void)
*/
static void start_process( void *kernel_start )
{
- call_thread_entry_point( kernel_start, NtCurrentTeb()->Peb );
+ IMAGE_NT_HEADERS *nt;
+ LPTHREAD_START_ROUTINE entry;
+ PEB *peb = NtCurrentTeb()->Peb;
+
+ nt = RtlImageNtHeader( peb->ImageBaseAddress );
+ entry = (LPTHREAD_START_ROUTINE)((char *)peb->ImageBaseAddress +
+ nt->OptionalHeader.AddressOfEntryPoint);
+
+#ifdef __x86_64__
+ if (is_cli_only_image( peb->ImageBaseAddress ))
+ entry = (LPTHREAD_START_ROUTINE)p_CorExeMain;
+#endif
+
+ call_thread_entry_point( kernel_start, entry );
}
/******************************************************************
diff --git a/server/mapping.c b/server/mapping.c
index f66f326..7c31c1a 100644
--- a/server/mapping.c
+++ b/server/mapping.c
@@ -411,8 +411,8 @@ static unsigned int get_image_params( struct mapping *mapping, int unix_fd, int
if (nt.opt.hdr32.Magic != IMAGE_NT_OPTIONAL_HDR32_MAGIC) return STATUS_INVALID_IMAGE_FORMAT;
break;
case CPU_x86_64:
- if (nt.FileHeader.Machine != IMAGE_FILE_MACHINE_AMD64) return STATUS_INVALID_IMAGE_FORMAT;
- if (nt.opt.hdr64.Magic != IMAGE_NT_OPTIONAL_HDR64_MAGIC) return STATUS_INVALID_IMAGE_FORMAT;
+ //if (nt.FileHeader.Machine != IMAGE_FILE_MACHINE_AMD64) return STATUS_INVALID_IMAGE_FORMAT;
+ //if (nt.opt.hdr64.Magic != IMAGE_NT_OPTIONAL_HDR64_MAGIC) return STATUS_INVALID_IMAGE_FORMAT;
break;
case CPU_POWERPC:
if (nt.FileHeader.Machine != IMAGE_FILE_MACHINE_POWERPC) return STATUS_INVALID_IMAGE_FORMAT;
More information about the wine-devel
mailing list