Example #1
0
// Modifies PatchGuard context (its value field and code) to disarm them.
// Note that this function is not necessary if you just want to stop PatchGuard.
// Thus, a lots of magic numbers in this function is just for presentation.
EXTERN_C static
void Win8pPatchPgContext(
    __inout PgContext_8_1* PgContext)
{
    // There are several condition checks in FsRtlMdlReadCompleteDevEx and
    // Pg_SelfValidation to see the result of validation check. Following
    // addresses are these addresses and will be modified.
    auto fsRtlUninitializeSmallMcb = reinterpret_cast<ULONG_PTR>(PgContext)
        + PgContext->offsetToFsUninitializeSmallMcbInBytes;
    auto fsRtlMdlReadCompleteDevEx = fsRtlUninitializeSmallMcb - 0xa000;
    auto fsResultCheck1 = fsRtlMdlReadCompleteDevEx + 0x90cd;
    auto fsResultCheck2 = fsRtlMdlReadCompleteDevEx + 0x92e1;
    auto pgSelfValidation = reinterpret_cast<ULONG_PTR>(PgContext)
        + PgContext->offsetToPg_SelfValidationInBytes;
    auto pgResultCheck = pgSelfValidation + 0x423;

    //DBG_BREAK();

    // Install patches on PatchGuard code
    static const UCHAR patch1[] =
    {
        WIN8_PG_CONTEXT_HOOK_ENTRY_CODE, 0x90, 0x90, 0x90, 0x90, 0x90,
    };
    PatchReal(reinterpret_cast<void*>(fsResultCheck1), patch1, sizeof(patch1));

    static const UCHAR patch2[] =
    {
        WIN8_PG_CONTEXT_HOOK_ENTRY_CODE, 0x0F, 0x85, 0x6D, 0x04,
    };
    PatchReal(reinterpret_cast<void*>(fsResultCheck2), patch2, sizeof(patch2));

    static const UCHAR patch3[] =
    {
        WIN8_PG_CONTEXT_HOOK_ENTRY_CODE, 0xe9, 0x09, 0x02,
    };
    PatchReal(reinterpret_cast<void*>(pgResultCheck), patch3, sizeof(patch3));


    // When ((the value & 2) == true), PatchGuard does self runtime
    // en(de)cryption. I do not want PatchGuard to do that for the sake of
    // debugging. It can be deleted.
    //PgContext->onTheFlyEnDecryptionFlag &= 0xFFFFFFFD;

    // When the value is not 0xFFFFFFFF, PatchGuard does Win32k verification.
    // I do not want PatchGuard to do that because when an error is detected
    // during Win32k validation, PatchGuard goes to BugCheck without calling
    // a necessary function (to be precise, MmDetachSession) to be a neutral
    // state.
    PgContext->checkWin32kIfNotNegativeOne = 0xFFFFFFFF;
}
Example #2
0
EXTERN_C static
void Win8pInstallHook2(
    __in ULONG_PTR PatchAddress,
    __in ULONG_PTR AsmHandler)
{
    UCHAR patchCode[] =
    {
        WIN8_HOOK_ENTRY_CODE,                                       // nop or int 3
        0x48, 0xbb, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // mov     rbx, 0FFFFFFFFFFFFFFFFh
        0xFF, 0xe3,                                                 // jmp     rbx
    };
    C_ASSERT(sizeof(patchCode) == 13);

    // Replace placeholder (0xffffffffffffffff) located at offset 3 of patchCode
    // with AsmHandler
    *reinterpret_cast<ULONG_PTR*>(patchCode + 3) = AsmHandler;

    // And install patch
    PatchReal(reinterpret_cast<void*>(PatchAddress), patchCode, sizeof(patchCode));
}
Example #3
0
EXTERN_C static
void WinXpInstallPatchForDecryptedPatchGuardContext(
    __in PatchGuardContextInfo& Info)
{
    // Do not do anything for a patched context, just in case.
    auto pgContext = reinterpret_cast<PgContextBase*>(Info.PgContext);
    if (WinXpIsPatchGuardContextPatched(*pgContext))
    {
        return;
    }

    // Install hook
    static const auto HEADER_SIZE =
        FIELD_OFFSET(PgContextBase, ExAcquireResourceSharedLite);
    const auto searchSizeInBytes =
        pgContext->ContextSizeInQWord * sizeof(ULONG64)+HEADER_SIZE;

    auto pgSdbpCheckDll = MemMem(pgContext, searchSizeInBytes,
        &WINX_SdbpCheckDll_PATTERN[0], sizeof(WINX_SdbpCheckDll_PATTERN));
    ASSERT(pgSdbpCheckDll);

    // Make r13 and r14 zero. These are used as PgContext pointer later, and if
    // values are zero, PatchGuard gracefully ends its activity.
    static const UCHAR PATCH_CODE[] =
    {
        WINX_HOOK_CODE,         // nop or int 3
        0x4D, 0x33, 0xED,       // xor     r13, r13
        0x4D, 0x33, 0xF6,       // xor     r14, r14
        0xc3,                   // ret
    };
    PatchReal(pgSdbpCheckDll, PATCH_CODE, sizeof(PATCH_CODE));

    // Also, install hook at CmpAppendDllSection because it may be called at
    // the next time as we disabled SdbpCheckDll.
    pgContext->CmpAppendDllSection[WINX_HOOK_OFFSET + 0] = WINX_HOOK_CODE;
    pgContext->CmpAppendDllSection[WINX_HOOK_OFFSET + 1] = 0xc3;   // RET
    ASSERT(WinXpIsPatchGuardContextPatched(*pgContext));
}