diff --git a/dll/win32/kernel32/client/utils.c b/dll/win32/kernel32/client/utils.c index 047fbec9fc2..32df2e1a0b6 100644 --- a/dll/win32/kernel32/client/utils.c +++ b/dll/win32/kernel32/client/utils.c @@ -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; diff --git a/ntoskrnl/ke/amd64/thrdini.c b/ntoskrnl/ke/amd64/thrdini.c index 612e1252df6..e6518e0bf82 100644 --- a/ntoskrnl/ke/amd64/thrdini.c +++ b/ntoskrnl/ke/amd64/thrdini.c @@ -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 { diff --git a/sdk/lib/rtl/amd64/stubs.c b/sdk/lib/rtl/amd64/stubs.c index 1b77d0d2b15..b68e41e5060 100644 --- a/sdk/lib/rtl/amd64/stubs.c +++ b/sdk/lib/rtl/amd64/stubs.c @@ -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; }