Module: wine Branch: master Commit: 06c5a9ab55751b1c66ea0847aea4d4a45d8d343c URL: http://source.winehq.org/git/wine.git/?a=commit;h=06c5a9ab55751b1c66ea0847ae...
Author: Andrew Wesie awesie@gmail.com Date: Thu Feb 9 20:11:52 2017 +0100
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 awesie@gmail.com Signed-off-by: Sebastian Lackner sebastian@fds-team.de Signed-off-by: Alexandre Julliard julliard@winehq.org
---
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 5a9fea2..0cb3d9b 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; - - 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/ntdll/loader.c b/dlls/ntdll/loader.c index f1ef7ab..cf75850 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",