aboutsummaryrefslogtreecommitdiff
path: root/EfiGuardDxe
diff options
context:
space:
mode:
authorMatthijs Lavrijsen <mattiwatti@gmail.com>2023-03-16 01:59:12 +0100
committerMatthijs Lavrijsen <mattiwatti@gmail.com>2023-03-16 18:02:47 +0100
commit2f4a666beb2256d7e849adc2862c7cd1c614971b (patch)
tree757b2d79bf1b10262eca49a71c61c9157df127d9 /EfiGuardDxe
parent741686c176775024ebc06f8ade2e198a30d65020 (diff)
EfiGuardDxe: disable VBS for the current boot
This prevents a bugcheck on Windows 10 and later when VBS is enabled, which was made the default setting in Windows 11. Additionally, EfiDSEFix will not proceed if it detects that VBS is still unexpectedly running (meaning either EfiGuardDxe was never loaded, or it failed to disable VBS). Fixes #59
Diffstat (limited to 'EfiGuardDxe')
-rw-r--r--EfiGuardDxe/PatchWinload.c57
1 files changed, 55 insertions, 2 deletions
diff --git a/EfiGuardDxe/PatchWinload.c b/EfiGuardDxe/PatchWinload.c
index e5bfd76..c231868 100644
--- a/EfiGuardDxe/PatchWinload.c
+++ b/EfiGuardDxe/PatchWinload.c
@@ -33,6 +33,15 @@ STATIC CONST UINT8 SigBlStatusPrint[] = {
0x74, 0xCC // jz XX
};
+// EFI vendor GUID used by Microsoft
+STATIC CONST EFI_GUID MicrosoftVendorGuid = {
+ 0x77fa9abd, 0x0359, 0x4d32, { 0xbd, 0x60, 0x28, 0xf4, 0xe7, 0x8f, 0x78, 0x4b }
+};
+
+// EFI variable used to set VBS enablement. Set by SecConfig.efi when disabling VBS/IUM,
+// read (and then deleted) by winload.efi during boot
+STATIC CONST CHAR16 VbsPolicyDisabledVariableName[] = L"VbsPolicyDisabled";
+
NTSTATUS
EFIAPI
@@ -71,6 +80,45 @@ GetBootLoadedModule(
}
//
+// Disables VBS for this boot
+//
+STATIC
+EFI_STATUS
+EFIAPI
+DisableVbs(
+ VOID
+ )
+{
+ CONST BOOLEAN Disabled = TRUE;
+ UINT32 Attributes;
+ UINTN Size = 0;
+
+ // Clear VbsPolicyDisabled variable if needed
+ EFI_STATUS Status = gRT->GetVariable((CHAR16*)VbsPolicyDisabledVariableName,
+ (EFI_GUID*)&MicrosoftVendorGuid,
+ &Attributes,
+ &Size,
+ NULL);
+ if (Status != EFI_NOT_FOUND &&
+ (Attributes != (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS) || Size != sizeof(Disabled)))
+ {
+ gRT->SetVariable((CHAR16*)VbsPolicyDisabledVariableName,
+ (EFI_GUID*)&MicrosoftVendorGuid,
+ 0,
+ 0,
+ NULL);
+ }
+
+ // Write the new value
+ Status = gRT->SetVariable((CHAR16*)VbsPolicyDisabledVariableName,
+ (EFI_GUID*)&MicrosoftVendorGuid,
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
+ sizeof(Disabled),
+ (BOOLEAN*)&Disabled);
+ return Status;
+}
+
+//
// winload.efi!OslFwpKernelSetupPhase1 hook to patch ntoskrnl.exe
//
EFI_STATUS
@@ -594,9 +642,9 @@ PatchWinload(
ASSERT(CodeSection != NULL);
ASSERT(PatternSection != NULL);
- // (Optional) On Windows 10, find winload!BlStatusPrint
if (BuildNumber >= 10240)
{
+ // (Optional) find winload!BlStatusPrint
gBlStatusPrint = (t_BlStatusPrint)GetProcedureAddress((UINTN)ImageBase, NtHeaders, "BlStatusPrint");
if (gBlStatusPrint == NULL)
{
@@ -613,6 +661,11 @@ PatchWinload(
Print(L"\r\nWARNING: winload!BlStatusPrint not found. No boot debugger output will be available.\r\n");
}
}
+
+ // Disable VBS for the duration of this boot
+ Status = DisableVbs();
+ if (EFI_ERROR(Status))
+ Print(L"\r\nWARNING: failed to set EFI runtime variable \"%ls\" in order to disable VBS.\r\n", VbsPolicyDisabledVariableName);
}
// Find winload!OslFwpKernelSetupPhase1
@@ -620,7 +673,7 @@ PatchWinload(
NtHeaders,
CodeSection,
PatternSection,
- (BOOLEAN)(BuildNumber >= 10240),
+ BuildNumber >= 10240,
(UINT8**)&gOriginalOslFwpKernelSetupPhase1);
if (EFI_ERROR(Status))
{