aboutsummaryrefslogtreecommitdiff
path: root/EfiGuardDxe
diff options
context:
space:
mode:
authorMattiwatti <mattiwatti@gmail.com>2020-05-07 19:26:14 +0200
committerMattiwatti <mattiwatti@gmail.com>2020-05-07 19:26:14 +0200
commite2ca738346e9d7f1b3758ee686d8ec7575af9b90 (patch)
tree03260e769e61841261e8f2caa0d586c4d1f6d135 /EfiGuardDxe
parent222d5e3b27597194018e7a272d40cd753d425836 (diff)
Patch nt!KiVerifyScopesExecute on Windows >= 8.1
Diffstat (limited to 'EfiGuardDxe')
-rw-r--r--EfiGuardDxe/PatchNtoskrnl.c44
1 files changed, 44 insertions, 0 deletions
diff --git a/EfiGuardDxe/PatchNtoskrnl.c b/EfiGuardDxe/PatchNtoskrnl.c
index 7ea8d86..7cbb77d 100644
--- a/EfiGuardDxe/PatchNtoskrnl.c
+++ b/EfiGuardDxe/PatchNtoskrnl.c
@@ -27,6 +27,14 @@ STATIC CONST UINT8 SigKeInitAmd64SpecificState[] = {
0x41, 0xF7, 0xF8 // idiv r8d
};
+// Signature for nt!KiVerifyScopesExecute
+// This function is present since Windows 8.1 and is responsible for executing all functions in the KiVerifyXcptRoutines array.
+// One of these functions, KiVerifyXcpt15, will indirectly initialize a PatchGuard context from its exception handler.
+STATIC CONST UINT8 SigKiVerifyScopesExecute[] = {
+ 0x48, 0x83, 0xCC, 0xCC, 0x00, // and [REG+XX], 0
+ 0x48, 0xB8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE // mov rax, 0FEFFFFFFFFFFFFFFh
+};
+
// Signature for nt!KiSwInterrupt
// This function is present since Windows 10 and is the interrupt handler for int 20h.
// This interrupt is a spurious interrupt on older versions of Windows, and does nothing useful on Windows 10.
@@ -240,6 +248,35 @@ DisablePatchGuard(
}
}
+ // Search for KiVerifyScopesExecute (only exists on Windows >= 8.1)
+ UINT8* KiVerifyScopesExecute = NULL;
+ if (BuildNumber >= 9600)
+ {
+ PRINT_KERNEL_PATCH_MSG(L"== Searching for nt!KiVerifyScopesExecute pattern in INIT ==\r\n");
+ UINT8* KiVerifyScopesExecutePatternAddress = NULL;
+ CONST EFI_STATUS FindKiVerifyScopesExecuteStatus = FindPattern(SigKiVerifyScopesExecute,
+ 0xCC,
+ sizeof(SigKiVerifyScopesExecute),
+ (VOID*)StartVa,
+ SizeOfRawData,
+ (VOID**)&KiVerifyScopesExecutePatternAddress);
+ if (EFI_ERROR(FindKiVerifyScopesExecuteStatus))
+ {
+ PRINT_KERNEL_PATCH_MSG(L" Failed to find KiVerifyScopesExecute pattern.\r\n");
+ return EFI_NOT_FOUND;
+ }
+ PRINT_KERNEL_PATCH_MSG(L" Found KiVerifyScopesExecute pattern at 0x%llX.\r\n", (UINTN)KiVerifyScopesExecutePatternAddress);
+
+ // Backtrack to function start
+ KiVerifyScopesExecute = BacktrackToFunctionStart(KiVerifyScopesExecutePatternAddress,
+ (UINT8*)(KiVerifyScopesExecutePatternAddress - StartVa));
+ if (KiVerifyScopesExecute == NULL)
+ {
+ PRINT_KERNEL_PATCH_MSG(L" Failed to find KiVerifyScopesExecute.\r\n");
+ return EFI_NOT_FOUND;
+ }
+ }
+
// Search for KiSwInterrupt (only exists on Windows >= 10)
UINT8* KiSwInterruptPatternAddress = NULL;
if (BuildNumber >= 10240)
@@ -274,6 +311,8 @@ DisablePatchGuard(
*((UINT32*)CcInitializeBcbProfiler) = Yes;
if (ExpLicenseWatchInitWorker != NULL)
*((UINT32*)ExpLicenseWatchInitWorker) = No;
+ if (KiVerifyScopesExecute != NULL)
+ *(UINT32*)KiVerifyScopesExecute = No;
if (KiSwInterruptPatternAddress != NULL)
SetMem(KiSwInterruptPatternAddress, sizeof(SigKiSwInterrupt), 0x90); // 11 x nop
@@ -287,6 +326,11 @@ DisablePatchGuard(
PRINT_KERNEL_PATCH_MSG(L" Patched ExpLicenseWatchInitWorker [RVA: 0x%X].\r\n",
(UINT32)(ExpLicenseWatchInitWorker - ImageBase));
}
+ if (KiVerifyScopesExecute != NULL)
+ {
+ PRINT_KERNEL_PATCH_MSG(L" Patched KiVerifyScopesExecute [RVA: 0x%X].\r\n",
+ (UINT32)(KiVerifyScopesExecute - ImageBase));
+ }
if (KiSwInterruptPatternAddress != NULL)
{
PRINT_KERNEL_PATCH_MSG(L" Patched KiSwInterrupt [RVA: 0x%X].\r\n",