Bitdefender Hypervisor Memory Introspection
winselfmap.c File Reference
#include "winselfmap.h"
#include "alerts.h"
#include "hook.h"

Go to the source code of this file.

Functions

static void IntWinSelfMapSelfMapUpdate (QWORD ModifiedCr3, WIN_PROCESS_OBJECT *Process, QWORD NewValue)
 Updates the self map entry value for a process. More...
 
static INTSTATUS IntWinSelfMapHandleCr3SelfMapModification (QWORD NewValue, QWORD OldValue, WIN_PROCESS_OBJECT *Process, QWORD Cr3)
 Handles self map entry modifications for a process. More...
 
static INTSTATUS IntWinSelfMapCheckSelfMapEntry (WIN_PROCESS_OBJECT *Process, const QWORD *CurrentKernelValue, const QWORD *CurrentUserValue)
 Checks the self map entry for a given process. More...
 
static INTSTATUS IntWinSelfMapHandleCr3SelfMapWrite (WIN_PROCESS_OBJECT *Context, void *Hook, QWORD Address, INTRO_ACTION *Action)
 Handles writes done to the self map entry inside a process page tables. More...
 
TIMER_FRIENDLY INTSTATUS IntWinSelfMapValidateSelfMapEntries (void)
 Validates the self map entries for every process in the system. More...
 
INTSTATUS IntWinSelfMapEnableSelfMapEntryProtection (void)
 Enables the self map protection mechanism for the entire system. More...
 
INTSTATUS IntWinSelfMapGetAndCheckSelfMapEntry (WIN_PROCESS_OBJECT *Process)
 Sets and validates the self map entry values for a process. More...
 
INTSTATUS IntWinSelfMapDisableSelfMapEntryProtection (void)
 Disables the self map entry protection for all the processes on the system. More...
 
INTSTATUS IntWinSelfMapProtectSelfMapIndex (WIN_PROCESS_OBJECT *Process)
 Protects the self map index of a process by placing an EPT write hook on it. More...
 
INTSTATUS IntWinSelfMapUnprotectSelfMapIndex (WIN_PROCESS_OBJECT *Process)
 Removes the EPT protection for the self map entry index of a process. More...
 

Variables

LIST_HEAD gWinProcesses
 The list of all the processes inside the guest. More...
 

Function Documentation

◆ IntWinSelfMapCheckSelfMapEntry()

static INTSTATUS IntWinSelfMapCheckSelfMapEntry ( WIN_PROCESS_OBJECT Process,
const QWORD CurrentKernelValue,
const QWORD CurrentUserValue 
)
static

Checks the self map entry for a given process.

This function verifies if any relevant bits have changed in the self map entry inside the Process page table. If it detects any changes, it lets IntWinSelfMapHandleCr3SelfMapModification handle those. The relevant changes are defined by SELF_MAP_ENTRY_IS_DETECTION.

If the process is swapped-out, the function does nothing.

Parameters
[in,out]ProcessThe process for which the checks are done
[in]CurrentKernelValueThe current value of the kernel Cr3. If this is NULL, the value will be read from the guest
[in]CurrentUserValueThe current value of the user Cr3. If KPTI is not enabled this should be NULL. If KPTI is enabled and this process has different Cr3 values for user and kernel mode, the value will be read from the guest
Returns
INT_STATUS_SUCCESS If successful, or an appropriate INTSTATUS error value.
INT_STATUS_NOT_NEEDED_HINT If the process is swapped-out.

Definition at line 141 of file winselfmap.c.

Referenced by IntWinSelfMapEnableSelfMapEntryProtection(), IntWinSelfMapGetAndCheckSelfMapEntry(), and IntWinSelfMapValidateSelfMapEntries().

◆ IntWinSelfMapDisableSelfMapEntryProtection()

INTSTATUS IntWinSelfMapDisableSelfMapEntryProtection ( void  )

Disables the self map entry protection for all the processes on the system.

This will deactivate protection and will remove any hooks set by IntWinSelfMapProtectSelfMapIndex

Return values
INT_STATUS_SUCCESSin case of success
INT_STATUS_NOT_INITIALIZED_HINTif the guest is not initialized or the protection is not active
INT_STATUS_NOT_NEEDED_HINTif the guest is not Windows, not using 4- or 5-level paging (the other paging modes do not use the self map mechanism)

