aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorToni Uhlig <matzeton@googlemail.com>2023-08-30 00:05:48 +0200
committerToni Uhlig <matzeton@googlemail.com>2024-10-25 12:31:15 +0200
commitd7cea90f607e6853c6cb5554cff249c2502a798b (patch)
treea3a4b4ffeddcef25f794627098520ca17e67dc31
parent584cb2e061e690d4ee5a7a415270ae5ceccdaf43 (diff)
Added partial PatchGuard disable at compile time with `-D EAC_COMPAT_MODE=1`.
* runtime DSE disabling still possible * compatible with EasyAntiCheat * no bsod so far Signed-off-by: Toni Uhlig <matzeton@googlemail.com>
-rw-r--r--EfiGuardDxe/PatchNtoskrnl.c15
-rw-r--r--EfiGuardPkg.dsc3
2 files changed, 16 insertions, 2 deletions
diff --git a/EfiGuardDxe/PatchNtoskrnl.c b/EfiGuardDxe/PatchNtoskrnl.c
index 6b390b6..fb0e2fc 100644
--- a/EfiGuardDxe/PatchNtoskrnl.c
+++ b/EfiGuardDxe/PatchNtoskrnl.c
@@ -2,6 +2,10 @@
#include <Library/BaseMemoryLib.h>
+#if defined(DO_NOT_DISABLE_PATCHGUARD) && defined(EAC_COMPAT_MODE)
+#error "Either DO_NOT_DISABLE_PATCHGUARD or EAC_COMPAT_MODE can be defined at the same time!"
+#endif
+
// Global kernel patch status information.
//
@@ -13,7 +17,7 @@
// because it allows the buffer to be accessed from both contexts at all stages of driver execution.
KERNEL_PATCH_INFORMATION gKernelPatchInfo;
-
+#ifndef DO_NOT_DISABLE_PATCHGUARD
// Signature for nt!KeInitAmd64SpecificState
// This function is present in all x64 kernels since Vista. It generates a #DE due to 32 bit idiv quotient overflow.
STATIC CONST UINT8 SigKeInitAmd64SpecificState[] = {
@@ -27,7 +31,6 @@ STATIC CONST UINT8 SigKeInitAmd64SpecificState[] = {
0x41, 0xF7, 0xF8 // idiv r8d
};
-#ifndef DO_NOT_DISABLE_PATCHGUARD
// 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.
@@ -36,6 +39,7 @@ STATIC CONST UINT8 SigKiVerifyScopesExecute[] = {
0x48, 0xB8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE // mov rax, 0FEFFFFFFFFFFFFFFh
};
+#ifndef EAC_COMPAT_MODE
// Signature for nt!KiMcaDeferredRecoveryService
// This function is present since Windows 8.1 and bugchecks the system with bugcode 0x109 after zeroing registers.
// It is called by KiScanQueues and KiSchedulerDpc, two PatchGuard DPCs which may be queued from various unrelated kernel functions.
@@ -59,6 +63,7 @@ STATIC CONST UINT8 SigKiSwInterrupt[] = {
};
STATIC CONST UINTN SigKiSwInterruptCallOffset = 5, SigKiSwInterruptCliOffset = 10;
#endif
+#endif
// Signature for nt!SeCodeIntegrityQueryInformation, called through NtQuerySystemInformation(SystemCodeIntegrityInformation).
// This function has actually existed since Vista in various forms, sometimes (8/8.1/early 10) inlined in ExpQuerySystemInformation.
@@ -288,6 +293,7 @@ DisablePatchGuard(
}
}
+#ifndef EAC_COMPAT_MODE
// Search for callers of KiMcaDeferredRecoveryService (only exists on Windows >= 8.1)
UINT8* KiMcaDeferredRecoveryServiceCallers[2];
ZeroMem(KiMcaDeferredRecoveryServiceCallers, sizeof(KiMcaDeferredRecoveryServiceCallers));
@@ -434,6 +440,7 @@ DisablePatchGuard(
}
}
}
+#endif
// We have all the addresses we need; now do the actual patching.
CONST UINT32 Yes = 0xC301B0; // mov al, 1, ret
@@ -444,6 +451,7 @@ DisablePatchGuard(
CopyWpMem(ExpLicenseWatchInitWorker, &No, sizeof(No));
if (KiVerifyScopesExecute != NULL)
CopyWpMem(KiVerifyScopesExecute, &No, sizeof(No));
+#ifndef EAC_COMPAT_MODE
if (KiMcaDeferredRecoveryServiceCallers[0] != NULL && KiMcaDeferredRecoveryServiceCallers[1] != NULL)
{
CopyWpMem(KiMcaDeferredRecoveryServiceCallers[0], &No, sizeof(No));
@@ -458,6 +466,7 @@ DisablePatchGuard(
{
SetWpMem(KiSwInterruptPatternAddress, sizeof(SigKiSwInterrupt), 0x90); // 11 x nop
}
+#endif
// Print info
PRINT_KERNEL_PATCH_MSG(L"\r\n Patched KeInitAmd64SpecificState [RVA: 0x%X].\r\n",
@@ -474,6 +483,7 @@ DisablePatchGuard(
PRINT_KERNEL_PATCH_MSG(L" Patched KiVerifyScopesExecute [RVA: 0x%X].\r\n",
(UINT32)(KiVerifyScopesExecute - ImageBase));
}
+#ifndef EAC_COMPAT_MODE
if (KiMcaDeferredRecoveryServiceCallers[0] != NULL && KiMcaDeferredRecoveryServiceCallers[1] != NULL)
{
PRINT_KERNEL_PATCH_MSG(L" Patched KiMcaDeferredRecoveryService [RVAs: 0x%X, 0x%X].\r\n",
@@ -490,6 +500,7 @@ DisablePatchGuard(
PRINT_KERNEL_PATCH_MSG(L" Patched KiSwInterrupt [RVA: 0x%X].\r\n",
(UINT32)(KiSwInterruptPatternAddress - ImageBase));
}
+#endif
return EFI_SUCCESS;
}
diff --git a/EfiGuardPkg.dsc b/EfiGuardPkg.dsc
index 92c8c14..2809196 100644
--- a/EfiGuardPkg.dsc
+++ b/EfiGuardPkg.dsc
@@ -92,6 +92,9 @@
!if $(DO_NOT_DISABLE_PATCHGUARD) == 1
*_*_*_CC_FLAGS = -D DO_NOT_DISABLE_PATCHGUARD=1
!endif
+!if $(EAC_COMPAT_MODE) == 1
+ *_*_*_CC_FLAGS = -D EAC_COMPAT_MODE=1
+!endif
# Source files are UTF-8 without BOM. MSVC will convert other encodings to this without asking, so this is not really a choice
MSFT:*_*_*_CC_FLAGS = /utf-8