/* FUNCTIONS *****************************************************************/
+/*
+ * @implemented
+ */
VOID STDCALL
KeAttachProcess (PEPROCESS Process)
{
KIRQL oldlvl;
PETHREAD CurrentThread;
+ PULONG AttachedProcessPageDir;
ULONG PageDir;
DPRINT("KeAttachProcess(Process %x)\n",Process);
if (CurrentThread->OldProcess != NULL)
{
DbgPrint("Invalid attach (thread is already attached)\n");
- KeBugCheck(0);
+ KEBUGCHECK(0);
}
KeRaiseIrql(DISPATCH_LEVEL, &oldlvl);
-
+
+ /* The stack of the current process may be located in a page which is
+ not present in the page directory of the process we're attaching to.
+ That would lead to a page fault when this function returns. However,
+ since the processor can't call the page fault handler 'cause it can't
+ push EIP on the stack, this will show up as a stack fault which will
+ crash the entire system.
+ To prevent this, make sure the page directory of the process we're
+ attaching to is up-to-date. */
+
+ AttachedProcessPageDir = ExAllocatePageWithPhysPage(Process->Pcb.DirectoryTableBase);
+ MmUpdateStackPageDir(AttachedProcessPageDir, &CurrentThread->Tcb);
+ ExUnmapPage(AttachedProcessPageDir);
+
CurrentThread->OldProcess = PsGetCurrentProcess();
CurrentThread->ThreadsProcess = Process;
- PageDir = CurrentThread->ThreadsProcess->Pcb.DirectoryTableBase.u.LowPart;
+ PageDir = Process->Pcb.DirectoryTableBase.u.LowPart;
DPRINT("Switching process context to %x\n",PageDir)
__asm__("movl %0,%%cr3\n\t"
- : /* no inputs */
+ : /* no outputs */
: "r" (PageDir));
KeLowerIrql(oldlvl);
}
+/*
+ * @implemented
+ */
VOID STDCALL
KeDetachProcess (VOID)
{
if (CurrentThread->OldProcess == NULL)
{
DbgPrint("Invalid detach (thread was not attached)\n");
- KeBugCheck(0);
+ KEBUGCHECK(0);
}
KeRaiseIrql(DISPATCH_LEVEL, &oldlvl);