Definition at line 656 of file winselfmap.c.

Referenced by IntGuestUpdateCoreOptions().

◆ IntWinSelfMapEnableSelfMapEntryProtection()

INTSTATUS IntWinSelfMapEnableSelfMapEntryProtection ( void  )

Enables the self map protection mechanism for the entire system.

It will first check the self map index of every process using IntWinSelfMapCheckSelfMapEntry, then the actual protection will be activated using IntWinSelfMapProtectSelfMapIndex.

Return values
INT_STATUS_SUCCESSin case of success
INT_STATUS_NOT_INITIALIZED_HINTif the guest is not initialized or the protection is not active
INT_STATUS_NOT_NEEDED_HINTif the guest is not Windows, not using 4- or 5-level paging (the other paging modes do not use the self map mechanism)

Definition at line 516 of file winselfmap.c.

Referenced by IntGuestUpdateCoreOptions().

◆ IntWinSelfMapGetAndCheckSelfMapEntry()

INTSTATUS IntWinSelfMapGetAndCheckSelfMapEntry ( WIN_PROCESS_OBJECT Process)

Sets and validates the self map entry values for a process.

If KPTI enabled for Process, this will read and validate both the kernel and the user Cr3. If not, only the kernel Cr3 will be considered, as the user Cr3 will be 0. The values are obtained from the _KPROCESS kernel structure. If the INTRO_OPT_PROT_KM_SELF_MAP_ENTRY option was used, and a malicious change of the self map value is detected, an alert will eventually be sent. If the process is swapped-out, the function does nothing.

Parameters
[in,out]ProcessThe process for which the values are read and validated
Return values
INT_STATUS_SUCCESSin case of success
INT_STATUS_INVALID_PARAMETER_1if Process is NULL
INT_STATUS_NOT_INITIALIZED_HINTif the guest is not initialized or the protection is not active
INT_STATUS_NOT_NEEDED_HINTif the guest is not Windows, not using 4- or 5-level paging (the other paging modes do not use the self map mechanism) or the process is swapped-out.

Definition at line 579 of file winselfmap.c.

Referenced by IntWinProcCreateProcessObject(), and IntWinProcDeleteProcessObject().

◆ IntWinSelfMapHandleCr3SelfMapModification()

static INTSTATUS IntWinSelfMapHandleCr3SelfMapModification ( QWORD  NewValue,
QWORD  OldValue,
WIN_PROCESS_OBJECT Process,
QWORD  Cr3 
)
static

Handles self map entry modifications for a process.

Parameters
[in]NewValueThe new self map entry value
[in]OldValueThe old self map entry value
[in,out]ProcessThe process for which the change was done
[in]Cr3The Cr3 for which the change was done
Return values
INT_STATUS_SUCCESSalways

Definition at line 41 of file winselfmap.c.

Referenced by IntWinSelfMapCheckSelfMapEntry().

◆ IntWinSelfMapHandleCr3SelfMapWrite()

static INTSTATUS IntWinSelfMapHandleCr3SelfMapWrite ( WIN_PROCESS_OBJECT Context,
void *  Hook,
QWORD  Address,
INTRO_ACTION Action 
)
static

Handles writes done to the self map entry inside a process page tables.

This is the handler of the EPT hook set by IntWinSelfMapProtectSelfMapIndex, which will be done for processes that are already protected. For processes that are not protected, the self map checks are done using the integrity mechanism by the IntWinSelfMapValidateSelfMapEntries function. In cases in which the present bit is removed, the hook on the page table entry is removed. This happens for privileged processes that do not keep their user Cr3 value. If the old value is 0, the action is allowed even if it would normally justify a detection, as we have to let the operating system load a Cr3 value if there is nothing loaded at the moment.

Parameters
[in,out]ContextThe process for which the change was made
[in]HookThe HOOK_GPA for which this callback was invoked
[in]AddressThe accessed guest physical address
[out]ActionThe action that must be taken
Returns
INT_STATUS_SUCCESS if successful, or an appropriate INTSTATUS error value

Definition at line 252 of file winselfmap.c.

Referenced by IntWinSelfMapProtectSelfMapIndex().

◆ IntWinSelfMapProtectSelfMapIndex()

INTSTATUS IntWinSelfMapProtectSelfMapIndex ( WIN_PROCESS_OBJECT Process)

