aboutsummaryrefslogtreecommitdiff
path: root/Application
diff options
context:
space:
mode:
Diffstat (limited to 'Application')
-rw-r--r--Application/EfiDSEFix/src/EfiDSEFix.cpp165
-rw-r--r--Application/EfiDSEFix/src/EfiDSEFix.exe.manifest2
-rw-r--r--Application/EfiDSEFix/src/EfiDSEFix.vcxproj10
-rw-r--r--Application/EfiDSEFix/src/main.cpp68
-rw-r--r--Application/EfiDSEFix/src/sysinfo.cpp6
-rw-r--r--Application/Loader/Loader.c288
-rw-r--r--Application/Loader/Loader.inf10
-rw-r--r--Application/Loader/Loader.vcxproj4
8 files changed, 309 insertions, 244 deletions
diff --git a/Application/EfiDSEFix/src/EfiDSEFix.cpp b/Application/EfiDSEFix/src/EfiDSEFix.cpp
index 924f759..03bfbba 100644
--- a/Application/EfiDSEFix/src/EfiDSEFix.cpp
+++ b/Application/EfiDSEFix/src/EfiDSEFix.cpp
@@ -31,11 +31,11 @@ FindKernelModule(
for (ULONG i = 0; i < Modules->NumberOfModules; ++i)
{
- RTL_PROCESS_MODULE_INFORMATION Module = Modules->Modules[i];
- if (_stricmp(ModuleName, reinterpret_cast<PCHAR>(Module.FullPathName) + Module.OffsetToFileName) == 0)
+ const PRTL_PROCESS_MODULE_INFORMATION Module = &Modules->Modules[i];
+ if (_stricmp(ModuleName, reinterpret_cast<PCHAR>(Module->FullPathName) + Module->OffsetToFileName) == 0)
{
- *ModuleBase = reinterpret_cast<ULONG_PTR>(Module.ImageBase);
- Status = Module.ImageBase == nullptr ? STATUS_NOT_FOUND : STATUS_SUCCESS;
+ *ModuleBase = reinterpret_cast<ULONG_PTR>(Module->ImageBase);
+ Status = Module->ImageBase == nullptr ? STATUS_NOT_FOUND : STATUS_SUCCESS;
break;
}
}
@@ -48,7 +48,7 @@ Exit:
// For Windows Vista/7. Credits: DSEFix by hfiref0x
static
LONG
-QueryCiEnabled(
+FindCiEnabled(
_In_ PVOID MappedBase,
_In_ SIZE_T SizeOfImage,
_In_ ULONG_PTR KernelBase,
@@ -73,7 +73,7 @@ QueryCiEnabled(
// For Windows 8 and worse. Credits: DSEFix by hfiref0x
static
LONG
-QueryCiOptions(
+FindCiOptions(
_In_ PVOID MappedBase,
_In_ ULONG_PTR CiDllBase,
_Out_ PULONG_PTR gCiOptionsAddress
@@ -183,34 +183,8 @@ QueryCiOptions(
}
static
-BOOLEAN
-QueryVbsEnabled(
- )
-{
- SYSTEM_CODEINTEGRITY_INFORMATION CodeIntegrityInfo = { sizeof(SYSTEM_CODEINTEGRITY_INFORMATION) };
- NTSTATUS Status = NtQuerySystemInformation(SystemCodeIntegrityInformation,
- &CodeIntegrityInfo,
- sizeof(CodeIntegrityInfo),
- nullptr);
- if (NT_SUCCESS(Status) &&
- (CodeIntegrityInfo.CodeIntegrityOptions & (CODEINTEGRITY_OPTION_HVCI_KMCI_ENABLED | CODEINTEGRITY_OPTION_HVCI_IUM_ENABLED)) != 0)
- return TRUE;
-
- SYSTEM_ISOLATED_USER_MODE_INFORMATION IumInfo = { 0 };
- Status = NtQuerySystemInformation(SystemIsolatedUserModeInformation,
- &IumInfo,
- sizeof(IumInfo),
- nullptr);
- if (NT_SUCCESS(Status) &&
- (IumInfo.SecureKernelRunning || IumInfo.HvciEnabled))
- return TRUE;
-
- return FALSE;
-}
-
-static
NTSTATUS
-AnalyzeCi(
+FindCiOptionsVariable(
_Out_ PVOID *CiOptionsAddress
)
{
@@ -243,7 +217,7 @@ AnalyzeCi(
goto Exit;
ULONG_PTR gCiOptionsAddress;
- const LONG Relative = QueryCiOptions(MappedBase, CiDllBase, &gCiOptionsAddress);
+ const LONG Relative = FindCiOptions(MappedBase, CiDllBase, &gCiOptionsAddress);
if (Relative != 0)
{
*CiOptionsAddress = reinterpret_cast<PVOID>(gCiOptionsAddress);
@@ -263,7 +237,7 @@ AnalyzeCi(
goto Exit;
ULONG_PTR gCiEnabledAddress;
- const LONG Relative = QueryCiEnabled(MappedBase, ViewSize, KernelBase, &gCiEnabledAddress);
+ const LONG Relative = FindCiEnabled(MappedBase, ViewSize, KernelBase, &gCiEnabledAddress);
if (Relative != 0)
{
*CiOptionsAddress = reinterpret_cast<PVOID>(gCiEnabledAddress);
@@ -281,47 +255,29 @@ Exit:
}
static
-NTSTATUS
-SetSystemEnvironmentPrivilege(
- _In_ BOOLEAN Enable,
- _Out_opt_ PBOOLEAN WasEnabled
- )
-{
- if (WasEnabled != nullptr)
- *WasEnabled = FALSE;
-
- BOOLEAN SeSystemEnvironmentWasEnabled;
- const NTSTATUS Status = RtlAdjustPrivilege(SE_SYSTEM_ENVIRONMENT_PRIVILEGE,
- Enable,
- FALSE,
- &SeSystemEnvironmentWasEnabled);
-
- if (NT_SUCCESS(Status) && WasEnabled != nullptr)
- *WasEnabled = SeSystemEnvironmentWasEnabled;
-
- return Status;
-}
-
-static
-NTSTATUS
-SetDebugPrivilege(
- _In_ BOOLEAN Enable,
- _Out_opt_ PBOOLEAN WasEnabled
+BOOLEAN
+IsVbsEnabled(
)
{
- if (WasEnabled != nullptr)
- *WasEnabled = FALSE;
-
- BOOLEAN SeDebugWasEnabled;
- const NTSTATUS Status = RtlAdjustPrivilege(SE_DEBUG_PRIVILEGE,
- Enable,
- FALSE,
- &SeDebugWasEnabled);
+ SYSTEM_CODEINTEGRITY_INFORMATION CodeIntegrityInfo = { sizeof(SYSTEM_CODEINTEGRITY_INFORMATION) };
+ NTSTATUS Status = NtQuerySystemInformation(SystemCodeIntegrityInformation,
+ &CodeIntegrityInfo,
+ sizeof(CodeIntegrityInfo),
+ nullptr);
+ if (NT_SUCCESS(Status) &&
+ (CodeIntegrityInfo.CodeIntegrityOptions & (CODEINTEGRITY_OPTION_HVCI_KMCI_ENABLED | CODEINTEGRITY_OPTION_HVCI_IUM_ENABLED)) != 0)
+ return TRUE;
- if (NT_SUCCESS(Status) && WasEnabled != nullptr)
- *WasEnabled = SeDebugWasEnabled;
+ SYSTEM_ISOLATED_USER_MODE_INFORMATION IumInfo = { 0 };
+ Status = NtQuerySystemInformation(SystemIsolatedUserModeInformation,
+ &IumInfo,
+ sizeof(IumInfo),
+ nullptr);
+ if (NT_SUCCESS(Status) &&
+ (IumInfo.SecureKernelRunning || IumInfo.HvciEnabled))
+ return TRUE;
- return Status;
+ return FALSE;
}
NTSTATUS
@@ -330,24 +286,9 @@ TestSetVariableHook(
{
UINT16 Mz;
- // Enable privileges in case we were called directly from the CLI with --check
- BOOLEAN SeSystemEnvironmentWasEnabled, SeDebugWasEnabled;
- NTSTATUS Status = SetSystemEnvironmentPrivilege(TRUE, &SeSystemEnvironmentWasEnabled);
- if (!NT_SUCCESS(Status))
+ if (IsVbsEnabled())
{
- Printf(L"Fatal error: failed to acquire SE_SYSTEM_ENVIRONMENT_PRIVILEGE. Make sure you are running as administrator.\n");
- return Status;
- }
- Status = SetDebugPrivilege(TRUE, &SeDebugWasEnabled);
- if (!NT_SUCCESS(Status))
- {
- Printf(L"Fatal error: failed to acquire SE_DEBUG_PRIVILEGE. Make sure you are running as administrator.\n");
- return Status;
- }
-
- if (QueryVbsEnabled())
- {
- Printf(L"Fatal error: VBS (Virtualization Based Security) is enabled and running on this system.\n"
+ Printf(L"Error: VBS (Virtualization Based Security) is enabled and running on this system.\n"
"Attempting to read or write to or from kernel space using EFI runtime services will result in a bugcheck.\n"
"Either the EfiGuard DXE driver is not loaded, or it failed to disable VBS during boot.\n"
"Not continuing.\n");
@@ -356,19 +297,18 @@ TestSetVariableHook(
// Find some kernel address to read
ULONG_PTR HalBase;
- Status = FindKernelModule("hal.dll", &HalBase);
+ NTSTATUS Status = FindKernelModule("hal.dll", &HalBase);
if (!NT_SUCCESS(Status))
return Status;
- // Set up the struct for a backdoor kernel mode read. See TriggerExploit for explanations
+ // Set up the struct for a backdoor kernel mode read. See WriteToCiOptions for explanations
EFIGUARD_BACKDOOR_DATA BackdoorData;
RtlZeroMemory(&BackdoorData, sizeof(BackdoorData));
BackdoorData.CookieValue = EFIGUARD_BACKDOOR_COOKIE_VALUE;
BackdoorData.KernelAddress = reinterpret_cast<PVOID>(HalBase);
BackdoorData.u.Qword = UINT64_MAX; // Bogus value to verify write-back after the read operation
- BackdoorData.IsMemCopy = FALSE;
- BackdoorData.IsReadOperation = TRUE;
BackdoorData.Size = sizeof(UINT16);
+ BackdoorData.ReadOnly = TRUE;
// Call SetVariable()
UNICODE_STRING VariableName = RTL_CONSTANT_STRING(EFIGUARD_BACKDOOR_VARIABLE_NAME);
@@ -397,7 +337,7 @@ TestSetVariableHook(
if (!NT_SUCCESS(Status))
{
Printf(L"The EfiGuard DXE driver is either not loaded in SETVARIABLE_HOOK mode, or it is malfunctioning.\n");
- goto Exit;
+ return Status;
}
// Check if hal.dll still starts with "MZ"
@@ -409,16 +349,12 @@ TestSetVariableHook(
Status = STATUS_INVALID_IMAGE_NOT_MZ; // Literally
}
-Exit:
- SetSystemEnvironmentPrivilege(SeSystemEnvironmentWasEnabled, nullptr);
- SetDebugPrivilege(SeDebugWasEnabled, nullptr);
-
return Status;
}
static
NTSTATUS
-TriggerExploit(
+WriteToCiOptions(
_In_ PVOID CiVariableAddress,
_In_ ULONG CiOptionsValue,
_Out_opt_ PULONG OldCiOptionsValue,
@@ -447,9 +383,8 @@ TriggerExploit(
BackdoorData.u.s.Dword = static_cast<UINT32>(CiOptionsValue);
else if (CiPatchSize == sizeof(UINT8))
BackdoorData.u.s.Byte = static_cast<UINT8>(CiOptionsValue);
- BackdoorData.IsMemCopy = FALSE; // This is a scalar operation, not memcpy
- BackdoorData.IsReadOperation = ReadOnly; // Specify whether this is a read or a write operation
- BackdoorData.Size = CiPatchSize; // This value determines the field (Byte/Word/Dword/Qword) that the value to write will be read from, and written to on return
+ BackdoorData.Size = CiPatchSize; // Determines which field the value will be read/written from/to
+ BackdoorData.ReadOnly = ReadOnly; // Whether this is a read or read + write
// Call NtSetSystemEnvironmentValueEx -> [...] -> hal!HalSetEnvironmentVariableEx -> hal!HalEfiSetEnvironmentVariable -> EfiRT->SetVariable.
// On Windows >= 8 it is possible to use SetFirmwareEnvironmentVariableExW. We use the syscall directly because it exists on Windows 7 and Vista.
@@ -475,6 +410,8 @@ TriggerExploit(
*OldCiOptionsValue = OldCiOptions;
}
+ RtlZeroMemory(&BackdoorData, sizeof(BackdoorData));
+
return STATUS_SUCCESS;
}
@@ -488,38 +425,18 @@ AdjustCiOptions(
if (OldCiOptionsValue != nullptr)
*OldCiOptionsValue = CODEINTEGRITY_OPTION_ENABLED;
- // Enable privileges
- BOOLEAN SeSystemEnvironmentWasEnabled, SeDebugWasEnabled;
- NTSTATUS Status = SetSystemEnvironmentPrivilege(TRUE, &SeSystemEnvironmentWasEnabled);
- if (!NT_SUCCESS(Status))
- {
- Printf(L"Fatal error: failed to acquire SE_SYSTEM_ENVIRONMENT_PRIVILEGE. Make sure you are running as administrator.\n");
- return Status;
- }
- Status = SetDebugPrivilege(TRUE, &SeDebugWasEnabled);
- if (!NT_SUCCESS(Status))
- {
- Printf(L"Fatal error: failed to acquire SE_DEBUG_PRIVILEGE. Make sure you are running as administrator.\n");
- return Status;
- }
-
// Find CI!g_CiOptions/nt!g_CiEnabled
PVOID CiOptionsAddress;
- Status = AnalyzeCi(&CiOptionsAddress);
+ NTSTATUS Status = FindCiOptionsVariable(&CiOptionsAddress);
if (!NT_SUCCESS(Status))
return Status;
Printf(L"%ls at 0x%p.\n", (NtCurrentPeb()->OSBuildNumber >= 9200 ? L"CI!g_CiOptions" : L"nt!g_CiEnabled"), CiOptionsAddress);
// Enable/disable CI
- Status = TriggerExploit(CiOptionsAddress,
+ Status = WriteToCiOptions(CiOptionsAddress,
CiOptionsValue,
OldCiOptionsValue,
ReadOnly);
-
- // Revert privileges
- SetSystemEnvironmentPrivilege(SeSystemEnvironmentWasEnabled, nullptr);
- SetDebugPrivilege(SeDebugWasEnabled, nullptr);
-
return Status;
}
diff --git a/Application/EfiDSEFix/src/EfiDSEFix.exe.manifest b/Application/EfiDSEFix/src/EfiDSEFix.exe.manifest
index af2f7de..16afbf5 100644
--- a/Application/EfiDSEFix/src/EfiDSEFix.exe.manifest
+++ b/Application/EfiDSEFix/src/EfiDSEFix.exe.manifest
@@ -3,7 +3,7 @@
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
<security>
<requestedPrivileges>
- <requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
+ <requestedExecutionLevel level="asInvoker" uiAccess="false" />
</requestedPrivileges>
</security>
</trustInfo>
diff --git a/Application/EfiDSEFix/src/EfiDSEFix.vcxproj b/Application/EfiDSEFix/src/EfiDSEFix.vcxproj
index 44675b5..c588f60 100644
--- a/Application/EfiDSEFix/src/EfiDSEFix.vcxproj
+++ b/Application/EfiDSEFix/src/EfiDSEFix.vcxproj
@@ -26,6 +26,8 @@
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v143</PlatformToolset>
<SpectreMitigation>false</SpectreMitigation>
+ <VcpkgEnabled>false</VcpkgEnabled>
+ <EnableStdModules>false</EnableStdModules>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release (native subsystem)|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
@@ -34,6 +36,8 @@
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v143</PlatformToolset>
<SpectreMitigation>false</SpectreMitigation>
+ <VcpkgEnabled>false</VcpkgEnabled>
+ <EnableStdModules>false</EnableStdModules>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
@@ -62,7 +66,7 @@
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<LanguageStandard>stdcpplatest</LanguageStandard>
- <AdditionalOptions>/Gw /utf-8 %(AdditionalOptions)</AdditionalOptions>
+ <AdditionalOptions>/Gw /utf-8 /Zc:threadSafeInit- %(AdditionalOptions)</AdditionalOptions>
<BufferSecurityCheck>false</BufferSecurityCheck>
<DisableSpecificWarnings>4201</DisableSpecificWarnings>
<ExceptionHandling>false</ExceptionHandling>
@@ -71,6 +75,7 @@
<AdditionalIncludeDirectories>$(SolutionDir)Include;$(SolutionDir)../MdePkg/Include;$(SolutionDir)../MdePkg/Include/X64;$(SolutionDir)../MdeModulePkg/Include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<IntrinsicFunctions>true</IntrinsicFunctions>
<BuildStlModules>false</BuildStlModules>
+ <EnableModules>false</EnableModules>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
@@ -101,7 +106,7 @@
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<LanguageStandard>stdcpplatest</LanguageStandard>
- <AdditionalOptions>/Gw /utf-8 %(AdditionalOptions)</AdditionalOptions>
+ <AdditionalOptions>/Gw /utf-8 /Zc:threadSafeInit- %(AdditionalOptions)</AdditionalOptions>
<BufferSecurityCheck>false</BufferSecurityCheck>
<DisableSpecificWarnings>4201</DisableSpecificWarnings>
<ExceptionHandling>false</ExceptionHandling>
@@ -110,6 +115,7 @@
<AdditionalIncludeDirectories>$(SolutionDir)Include;$(SolutionDir)../MdePkg/Include;$(SolutionDir)../MdePkg/Include/X64;$(SolutionDir)../MdeModulePkg/Include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<IntrinsicFunctions>true</IntrinsicFunctions>
<BuildStlModules>false</BuildStlModules>
+ <EnableModules>false</EnableModules>
</ClCompile>
<Link>
<SubSystem>Native</SubSystem>
diff --git a/Application/EfiDSEFix/src/main.cpp b/Application/EfiDSEFix/src/main.cpp
index 50e336a..8cd8cb9 100644
--- a/Application/EfiDSEFix/src/main.cpp
+++ b/Application/EfiDSEFix/src/main.cpp
@@ -9,13 +9,13 @@ PrintUsage(
{
const BOOLEAN Win8OrHigher = (RtlNtMajorVersion() >= 6 && RtlNtMinorVersion() >= 2) || RtlNtMajorVersion() > 6;
const PCWCHAR CiOptionsName = Win8OrHigher ? L"g_CiOptions" : L"g_CiEnabled";
- Printf(L"\nUsage: %ls [COMMAND]\n\n"
- L"Commands:\n\n"
- L"-c, --check%17lsTest backdoor hook\n"
- L"-r, --read%18lsRead current %ls value\n"
- L"-d, --disable%15lsDisable DSE\n"
- L"-e, --enable%ls%2ls(Re)enable DSE\n"
- L"-i, --info%18lsDump system info\n",
+ Printf(L"\nUsage: %ls <COMMAND>\n\n"
+ L"Commands:\n"
+ L" -c, --check%17lsTest EFI SetVariable hook\n"
+ L" -r, --read%18lsRead current %ls value\n"
+ L" -d, --disable%15lsDisable DSE\n"
+ L" -e, --enable%ls%2ls(Re)enable DSE\n"
+ L" -i, --info%18lsDump system info\n",
ProgramName, L"", L"",
CiOptionsName, L"",
(Win8OrHigher ? L" [g_CiOptions]" : L" "),
@@ -26,14 +26,31 @@ int wmain(int argc, wchar_t** argv)
{
NT_ASSERT(argc != 0);
- if (argc == 1 || argc > 3 ||
- (argc == 3 && wcstoul(argv[2], nullptr, 16) == 0))
+ if (argc <= 1 || argc > 3 ||
+ (argc == 3 && wcstoul(argv[2], nullptr, 16) == 0) ||
+ wcsncmp(argv[1], L"-h", sizeof(L"-h") / sizeof(WCHAR) - 1) == 0 ||
+ wcsncmp(argv[1], L"--help", sizeof(L"--help") / sizeof(WCHAR) - 1) == 0)
{
// Print help text
PrintUsage(argv[0]);
return 0;
}
+ // All remaining commands require admin privileges
+ BOOLEAN SeSystemEnvironmentWasEnabled, SeDebugWasEnabled;
+ NTSTATUS Status = RtlAdjustPrivilege(SE_SYSTEM_ENVIRONMENT_PRIVILEGE, TRUE, FALSE, &SeSystemEnvironmentWasEnabled);
+ if (!NT_SUCCESS(Status))
+ {
+ Printf(L"Error: failed to acquire SE_SYSTEM_ENVIRONMENT_PRIVILEGE.\n%ls must be run as Administrator.\n", argv[0]);
+ return Status;
+ }
+ Status = RtlAdjustPrivilege(SE_DEBUG_PRIVILEGE, TRUE, FALSE, &SeDebugWasEnabled);
+ if (!NT_SUCCESS(Status))
+ {
+ Printf(L"Error: failed to acquire SE_DEBUG_PRIVILEGE.\n%ls must be run as Administrator.\n", argv[0]);
+ return Status;
+ }
+
// Parse command line params
const BOOLEAN Win8OrHigher = (RtlNtMajorVersion() >= 6 && RtlNtMinorVersion() >= 2) || RtlNtMajorVersion() > 6;
const ULONG EnabledCiOptionsValue = Win8OrHigher ? 0x6 : CODEINTEGRITY_OPTION_ENABLED;
@@ -41,15 +58,6 @@ int wmain(int argc, wchar_t** argv)
ULONG CiOptionsValue;
BOOLEAN ReadOnly = FALSE;
- if (wcsncmp(argv[1], L"-c", sizeof(L"-c") / sizeof(WCHAR) - 1) == 0 ||
- wcsncmp(argv[1], L"--check", sizeof(L"--check") / sizeof(WCHAR) - 1) == 0)
- {
- Printf(L"Checking for working EFI SetVariable() backdoor...\n");
- const NTSTATUS Status = TestSetVariableHook();
- if (NT_SUCCESS(Status)) // Any errors have already been printed
- Printf(L"Success!\n");
- return Status;
- }
if (wcsncmp(argv[1], L"-r", sizeof(L"-r") / sizeof(WCHAR) - 1) == 0 ||
wcsncmp(argv[1], L"--read", sizeof(L"--read") / sizeof(WCHAR) - 1) == 0)
{
@@ -77,20 +85,31 @@ int wmain(int argc, wchar_t** argv)
Printf(L"(Re)enabling DSE...\n");
}
}
+ else if (wcsncmp(argv[1], L"-c", sizeof(L"-c") / sizeof(WCHAR) - 1) == 0 ||
+ wcsncmp(argv[1], L"--check", sizeof(L"--check") / sizeof(WCHAR) - 1) == 0)
+ {
+ Printf(L"Checking for working EFI SetVariable hook...\n");
+ Status = TestSetVariableHook();
+ if (NT_SUCCESS(Status)) // Any errors have already been printed
+ Printf(L"Success.\n");
+ goto Exit;
+ }
else if (wcsncmp(argv[1], L"-i", sizeof(L"-i") / sizeof(WCHAR) - 1) == 0 ||
wcsncmp(argv[1], L"--info", sizeof(L"--info") / sizeof(WCHAR) - 1) == 0)
{
- return DumpSystemInformation();
+ Status = DumpSystemInformation();
+ goto Exit;
}
else
{
PrintUsage(argv[0]);
- return STATUS_INVALID_PARAMETER;
+ Status = STATUS_INVALID_PARAMETER;
+ goto Exit;
}
- // Trigger EFI driver exploit and write new value to g_CiOptions/g_CiEnabled
+ // Call EFI runtime SetVariable service and write new value to g_CiOptions/g_CiEnabled
ULONG OldCiOptionsValue;
- const NTSTATUS Status = AdjustCiOptions(CiOptionsValue, &OldCiOptionsValue, ReadOnly);
+ Status = AdjustCiOptions(CiOptionsValue, &OldCiOptionsValue, ReadOnly);
// Print result
if (!NT_SUCCESS(Status))
@@ -105,6 +124,11 @@ int wmain(int argc, wchar_t** argv)
Printf(L"Successfully %ls DSE. Original", CiOptionsValue == 0 ? L"disabled" : L"(re)enabled");
Printf(L" %ls value: 0x%lX\n", CiOptionsName, OldCiOptionsValue);
}
+
+Exit:
+ RtlAdjustPrivilege(SE_SYSTEM_ENVIRONMENT_PRIVILEGE, SeSystemEnvironmentWasEnabled, FALSE, &SeSystemEnvironmentWasEnabled);
+ RtlAdjustPrivilege(SE_DEBUG_PRIVILEGE, SeDebugWasEnabled, FALSE, &SeDebugWasEnabled);
+
return Status;
}
diff --git a/Application/EfiDSEFix/src/sysinfo.cpp b/Application/EfiDSEFix/src/sysinfo.cpp
index 6b236e4..a0ad289 100644
--- a/Application/EfiDSEFix/src/sysinfo.cpp
+++ b/Application/EfiDSEFix/src/sysinfo.cpp
@@ -75,10 +75,10 @@ DumpSystemInformation(
Printf(L"SystemModuleInformation: %08lX\n\n", Status);
else
{
- const RTL_PROCESS_MODULE_INFORMATION Ntoskrnl = ModuleInfo->Modules[0];
+ const PRTL_PROCESS_MODULE_INFORMATION Ntoskrnl = &ModuleInfo->Modules[0];
Printf(L"SystemModuleInformation:\n\t- Kernel: %S (%S)\n\n",
- reinterpret_cast<PCCH>(Ntoskrnl.FullPathName + Ntoskrnl.OffsetToFileName),
- reinterpret_cast<PCCH>(Ntoskrnl.FullPathName));
+ reinterpret_cast<PCCH>(Ntoskrnl->FullPathName + Ntoskrnl->OffsetToFileName),
+ reinterpret_cast<PCCH>(Ntoskrnl->FullPathName));
}
RtlFreeHeap(RtlProcessHeap(), 0, ModuleInfo);
}
diff --git a/Application/Loader/Loader.c b/Application/Loader/Loader.c
index 665b2fe..aab4a5c 100644
--- a/Application/Loader/Loader.c
+++ b/Application/Loader/Loader.c
@@ -5,9 +5,11 @@
#include <Protocol/SimpleFileSystem.h>
#include <Protocol/LoadedImage.h>
#include <Protocol/LegacyBios.h>
+#include <Library/PcdLib.h>
#include <Library/UefiLib.h>
#include <Library/DebugLib.h>
#include <Library/MemoryAllocationLib.h>
+#include <Library/ReportStatusCodeLib.h>
#include <Library/DevicePathLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiBootManagerLib.h>
@@ -15,16 +17,6 @@
//
-// Define whether the loader should prompt for driver configuration or not.
-// If this is 0, the defaults are used and Windows will be booted with no user interaction.
-// This can be overridden on the command line with -D CONFIGURE_DRIVER=[0|1]
-//
-#ifndef CONFIGURE_DRIVER
-#define CONFIGURE_DRIVER 0
-#endif
-
-
-//
// Paths to the driver to try
//
#ifndef EFIGUARD_DRIVER_FILENAME
@@ -36,6 +28,13 @@ STATIC CHAR16* mDriverPaths[] = {
L"\\" EFIGUARD_DRIVER_FILENAME
};
+STATIC EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *mTextInputEx = NULL;
+
+VOID
+EFIAPI
+BmRepairAllControllers(
+ IN UINTN ReconnectRepairCount
+ );
VOID
EFIAPI
@@ -43,23 +42,65 @@ BmSetMemoryTypeInformationVariable(
IN BOOLEAN Boot
);
+BOOLEAN
+EFIAPI
+BmIsAutoCreateBootOption(
+ IN EFI_BOOT_MANAGER_LOAD_OPTION *BootOption
+ );
STATIC
-BOOLEAN
+VOID
+ResetTextInput(
+ VOID
+ )
+{
+ if (mTextInputEx != NULL)
+ mTextInputEx->Reset(mTextInputEx, FALSE);
+ else
+ gST->ConIn->Reset(gST->ConIn, FALSE);
+}
+
+STATIC
+UINT16
EFIAPI
WaitForKey(
VOID
)
{
- EFI_INPUT_KEY Key = { 0, 0 };
+ EFI_KEY_DATA KeyData = { 0 };
UINTN Index = 0;
- gBS->WaitForEvent(1, &gST->ConIn->WaitForKey, &Index);
- gST->ConIn->ReadKeyStroke(gST->ConIn, &Key);
-
- return Key.ScanCode != SCAN_ESC;
+ if (mTextInputEx != NULL)
+ {
+ gBS->WaitForEvent(1, &mTextInputEx->WaitForKeyEx, &Index);
+ mTextInputEx->ReadKeyStrokeEx(mTextInputEx, &KeyData);
+ }
+ else
+ {
+ gBS->WaitForEvent(1, &gST->ConIn->WaitForKey, &Index);
+ gST->ConIn->ReadKeyStroke(gST->ConIn, &KeyData.Key);
+ }
+ return KeyData.Key.ScanCode;
}
-#if CONFIGURE_DRIVER
+STATIC
+UINT16
+EFIAPI
+WaitForKeyWithTimeout(
+ IN UINTN Milliseconds
+ )
+{
+ ResetTextInput();
+ gBS->Stall(Milliseconds * 1000);
+
+ EFI_KEY_DATA KeyData = { 0 };
+ if (mTextInputEx != NULL)
+ mTextInputEx->ReadKeyStrokeEx(mTextInputEx, &KeyData);
+ else
+ gST->ConIn->ReadKeyStroke(gST->ConIn, &KeyData.Key);
+
+ ResetTextInput();
+ return KeyData.Key.ScanCode;
+}
STATIC
UINT16
@@ -76,12 +117,20 @@ PromptInput(
{
SelectedChar = CHAR_NULL;
- EFI_INPUT_KEY Key = { 0, 0 };
+ EFI_KEY_DATA KeyData = { 0 };
UINTN Index = 0;
- gBS->WaitForEvent(1, &gST->ConIn->WaitForKey, &Index);
- gST->ConIn->ReadKeyStroke(gST->ConIn, &Key);
+ if (mTextInputEx != NULL)
+ {
+ gBS->WaitForEvent(1, &mTextInputEx->WaitForKeyEx, &Index);
+ mTextInputEx->ReadKeyStrokeEx(mTextInputEx, &KeyData);
+ }
+ else
+ {
+ gBS->WaitForEvent(1, &gST->ConIn->WaitForKey, &Index);
+ gST->ConIn->ReadKeyStroke(gST->ConIn, &KeyData.Key);
+ }
- if (Key.UnicodeChar == CHAR_LINEFEED || Key.UnicodeChar == CHAR_CARRIAGE_RETURN)
+ if (KeyData.Key.UnicodeChar == CHAR_LINEFEED || KeyData.Key.UnicodeChar == CHAR_CARRIAGE_RETURN)
{
SelectedChar = DefaultSelection;
break;
@@ -89,9 +138,9 @@ PromptInput(
for (UINTN i = 0; i < NumAcceptedChars; ++i)
{
- if (Key.UnicodeChar == AcceptedChars[i])
+ if (KeyData.Key.UnicodeChar == AcceptedChars[i])
{
- SelectedChar = Key.UnicodeChar;
+ SelectedChar = KeyData.Key.UnicodeChar;
break;
}
}
@@ -104,8 +153,43 @@ PromptInput(
return SelectedChar;
}
-#endif
+STATIC
+CONST CHAR16*
+EFIAPI
+StriStr(
+ IN CONST CHAR16 *String1,
+ IN CONST CHAR16 *String2
+ )
+{
+ if (*String2 == L'\0')
+ return String1;
+
+ while (*String1 != L'\0')
+ {
+ CONST CHAR16* FirstMatch = String1;
+ CONST CHAR16* String2Ptr = String2;
+ CHAR16 String1Char = CharToUpper(*String1);
+ CHAR16 String2Char = CharToUpper(*String2Ptr);
+
+ while (String1Char == String2Char && String1Char != L'\0')
+ {
+ String1++;
+ String2Ptr++;
+
+ String1Char = CharToUpper(*String1);
+ String2Char = CharToUpper(*String2Ptr);
+ }
+
+ if (String2Char == L'\0')
+ return FirstMatch;
+ if (String1Char == L'\0')
+ return NULL;
+
+ String1 = FirstMatch + 1;
+ }
+ return NULL;
+}
//
// Try to find a file by browsing each device
@@ -156,7 +240,8 @@ LocateFile(
EFI_FILE_READ_ONLY);
if (!EFI_ERROR(Status))
{
- VolumeHandle->Close(FileHandle);
+ FileHandle->Close(FileHandle);
+ VolumeHandle->Close(VolumeHandle);
*DevicePath = FileDevicePath(Handles[i], ImagePath);
CHAR16 *PathString = ConvertDevicePathToText(*DevicePath, TRUE, TRUE);
DEBUG((DEBUG_INFO, "[LOADER] Found file at %S.\r\n", PathString));
@@ -164,9 +249,10 @@ LocateFile(
FreePool(PathString);
break;
}
+ VolumeHandle->Close(VolumeHandle);
}
- FreePool(Handles);
+ FreePool((VOID*)Handles);
return Status;
}
@@ -219,9 +305,8 @@ SetHighestAvailableTextMode(
STATIC
EFI_STATUS
EFIAPI
-StartAndConfigureDriver(
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE* SystemTable
+StartEfiGuard(
+ IN BOOLEAN InteractiveConfiguration
)
{
EFIGUARD_DRIVER_PROTOCOL* EfiGuardDriverProtocol;
@@ -251,7 +336,7 @@ StartAndConfigureDriver(
EFI_HANDLE DriverHandle = NULL;
Status = gBS->LoadImage(FALSE, // Request is not from boot manager
- ImageHandle,
+ gImageHandle,
DriverDevicePath,
NULL,
0,
@@ -268,58 +353,65 @@ StartAndConfigureDriver(
Print(L"[LOADER] StartImage failed: %llx (%r).\r\n", Status, Status);
goto Exit;
}
-
- Status = gBS->LocateProtocol(&gEfiGuardDriverProtocolGuid,
- NULL,
- (VOID**)&EfiGuardDriverProtocol);
- if (EFI_ERROR(Status))
- {
- Print(L"[LOADER] LocateProtocol failed: %llx (%r).\r\n", Status, Status);
- goto Exit;
- }
}
else
{
+ ASSERT_EFI_ERROR(Status);
Print(L"[LOADER] The driver is already loaded.\r\n");
- Status = EFI_ALREADY_STARTED;
+ }
+
+ Status = gBS->LocateProtocol(&gEfiGuardDriverProtocolGuid,
+ NULL,
+ (VOID**)&EfiGuardDriverProtocol);
+ if (EFI_ERROR(Status))
+ {
+ Print(L"[LOADER] LocateProtocol failed: %llx (%r).\r\n", Status, Status);
goto Exit;
}
-#if CONFIGURE_DRIVER
- //
- // Interactive driver configuration
- //
- Print(L"\r\nChoose the type of DSE bypass to use, or press ENTER for default:\r\n"
- L" [1] No DSE bypass\r\n [2] Boot time DSE bypass\r\n [3] Runtime SetVariable hook (default)\r\n ");
- CONST UINT16 AcceptedDseBypasses[] = { L'1', L'2', L'3' };
- CONST UINT16 SelectedDseBypass = PromptInput(AcceptedDseBypasses,
- sizeof(AcceptedDseBypasses) / sizeof(UINT16),
- L'3');
-
- Print(L"Wait for a keypress to continue after each patch stage? (for debugging)\n"
- L" [1] Yes\r\n [2] No (default)\r\n ");
- CONST UINT16 YesNo[] = { L'1', L'2' };
- CONST UINT16 SelectedWaitForKeyPress = PromptInput(YesNo,
- sizeof(YesNo) / sizeof(UINT16),
- L'2');
-
- EFIGUARD_CONFIGURATION_DATA ConfigData;
- if (SelectedDseBypass == L'1')
- ConfigData.DseBypassMethod = DSE_DISABLE_NONE;
- else if (SelectedDseBypass == L'2')
- ConfigData.DseBypassMethod = DSE_DISABLE_AT_BOOT;
- else
- ConfigData.DseBypassMethod = DSE_DISABLE_SETVARIABLE_HOOK;
- ConfigData.WaitForKeyPress = (BOOLEAN)(SelectedWaitForKeyPress == L'1');
+ if (InteractiveConfiguration)
+ {
+ //
+ // Interactive driver configuration
+ //
+ Print(L"\r\nChoose the type of DSE bypass to use, or press ENTER for default:\r\n"
+ L" [1] Runtime SetVariable hook (default)\r\n [2] Boot time DSE bypass\r\n [3] No DSE bypass\r\n ");
+ CONST UINT16 AcceptedDseBypasses[] = { L'1', L'2', L'3' };
+ CONST UINT16 SelectedDseBypass = PromptInput(AcceptedDseBypasses,
+ sizeof(AcceptedDseBypasses) / sizeof(UINT16),
+ L'1');
+
+ Print(L"Wait for a keypress to continue after each patch stage?\n"
+ L" [1] No (default)\r\n [2] Yes (for debugging)\r\n ");
+ CONST UINT16 NoYes[] = { L'1', L'2' };
+ CONST UINT16 SelectedWaitForKeyPress = PromptInput(NoYes,
+ sizeof(NoYes) / sizeof(UINT16),
+ L'1');
+
+ EFIGUARD_CONFIGURATION_DATA ConfigData;
+ switch (SelectedDseBypass)
+ {
+ case L'1':
+ default:
+ ConfigData.DseBypassMethod = DSE_DISABLE_SETVARIABLE_HOOK;
+ break;
+ case L'2':
+ ConfigData.DseBypassMethod = DSE_DISABLE_AT_BOOT;
+ break;
+ case L'3':
+ ConfigData.DseBypassMethod = DSE_DISABLE_NONE;
+ break;
+ }
+ ConfigData.WaitForKeyPress = (BOOLEAN)(SelectedWaitForKeyPress == L'2');
- //
- // Send the configuration data to the driver
- //
- Status = EfiGuardDriverProtocol->Configure(&ConfigData);
+ //
+ // Send the configuration data to the driver
+ //
+ Status = EfiGuardDriverProtocol->Configure(&ConfigData);
- if (EFI_ERROR(Status))
- Print(L"[LOADER] Driver Configure() returned error %llx (%r).\r\n", Status, Status);
-#endif
+ if (EFI_ERROR(Status))
+ Print(L"[LOADER] Driver Configure() returned error %llx (%r).\r\n", Status, Status);
+ }
Exit:
if (DriverDevicePath != NULL)
@@ -406,8 +498,7 @@ TryBootOptionsInOrder(
// but for some types of boots the filename will always be bootx64.efi, so this can't be avoided.
if (!MaybeWindows &&
ConvertedPath != NULL &&
- (StrStr(ConvertedPath, L"bootmgfw.efi") != NULL || StrStr(ConvertedPath, L"BOOTMGFW.EFI") != NULL ||
- StrStr(ConvertedPath, L"bootx64.efi") != NULL || StrStr(ConvertedPath, L"BOOTX64.EFI") != NULL))
+ (StriStr(ConvertedPath, L"bootmgfw.efi") != NULL || StriStr(ConvertedPath, L"bootx64.efi") != NULL))
{
MaybeWindows = TRUE;
}
@@ -426,7 +517,9 @@ TryBootOptionsInOrder(
// Print what we're booting
if (ConvertedPath != NULL)
{
- Print(L"Booting %Sdevice path %S...\r\n", IsLegacy ? L"legacy " : L"", ConvertedPath);
+ Print(L"Booting \"%S\"...\r\n -> %S = %S\r\n",
+ (BootOptions[Index].Description != NULL ? BootOptions[Index].Description : L"<null description>"),
+ IsLegacy ? L"Legacy path" : L"Path", ConvertedPath);
FreePool(ConvertedPath);
}
@@ -449,6 +542,13 @@ TryBootOptionsInOrder(
// Signal the EVT_SIGNAL_READY_TO_BOOT event
EfiSignalEventReadyToBoot();
+ REPORT_STATUS_CODE(EFI_PROGRESS_CODE, (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_DXE_BS_PC_READY_TO_BOOT_EVENT));
+
+ // Repair system through DriverHealth protocol
+ BmRepairAllControllers(0);
+
+ // Save the memory map in the MemoryTypeInformation variable for resuming from ACPI S4 (hibernate)
+ BmSetMemoryTypeInformationVariable((BootOptions[Index].Attributes & LOAD_OPTION_CATEGORY) == LOAD_OPTION_CATEGORY_BOOT);
// Handle BBS entries
if (IsLegacy)
@@ -470,18 +570,12 @@ TryBootOptionsInOrder(
return !EFI_ERROR(BootOptions[Index].Status);
}
- // So again, DO NOT call this abortion:
- //BmSetMemoryTypeInformationVariable((BOOLEAN)((BootOptions[Index].Attributes & LOAD_OPTION_CATEGORY) == LOAD_OPTION_CATEGORY_BOOT));
- //
- // OK, maybe call it after all, but pretend this is *not* a boot entry, so that the system will not go into an infinite boot (reset) loop.
- // This may or may not fix hibernation related issues (S4 entry/resume). See https://github.com/Mattiwatti/EfiGuard/issues/12
- BmSetMemoryTypeInformationVariable(FALSE);
-
// Ensure the image path is connected end-to-end by Dispatch()ing any required drivers through DXE services
EfiBootManagerConnectDevicePath(BootOptions[Index].FilePath, NULL);
// Instead of creating a ramdisk and reading the file into it (¿que?), just pass the path we saved earlier.
// This is the point where the driver kicks in via its LoadImage hook.
+ REPORT_STATUS_CODE(EFI_PROGRESS_CODE, PcdGet32(PcdProgressCodeOsLoaderLoad));
EFI_HANDLE ImageHandle = NULL;
Status = gBS->LoadImage(TRUE,
gImageHandle,
@@ -500,6 +594,7 @@ TryBootOptionsInOrder(
gBS->UnloadImage(ImageHandle);
Print(L"LoadImage error %llx (%r)\r\n", Status, Status);
+ BootOptions[Index].Status = Status;
continue;
}
@@ -514,8 +609,11 @@ TryBootOptionsInOrder(
ASSERT_EFI_ERROR(Status);
// Set image load options from the boot option
- ImageInfo->LoadOptionsSize = BootOptions[Index].OptionalDataSize;
- ImageInfo->LoadOptions = BootOptions[Index].OptionalData;
+ if (!BmIsAutoCreateBootOption(&BootOptions[Index]))
+ {
+ ImageInfo->LoadOptionsSize = BootOptions[Index].OptionalDataSize;
+ ImageInfo->LoadOptions = BootOptions[Index].OptionalData;
+ }
// "Clean to NULL because the image is loaded directly from the firmware's boot manager." (EDK2) Good call, I agree
ImageInfo->ParentHandle = NULL;
@@ -524,6 +622,7 @@ TryBootOptionsInOrder(
gBS->SetWatchdogTimer((UINTN)(5 * 60), 0x0000, 0x00, NULL);
// Start the image and set the return code in the boot option status
+ REPORT_STATUS_CODE(EFI_PROGRESS_CODE, PcdGet32(PcdProgressCodeOsLoaderStart));
Status = gBS->StartImage(ImageHandle,
&BootOptions[Index].ExitDataSize,
&BootOptions[Index].ExitData);
@@ -579,19 +678,28 @@ UefiMain(
gBS->SetWatchdogTimer(0, 0, 0, NULL);
//
- // Locate, load, start and configure the driver
+ // Query the console input handle for the Simple Text Input Ex protocol
//
- CONST EFI_STATUS DriverStatus = StartAndConfigureDriver(ImageHandle, SystemTable);
- if (DriverStatus == EFI_ALREADY_STARTED)
- return EFI_SUCCESS;
+ gBS->HandleProtocol(gST->ConsoleInHandle, &gEfiSimpleTextInputExProtocolGuid, (VOID **)&mTextInputEx);
+ //
+ // Allow user to configure the driver by pressing a hotkey
+ //
+ Print(L"Press <HOME> to configure EfiGuard...\r\n");
+ CONST BOOLEAN InteractiveConfiguration = WaitForKeyWithTimeout(1500) == SCAN_HOME;
+
+ //
+ // Locate, load, start and configure the driver
+ //
+ CONST EFI_STATUS DriverStatus = StartEfiGuard(InteractiveConfiguration);
if (EFI_ERROR(DriverStatus))
{
Print(L"\r\nERROR: driver load failed with status %llx (%r).\r\n"
L"Press any key to continue, or press ESC to return to the firmware or shell.\r\n",
DriverStatus, DriverStatus);
- if (!WaitForKey())
+ if (WaitForKey() == SCAN_ESC)
{
+ gBS->Exit(gImageHandle, DriverStatus, 0, NULL);
return DriverStatus;
}
}
diff --git a/Application/Loader/Loader.inf b/Application/Loader/Loader.inf
index e817bd5..8d98034 100644
--- a/Application/Loader/Loader.inf
+++ b/Application/Loader/Loader.inf
@@ -14,13 +14,13 @@
MdePkg/MdePkg.dec
EfiGuardPkg/EfiGuardPkg.dec
MdeModulePkg/MdeModulePkg.dec
- OvmfPkg/OvmfPkg.dec
[LibraryClasses]
UefiApplicationEntryPoint
UefiBootServicesTableLib
DebugLib
UefiLib
+ ReportStatusCodeLib
DevicePathLib
PrintLib
UefiBootManagerLib
@@ -28,6 +28,8 @@
[Guids]
## SOMETIMES_PRODUCES ## Variable:L"BootCurrent" (The boot option of current boot)
gEfiGlobalVariableGuid
+ ## SOMETIMES_PRODUCES ## Variable:L"MemoryTypeInformation."
+ gEfiMemoryTypeInformationGuid ## SOMETIMES_PRODUCES
gEfiEventReadyToBootGuid ## SOMETIMES_PRODUCES
gEfiHobListGuid ## CONSUMES
gEfiDxeServicesTableGuid ## CONSUMES
@@ -52,9 +54,15 @@
gEfiUsbIoProtocolGuid ## CONSUMES
gEfiFirmwareVolume2ProtocolGuid ## CONSUMES
gEfiSimpleTextInProtocolGuid ## CONSUMES
+ gEfiSimpleTextInputExProtocolGuid ## CONSUMES
gEfiSimpleTextOutProtocolGuid ## CONSUMES
gEfiLegacyBiosProtocolGuid ## CONSUMES
+[Pcd]
+ gEfiMdeModulePkgTokenSpaceGuid.PcdResetOnMemoryTypeInformationChange ## SOMETIMES_CONSUMES
+ gEfiMdeModulePkgTokenSpaceGuid.PcdProgressCodeOsLoaderLoad ## SOMETIMES_CONSUMES
+ gEfiMdeModulePkgTokenSpaceGuid.PcdProgressCodeOsLoaderStart ## SOMETIMES_CONSUMES
+
[BuildOptions.Common]
*:DEBUG_*_*_PP_FLAGS = -D EFI_DEBUG
*:DEBUG_*_*_CC_FLAGS = -D EFI_DEBUG
diff --git a/Application/Loader/Loader.vcxproj b/Application/Loader/Loader.vcxproj
index 512b624..9254ab7 100644
--- a/Application/Loader/Loader.vcxproj
+++ b/Application/Loader/Loader.vcxproj
@@ -19,13 +19,15 @@
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
<SpectreMitigation>false</SpectreMitigation>
+ <VcpkgEnabled>false</VcpkgEnabled>
+ <EnableStdModules>false</EnableStdModules>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<Import Project="$(SolutionDir)\EfiGuard.props" />
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ItemDefinitionGroup>
<ClCompile>
- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">CONFIGURE_DRIVER=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">_PCD_GET_MODE_32_PcdProgressCodeOsLoaderLoad=0x3058000;_PCD_GET_MODE_32_PcdProgressCodeOsLoaderStart=0x3058001;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)Include;$(EDK_PATH)\OvmfPkg\Csm\Include</AdditionalIncludeDirectories>
</ClCompile>
<Link>