Пример #1
0
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;
}
Пример #2
0
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;
}