[KERNEL32] Minor enhancements for CreateRemoteThread(). (#804)

- Add some cleanup code in failure code paths, instead of asserting.
- Move BasepNotifyCsrOfThread() helper to the only file where it is used.
- Don't use ERROR_DBGBREAK in failure paths but just DPRINT the error
  message: we handle the failures properly.
- When creating the remote thread, sync its service tag with the parent
  thread's one.
This commit is contained in:
Hermès Bélusca-Maïto 2018-08-23 21:44:53 +02:00
parent effdb6f232
commit 44cddadba8
No known key found for this signature in database
GPG key ID: 3B2539C65E7B93D0
2 changed files with 76 additions and 69 deletions

View file

@ -479,36 +479,6 @@ BaseProcessStartup(PPROCESS_START_ROUTINE lpStartAddress)
_SEH2_END; _SEH2_END;
} }
NTSTATUS
WINAPI
BasepNotifyCsrOfThread(IN HANDLE ThreadHandle,
IN PCLIENT_ID ClientId)
{
BASE_API_MESSAGE ApiMessage;
PBASE_CREATE_THREAD CreateThreadRequest = &ApiMessage.Data.CreateThreadRequest;
DPRINT("BasepNotifyCsrOfThread: Thread: %p, Handle %p\n",
ClientId->UniqueThread, ThreadHandle);
/* Fill out the request */
CreateThreadRequest->ClientId = *ClientId;
CreateThreadRequest->ThreadHandle = ThreadHandle;
/* Call CSR */
CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
NULL,
CSR_CREATE_API_NUMBER(BASESRV_SERVERDLL_INDEX, BasepCreateThread),
sizeof(*CreateThreadRequest));
if (!NT_SUCCESS(ApiMessage.Status))
{
DPRINT1("Failed to tell CSRSS about new thread: %lx\n", ApiMessage.Status);
return ApiMessage.Status;
}
/* Return Success */
return STATUS_SUCCESS;
}
BOOLEAN BOOLEAN
WINAPI WINAPI
BasePushProcessParameters(IN ULONG ParameterFlags, BasePushProcessParameters(IN ULONG ParameterFlags,

View file

@ -18,12 +18,37 @@
typedef NTSTATUS (NTAPI *PCSR_CREATE_REMOTE_THREAD)(IN HANDLE ThreadHandle, IN PCLIENT_ID ClientId); typedef NTSTATUS (NTAPI *PCSR_CREATE_REMOTE_THREAD)(IN HANDLE ThreadHandle, IN PCLIENT_ID ClientId);
/* FUNCTIONS ******************************************************************/
NTSTATUS NTSTATUS
WINAPI WINAPI
BasepNotifyCsrOfThread(IN HANDLE ThreadHandle, BasepNotifyCsrOfThread(IN HANDLE ThreadHandle,
IN PCLIENT_ID ClientId); IN PCLIENT_ID ClientId)
{
BASE_API_MESSAGE ApiMessage;
PBASE_CREATE_THREAD CreateThreadRequest = &ApiMessage.Data.CreateThreadRequest;
/* FUNCTIONS ******************************************************************/ DPRINT("BasepNotifyCsrOfThread: Thread: %p, Handle %p\n",
ClientId->UniqueThread, ThreadHandle);
/* Fill out the request */
CreateThreadRequest->ClientId = *ClientId;
CreateThreadRequest->ThreadHandle = ThreadHandle;
/* Call CSR */
CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
NULL,
CSR_CREATE_API_NUMBER(BASESRV_SERVERDLL_INDEX, BasepCreateThread),
sizeof(*CreateThreadRequest));
if (!NT_SUCCESS(ApiMessage.Status))
{
DPRINT1("Failed to tell CSRSS about new thread: %lx\n", ApiMessage.Status);
return ApiMessage.Status;
}
/* Return Success */
return STATUS_SUCCESS;
}
__declspec(noreturn) __declspec(noreturn)
VOID VOID
@ -153,12 +178,13 @@ CreateRemoteThread(IN HANDLE hProcess,
ULONG_PTR Cookie; ULONG_PTR Cookie;
ULONG ReturnLength; ULONG ReturnLength;
SIZE_T ReturnSize; SIZE_T ReturnSize;
DPRINT("CreateRemoteThread: hProcess: %p dwStackSize: %lu lpStartAddress" DPRINT("CreateRemoteThread: hProcess: %p dwStackSize: %lu lpStartAddress"
": %p lpParameter: %p, dwCreationFlags: %lx\n", hProcess, ": %p lpParameter: %p, dwCreationFlags: %lx\n", hProcess,
dwStackSize, lpStartAddress, lpParameter, dwCreationFlags); dwStackSize, lpStartAddress, lpParameter, dwCreationFlags);
/* Clear the Context */ /* Clear the Context */
RtlZeroMemory(&Context, sizeof(CONTEXT)); RtlZeroMemory(&Context, sizeof(Context));
/* Write PID */ /* Write PID */
ClientId.UniqueProcess = hProcess; ClientId.UniqueProcess = hProcess;
@ -176,14 +202,14 @@ CreateRemoteThread(IN HANDLE hProcess,
return NULL; return NULL;
} }
/* Create Initial Context */ /* Create the Initial Context */
BaseInitializeContext(&Context, BaseInitializeContext(&Context,
lpParameter, lpParameter,
lpStartAddress, lpStartAddress,
InitialTeb.StackBase, InitialTeb.StackBase,
1); 1);
/* initialize the attributes for the thread object */ /* Initialize the attributes for the thread object */
ObjectAttributes = BaseFormatObjectAttributes(&LocalObjectAttributes, ObjectAttributes = BaseFormatObjectAttributes(&LocalObjectAttributes,
lpThreadAttributes, lpThreadAttributes,
NULL); NULL);
@ -217,10 +243,10 @@ CreateRemoteThread(IN HANDLE hProcess,
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
/* Fail */ /* Fail */
ERROR_DBGBREAK("SXS: %s - Failing thread create because " DPRINT1("SXS: %s - Failing thread create because "
"NtQueryInformationThread() failed with status %08lx\n", "NtQueryInformationThread() failed with status %08lx\n",
__FUNCTION__, Status); __FUNCTION__, Status);
return NULL; goto Quit;
} }
/* Allocate the Activation Context Stack */ /* Allocate the Activation Context Stack */
@ -228,10 +254,10 @@ CreateRemoteThread(IN HANDLE hProcess,
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
/* Fail */ /* Fail */
ERROR_DBGBREAK("SXS: %s - Failing thread create because " DPRINT1("SXS: %s - Failing thread create because "
"RtlAllocateActivationContextStack() failed with status %08lx\n", "RtlAllocateActivationContextStack() failed with status %08lx\n",
__FUNCTION__, Status); __FUNCTION__, Status);
return NULL; goto Quit;
} }
/* Save it */ /* Save it */
@ -249,15 +275,10 @@ CreateRemoteThread(IN HANDLE hProcess,
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
/* Fail */ /* Fail */
ERROR_DBGBREAK("SXS: %s - Failing thread create because " DPRINT1("SXS: %s - Failing thread create because "
"RtlQueryInformationActivationContext() failed with status %08lx\n", "RtlQueryInformationActivationContext() failed with status %08lx\n",
__FUNCTION__, Status); __FUNCTION__, Status);
goto Quit;
/* Free the activation context stack */
// RtlFreeThreadActivationContextStack();
RtlFreeActivationContextStack(Teb->ActivationContextStackPointer);
return NULL;
} }
/* Does it need to be activated? */ /* Does it need to be activated? */
@ -271,24 +292,21 @@ CreateRemoteThread(IN HANDLE hProcess,
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
/* Fail */ /* Fail */
ERROR_DBGBREAK("SXS: %s - Failing thread create because " DPRINT1("SXS: %s - Failing thread create because "
"RtlActivateActivationContextEx() failed with status %08lx\n", "RtlActivateActivationContextEx() failed with status %08lx\n",
__FUNCTION__, Status); __FUNCTION__, Status);
goto Quit;
/* Free the activation context stack */
// RtlFreeThreadActivationContextStack();
RtlFreeActivationContextStack(Teb->ActivationContextStackPointer);
return NULL;
} }
} }
/* Sync the service tag with the parent thread's one */
Teb->SubProcessTag = NtCurrentTeb()->SubProcessTag;
} }
/* Notify CSR */ /* Notify CSR */
if (!BaseRunningInServerProcess) if (!BaseRunningInServerProcess)
{ {
Status = BasepNotifyCsrOfThread(hThread, &ClientId); Status = BasepNotifyCsrOfThread(hThread, &ClientId);
ASSERT(NT_SUCCESS(Status));
} }
else else
{ {
@ -304,16 +322,35 @@ CreateRemoteThread(IN HANDLE hProcess,
{ {
/* Call it instead of going through LPC */ /* Call it instead of going through LPC */
Status = CsrCreateRemoteThread(hThread, &ClientId); Status = CsrCreateRemoteThread(hThread, &ClientId);
ASSERT(NT_SUCCESS(Status));
} }
} }
} }
Quit:
if (!NT_SUCCESS(Status))
{
/* Failed to create the thread */
/* Free the activation context stack */
if (ActivationContextStack)
RtlFreeActivationContextStack(ActivationContextStack);
NtTerminateThread(hThread, Status);
// FIXME: Wait for the thread to terminate?
BaseFreeThreadStack(hProcess, &InitialTeb);
NtClose(hThread);
BaseSetLastNTError(Status);
return NULL;
}
/* Success */ /* Success */
if (lpThreadId) *lpThreadId = HandleToUlong(ClientId.UniqueThread); if (lpThreadId)
*lpThreadId = HandleToUlong(ClientId.UniqueThread);
/* Resume it if asked */ /* Resume the thread if asked */
if (!(dwCreationFlags & CREATE_SUSPENDED)) NtResumeThread(hThread, &Dummy); if (!(dwCreationFlags & CREATE_SUSPENDED))
NtResumeThread(hThread, &Dummy);
/* Return handle to thread */ /* Return handle to thread */
return hThread; return hThread;