From 39c8875ff8aa543eaa50e52db0c546717de691af Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Wed, 21 Feb 2018 09:55:05 +0100 Subject: [PATCH] ntdll: Add support for running IL-only .NET executables. Signed-off-by: Alexandre Julliard --- dlls/ntdll/loader.c | 50 +++++++++++++++++++++++++++++++++++-- dlls/ntdll/ntdll_misc.h | 2 +- dlls/ntdll/signal_arm.c | 2 +- dlls/ntdll/signal_arm64.c | 2 +- dlls/ntdll/signal_i386.c | 2 +- dlls/ntdll/signal_powerpc.c | 2 +- dlls/ntdll/signal_x86_64.c | 2 +- include/winternl.h | 3 ++- 8 files changed, 56 insertions(+), 9 deletions(-) diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c index 3fcbbf77a53..51aa33415f9 100644 --- a/dlls/ntdll/loader.c +++ b/dlls/ntdll/loader.c @@ -886,6 +886,44 @@ static void free_tls_slot( LDR_MODULE *mod ) } +/**************************************************************** + * fixup_imports_ilonly + * + * Fixup imports for an IL-only module. All we do is import mscoree. + * The loader_section must be locked while calling this function. + */ +static NTSTATUS fixup_imports_ilonly( WINE_MODREF *wm, LPCWSTR load_path, void **entry ) +{ + static const WCHAR mscoreeW[] = {'m','s','c','o','r','e','e','.','d','l','l',0}; + IMAGE_EXPORT_DIRECTORY *exports; + DWORD exp_size; + NTSTATUS status; + void *proc = NULL; + WINE_MODREF *prev, *imp; + + if (!(wm->ldr.Flags & LDR_DONT_RESOLVE_REFS)) return STATUS_SUCCESS; /* already done */ + wm->ldr.Flags &= ~LDR_DONT_RESOLVE_REFS; + + wm->nDeps = 1; + wm->deps = RtlAllocateHeap( GetProcessHeap(), 0, sizeof(WINE_MODREF *) ); + + prev = current_modref; + current_modref = wm; + if (!(status = load_dll( load_path, mscoreeW, 0, &imp ))) wm->deps[0] = imp; + current_modref = prev; + if (status) return status; + + TRACE( "loaded mscoree for %s\n", debugstr_w(wm->ldr.FullDllName.Buffer) ); + + if ((exports = RtlImageDirectoryEntryToData( imp->ldr.BaseAddress, TRUE, + IMAGE_DIRECTORY_ENTRY_EXPORT, &exp_size ))) + proc = find_named_export( imp->ldr.BaseAddress, exports, exp_size, "_CorExeMain", -1, load_path ); + if (!proc) return STATUS_PROCEDURE_NOT_FOUND; + *entry = proc; + return STATUS_SUCCESS; +} + + /**************************************************************** * fixup_imports * @@ -1837,6 +1875,9 @@ static NTSTATUS load_native_dll( LPCWSTR load_path, LPCWSTR name, HANDLE file, return STATUS_NO_MEMORY; } + if (image_info.loader_flags) wm->ldr.Flags |= LDR_COR_IMAGE; + if (image_info.image_flags & IMAGE_FLAGS_ComPlusILOnly) wm->ldr.Flags |= LDR_COR_ILONLY; + set_security_cookie( module, len ); /* fixup imports */ @@ -2991,7 +3032,7 @@ PIMAGE_NT_HEADERS WINAPI RtlImageNtHeader(HMODULE hModule) * Attach to all the loaded dlls. * If this is the first time, perform the full process initialization. */ -NTSTATUS attach_dlls( CONTEXT *context ) +NTSTATUS attach_dlls( CONTEXT *context, void **entry ) { NTSTATUS status; WINE_MODREF *wm; @@ -3009,7 +3050,12 @@ NTSTATUS attach_dlls( CONTEXT *context ) if (!imports_fixup_done) { actctx_init(); - if ((status = fixup_imports( wm, load_path )) != STATUS_SUCCESS) + if (wm->ldr.Flags & LDR_COR_ILONLY) + status = fixup_imports_ilonly( wm, load_path, entry ); + else + status = fixup_imports( wm, load_path ); + + if (status) { ERR( "Importing dlls for %s failed, status %x\n", debugstr_w(NtCurrentTeb()->Peb->ProcessParameters->ImagePathName.Buffer), status ); diff --git a/dlls/ntdll/ntdll_misc.h b/dlls/ntdll/ntdll_misc.h index 3fbccbab7ec..85bdd9ed056 100644 --- a/dlls/ntdll/ntdll_misc.h +++ b/dlls/ntdll/ntdll_misc.h @@ -106,7 +106,7 @@ extern NTSTATUS validate_open_object_attributes( const OBJECT_ATTRIBUTES *attr ) /* module handling */ extern LIST_ENTRY tls_links DECLSPEC_HIDDEN; -extern NTSTATUS attach_dlls( CONTEXT *context ) DECLSPEC_HIDDEN; +extern NTSTATUS attach_dlls( CONTEXT *context, void **entry ) DECLSPEC_HIDDEN; extern FARPROC RELAY_GetProcAddress( HMODULE module, const IMAGE_EXPORT_DIRECTORY *exports, DWORD exp_size, FARPROC proc, DWORD ordinal, const WCHAR *user ) DECLSPEC_HIDDEN; extern FARPROC SNOOP_GetProcAddress( HMODULE hmod, const IMAGE_EXPORT_DIRECTORY *exports, DWORD exp_size, diff --git a/dlls/ntdll/signal_arm.c b/dlls/ntdll/signal_arm.c index 79aeb2a4523..7fe698c131e 100644 --- a/dlls/ntdll/signal_arm.c +++ b/dlls/ntdll/signal_arm.c @@ -1277,7 +1277,7 @@ PCONTEXT DECLSPEC_HIDDEN attach_thread( LPTHREAD_START_ROUTINE entry, void *arg, init_thread_context( ctx, entry, arg, relay ); } ctx->ContextFlags = CONTEXT_FULL; - attach_dlls( ctx ); + attach_dlls( ctx, (void **)&ctx->R0 ); return ctx; } diff --git a/dlls/ntdll/signal_arm64.c b/dlls/ntdll/signal_arm64.c index 7be64fdb81c..c461e8804f1 100644 --- a/dlls/ntdll/signal_arm64.c +++ b/dlls/ntdll/signal_arm64.c @@ -1009,7 +1009,7 @@ static void thread_startup( void *param ) context.Pc = (DWORD_PTR)info->start; if (info->suspend) wait_suspend( &context ); - attach_dlls( &context ); + attach_dlls( &context, (void **)&context.u.s.X0 ); ((thread_start_func)context.Pc)( (LPTHREAD_START_ROUTINE)context.u.s.X0, (void *)context.u.s.X1 ); } diff --git a/dlls/ntdll/signal_i386.c b/dlls/ntdll/signal_i386.c index fcadcf9cba4..71eff668fe7 100644 --- a/dlls/ntdll/signal_i386.c +++ b/dlls/ntdll/signal_i386.c @@ -2675,7 +2675,7 @@ PCONTEXT DECLSPEC_HIDDEN attach_thread( LPTHREAD_START_ROUTINE entry, void *arg, init_thread_context( ctx, entry, arg, relay ); } ctx->ContextFlags = CONTEXT_FULL; - attach_dlls( ctx ); + attach_dlls( ctx, (void **)&ctx->Eax ); return ctx; } diff --git a/dlls/ntdll/signal_powerpc.c b/dlls/ntdll/signal_powerpc.c index 39e8f42c03b..cb5089bcaa1 100644 --- a/dlls/ntdll/signal_powerpc.c +++ b/dlls/ntdll/signal_powerpc.c @@ -1171,7 +1171,7 @@ static void thread_startup( void *param ) context.Iar = (DWORD)info->start; if (info->suspend) wait_suspend( &context ); - attach_dlls( &context ); + attach_dlls( &context, (void **)&context->Gpr3 ); ((thread_start_func)context.Iar)( (LPTHREAD_START_ROUTINE)context.Gpr3, (void *)context.Gpr4 ); } diff --git a/dlls/ntdll/signal_x86_64.c b/dlls/ntdll/signal_x86_64.c index f75ba57c6f6..169793b4d85 100644 --- a/dlls/ntdll/signal_x86_64.c +++ b/dlls/ntdll/signal_x86_64.c @@ -4169,7 +4169,7 @@ PCONTEXT DECLSPEC_HIDDEN attach_thread( LPTHREAD_START_ROUTINE entry, void *arg, init_thread_context( ctx, entry, arg, relay ); } ctx->ContextFlags = CONTEXT_FULL; - attach_dlls( ctx ); + attach_dlls( ctx, (void **)&ctx->Rcx ); return ctx; } diff --git a/include/winternl.h b/include/winternl.h index ec6850a927f..c3cca80677c 100644 --- a/include/winternl.h +++ b/include/winternl.h @@ -2158,7 +2158,8 @@ typedef struct _LDR_MODULE #define LDR_UNLOAD_IN_PROGRESS 0x00002000 #define LDR_NO_DLL_CALLS 0x00040000 #define LDR_PROCESS_ATTACHED 0x00080000 -#define LDR_MODULE_REBASED 0x00200000 +#define LDR_COR_IMAGE 0x00400000 +#define LDR_COR_ILONLY 0x01000000 /* these ones is Wine specific */ #define LDR_DONT_RESOLVE_REFS 0x40000000