ntdll: Abuse RtlCreateUserThread to call the thread function for CreateThread directly.
This commit is contained in:
parent
21d631e270
commit
7a383cf83f
@ -45,42 +45,6 @@
|
|||||||
#include "kernel_private.h"
|
#include "kernel_private.h"
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(thread);
|
WINE_DEFAULT_DEBUG_CHANNEL(thread);
|
||||||
WINE_DECLARE_DEBUG_CHANNEL(relay);
|
|
||||||
|
|
||||||
|
|
||||||
struct new_thread_info
|
|
||||||
{
|
|
||||||
LPTHREAD_START_ROUTINE func;
|
|
||||||
void *arg;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
|
||||||
* THREAD_Start
|
|
||||||
*
|
|
||||||
* Start execution of a newly created thread. Does not return.
|
|
||||||
*/
|
|
||||||
static void CALLBACK THREAD_Start( void *ptr )
|
|
||||||
{
|
|
||||||
struct new_thread_info *info = ptr;
|
|
||||||
LPTHREAD_START_ROUTINE func = info->func;
|
|
||||||
void *arg = info->arg;
|
|
||||||
|
|
||||||
RtlFreeHeap( GetProcessHeap(), 0, info );
|
|
||||||
|
|
||||||
if (TRACE_ON(relay))
|
|
||||||
DPRINTF("%04x:Starting thread (entryproc=%p)\n", GetCurrentThreadId(), func );
|
|
||||||
|
|
||||||
__TRY
|
|
||||||
{
|
|
||||||
ExitThread( func( arg ) );
|
|
||||||
}
|
|
||||||
__EXCEPT(UnhandledExceptionFilter)
|
|
||||||
{
|
|
||||||
TerminateThread( GetCurrentThread(), GetExceptionCode() );
|
|
||||||
}
|
|
||||||
__ENDTRY
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
@ -120,22 +84,13 @@ HANDLE WINAPI CreateRemoteThread( HANDLE hProcess, SECURITY_ATTRIBUTES *sa, SIZE
|
|||||||
CLIENT_ID client_id;
|
CLIENT_ID client_id;
|
||||||
NTSTATUS status;
|
NTSTATUS status;
|
||||||
SIZE_T stack_reserve = 0, stack_commit = 0;
|
SIZE_T stack_reserve = 0, stack_commit = 0;
|
||||||
struct new_thread_info *info;
|
|
||||||
|
|
||||||
if (!(info = RtlAllocateHeap( GetProcessHeap(), 0, sizeof(*info) )))
|
|
||||||
{
|
|
||||||
SetLastError( ERROR_NOT_ENOUGH_MEMORY );
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
info->func = start;
|
|
||||||
info->arg = param;
|
|
||||||
|
|
||||||
if (flags & STACK_SIZE_PARAM_IS_A_RESERVATION) stack_reserve = stack;
|
if (flags & STACK_SIZE_PARAM_IS_A_RESERVATION) stack_reserve = stack;
|
||||||
else stack_commit = stack;
|
else stack_commit = stack;
|
||||||
|
|
||||||
status = RtlCreateUserThread( hProcess, NULL, TRUE,
|
status = RtlCreateUserThread( hProcess, NULL, TRUE,
|
||||||
NULL, stack_reserve, stack_commit,
|
NULL, stack_reserve, stack_commit,
|
||||||
THREAD_Start, info, &handle, &client_id );
|
(PRTL_THREAD_START_ROUTINE)start, param, &handle, &client_id );
|
||||||
if (status == STATUS_SUCCESS)
|
if (status == STATUS_SUCCESS)
|
||||||
{
|
{
|
||||||
if (id) *id = (DWORD)client_id.UniqueThread;
|
if (id) *id = (DWORD)client_id.UniqueThread;
|
||||||
@ -147,7 +102,6 @@ HANDLE WINAPI CreateRemoteThread( HANDLE hProcess, SECURITY_ATTRIBUTES *sa, SIZE
|
|||||||
if (NtResumeThread( handle, &ret ))
|
if (NtResumeThread( handle, &ret ))
|
||||||
{
|
{
|
||||||
NtClose( handle );
|
NtClose( handle );
|
||||||
RtlFreeHeap( GetProcessHeap(), 0, info );
|
|
||||||
SetLastError( ERROR_NOT_ENOUGH_MEMORY );
|
SetLastError( ERROR_NOT_ENOUGH_MEMORY );
|
||||||
handle = 0;
|
handle = 0;
|
||||||
}
|
}
|
||||||
@ -155,7 +109,6 @@ HANDLE WINAPI CreateRemoteThread( HANDLE hProcess, SECURITY_ATTRIBUTES *sa, SIZE
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
RtlFreeHeap( GetProcessHeap(), 0, info );
|
|
||||||
SetLastError( RtlNtStatusToDosError(status) );
|
SetLastError( RtlNtStatusToDosError(status) );
|
||||||
handle = 0;
|
handle = 0;
|
||||||
}
|
}
|
||||||
|
@ -43,6 +43,7 @@
|
|||||||
#include "wine/exception.h"
|
#include "wine/exception.h"
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(thread);
|
WINE_DEFAULT_DEBUG_CHANNEL(thread);
|
||||||
|
WINE_DECLARE_DEBUG_CHANNEL(relay);
|
||||||
|
|
||||||
/* info passed to a starting thread */
|
/* info passed to a starting thread */
|
||||||
struct startup_info
|
struct startup_info
|
||||||
@ -348,6 +349,47 @@ static PUNHANDLED_EXCEPTION_FILTER get_unhandled_exception_filter(void)
|
|||||||
return unhandled_exception_filter;
|
return unhandled_exception_filter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* call_thread_func
|
||||||
|
*
|
||||||
|
* Hack to make things compatible with the thread procedures used by kernel32.CreateThread.
|
||||||
|
*/
|
||||||
|
static void DECLSPEC_NORETURN call_thread_func( PRTL_THREAD_START_ROUTINE rtl_func, void *arg )
|
||||||
|
{
|
||||||
|
LPTHREAD_START_ROUTINE func = (LPTHREAD_START_ROUTINE)rtl_func;
|
||||||
|
DWORD exit_code;
|
||||||
|
BOOL last;
|
||||||
|
|
||||||
|
MODULE_DllThreadAttach( NULL );
|
||||||
|
|
||||||
|
if (TRACE_ON(relay))
|
||||||
|
DPRINTF( "%04x:Starting thread proc %p (arg=%p)\n", GetCurrentThreadId(), func, arg );
|
||||||
|
|
||||||
|
exit_code = func( arg );
|
||||||
|
|
||||||
|
/* send the exit code to the server */
|
||||||
|
SERVER_START_REQ( terminate_thread )
|
||||||
|
{
|
||||||
|
req->handle = GetCurrentThread();
|
||||||
|
req->exit_code = exit_code;
|
||||||
|
wine_server_call( req );
|
||||||
|
last = reply->last;
|
||||||
|
}
|
||||||
|
SERVER_END_REQ;
|
||||||
|
|
||||||
|
if (last)
|
||||||
|
{
|
||||||
|
LdrShutdownProcess();
|
||||||
|
exit( exit_code );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LdrShutdownThread();
|
||||||
|
server_exit_thread( exit_code );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* start_thread
|
* start_thread
|
||||||
*
|
*
|
||||||
@ -397,7 +439,7 @@ static void start_thread( struct wine_pthread_thread_info *info )
|
|||||||
{
|
{
|
||||||
__TRY
|
__TRY
|
||||||
{
|
{
|
||||||
MODULE_DllThreadAttach( NULL );
|
call_thread_func( func, arg );
|
||||||
}
|
}
|
||||||
__EXCEPT(get_unhandled_exception_filter())
|
__EXCEPT(get_unhandled_exception_filter())
|
||||||
{
|
{
|
||||||
@ -406,9 +448,7 @@ static void start_thread( struct wine_pthread_thread_info *info )
|
|||||||
__ENDTRY
|
__ENDTRY
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
MODULE_DllThreadAttach( NULL );
|
call_thread_func( func, arg );
|
||||||
|
|
||||||
func( arg );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user