aboutsummaryrefslogtreecommitdiff
path: root/EfiGuardDxe/EfiGuardDxe.c
diff options
context:
space:
mode:
Diffstat (limited to 'EfiGuardDxe/EfiGuardDxe.c')
-rw-r--r--EfiGuardDxe/EfiGuardDxe.c107
1 files changed, 56 insertions, 51 deletions
diff --git a/EfiGuardDxe/EfiGuardDxe.c b/EfiGuardDxe/EfiGuardDxe.c
index 170a433..74dbf37 100644
--- a/EfiGuardDxe/EfiGuardDxe.c
+++ b/EfiGuardDxe/EfiGuardDxe.c
@@ -54,6 +54,7 @@ EFI_HANDLE gBootmgfwHandle = NULL;
//
// EFI runtime globals
//
+EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL* gTextInputEx = NULL;
EFI_EVENT gEfiExitBootServicesEvent = NULL;
BOOLEAN gEfiAtRuntime = FALSE;
EFI_EVENT gEfiVirtualNotifyEvent = NULL;
@@ -155,8 +156,7 @@ HookedLoadImage(
// We only have a filename to go on at this point. We will determine the final 'is this bootmgfw.efi?' status after the image has been loaded
CONST BOOLEAN MaybeBootmgfw = ImagePath != NULL
- ? (StrStr(ImagePath, L"bootmgfw.efi") != NULL || StrStr(ImagePath, L"BOOTMGFW.EFI") != NULL ||
- StrStr(ImagePath, L"bootx64.efi") != NULL || StrStr(ImagePath, L"BOOTX64.EFI") != NULL)
+ ? StriStr(ImagePath, L"bootmgfw.efi") != NULL || StriStr(ImagePath, L"Bootmgfw_ms.vc") != NULL || StriStr(ImagePath, L"bootx64.efi") != NULL
: FALSE;
CONST BOOLEAN IsBoot = (MaybeBootmgfw || (BootPolicy == TRUE && SourceBuffer == NULL));
@@ -220,11 +220,6 @@ HookedLoadImage(
LoadedImage->ImageBase,
LoadedImage->ImageSize);
}
- else
- {
- // A non-Windows OS is being booted. Unload ourselves
- EfiGuardUnload(gImageHandle);
- }
}
}
@@ -248,7 +243,12 @@ HookedSetVariable(
)
{
// We should not be hooking the runtime table after ExitBootServices() unless this is the selected DSE bypass method
- ASSERT(!gEfiAtRuntime || gDriverConfig.DseBypassMethod == DSE_DISABLE_SETVARIABLE_HOOK);
+ ASSERT(!gEfiAtRuntime || (gDriverConfig.DseBypassMethod == DSE_DISABLE_SETVARIABLE_HOOK && gBootmgfwHandle != NULL));
+
+ if (StrCmp(VariableName, L"SecureBoot") == 0)
+ {
+ return EFI_WRITE_PROTECTED;
+ }
// Do we have a match for the variable name and vendor GUID?
if (gEfiAtRuntime && gEfiGoneVirtual &&
@@ -274,52 +274,52 @@ HookedSetVariable(
BackdoorData->Size > 0 &&
(UINTN)BackdoorData->KernelAddress >= (UINTN)MM_SYSTEM_RANGE_START)
{
- if (BackdoorData->IsMemCopy && BackdoorData->u.UserBuffer != NULL)
- {
- if (BackdoorData->IsReadOperation) // Copy kernel buffer to user address
- CopyMem(BackdoorData->u.UserBuffer, BackdoorData->KernelAddress, BackdoorData->Size);
- else // Copy user buffer to kernel address
- CopyMem(BackdoorData->KernelAddress, BackdoorData->u.UserBuffer, BackdoorData->Size);
- }
- else
+ // For scalars, copy user value to kernel memory and put the old value in BackdoorData->u.XXX
+ switch (BackdoorData->Size)
{
- // Copy user scalar to kernel memory, and put the old value in BackdoorData->u.XXX
- switch (BackdoorData->Size)
+ case 1:
{
- case 1:
- {
- CONST UINT8 NewByte = (UINT8)BackdoorData->u.s.Byte;
- BackdoorData->u.s.Byte = *(UINT8*)BackdoorData->KernelAddress;
- if (!BackdoorData->IsReadOperation)
- *(UINT8*)BackdoorData->KernelAddress = NewByte;
- break;
- }
- case 2:
- {
- CONST UINT16 NewWord = (UINT16)BackdoorData->u.s.Word;
- BackdoorData->u.s.Word = *(UINT16*)BackdoorData->KernelAddress;
- if (!BackdoorData->IsReadOperation)
- *(UINT16*)BackdoorData->KernelAddress = NewWord;
- break;
- }
- case 4:
- {
- CONST UINT32 NewDword = (UINT32)BackdoorData->u.s.Dword;
- BackdoorData->u.s.Dword = *(UINT32*)BackdoorData->KernelAddress;
- if (!BackdoorData->IsReadOperation)
- *(UINT32*)BackdoorData->KernelAddress = NewDword;
- break;
- }
- case 8:
+ CONST UINT8 NewByte = (UINT8)BackdoorData->u.s.Byte;
+ BackdoorData->u.s.Byte = *(UINT8*)BackdoorData->KernelAddress;
+ if (!BackdoorData->ReadOnly)
+ CopyWpMem(BackdoorData->KernelAddress, &NewByte, sizeof(NewByte));
+ break;
+ }
+ case 2:
+ {
+ CONST UINT16 NewWord = (UINT16)BackdoorData->u.s.Word;
+ BackdoorData->u.s.Word = *(UINT16*)BackdoorData->KernelAddress;
+ if (!BackdoorData->ReadOnly)
+ CopyWpMem(BackdoorData->KernelAddress, &NewWord, sizeof(NewWord));
+ break;
+ }
+ case 4:
+ {
+ CONST UINT32 NewDword = (UINT32)BackdoorData->u.s.Dword;
+ BackdoorData->u.s.Dword = *(UINT32*)BackdoorData->KernelAddress;
+ if (!BackdoorData->ReadOnly)
+ CopyWpMem(BackdoorData->KernelAddress, &NewDword, sizeof(NewDword));
+ break;
+ }
+ case 8:
+ {
+ CONST UINT64 NewQword = BackdoorData->u.Qword;
+ BackdoorData->u.Qword = *(UINT64*)BackdoorData->KernelAddress;
+ if (!BackdoorData->ReadOnly)
+ CopyWpMem(BackdoorData->KernelAddress, &NewQword, sizeof(NewQword));
+ break;
+ }
+ default:
+ {
+ // Arbitrary size memcpy
+ if (BackdoorData->u.UserBuffer != NULL)
{
- CONST UINT64 NewQword = BackdoorData->u.Qword;
- BackdoorData->u.Qword = *(UINT64*)BackdoorData->KernelAddress;
- if (!BackdoorData->IsReadOperation)
- *(UINT64*)BackdoorData->KernelAddress = NewQword;
- break;
+ if (BackdoorData->ReadOnly)
+ CopyWpMem(BackdoorData->u.UserBuffer, BackdoorData->KernelAddress, BackdoorData->Size);
+ else
+ CopyWpMem(BackdoorData->KernelAddress, BackdoorData->u.UserBuffer, BackdoorData->Size);
}
- default:
- break; // Invalid size; do nothing
+ break;
}
}
@@ -402,7 +402,7 @@ ExitBootServicesEvent(
// If the DSE bypass method is *not* DSE_DISABLE_SETVARIABLE_HOOK, perform some cleanup now. In principle this should allow
// linking with /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER, because our driver image may be freed after this callback returns.
// Using DSE_DISABLE_SETVARIABLE_HOOK requires linking with /SUBSYSTEM:EFI_RUNTIME_DRIVER, because the image must not be freed.
- if (gDriverConfig.DseBypassMethod != DSE_DISABLE_SETVARIABLE_HOOK)
+ if (gDriverConfig.DseBypassMethod != DSE_DISABLE_SETVARIABLE_HOOK || gBootmgfwHandle == NULL)
{
// Uninstall our installed driver protocols
gBS->UninstallMultipleProtocolInterfaces(gImageHandle,
@@ -572,6 +572,11 @@ EfiGuardInitialize(
}
//
+ // Query the console input handle for the Simple Text Input Ex protocol
+ //
+ gBS->HandleProtocol(gST->ConsoleInHandle, &gEfiSimpleTextInputExProtocolGuid, (VOID **)&gTextInputEx);
+
+ //
// Install EfiGuard driver protocol
//
Status = gBS->InstallProtocolInterface(&gImageHandle,