Protects the self map index of a process by placing an EPT write hook on it.

Essentially, this will protect the user/supervisor bit, in order to make sure that user mode code can not access the page tables. Currently, this is enabled only for the system process, as other processes may swap out their Cr3 contents. Processes that have their self map entry protected in this way will have an EPT hook set on the page of their kernel and user Cr3 (if KPTI is enabled). Because of this, care should be taken when activating this for processes, as it may have a negative impact on performance because the kernel may do a lot of writes on those pages. This is manageable for processes that are already protected, as we have other hooks placed on their page tables already. The EPT hook handler used is IntWinSelfMapHandleCr3SelfMapWrite.

Parameters
[in]ProcessThe process for which the protection is activated
Return values
INT_STATUS_SUCCESSin case of success
INT_STATUS_INVALID_PARAMETER_1if Process is NULL
INT_STATUS_NOT_NEEDED_HINTif the guest is not Windows, not using 4- or 5-level paging (the other paging modes do not use the self map mechanism)

Definition at line 710 of file winselfmap.c.

Referenced by IntWinProcChangeProtectionFlags(), IntWinProcCreateProcessObject(), and IntWinSelfMapEnableSelfMapEntryProtection().

◆ IntWinSelfMapSelfMapUpdate()

static void IntWinSelfMapSelfMapUpdate ( QWORD  ModifiedCr3,
WIN_PROCESS_OBJECT Process,
QWORD  NewValue 
)
static

Updates the self map entry value for a process.

Parameters
[in]ModifiedCr3Used to signal which Cr3 is changed. If KPTI is enabled, this can either be the kernel (is it is equal to WIN_PROCESS_OBJECT.Cr3), or the user (if it is not) Cr3.
[in,out]ProcessThe process which will be updated. If ModifiedCr3 is equal to WIN_PROCESS_OBJECT.Cr3, the WIN_PROCESS_OBJECT.SelfMapEntryValue field will be updated; otherwise, the WIN_PROCESS_OBJECT.UserSelfMapEntryValue field will be updated
[in]NewValueThe new value to be used

Definition at line 13 of file winselfmap.c.

Referenced by IntWinSelfMapHandleCr3SelfMapModification(), and IntWinSelfMapHandleCr3SelfMapWrite().

◆ IntWinSelfMapUnprotectSelfMapIndex()

INTSTATUS IntWinSelfMapUnprotectSelfMapIndex ( WIN_PROCESS_OBJECT Process)

Removes the EPT protection for the self map entry index of a process.

This removes the EPT hooks set by IntWinSelfMapProtectSelfMapIndex.

Parameters
[in]ProcessThe process for which the protection is removed.
Return values
INT_STATUS_SUCCESSin case of success
INT_STATUS_INVALID_PARAMETER_1if Process is NULL

Definition at line 802 of file winselfmap.c.

Referenced by IntWinProcChangeProtectionFlags(), IntWinProcDeleteProcessObject(), and IntWinSelfMapDisableSelfMapEntryProtection().

◆ IntWinSelfMapValidateSelfMapEntries()

TIMER_FRIENDLY INTSTATUS IntWinSelfMapValidateSelfMapEntries ( void  )

Validates the self map entries for every process in the system.

This function is used by the integrity mechanism in order to perform self map entry validations. Due to performance reasons, we can't hook the self map entry for every process in the system. For processes that are already protected this is not a problem, as we already have hooks placed inside their page tables. For the other processes we delegate the check to the periodic integrity callback. It uses the IntWinSelfMapCheckSelfMapEntry function to check the self map entry for every process on the system.

Return values
INT_STATUS_SUCCESSin case of success
INT_STATUS_NOT_INITIALIZED_HINTif the guest is not initialized or the protection is not active
INT_STATUS_NOT_NEEDED_HINTif the guest is not Windows, not using 4- or 5-level paging (the other paging modes do not use the self map mechanism), or if the INTRO_OPT_PROT_KM_SELF_MAP_ENTRY activation option was not provided

Definition at line 453 of file winselfmap.c.

Referenced by IntHandleTimer().

Variable Documentation

◆ gWinProcesses

LIST_HEAD gWinProcesses

The list of all the processes inside the guest.

Definition at line 11 of file winprocesshp.c.