[RTL/x64][NTOS:KE/x64] Fix RtlInitializeContext

- In RtlInitializeContext only set the registers required, don't offset RSP
- In KiInitializeContextThread force control segments, which are not set by RtlInitializeContext
- Allocate the stack home space in KiInitializeContextThread
- Fix BaseInitializeContext to work with the changed stack adjustments
This commit is contained in:
Timo Kreuzer
2026-08-01 11:05:47 +00:00
parent 39ea28d4c6
commit 652403caf2
3 changed files with 40 additions and 39 deletions
+1 -1
View File
@@ -588,7 +588,7 @@ BaseInitializeContext(IN PCONTEXT Context,
/* Setup the Initial Win32 Thread Context */
Context->Rcx = (ULONG_PTR)StartAddress;
Context->Rdx = (ULONG_PTR)Parameter;
Context->Rsp = (ULONG_PTR)StackAddress - 5 * sizeof(PVOID);
Context->Rsp = (ULONG_PTR)StackAddress;
/* Setup the Segments */
Context->SegGs = KGDT64_R3_DATA | RPL_MASK;
+12 -4
View File
@@ -116,10 +116,15 @@ KiInitializeContextThread(IN PKTHREAD Thread,
CONTEXT_AMD64 | ContextFlags,
UserMode);
/* Set SS, DS, ES's RPL Mask properly */
TrapFrame->SegSs |= RPL_MASK;
TrapFrame->SegDs |= RPL_MASK;
TrapFrame->SegEs |= RPL_MASK;
/* Set user mode segment selectors */
TrapFrame->SegDs = KGDT64_R3_DATA | RPL_MASK;
TrapFrame->SegEs = KGDT64_R3_DATA | RPL_MASK;
TrapFrame->SegFs = KGDT64_R3_CMTEB | RPL_MASK;
TrapFrame->SegGs = KGDT64_R3_DATA | RPL_MASK;
TrapFrame->SegCs = KGDT64_R3_CODE | RPL_MASK;
TrapFrame->SegSs = KGDT64_R3_DATA | RPL_MASK;
/* Clear DR7 */
TrapFrame->Dr7 = 0;
/* Set the previous mode as user */
@@ -133,6 +138,9 @@ KiInitializeContextThread(IN PKTHREAD Thread,
/* KiUserThreadStartupExit returns to KiServiceExit3 */
InitFrame->ExceptionFrame.Return = (ULONG64)KiServiceExit3;
/* Allocate home space on the stack */
TrapFrame->Rsp -= 5 * sizeof(PVOID);
}
else
{
+27 -34
View File
@@ -27,16 +27,15 @@ RtlInitializeContext(
_In_ PTHREAD_START_ROUTINE ThreadStartAddress,
_In_ PVOID StackBase)
{
/* Initialize everything to 0 */
RtlZeroMemory(ThreadContext, sizeof(*ThreadContext));
/* Make sure the stack is aligned */
if (((ULONG_PTR)StackBase & 0xF) != 0)
{
RtlRaiseStatus(STATUS_BAD_INITIAL_STACK);
}
/* Initialize StartAddress and Stack */
ThreadContext->Rip = (ULONG64)ThreadStartAddress;
ThreadContext->Rsp = (ULONG64)StackBase - 6 * sizeof(PVOID);
/* Align stack by 16 and substract 8 (unaligned on function entry) */
ThreadContext->Rsp &= ~15;
ThreadContext->Rsp -= 8;
ThreadContext->Rsp = (ULONG64)StackBase;
/* Enable Interrupts */
ThreadContext->EFlags = EFLAGS_INTERRUPT_MASK;
@@ -44,35 +43,29 @@ RtlInitializeContext(
/* Set start parameter */
ThreadContext->Rcx = (ULONG64)ThreadStartParam;
/* Set the Selectors */
if ((LONG64)ThreadStartAddress < 0)
{
/* Initialize kernel mode segments */
ThreadContext->SegCs = KGDT64_R0_CODE;
ThreadContext->SegDs = KGDT64_R3_DATA;
ThreadContext->SegEs = KGDT64_R3_DATA;
ThreadContext->SegFs = KGDT64_R3_CMTEB;
ThreadContext->SegGs = KGDT64_R3_DATA;
ThreadContext->SegSs = KGDT64_R0_DATA;
}
else
{
/* Initialize user mode segments */
ThreadContext->SegCs = KGDT64_R3_CODE | RPL_MASK;
ThreadContext->SegDs = KGDT64_R3_DATA | RPL_MASK;
ThreadContext->SegEs = KGDT64_R3_DATA | RPL_MASK;
ThreadContext->SegFs = KGDT64_R3_CMTEB | RPL_MASK;
ThreadContext->SegGs = KGDT64_R3_DATA | RPL_MASK;
ThreadContext->SegSs = KGDT64_R3_DATA | RPL_MASK;
}
/* Initialize floating point and SSE state */
RtlZeroMemory(&ThreadContext->FltSave, sizeof(ThreadContext->FltSave));
ThreadContext->MxCsr = INITIAL_MXCSR;
ThreadContext->FltSave.MxCsr = INITIAL_MXCSR;
ThreadContext->FltSave.ControlWord = INITIAL_FPCSR;
/* Only the basic Context is initialized */
ThreadContext->ContextFlags = CONTEXT_CONTROL |
CONTEXT_INTEGER |
CONTEXT_SEGMENTS |
CONTEXT_FLOATING_POINT;
/* Initialize integer registers */
ThreadContext->Rbp = 0x0000000000000000ull;
ThreadContext->Rax = 0x0000000000000000ull;
ThreadContext->Rbx = 0x0000000000000001ull;
ThreadContext->Rsi = 0x0000000000000004ull;
ThreadContext->Rdi = 0x0000000000000005ull;
ThreadContext->R8 = 0x0000000000000008ull;
ThreadContext->R9 = 0xF0E0D0C0A0908070ull;
ThreadContext->R10 = 0x000000000000000Aull;
ThreadContext->R11 = 0x000000000000000Bull;
ThreadContext->R12 = 0x000000000000000Cull;
ThreadContext->R13 = 0x000000000000000Dull;
ThreadContext->R14 = 0x000000000000000Eull;
ThreadContext->R15 = 0x000000000000000Full;
/* Set the context flags */
ThreadContext->ContextFlags = CONTEXT_FULL;
return;
}