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

Go to the source code of this file.

Functions

static INTSTATUS IntWinIdtSendIntegrityAlert (EXCEPTION_VICTIM_ZONE *Victim, EXCEPTION_KM_ORIGINATOR *Originator, INTRO_ACTION Action, INTRO_ACTION_REASON Reason)
 Sends an introEventIntegrityViolation alert for an IDT entry. More...
 
static INTSTATUS IntWinIdtHandleModification (INTEGRITY_REGION *IntegrityRegion)
 Handles IDT modifications detected by the integrity mechanism. This is the integrity callback set by IntWinIdtProtectOnCpuIntegrity. More...
 
static INTSTATUS IntWinIdtWriteHandler (void *Context, void *Hook, QWORD Address, INTRO_ACTION *Action)
 Handles IDT modifications detected by the EPT mechanism. This is the EPT callback set by IntWinIdtProtectOnCpuEpt. More...
 
static INTSTATUS IntWinIdtProtectOnCpuEpt (DWORD CpuNumber)
 Protects the IDT on a guest CPU against writes using an EPT hook. More...
 
static INTSTATUS IntWinIdtProtectOnCpuIntegrity (DWORD CpuNumber)
 Protects the IDT on a guest CPU against writes using the integrity mechanism. More...
 
static INTSTATUS IntWinIdtUnprotectOnCpuEpt (DWORD CpuNumber)
 Removes the EPT write protection for a IDT. More...
 
static INTSTATUS IntWinIdtUnprotectOnCpuIntergity (DWORD CpuNumber)
 Removes the integrity protection for a IDT. More...
 
INTSTATUS IntWinIdtProtectOnCpu (DWORD CpuNumber)
 Protects the IDT against writes on a CPU. More...
 
INTSTATUS IntWinIdtUnprotectOnCpu (DWORD CpuNumber)
 Removes the IDT write protection for a CPU. More...
 
INTSTATUS IntWinIdtProtectAll (void)
 Activates the IDT protection for all the guest CPUs. More...
 
INTSTATUS IntWinIdtUnprotectAll (void)
 Removes the IDT protection for all the guest CPUs. More...
 

Function Documentation

◆ IntWinIdtHandleModification()

static INTSTATUS IntWinIdtHandleModification ( INTEGRITY_REGION IntegrityRegion)
static

Handles IDT modifications detected by the integrity mechanism. This is the integrity callback set by IntWinIdtProtectOnCpuIntegrity.

When this callback is invoked, we know for sure that a change to the IDT was made, but we don't know exactly what changed. This function will find the modified region, revert the changes and report the violation. If the INTRO_OPT_KM_BETA_DETECTIONS option is active, or if the IDT protection is set to log-only or feedback-only the changes will not be reverted.

If the changes are allowed, the new contents of the protected region will be considered to be the original ones, so if a further change is done (for example, if the guest restore the previous contents), a new alert will be triggered.

Parameters
[in,out]IntegrityRegionThe integrity region that protects the IDT.
Returns
INT_STATUS_SUCCESS if successful, or an appropriate INTSTATUS error value.

Definition at line 70 of file winidt.c.

Referenced by IntWinIdtProtectOnCpuIntegrity().

◆ IntWinIdtProtectAll()

INTSTATUS IntWinIdtProtectAll ( void  )

Activates the IDT protection for all the guest CPUs.

Returns
INT_STATUS_SUCCESS if successful, or an appropriate INTSTATUS error value

Definition at line 559 of file winidt.c.

Referenced by IntGuestUpdateCoreOptions(), and IntWinGuestActivateProtection().

◆ IntWinIdtProtectOnCpu()

INTSTATUS IntWinIdtProtectOnCpu ( DWORD  CpuNumber)

Protects the IDT against writes on a CPU.

For Windows versions older than 16299 or for 32-bit Windows versions the integrity mechanism is used because the IDT and the GDT are placed in the same page on those versions, and the GDT is written very often, which will end up causing performance problems, due to the high amount of VMEXITs that will be generated. The integrity mechanism will not be able to catch a change as soon as it is done, as it does the checks periodically, and will not be able to consult the exceptions mechanism. For all the other Windows versions, an EPT write hook is placed on the IDT. We can do that because on those versions the IDT is in its own page, so we can hook it without expecting a large number of VMEXITs, as the IDT is not written very often.

Parameters
[in]CpuNumberThe CPU for which the IDT will be protected. Can not be IG_CURRENT_VCPU.
Return values
INT_STATUS_SUCCESSin case of success.
INT_STATUS_INVALID_PARAMETER_2if CpuNumber is not valid.
INT_STATUS_NOT_INITIALIZED_HINTif the base of the IDT on the given CPU is not a valid kernel pointer.

Definition at line 479 of file winidt.c.

Referenced by IntDtrHandleWrite(), and IntWinIdtProtectAll().

◆ IntWinIdtProtectOnCpuEpt()

static INTSTATUS IntWinIdtProtectOnCpuEpt ( DWORD  CpuNumber)
static

Protects the IDT on a guest CPU against writes using an EPT hook.

This will set IntWinIdtWriteHandler as the EPT violation handler and will protect the first 32 entries of the IDT (or up to the IDT limit, if less than 32 entries are valid).

