diff options
Diffstat (limited to 'EfiGuardDxe/EfiGuardDxe.c')
-rw-r--r-- | EfiGuardDxe/EfiGuardDxe.c | 107 |
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, |