From 23ec3ce2a3edc046872709733940dc51e77e0e91 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Mon, 4 Dec 2017 13:13:05 +0100 Subject: [PATCH] ntdll: Start process execution directly at the kernel32 process entry point. Signed-off-by: Alexandre Julliard --- dlls/kernel32/process.c | 39 +++++++++++++++++++++++++++++-------- dlls/ntdll/ntdll_misc.h | 2 +- dlls/ntdll/signal_arm.c | 12 +++++++----- dlls/ntdll/signal_arm64.c | 16 ++++++++------- dlls/ntdll/signal_i386.c | 35 ++------------------------------- dlls/ntdll/signal_powerpc.c | 16 ++++++++------- dlls/ntdll/signal_x86_64.c | 23 ++-------------------- dlls/ntdll/thread.c | 2 +- 8 files changed, 62 insertions(+), 83 deletions(-) diff --git a/dlls/kernel32/process.c b/dlls/kernel32/process.c index 26d2dd9902d..62dc815c935 100644 --- a/dlls/kernel32/process.c +++ b/dlls/kernel32/process.c @@ -57,6 +57,7 @@ #include "winternl.h" #include "kernel_private.h" #include "psapi.h" +#include "wine/exception.h" #include "wine/library.h" #include "wine/server.h" #include "wine/unicode.h" @@ -1088,11 +1089,25 @@ __ASM_GLOBAL_FUNC( call_process_entry, __ASM_CFI(".cfi_def_cfa %esp,4\n\t") __ASM_CFI(".cfi_same_value %ebp\n\t") "ret" ) + +extern void WINAPI start_process( LPTHREAD_START_ROUTINE entry, PEB *peb ) DECLSPEC_HIDDEN; +extern void WINAPI start_process_wrapper(void) DECLSPEC_HIDDEN; +__ASM_GLOBAL_FUNC( start_process_wrapper, + "pushl %ebp\n\t" + __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t") + __ASM_CFI(".cfi_rel_offset %ebp,0\n\t") + "movl %esp,%ebp\n\t" + __ASM_CFI(".cfi_def_cfa_register %ebp\n\t") + "pushl %ebx\n\t" /* arg */ + "pushl %eax\n\t" /* entry */ + "call " __ASM_NAME("start_process") ) #else static inline DWORD call_process_entry( PEB *peb, LPTHREAD_START_ROUTINE entry ) { return entry( peb ); } +static void WINAPI start_process( LPTHREAD_START_ROUTINE entry, PEB *peb ); +#define start_process_wrapper start_process #endif /*********************************************************************** @@ -1100,10 +1115,9 @@ 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( LPTHREAD_START_ROUTINE entry ) +void WINAPI start_process( LPTHREAD_START_ROUTINE entry, PEB *peb ) { BOOL being_debugged; - PEB *peb = NtCurrentTeb()->Peb; if (!entry) { @@ -1115,12 +1129,21 @@ static DWORD WINAPI start_process( LPTHREAD_START_ROUTINE entry ) TRACE_(relay)( "\1Starting process %s (entryproc=%p)\n", debugstr_w(peb->ProcessParameters->ImagePathName.Buffer), entry ); - if (!CheckRemoteDebuggerPresent( GetCurrentProcess(), &being_debugged )) - being_debugged = FALSE; + __TRY + { + if (!CheckRemoteDebuggerPresent( GetCurrentProcess(), &being_debugged )) + being_debugged = FALSE; - SetLastError( 0 ); /* clear error code */ - if (being_debugged) DbgBreakPoint(); - return call_process_entry( peb, entry ); + SetLastError( 0 ); /* clear error code */ + if (being_debugged) DbgBreakPoint(); + ExitThread( call_process_entry( peb, entry )); + } + __EXCEPT(UnhandledExceptionFilter) + { + TerminateThread( GetCurrentThread(), GetExceptionCode() ); + } + __ENDTRY + abort(); /* should not be reached */ } @@ -1314,7 +1337,7 @@ void CDECL __wine_kernel_init(void) if (!params->CurrentDirectory.Handle) chdir("/"); /* avoid locking removable devices */ - LdrInitializeThunk( start_process, 0, 0, 0 ); + LdrInitializeThunk( start_process_wrapper, 0, 0, 0 ); error: ExitProcess( GetLastError() ); diff --git a/dlls/ntdll/ntdll_misc.h b/dlls/ntdll/ntdll_misc.h index 149462d46c7..72c33fe3763 100644 --- a/dlls/ntdll/ntdll_misc.h +++ b/dlls/ntdll/ntdll_misc.h @@ -116,7 +116,7 @@ extern UNICODE_STRING system_dir DECLSPEC_HIDDEN; typedef LONG (WINAPI *PUNHANDLED_EXCEPTION_FILTER)(PEXCEPTION_POINTERS); extern PUNHANDLED_EXCEPTION_FILTER unhandled_exception_filter DECLSPEC_HIDDEN; -extern LPTHREAD_START_ROUTINE kernel32_start_process DECLSPEC_HIDDEN; +extern void (WINAPI *kernel32_start_process)(LPTHREAD_START_ROUTINE,void*) DECLSPEC_HIDDEN; /* redefine these to make sure we don't reference kernel symbols */ #define GetProcessHeap() (NtCurrentTeb()->Peb->ProcessHeap) diff --git a/dlls/ntdll/signal_arm.c b/dlls/ntdll/signal_arm.c index 59ae765e353..2e0038d5cbb 100644 --- a/dlls/ntdll/signal_arm.c +++ b/dlls/ntdll/signal_arm.c @@ -1208,8 +1208,11 @@ static void call_thread_entry_point( LPTHREAD_START_ROUTINE entry, void *arg ) abort(); /* should not be reached */ } +typedef void (WINAPI *thread_start_func)(LPTHREAD_START_ROUTINE,void *); + struct startup_info { + thread_start_func start; LPTHREAD_START_ROUTINE entry; void *arg; BOOL suspend; @@ -1228,7 +1231,7 @@ static void thread_startup( void *param ) context.R0 = (DWORD)info->entry; context.R1 = (DWORD)info->arg; context.Sp = (DWORD)NtCurrentTeb()->Tib.StackBase; - context.Pc = (DWORD)call_thread_entry_point; + context.Pc = (DWORD)info->start; attach_dlls( &context, info->suspend ); @@ -1245,7 +1248,7 @@ static void thread_startup( void *param ) */ void signal_start_thread( LPTHREAD_START_ROUTINE entry, void *arg, BOOL suspend ) { - struct startup_info info = { entry, arg, suspend }; + struct startup_info info = { call_thread_entry_point, entry, arg, suspend }; wine_switch_to_stack( thread_startup, &info, NtCurrentTeb()->Tib.StackBase ); } @@ -1255,12 +1258,11 @@ void signal_start_thread( LPTHREAD_START_ROUTINE entry, void *arg, BOOL suspend * Process startup sequence: * signal_start_process() * -> thread_startup() - * -> call_thread_entry_point() - * -> kernel32_start_process() + * -> kernel32_start_process() */ void signal_start_process( LPTHREAD_START_ROUTINE entry, BOOL suspend ) { - struct startup_info info = { kernel32_start_process, entry, suspend }; + struct startup_info info = { kernel32_start_process, entry, NtCurrentTeb()->Peb, suspend }; wine_switch_to_stack( thread_startup, &info, NtCurrentTeb()->Tib.StackBase ); } diff --git a/dlls/ntdll/signal_arm64.c b/dlls/ntdll/signal_arm64.c index 36c7f2fc2e8..bbce4a7e3f5 100644 --- a/dlls/ntdll/signal_arm64.c +++ b/dlls/ntdll/signal_arm64.c @@ -936,7 +936,7 @@ USHORT WINAPI RtlCaptureStackBackTrace( ULONG skip, ULONG count, PVOID *buffer, /*********************************************************************** * call_thread_entry_point */ -static void call_thread_entry_point( LPTHREAD_START_ROUTINE entry, void *arg ) +static void WINAPI call_thread_entry_point( LPTHREAD_START_ROUTINE entry, void *arg ) { __TRY { @@ -951,8 +951,11 @@ static void call_thread_entry_point( LPTHREAD_START_ROUTINE entry, void *arg ) abort(); /* should not be reached */ } +typedef void (WINAPI *thread_start_func)(LPTHREAD_START_ROUTINE,void *); + struct startup_info { + thread_start_func start; LPTHREAD_START_ROUTINE entry; void *arg; BOOL suspend; @@ -971,11 +974,11 @@ static void thread_startup( void *param ) context.X0 = (DWORD_PTR)info->entry; context.X1 = (DWORD_PTR)info->arg; context.Sp = (DWORD_PTR)NtCurrentTeb()->Tib.StackBase; - context.Pc = (DWORD_PTR)call_thread_entry_point; + context.Pc = (DWORD_PTR)info->start; attach_dlls( &context, info->suspend ); - call_thread_entry_point( (LPTHREAD_START_ROUTINE)context.X0, (void *)context.X1 ); + ((thread_start_func)context.Pc)( (LPTHREAD_START_ROUTINE)context.X0, (void *)context.X1 ); } /*********************************************************************** @@ -988,7 +991,7 @@ static void thread_startup( void *param ) */ void signal_start_thread( LPTHREAD_START_ROUTINE entry, void *arg, BOOL suspend ) { - struct startup_info info = { entry, arg, suspend }; + struct startup_info info = { call_thread_entry_point, entry, arg, suspend }; wine_switch_to_stack( thread_startup, &info, NtCurrentTeb()->Tib.StackBase ); } @@ -998,12 +1001,11 @@ void signal_start_thread( LPTHREAD_START_ROUTINE entry, void *arg, BOOL suspend * Process startup sequence: * signal_start_process() * -> thread_startup() - * -> call_thread_entry_point() - * -> kernel32_start_process() + * -> kernel32_start_process() */ void signal_start_process( LPTHREAD_START_ROUTINE entry, BOOL suspend ) { - struct startup_info info = { kernel32_start_process, entry, suspend }; + struct startup_info info = { kernel32_start_process, entry, NtCurrentTeb()->Peb, suspend }; wine_switch_to_stack( thread_startup, &info, NtCurrentTeb()->Tib.StackBase ); } diff --git a/dlls/ntdll/signal_i386.c b/dlls/ntdll/signal_i386.c index 1c04c82cdf4..8623152596a 100644 --- a/dlls/ntdll/signal_i386.c +++ b/dlls/ntdll/signal_i386.c @@ -2915,17 +2915,6 @@ __ASM_GLOBAL_FUNC( call_thread_entry, "pushl %eax\n\t" /* entry */ "call " __ASM_NAME("call_thread_func") ) -extern void call_process_entry(void) DECLSPEC_HIDDEN; -__ASM_GLOBAL_FUNC( call_process_entry, - "pushl %ebp\n\t" - __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t") - __ASM_CFI(".cfi_rel_offset %ebp,0\n\t") - "movl %esp,%ebp\n\t" - __ASM_CFI(".cfi_def_cfa_register %ebp\n\t") - "pushl %ebx\n\t" /* arg */ - "pushl %eax\n\t" /* entry */ - "call " __ASM_NAME("call_process_func") ) - /* wrapper for apps that don't declare the thread function correctly */ extern DWORD call_thread_func_wrapper( LPTHREAD_START_ROUTINE entry, void *arg ); __ASM_GLOBAL_FUNC(call_thread_func_wrapper, @@ -2961,24 +2950,6 @@ void DECLSPEC_HIDDEN call_thread_func( LPTHREAD_START_ROUTINE entry, void *arg ) } -/*********************************************************************** - * call_process_func - */ -void DECLSPEC_HIDDEN call_process_func( LPTHREAD_START_ROUTINE entry, void *arg ) -{ - __TRY - { - RtlExitUserThread( kernel32_start_process( entry )); - } - __EXCEPT(unhandled_exception_filter) - { - NtTerminateThread( GetCurrentThread(), GetExceptionCode() ); - } - __ENDTRY - abort(); /* should not be reached */ -} - - /*********************************************************************** * thread_startup */ @@ -3011,14 +2982,12 @@ void signal_start_thread( LPTHREAD_START_ROUTINE entry, void *arg, BOOL suspend * signal_start_process() * -> start_thread() * -> thread_startup() - * -> call_process_entry() - * -> call_process_func() - * -> kernel32_start_process() + * -> kernel32_start_process() */ void signal_start_process( LPTHREAD_START_ROUTINE entry, BOOL suspend ) { start_thread( entry, NtCurrentTeb()->Peb, suspend, - call_process_entry, &x86_thread_data()->exit_frame ); + kernel32_start_process, &x86_thread_data()->exit_frame ); } diff --git a/dlls/ntdll/signal_powerpc.c b/dlls/ntdll/signal_powerpc.c index 5122c5483e6..234fdc4d478 100644 --- a/dlls/ntdll/signal_powerpc.c +++ b/dlls/ntdll/signal_powerpc.c @@ -1138,7 +1138,7 @@ USHORT WINAPI RtlCaptureStackBackTrace( ULONG skip, ULONG count, PVOID *buffer, /*********************************************************************** * call_thread_entry_point */ -static void call_thread_entry_point( LPTHREAD_START_ROUTINE entry, void *arg ) +static void WINAPI call_thread_entry_point( LPTHREAD_START_ROUTINE entry, void *arg ) { __TRY { @@ -1153,8 +1153,11 @@ static void call_thread_entry_point( LPTHREAD_START_ROUTINE entry, void *arg ) abort(); /* should not be reached */ } +typedef void (WINAPI *thread_start_func)(LPTHREAD_START_ROUTINE,void *); + struct startup_info { + thread_start_func start; LPTHREAD_START_ROUTINE entry; void *arg; BOOL suspend; @@ -1173,11 +1176,11 @@ static void thread_startup( void *param ) context.Gpr1 = (DWORD)NtCurrentTeb()->Tib.StackBase; context.Gpr3 = (DWORD)info->entry; context.Gpr4 = (DWORD)info->arg; - context.Iar = (DWORD)call_thread_entry_point; + context.Iar = (DWORD)info->start; attach_dlls( &context, info->suspend ); - call_thread_entry_point( (LPTHREAD_START_ROUTINE)context.Gpr3, (void *)context.Gpr4 ); + ((thread_start_func)context.Iar)( (LPTHREAD_START_ROUTINE)context.Gpr3, (void *)context.Gpr4 ); } /*********************************************************************** @@ -1190,7 +1193,7 @@ static void thread_startup( void *param ) */ void signal_start_thread( LPTHREAD_START_ROUTINE entry, void *arg, BOOL suspend ) { - struct startup_info info = { entry, arg, suspend }; + struct startup_info info = { call_thread_entry_point, entry, arg, suspend }; wine_switch_to_stack( thread_startup, &info, NtCurrentTeb()->Tib.StackBase ); } @@ -1200,12 +1203,11 @@ void signal_start_thread( LPTHREAD_START_ROUTINE entry, void *arg, BOOL suspend * Process startup sequence: * signal_start_process() * -> thread_startup() - * -> call_thread_entry_point() - * -> kernel32_start_process() + * -> kernel32_start_process() */ void signal_start_process( LPTHREAD_START_ROUTINE entry, BOOL suspend ) { - struct startup_info info = { kernel32_start_process, entry, suspend }; + struct startup_info info = { kernel32_start_process, entry, NtCurrentTeb()->Peb, suspend }; wine_switch_to_stack( thread_startup, &info, NtCurrentTeb()->Tib.StackBase ); } diff --git a/dlls/ntdll/signal_x86_64.c b/dlls/ntdll/signal_x86_64.c index af2682e0ae5..83521ee0ec5 100644 --- a/dlls/ntdll/signal_x86_64.c +++ b/dlls/ntdll/signal_x86_64.c @@ -4073,24 +4073,6 @@ static void WINAPI call_thread_func( LPTHREAD_START_ROUTINE entry, void *arg ) } -/*********************************************************************** - * call_process_func - */ -static void WINAPI call_process_func( LPTHREAD_START_ROUTINE entry, void *arg ) -{ - __TRY - { - RtlExitUserThread( kernel32_start_process( entry )); - } - __EXCEPT(unhandled_exception_filter) - { - NtTerminateThread( GetCurrentThread(), GetExceptionCode() ); - } - __ENDTRY - abort(); /* should not be reached */ -} - - extern void DECLSPEC_NORETURN start_thread( LPTHREAD_START_ROUTINE entry, void *arg, BOOL suspend, void *relay, void *stack, void **exit_frame ); __ASM_GLOBAL_FUNC( start_thread, @@ -4174,12 +4156,11 @@ void signal_start_thread( LPTHREAD_START_ROUTINE entry, void *arg, BOOL suspend * signal_start_process() * -> start_thread() * -> thread_startup() - * -> call_process_func() - * -> kernel32_start_process() + * -> kernel32_start_process() */ void signal_start_process( LPTHREAD_START_ROUTINE entry, BOOL suspend ) { - start_thread( entry, NtCurrentTeb()->Peb, suspend, call_process_func, + start_thread( entry, NtCurrentTeb()->Peb, suspend, kernel32_start_process, NtCurrentTeb()->Tib.StackBase, &amd64_thread_data()->exit_frame ); } diff --git a/dlls/ntdll/thread.c b/dlls/ntdll/thread.c index 587cdde157e..7b726ab7010 100644 --- a/dlls/ntdll/thread.c +++ b/dlls/ntdll/thread.c @@ -51,7 +51,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(thread); struct _KUSER_SHARED_DATA *user_shared_data = NULL; PUNHANDLED_EXCEPTION_FILTER unhandled_exception_filter = NULL; -LPTHREAD_START_ROUTINE kernel32_start_process = NULL; +void (WINAPI *kernel32_start_process)(LPTHREAD_START_ROUTINE,void*) = NULL; /* info passed to a starting thread */ struct startup_info