Parameters
[in]CpuNumberThe CPU on which to protect the IDT. Can not be IG_CURRENT_VCPU.
Return values
INT_STATUS_SUCCESSin case of success.
INT_STATUS_ALREADY_INITIALIZED_HINTif the IDT for the given CPU is already protected.

Definition at line 301 of file winidt.c.

Referenced by IntWinIdtProtectOnCpu().

◆ IntWinIdtProtectOnCpuIntegrity()

static INTSTATUS IntWinIdtProtectOnCpuIntegrity ( DWORD  CpuNumber)
static

Protects the IDT on a guest CPU against writes using the integrity mechanism.

This will set IntWinIdtHandleModification as the EPT violation handler and will protect the first 32 entries of the IDT (or up to the IDT limit, if less than 32 entries are valid).

Parameters
[in]CpuNumberThe CPU on which to protect the IDT. Can not be IG_CURRENT_VCPU.
Return values
INT_STATUS_SUCCESSin case of success.
INT_STATUS_ALREADY_INITIALIZED_HINTif the IDT for the given CPU is already protected.

Definition at line 358 of file winidt.c.

Referenced by IntWinIdtProtectOnCpu().

◆ IntWinIdtSendIntegrityAlert()

static INTSTATUS IntWinIdtSendIntegrityAlert ( EXCEPTION_VICTIM_ZONE Victim,
EXCEPTION_KM_ORIGINATOR Originator,
INTRO_ACTION  Action,
INTRO_ACTION_REASON  Reason 
)
static

Sends an introEventIntegrityViolation alert for an IDT entry.

Parameters
[in]VictimThe victim information, as obtained from the exception mechanism.
[in]OriginatorOriginator information, as obtained from the exception mechanism.
[in]ActionThe action that was taken.
[in]ReasonThe reason for which Action was taken.
Returns
INT_STATUS_SUCCESS if successful, or an appropriate INTSTATUS error value.

Definition at line 11 of file winidt.c.

Referenced by IntWinIdtHandleModification().

◆ IntWinIdtUnprotectAll()

INTSTATUS IntWinIdtUnprotectAll ( void  )

Removes the IDT protection for all the guest CPUs.

Returns
INT_STATUS_SUCCESS if successful, or an appropriate INTSTATUS error value

Definition at line 590 of file winidt.c.

Referenced by IntGuestUpdateCoreOptions().

◆ IntWinIdtUnprotectOnCpu()

INTSTATUS IntWinIdtUnprotectOnCpu ( DWORD  CpuNumber)

Removes the IDT write protection for a CPU.

Parameters
[in]CpuNumberThe CPU for which the protection is removed. Can not be IG_CURRENT_VCPU.
Return values
INT_STATUS_SUCCESSin case of success.
INT_STATUS_INVALID_PARAMETER_2if CpuNumber is not valid.
INT_STATUS_NOT_INITIALIZED_HINTif the base of the IDT on the given CPU is not a valid kernel pointer.

Definition at line 524 of file winidt.c.

Referenced by IntDtrHandleWrite(), and IntWinIdtUnprotectAll().

◆ IntWinIdtUnprotectOnCpuEpt()

static INTSTATUS IntWinIdtUnprotectOnCpuEpt ( DWORD  CpuNumber)
static

Removes the EPT write protection for a IDT.

This removes the hook set by IntWinIdtProtectOnCpuEpt.

Parameters
[in]CpuNumberThe CPU on which to remove the protection.
Return values
INT_STATUS_SUCCESSin case of success.
INT_STATUS_NOT_NEEDED_HINTif the IDT is not protected using the EPT on this CPU.

Definition at line 405 of file winidt.c.

Referenced by IntWinIdtUnprotectOnCpu().

◆ IntWinIdtUnprotectOnCpuIntergity()

static INTSTATUS IntWinIdtUnprotectOnCpuIntergity ( DWORD  CpuNumber)
static

Removes the integrity protection for a IDT.

This removes the integrity region set by IntWinIdtProtectOnCpuIntegrity.

Parameters
[in]CpuNumberThe CPU on which to remove the protection.
Return values
INT_STATUS_SUCCESSin case of success.
INT_STATUS_NOT_NEEDED_HINTif the IDT is not protected using the EPT on this CPU.

Definition at line 441 of file winidt.c.

Referenced by IntWinIdtUnprotectOnCpu().

◆ IntWinIdtWriteHandler()

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

Handles IDT modifications detected by the EPT mechanism. This is the EPT callback set by IntWinIdtProtectOnCpuEpt.

This function will check the exceptions mechanism and will decide if the write should be blocked and reported. If the INTRO_OPT_KM_BETA_DETECTIONS option is active, or if the IDT protection is set to log-only or feedback-only the changes will not be reverted.

Parameters
[in]ContextIgnored.
[in]HookThe hook for which this callback was invoked. Ignored.
[in]AddressThe written guest physical address. Ignored.
[out]ActionThe action that will be taken.
Return values
INT_STATUS_SUCCESSin case of success.
INT_STATUS_INVALID_PARAMETER_4if Action is NULL.
INT_STATUS_NOT_NEEDED_HINTif we can not find a valid IDT for the guest linear address from gVcpu. In this case Action will be introGuestAllowed.

Definition at line 172 of file winidt.c.

Referenced by IntWinIdtProtectOnCpuEpt().