EXTERN_C NTSTATUS WinXDisablePatchGuard( __in const WinXSymbols& Symbols) { // Based on the size of FsRtlMdlReadCompleteDevEx on each platform static const SIZE_T MIN_SIZE_FILTER_XP = 0x2000; static const SIZE_T MIN_SIZE_FILTER = 0x4000; g_WinXSymbols = Symbols; auto exclusivity = std::experimental::unique_resource( ExclGainExclusivity(), ExclReleaseExclusivity); if (!exclusivity) { return STATUS_UNSUCCESSFUL; } // Collects all PatchGuard contexts PatchGuardContexts contexts = {}; if (Symbols.PoolBigPageTableXp) { // For XP WinXpEnumBigPages(WinXpCollectPatchGuardContexts, &contexts, 0, MIN_SIZE_FILTER_XP, *g_WinXSymbols.PoolBigPageTableXp, *g_WinXSymbols.PoolBigPageTableSize); } else { // For 7 and Vista WinXpEnumBigPages(WinXpCollectPatchGuardContexts, &contexts, 0, MIN_SIZE_FILTER, *g_WinXSymbols.PoolBigPageTable, *g_WinXSymbols.PoolBigPageTableSize); } //DBG_BREAK(); DBG_PRINT("[%5Iu:%5Iu] Initialize : %Iu contexts found.\n", reinterpret_cast<ULONG_PTR>(PsGetCurrentProcessId()), reinterpret_cast<ULONG_PTR>(PsGetCurrentThreadId()), contexts.NumberOfPgContexts); auto status = STATUS_SUCCESS; if (!contexts.NumberOfPgContexts || contexts.NumberOfPgContexts == contexts.MAX_SUPPORTED_NUMBER_OF_PG_CONTEXTS) { // If a lot of PatchGuard contexts were found, it is likely an error status = STATUS_UNSUCCESSFUL; } else { // Install patches for all contexts for (SIZE_T i = 0; i < contexts.NumberOfPgContexts; ++i) { WinXpInstallPatchOnPatchGuardContext(contexts.PgContexts[i]); } } return status; }
EXTERN_C static NTSTATUS Win8pInstallHooks( __in const Win8Symbols& Symbols) { PAGED_CODE(); auto exclusivity = std::experimental::unique_resource( ExclGainExclusivity(), ExclReleaseExclusivity); if (!exclusivity) { return STATUS_UNSUCCESSFUL; } // Install hook on the end of KiCommitThreadWait and // KiAttemptFastRemovePriQueue to examine return value that may be a Work // Item queued by PatchGuard if (Symbols.KernelVersion == 16452) { Win8pInstallHook2( Symbols.KiCommitThreadWait + 0x12a, reinterpret_cast<ULONG_PTR>(AsmKiCommitThreadWait_16452)); } else if (Symbols.KernelVersion == 17041 || Symbols.KernelVersion == 17085) { Win8pInstallHook2( Symbols.KiCommitThreadWait + 0x12c, reinterpret_cast<ULONG_PTR>(AsmKiCommitThreadWait_17041)); } Win8pInstallHook2( Symbols.KiAttemptFastRemovePriQueue + 0x98, reinterpret_cast<ULONG_PTR>(AsmKiAttemptFastRemovePriQueue)); // Install hook on the beginning of Pg_IndependentContextWorkItemRoutine to // catch Independent PatchGuard contexts const auto pg_IndependentContextWorkItemRoutine = Symbols.HalPerformEndOfInterrupt - 0x4c; Win8pInstallHook( pg_IndependentContextWorkItemRoutine, pg_IndependentContextWorkItemRoutine + 0x14, reinterpret_cast<ULONG_PTR>(AsmPg_IndependentContextWorkItemRoutine), reinterpret_cast<ULONG_PTR>(AsmPg_IndependentContextWorkItemRoutineEnd)); // Install hook on the end of KeDelayExecutionThread and // KeWaitForSingleObject to examine a return address that may be somewhere // in PatchGuard functions. Win8pInstallHook2( Symbols.KeDelayExecutionThread + 0x6f, reinterpret_cast<ULONG_PTR>(AsmKeDelayExecutionThread)); if (Symbols.KernelVersion == 16452) { Win8pInstallHook2( Symbols.KeWaitForSingleObject + 0x1dd, reinterpret_cast<ULONG_PTR>(AsmKeWaitForSingleObject_16452)); } else if (Symbols.KernelVersion == 17041 || Symbols.KernelVersion == 17085) { Win8pInstallHook2( Symbols.KeWaitForSingleObject + 0x1c4, reinterpret_cast<ULONG_PTR>(AsmKeWaitForSingleObject_17041)); } return STATUS_SUCCESS; }