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>
This commit is contained in:
Andrew Wesie 2017-02-09 20:11:52 +01:00 committed by Alexandre Julliard
parent 2f447bb49c
commit 06c5a9ab55
2 changed files with 18 additions and 11 deletions

View File

@ -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. * 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; PEB *peb = NtCurrentTeb()->Peb;
LPTHREAD_START_ROUTINE entry;
nt = RtlImageNtHeader( peb->ImageBaseAddress ); if (!entry)
entry = (LPTHREAD_START_ROUTINE)((char *)peb->ImageBaseAddress +
nt->OptionalHeader.AddressOfEntryPoint);
if (!nt->OptionalHeader.AddressOfEntryPoint)
{ {
ERR( "%s doesn't have an entry point, it cannot be executed\n", ERR( "%s doesn't have an entry point, it cannot be executed\n",
debugstr_w(peb->ProcessParameters->ImagePathName.Buffer) ); debugstr_w(peb->ProcessParameters->ImagePathName.Buffer) );

View File

@ -99,6 +99,12 @@ struct builtin_load_info
static struct builtin_load_info default_load_info; static struct builtin_load_info default_load_info;
static struct builtin_load_info *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 HANDLE main_exe_file;
static UINT tls_module_count; /* number of modules with TLS directory */ static UINT tls_module_count; /* number of modules with TLS directory */
static IMAGE_TLS_DIRECTORY *tls_dirs; /* array of TLS directories */ static IMAGE_TLS_DIRECTORY *tls_dirs; /* array of TLS directories */
@ -3042,9 +3048,10 @@ static void load_global_options(void)
/*********************************************************************** /***********************************************************************
* start_process * 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; WINE_MODREF *wm;
LPCWSTR load_path; LPCWSTR load_path;
PEB *peb = NtCurrentTeb()->Peb; 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 */ 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; if ((status = fixup_imports( wm, load_path )) != STATUS_SUCCESS) goto error;
heap_set_debug_flags( GetProcessHeap() ); 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 ); status = wine_call_on_stack( attach_process_dlls, wm, NtCurrentTeb()->Tib.StackBase );
if (status != STATUS_SUCCESS) goto error; if (status != STATUS_SUCCESS) goto error;
virtual_release_address_space(); virtual_release_address_space();
virtual_clear_thread_stack(); 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: error:
ERR( "Main exe initialization for %s failed, status %x\n", ERR( "Main exe initialization for %s failed, status %x\n",