mirror of
https://github.com/HyperDbg/HyperDbg.git
synced 2026-07-09 17:19:26 +00:00
set user mode execute bit for different core EPTPs
This commit is contained in:
parent
beed7ccc34
commit
0e5ff45c30
6 changed files with 104 additions and 9 deletions
|
|
@ -2570,7 +2570,7 @@ EptHookModifyInstructionFetchState(VIRTUAL_MACHINE_STATE * VCpu,
|
|||
PVOID PmlEntry = NULL;
|
||||
BOOLEAN IsLargePage = FALSE;
|
||||
|
||||
PmlEntry = EptGetPml1OrPml2Entry(g_EptState->EptPageTable, (SIZE_T)PhysicalAddress, &IsLargePage);
|
||||
PmlEntry = EptGetPml1OrPml2Entry(VCpu->EptPageTable, (SIZE_T)PhysicalAddress, &IsLargePage);
|
||||
|
||||
if (PmlEntry)
|
||||
{
|
||||
|
|
@ -2628,7 +2628,7 @@ EptHookModifyPageReadState(VIRTUAL_MACHINE_STATE * VCpu,
|
|||
PVOID PmlEntry = NULL;
|
||||
BOOLEAN IsLargePage = FALSE;
|
||||
|
||||
PmlEntry = EptGetPml1OrPml2Entry(g_EptState->EptPageTable, (SIZE_T)PhysicalAddress, &IsLargePage);
|
||||
PmlEntry = EptGetPml1OrPml2Entry(VCpu->EptPageTable, (SIZE_T)PhysicalAddress, &IsLargePage);
|
||||
|
||||
if (PmlEntry)
|
||||
{
|
||||
|
|
@ -2686,7 +2686,7 @@ EptHookModifyPageWriteState(VIRTUAL_MACHINE_STATE * VCpu,
|
|||
PVOID PmlEntry = NULL;
|
||||
BOOLEAN IsLargePage = FALSE;
|
||||
|
||||
PmlEntry = EptGetPml1OrPml2Entry(g_EptState->EptPageTable, (SIZE_T)PhysicalAddress, &IsLargePage);
|
||||
PmlEntry = EptGetPml1OrPml2Entry(VCpu->EptPageTable, (SIZE_T)PhysicalAddress, &IsLargePage);
|
||||
|
||||
if (PmlEntry)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -572,6 +572,47 @@ ExecTrapChangeToKernelDisabledMbecEptp(VIRTUAL_MACHINE_STATE * VCpu)
|
|||
VCpu->NotNormalEptp = TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief change to normal MBEC EPTP
|
||||
* @param VCpu The virtual processor's state
|
||||
*
|
||||
* @return VOID
|
||||
*/
|
||||
VOID
|
||||
ExecTrapChangeToNormalMbecEptp(VIRTUAL_MACHINE_STATE * VCpu)
|
||||
{
|
||||
//
|
||||
// From Intel Manual:
|
||||
// [Bit 2] If the "mode-based execute control for EPT" VM - execution control is 0, execute access;
|
||||
// indicates whether instruction fetches are allowed from the 2-MByte page controlled by this entry.
|
||||
// If that control is 1, execute access for supervisor-mode linear addresses; indicates whether instruction
|
||||
// fetches are allowed from supervisor - mode linear addresses in the 2 - MByte page controlled by this entry
|
||||
//
|
||||
|
||||
//
|
||||
// Set execute access for PML4s
|
||||
//
|
||||
// for (size_t i = 0; i < VMM_EPT_PML4E_COUNT; i++)
|
||||
// {
|
||||
VCpu->EptPageTable->PML4[0].UserModeExecute = TRUE;
|
||||
|
||||
//
|
||||
// We only set the top-level PML4 for intercepting kernel-mode execution
|
||||
//
|
||||
VCpu->EptPageTable->PML4[0].ExecuteAccess = TRUE;
|
||||
// }
|
||||
|
||||
//
|
||||
// Invalidate the EPT cache
|
||||
//
|
||||
EptInveptSingleContext(VCpu->EptPointer.AsUInt);
|
||||
|
||||
//
|
||||
// It's not on normal EPTP
|
||||
//
|
||||
VCpu->NotNormalEptp = FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Restore the execution of the trap to adjusted trap state
|
||||
* @param VCpu The virtual processor's state
|
||||
|
|
@ -711,6 +752,7 @@ ExecTrapApplyMbecConfiguratinFromKernelSide(VIRTUAL_MACHINE_STATE * VCpu)
|
|||
//
|
||||
// Enable MBEC to detect execution in user-mode
|
||||
//
|
||||
ExecTrapChangeToNormalMbecEptp(VCpu);
|
||||
HvSetModeBasedExecutionEnableFlag(TRUE);
|
||||
VCpu->MbecEnabled = TRUE;
|
||||
|
||||
|
|
@ -724,6 +766,7 @@ ExecTrapApplyMbecConfiguratinFromKernelSide(VIRTUAL_MACHINE_STATE * VCpu)
|
|||
//
|
||||
// In case, the process is changed, we've disable the MBEC
|
||||
//
|
||||
ExecTrapChangeToNormalMbecEptp(VCpu);
|
||||
HvSetModeBasedExecutionEnableFlag(FALSE);
|
||||
VCpu->MbecEnabled = FALSE;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -118,6 +118,8 @@ ModeBasedExecHookDisableKernelModeExecution(PVMM_EPT_PAGE_TABLE EptTable)
|
|||
BOOLEAN
|
||||
ModeBasedExecHookEnableUsermodeExecution(PVMM_EPT_PAGE_TABLE EptTable)
|
||||
{
|
||||
EPT_PML1_ENTRY Pml1Entries[VMM_EPT_PML1E_COUNT];
|
||||
|
||||
//
|
||||
// Set execute access for PML4s
|
||||
//
|
||||
|
|
@ -145,6 +147,32 @@ ModeBasedExecHookEnableUsermodeExecution(PVMM_EPT_PAGE_TABLE EptTable)
|
|||
for (size_t j = 0; j < VMM_EPT_PML2E_COUNT; j++)
|
||||
{
|
||||
EptTable->PML2[i][j].UserModeExecute = TRUE;
|
||||
|
||||
//
|
||||
// If the PML2 entry is not a large page, we should set execute access for PML1s
|
||||
// It usually happens when the PML2 entry is not a large page and is previously
|
||||
// used for an EPT hook, so, it has PML1 entries
|
||||
//
|
||||
if (!EptTable->PML2[i][j].LargePage)
|
||||
{
|
||||
//
|
||||
// Shift to the left to get the PFN
|
||||
//
|
||||
MemoryMapperReadMemorySafeByPhysicalAddress(EptTable->PML2[i][j].PageFrameNumber << 12, (UINT64)Pml1Entries, PAGE_SIZE);
|
||||
|
||||
//
|
||||
// Set execute access for PML1s
|
||||
//
|
||||
for (size_t k = 0; k < VMM_EPT_PML1E_COUNT; k++)
|
||||
{
|
||||
Pml1Entries[k].UserModeExecute = TRUE;
|
||||
}
|
||||
|
||||
//
|
||||
// Write back the PML1 entries to the EPT page table
|
||||
//
|
||||
MemoryMapperWriteMemorySafeByPhysicalAddress(EptTable->PML2[i][j].PageFrameNumber << 12, (UINT64)Pml1Entries, PAGE_SIZE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -520,6 +520,18 @@ EptSplitLargePage(PVMM_EPT_PAGE_TABLE EptPageTable,
|
|||
EntryTemplate.WriteAccess = 1;
|
||||
EntryTemplate.ExecuteAccess = 1;
|
||||
|
||||
//
|
||||
// Set the UserModeExecute bit based on the global state of MBEC
|
||||
//
|
||||
if (g_ModeBasedExecutionControlState)
|
||||
{
|
||||
EntryTemplate.UserModeExecute = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
EntryTemplate.UserModeExecute = 0;
|
||||
}
|
||||
|
||||
//
|
||||
// copy other bits from target entry
|
||||
//
|
||||
|
|
@ -547,10 +559,23 @@ EptSplitLargePage(PVMM_EPT_PAGE_TABLE EptPageTable,
|
|||
//
|
||||
// Allocate a new pointer which will replace the 2MB entry with a pointer to 512 4096 byte entries
|
||||
//
|
||||
NewPointer.AsUInt = 0;
|
||||
NewPointer.WriteAccess = 1;
|
||||
NewPointer.ReadAccess = 1;
|
||||
NewPointer.ExecuteAccess = 1;
|
||||
NewPointer.AsUInt = 0;
|
||||
NewPointer.WriteAccess = 1;
|
||||
NewPointer.ReadAccess = 1;
|
||||
NewPointer.ExecuteAccess = 1;
|
||||
|
||||
//
|
||||
// Set the UserModeExecute bit based on the global state of MBEC
|
||||
//
|
||||
if (g_ModeBasedExecutionControlState)
|
||||
{
|
||||
NewPointer.UserModeExecute = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
NewPointer.UserModeExecute = 0;
|
||||
}
|
||||
|
||||
NewPointer.PageFrameNumber = (SIZE_T)VirtualAddressToPhysicalAddress(&NewSplit->PML1[0]) / PAGE_SIZE;
|
||||
|
||||
//
|
||||
|
|
|
|||
|
|
@ -118,7 +118,6 @@ typedef struct _EPT_STATE
|
|||
LIST_ENTRY HookedPagesList; // A list of the details about hooked pages
|
||||
MTRR_RANGE_DESCRIPTOR MemoryRanges[NUM_MTRR_ENTRIES]; // Physical memory ranges described by the BIOS in the MTRRs. Used to build the EPT identity mapping.
|
||||
UINT32 NumberOfEnabledMemoryRanges; // Number of memory ranges specified in MemoryRanges
|
||||
PVMM_EPT_PAGE_TABLE EptPageTable; // Page table entries for EPT operation
|
||||
UINT8 DefaultMemoryType;
|
||||
} EPT_STATE, *PEPT_STATE;
|
||||
|
||||
|
|
|
|||
|
|
@ -148,7 +148,7 @@ UdHandleInstantBreak(PROCESSOR_DEBUGGING_STATE * DbgState,
|
|||
// Since the adding it to the watching list will take effect from the next
|
||||
// CR3 vm-exit, we should change the state of the core to prevent further execution
|
||||
//
|
||||
// ConfigureExecTrapApplyMbecConfiguratinFromKernelSide(DbgState->CoreId);
|
||||
ConfigureExecTrapApplyMbecConfiguratinFromKernelSide(DbgState->CoreId);
|
||||
|
||||
//
|
||||
// Handling state through the user-mode debugger
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue