From 433b6266c646d52b5756ee8faa90f8964ba1dde1 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Thu, 26 Jan 2012 21:16:59 +0000 Subject: [PATCH] Laa-a-a-a-dies and gentlemen..... For your unique, viewing and executing pleasure.. For one time only....by popular demand.... The one... The only... The unforgettable, unforgivable... Meanest, baddest, piece of code around... He's back..... with a vengeance... The ultimate... Mega... Uber.. Amazing... HACK OF DOOOOOOOOOOOOOOOOOOOOOOOOOOOOOM svn path=/trunk/; revision=55227 --- reactos/ntoskrnl/include/internal/mm.h | 14 ++++++++ reactos/ntoskrnl/ke/i386/thrdini.c | 3 ++ reactos/ntoskrnl/ke/procobj.c | 9 +++++ reactos/ntoskrnl/ke/thrdobj.c | 3 ++ reactos/ntoskrnl/ke/thrdschd.c | 6 ++++ reactos/ntoskrnl/mm/i386/page.c | 48 ++++++++++++++++++++++++++ reactos/ntoskrnl/mm/mmfault.c | 35 +++++++++++++++++++ 7 files changed, 118 insertions(+) diff --git a/reactos/ntoskrnl/include/internal/mm.h b/reactos/ntoskrnl/include/internal/mm.h index 09918a62af6..278b667f40e 100644 --- a/reactos/ntoskrnl/include/internal/mm.h +++ b/reactos/ntoskrnl/include/internal/mm.h @@ -6,6 +6,20 @@ struct _EPROCESS; +/* ReactOS Mm Hacks */ +VOID +FASTCALL +MiSyncForProcessAttach( + IN PKTHREAD NextThread, + IN PEPROCESS Process +); + +VOID +FASTCALL +MiSyncForContextSwitch( + IN PKTHREAD Thread +); + extern PMMSUPPORT MmKernelAddressSpace; extern PFN_COUNT MiFreeSwapPages; extern PFN_COUNT MiUsedSwapPages; diff --git a/reactos/ntoskrnl/ke/i386/thrdini.c b/reactos/ntoskrnl/ke/i386/thrdini.c index 8ee631428d1..cb120d39cb3 100644 --- a/reactos/ntoskrnl/ke/i386/thrdini.c +++ b/reactos/ntoskrnl/ke/i386/thrdini.c @@ -433,6 +433,9 @@ KiSwapContextEntry(IN PKSWITCHFRAME SwitchFrame, /* Get thread pointers */ OldThread = (PKTHREAD)(OldThreadAndApcFlag & ~3); NewThread = Pcr->PrcbData.CurrentThread; + + /* ReactOS Mm Hack */ + MiSyncForContextSwitch(NewThread); /* Get the old thread and set its kernel stack */ OldThread->KernelStack = SwitchFrame; diff --git a/reactos/ntoskrnl/ke/procobj.c b/reactos/ntoskrnl/ke/procobj.c index 7051c8241e1..c8de4f05f43 100644 --- a/reactos/ntoskrnl/ke/procobj.c +++ b/reactos/ntoskrnl/ke/procobj.c @@ -97,6 +97,9 @@ KiAttachProcess(IN PKTHREAD Thread, /* Release lock */ KiReleaseApcLockFromDpcLevel(ApcLock); + /* Make sure that we are in the right page directory (ReactOS Mm Hack) */ + MiSyncForProcessAttach(Thread, (PEPROCESS)Process); + /* Swap Processes */ KiSwapProcess(Process, SavedApcState->Process); @@ -615,6 +618,9 @@ KeDetachProcess(VOID) /* Release lock */ KiReleaseApcLockFromDpcLevel(&ApcLock); + /* Make sure that we are in the right page directory (ReactOS Mm Hack) */ + MiSyncForProcessAttach(Thread, (PEPROCESS)Process); + /* Swap Processes */ KiSwapProcess(Thread->ApcState.Process, Process); @@ -782,6 +788,9 @@ KeUnstackDetachProcess(IN PRKAPC_STATE ApcState) /* Release lock */ KiReleaseApcLockFromDpcLevel(&ApcLock); + /* Make sure that we are in the right page directory (ReactOS Mm Hack) */ + MiSyncForProcessAttach(Thread, (PEPROCESS)Process); + /* Swap Processes */ KiSwapProcess(Thread->ApcState.Process, Process); diff --git a/reactos/ntoskrnl/ke/thrdobj.c b/reactos/ntoskrnl/ke/thrdobj.c index cfccf0de1b2..686fbbbe4ad 100644 --- a/reactos/ntoskrnl/ke/thrdobj.c +++ b/reactos/ntoskrnl/ke/thrdobj.c @@ -856,6 +856,9 @@ KeInitThread(IN OUT PKTHREAD Thread, Thread->StackBase = KernelStack; Thread->StackLimit = (ULONG_PTR)KernelStack - KERNEL_STACK_SIZE; Thread->KernelStackResident = TRUE; + + /* Make sure that we are in the right page directory (ReactOS Mm Hack) */ + MiSyncForProcessAttach(Thread, (PEPROCESS)Process); /* Enter SEH to avoid crashes due to user mode */ Status = STATUS_SUCCESS; diff --git a/reactos/ntoskrnl/ke/thrdschd.c b/reactos/ntoskrnl/ke/thrdschd.c index ee418c7e7ef..b9a063846d3 100644 --- a/reactos/ntoskrnl/ke/thrdschd.c +++ b/reactos/ntoskrnl/ke/thrdschd.c @@ -394,6 +394,9 @@ KiSwapThread(IN PKTHREAD CurrentThread, /* Save the wait IRQL */ WaitIrql = CurrentThread->WaitIrql; + /* REACTOS Mm Hack of Doom */ + MiSyncForContextSwitch(NextThread); + /* Swap contexts */ ApcState = KiSwapContext(WaitIrql, CurrentThread); @@ -790,6 +793,9 @@ NtYieldExecution(VOID) /* Sanity check */ ASSERT(OldIrql <= DISPATCH_LEVEL); + /* REACTOS Mm Hack of Doom */ + MiSyncForContextSwitch(NextThread); + /* Swap to new thread */ KiSwapContext(APC_LEVEL, Thread); Status = STATUS_SUCCESS; diff --git a/reactos/ntoskrnl/mm/i386/page.c b/reactos/ntoskrnl/mm/i386/page.c index 9ebf1bd2b93..2b80afd0c4f 100644 --- a/reactos/ntoskrnl/mm/i386/page.c +++ b/reactos/ntoskrnl/mm/i386/page.c @@ -1028,6 +1028,54 @@ MmGetPhysicalAddress(PVOID vaddr) return p; } +VOID +NTAPI +MmUpdatePageDir(PEPROCESS Process, PVOID Address, ULONG Size) +{ + ULONG StartOffset, EndOffset, Offset; + PULONG Pde; + + // + // Check if the process isn't there anymore + // This is probably a bad sign, since it means the caller is setting cr3 to + // 0 or something... + // + if ((PTE_TO_PFN(Process->Pcb.DirectoryTableBase[0]) == 0) && (Process != PsGetCurrentProcess())) + { + DPRINT1("Process: %16s is dead: %p\n", Process->ImageFileName, Process->Pcb.DirectoryTableBase[0]); + ASSERT(FALSE); + return; + } + + if (Address < MmSystemRangeStart) + { + KeBugCheck(MEMORY_MANAGEMENT); + } + + StartOffset = ADDR_TO_PDE_OFFSET(Address); + EndOffset = ADDR_TO_PDE_OFFSET((PVOID)((ULONG_PTR)Address + Size)); + + if (Process != NULL && Process != PsGetCurrentProcess()) + { + Pde = MmCreateHyperspaceMapping(PTE_TO_PFN(Process->Pcb.DirectoryTableBase[0])); + } + else + { + Pde = (PULONG)PAGEDIRECTORY_MAP; + } + for (Offset = StartOffset; Offset <= EndOffset; Offset++) + { + if (Offset != ADDR_TO_PDE_OFFSET(PAGETABLE_MAP)) + { + InterlockedCompareExchangePte(&Pde[Offset], MmGlobalKernelPageDirectory[Offset], 0); + } + } + if (Pde != (PULONG)PAGEDIRECTORY_MAP) + { + MmDeleteHyperspaceMapping(Pde); + } +} + VOID INIT_FUNCTION NTAPI diff --git a/reactos/ntoskrnl/mm/mmfault.c b/reactos/ntoskrnl/mm/mmfault.c index b8628a8db25..c749f187232 100644 --- a/reactos/ntoskrnl/mm/mmfault.c +++ b/reactos/ntoskrnl/mm/mmfault.c @@ -20,6 +20,41 @@ /* PRIVATE FUNCTIONS **********************************************************/ +VOID +FASTCALL +MiSyncForProcessAttach(IN PKTHREAD Thread, + IN PEPROCESS Process) +{ + PETHREAD Ethread = CONTAINING_RECORD(Thread, ETHREAD, Tcb); + //DPRINT1("Hack sync for process: %p and thread: %p\n", Process, Thread); + //DPRINT1("Thread stack hack: %p %d\n", Thread->StackLimit, Thread->LargeStack); + + /* Hack Sync because Mm is broken */ + MmUpdatePageDir(Process, Ethread, sizeof(ETHREAD)); + MmUpdatePageDir(Process, Ethread->ThreadsProcess, sizeof(EPROCESS)); + MmUpdatePageDir(Process, + (PVOID)Thread->StackLimit, + Thread->LargeStack ? + KERNEL_LARGE_STACK_SIZE : KERNEL_STACK_SIZE); +} + +VOID +FASTCALL +MiSyncForContextSwitch(IN PKTHREAD Thread) +{ + PVOID Process = PsGetCurrentProcess(); + PETHREAD Ethread = CONTAINING_RECORD(Thread, ETHREAD, Tcb); + //DPRINT1("Hack sync for thread: %p and process: %p\n", Thread, Process); + //DPRINT1("Thread stack hack: %p %d\n", Thread->StackLimit, Thread->LargeStack); + + /* Hack Sync because Mm is broken */ + MmUpdatePageDir(Process, Ethread->ThreadsProcess, sizeof(EPROCESS)); + MmUpdatePageDir(Process, + (PVOID)Thread->StackLimit, + Thread->LargeStack ? + KERNEL_LARGE_STACK_SIZE : KERNEL_STACK_SIZE); +} + NTSTATUS NTAPI MmpAccessFault(KPROCESSOR_MODE Mode,