From 06c5a9ab55751b1c66ea0847aea4d4a45d8d343c Mon Sep 17 00:00:00 2001 From: Andrew Wesie Date: Thu, 9 Feb 2017 20:11:52 +0100 Subject: [PATCH] ntdll: Read entry point in LdrInitializeThunk. Overwatch overwrites the PE header contents in a TLS callback. This results in a crash on wine, because the entry point will be incorrect in start_process. Signed-off-by: Andrew Wesie Signed-off-by: Sebastian Lackner Signed-off-by: Alexandre Julliard --- dlls/kernel32/process.c | 11 +++-------- dlls/ntdll/loader.c | 18 +++++++++++++++--- 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/dlls/kernel32/process.c b/dlls/kernel32/process.c index 5a9fea219a0..0cb3d9bdcb7 100644 --- a/dlls/kernel32/process.c +++ b/dlls/kernel32/process.c @@ -1083,16 +1083,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; + PEB *peb = NtCurrentTeb()->Peb; - nt = RtlImageNtHeader( peb->ImageBaseAddress ); - entry = (LPTHREAD_START_ROUTINE)((char *)peb->ImageBaseAddress + - nt->OptionalHeader.AddressOfEntryPoint); - - 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/ntdll/loader.c b/dlls/ntdll/loader.c index f1ef7ab1bdd..cf758505a4c 100644 --- a/dlls/ntdll/loader.c +++ b/dlls/ntdll/loader.c @@ -99,6 +99,12 @@ struct builtin_load_info static struct builtin_load_info default_load_info; static struct builtin_load_info *builtin_load_info = &default_load_info; +struct start_params +{ + void *kernel_start; + LPTHREAD_START_ROUTINE entry; +}; + static HANDLE main_exe_file; static UINT tls_module_count; /* number of modules with TLS directory */ static IMAGE_TLS_DIRECTORY *tls_dirs; /* array of TLS directories */ @@ -3042,9 +3048,10 @@ static void load_global_options(void) /*********************************************************************** * start_process */ -static void start_process( void *kernel_start ) +static void start_process( void *arg ) { - call_thread_entry_point( kernel_start, NtCurrentTeb()->Peb ); + struct start_params *start_params = (struct start_params *)arg; + call_thread_entry_point( start_params->kernel_start, start_params->entry ); } /****************************************************************** @@ -3059,6 +3066,7 @@ void WINAPI LdrInitializeThunk( void *kernel_start, ULONG_PTR unknown2, WINE_MODREF *wm; LPCWSTR load_path; PEB *peb = NtCurrentTeb()->Peb; + struct start_params start_params; if (main_exe_file) NtClose( main_exe_file ); /* at this point the main module is created */ @@ -3095,12 +3103,16 @@ void WINAPI LdrInitializeThunk( void *kernel_start, ULONG_PTR unknown2, if ((status = fixup_imports( wm, load_path )) != STATUS_SUCCESS) goto error; heap_set_debug_flags( GetProcessHeap() ); + /* Store original entrypoint (in case it gets corrupted) */ + start_params.kernel_start = kernel_start; + start_params.entry = wm->ldr.EntryPoint; + status = wine_call_on_stack( attach_process_dlls, wm, NtCurrentTeb()->Tib.StackBase ); if (status != STATUS_SUCCESS) goto error; virtual_release_address_space(); virtual_clear_thread_stack(); - wine_switch_to_stack( start_process, kernel_start, NtCurrentTeb()->Tib.StackBase ); + wine_switch_to_stack( start_process, &start_params, NtCurrentTeb()->Tib.StackBase ); error: ERR( "Main exe initialization for %s failed, status %x\n",