Bitdefender Hypervisor Memory Introspection
winhal.c File Reference
#include "drivers.h"
#include "winhal.h"
#include "alerts.h"
#include "decoder.h"
#include "hook.h"
#include "winpe.h"

Go to the source code of this file.

Macros

#define HAL_HEAP_PROT_PAGES_EXEC   0x20
 The number of HAL heap pages to protect against executions. More...
 
#define MAX_INT_CTRL_TYPE_OFFSET   (gGuest.Guest64 ? 0xf0 : 0x6c)
 
#define MIN_INT_CTRL_TYPE_OFFSET   (gGuest.Guest64 ? 0xc0 : 0x60)
 
#define MAX_INT_CTRL_COUNT   20
 
#define HAL_HEAP_ORIGINAL   0xFFFFFFFFF0000000
 
#define MASK_DEVICE_ADDRESS_FEC   0x00000000fec00000
 
#define MASK_DEVICE_ADDRESS_FED   0x00000000fed00000
 
#define MASK_DEVICE_ADDRESS_FEE   0x00000000fee00000
 
#define HAL_HEAP_PHYSICAL_ADDRESS   0x1000
 

Functions

static void IntWinHalSendAlert (EXCEPTION_VICTIM_ZONE const *Victim, EXCEPTION_KM_ORIGINATOR const *Originator, INTRO_ACTION Action, INTRO_ACTION_REASON Reason)
 Sends an introEventEptViolation for HAL alerts. More...
 
static INTSTATUS IntWinHalHandleHalIntCtrlWrite (KERNEL_DRIVER *Context, HOOK_GPA const *Hook, QWORD Address, INTRO_ACTION *Action)
 Handles writes done over the HAL interrupt controller. More...
 
static INTSTATUS IntWinHalHandleHalHeapExec (void *Context, HOOK_GPA *Hook, QWORD Address, INTRO_ACTION *Action)
 Handles execution attempts from the HAL heap. More...
 
static INTSTATUS IntWinHalHandleDispatchTableWrite (PINTEGRITY_REGION IntegrityRegion)
 Handles modifications done to the HAL dispatch table. More...
 
INTSTATUS IntWinHalProtectHalHeapExecs (void)
 Hooks the HAL heap against execution. More...
 
INTSTATUS IntWinHalUnprotectHalHeapExecs (void)
 Deactivates the HAL heap execution protection. More...
 
INTSTATUS IntWinHalProtectHalIntCtrl (void)
 Protects the HAL interrupt controller against writes. More...
 
INTSTATUS IntWinHalUnprotectHalIntCtrl (void)
 Deactivates the HAL interrupt controller write protection. More...
 
INTSTATUS IntWinHalProtectHalDispatchTable (void)
 Activates the HAL dispatch table protection. More...
 
INTSTATUS IntWinHalUnprotectHalDispatchTable (void)
 Deactivates the HAL dispatch table protection. More...
 
static BOOLEAN IntWinHalIsIntController (QWORD CheckedAddress, QWORD HalHeap)
 Checks if a guest memory range is the HAL interrupt controller. More...
 
static INTSTATUS IntWinHalFindInterruptController (QWORD HalHeap, QWORD HalHeapSize, QWORD *HalInterruptController)
 Attempts to find the Hal Interrupt Controller address within the .data section of Hal. More...
 
static INTSTATUS IntWinHalFindHalHeapAndInterruptController (QWORD *HalHeapBaseAddress, QWORD *HalInterruptController)
 Attempts to find the Hal Heap and the Hal Interrupt Controller address within the .data section of Hal. More...
 
INTSTATUS IntWinHalCreateHalData (void)
 Initializes gHalData. More...
 
INTSTATUS IntWinHalUpdateProtection (void)
 Updates any of the HAL protections. More...
 
void IntWinHalUninit (void)
 Frees any resources held by gHalData and removes all the HAL protections. More...
 

Variables

static WIN_HAL_DATA gHalData = { 0 }
 The HAL information. More...
 

Macro Definition Documentation

◆ HAL_HEAP_ORIGINAL

#define HAL_HEAP_ORIGINAL   0xFFFFFFFFF0000000

◆ HAL_HEAP_PHYSICAL_ADDRESS

#define HAL_HEAP_PHYSICAL_ADDRESS   0x1000

◆ HAL_HEAP_PROT_PAGES_EXEC

#define HAL_HEAP_PROT_PAGES_EXEC   0x20

The number of HAL heap pages to protect against executions.

Definition at line 12 of file winhal.c.

Referenced by IntWinHalCreateHalData(), and IntWinHalFindHalHeapAndInterruptController().

◆ MASK_DEVICE_ADDRESS_FEC

#define MASK_DEVICE_ADDRESS_FEC   0x00000000fec00000

◆ MASK_DEVICE_ADDRESS_FED

#define MASK_DEVICE_ADDRESS_FED   0x00000000fed00000

◆ MASK_DEVICE_ADDRESS_FEE

#define MASK_DEVICE_ADDRESS_FEE   0x00000000fee00000

◆ MAX_INT_CTRL_COUNT

#define MAX_INT_CTRL_COUNT   20

◆ MAX_INT_CTRL_TYPE_OFFSET

#define MAX_INT_CTRL_TYPE_OFFSET   (gGuest.Guest64 ? 0xf0 : 0x6c)

◆ MIN_INT_CTRL_TYPE_OFFSET

#define MIN_INT_CTRL_TYPE_OFFSET   (gGuest.Guest64 ? 0xc0 : 0x60)

Function Documentation

◆ IntWinHalCreateHalData()

INTSTATUS IntWinHalCreateHalData ( void  )

Initializes gHalData.

Will collect the relevant information from the guest and if any of the INTRO_OPT_PROT_KM_HAL_DISP_TABLE, INTRO_OPT_PROT_KM_HAL_HEAP_EXEC, or INTRO_OPT_PROT_KM_HAL_INT_CTRL option is active, will activate the needed protections.

Returns
INT_STATUS_SUCCESS if successful, or an appropriate INTSTATUS error value

Definition at line 1258 of file winhal.c.

Referenced by IntWinGuestFinishInit().

◆ IntWinHalFindHalHeapAndInterruptController()

static INTSTATUS IntWinHalFindHalHeapAndInterruptController ( QWORD HalHeapBaseAddress,
QWORD HalInterruptController 
)
static

Attempts to find the Hal Heap and the Hal Interrupt Controller address within the .data section of Hal.

On Windows versions newer than RS2 the Hal Hep is randomized using KASLR. Within the .data section of Hal there are 2 variables (HalpHeapStart and HalpOriginalHeapStart) that seem to point to the Hal Heap. This function aims to find the Hal Heap using the following mechanism:

  • Find kernel addresses within the .data section of Hal
  • Translate the addresses and analyze the other entries from the same PT
  • If other entries from the same PT point to physical devices, we have a candidate address
  • In order to make sure our candidate address is actually the Hal Heap start, try to find the Hal Interrupt Controller using that address
Parameters
[out]HalHeapBaseAddressThe Hal Heap address.
[out]HalInterruptControllerThe Hal Interrupt Controller address.
Returns
INT_STATUS_SUCCESS On success
INT_STATUS_NOT_FOUND If the Hal Heap was not found

Definition at line 1046 of file winhal.c.

Referenced by IntWinHalCreateHalData().

◆ IntWinHalFindInterruptController()

static INTSTATUS IntWinHalFindInterruptController ( QWORD  HalHeap,
QWORD  HalHeapSize,
QWORD HalInterruptController 
)
static

Attempts to find the Hal Interrupt Controller address within the .data section of Hal.

This functions reads the .data section of the Hal module in order to find the RVA of the Hal Interrupt Controller. Candidate RVAs are verified using IntWinHalIsIntController in order to find the correct address.

Parameters
[in]HalHeapThe Hal Heap address.
[in]HalHeapSizeThe Hal Heap size (may not be the entire Hal Heap).
[out]HalInterruptControllerThe Hal Interrupt Controller address.
Returns
INT_STATUS_SUCCESS On success
INT_STATUS_NOT_FOUND If the Hal Interrupt Controller was not found

Definition at line 962 of file winhal.c.

Referenced by IntWinHalCreateHalData(), and IntWinHalFindHalHeapAndInterruptController().

◆ IntWinHalHandleDispatchTableWrite()

static INTSTATUS IntWinHalHandleDispatchTableWrite ( PINTEGRITY_REGION  IntegrityRegion)
static

Handles modifications done to the HAL dispatch table.

This is the integrity callback set by IntWinHalProtectHalDispatchTable.

Parameters
[in,out]IntegrityRegionThe integrity region used to protect the HAL dispatch table.
Returns
INT_STATUS_SUCCESS if successful, or an appropriate INTSTATUS error value.

Definition at line 382 of file winhal.c.

Referenced by IntWinHalProtectHalDispatchTable().

◆ IntWinHalHandleHalHeapExec()

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

Handles execution attempts from the HAL heap.

This is the EPT hook handler set by IntWinHalProtectHalHeapExecs. If execution comes from a CPU that is in real mode it is allowed, as it will be the result of an IPI sent at boot in order to wake up an AP. If there is an exception for the executed code, the execution is allowed, and the hook will be removed.

Parameters
[in]ContextThe context set by IntWinHalProtectHalHeapExecs. Ignored.
[in,out]HookThe hook for which this callback was invoked.
[in]AddressThe accessed physical address.
[out]ActionThe action to be taken.
Returns
INT_STATUS_SUCCESS if successful, or an appropriate INTSTATUS error value.

Definition at line 160 of file winhal.c.

Referenced by IntWinHalProtectHalHeapExecs().

◆ IntWinHalHandleHalIntCtrlWrite()

static INTSTATUS IntWinHalHandleHalIntCtrlWrite ( KERNEL_DRIVER Context,
HOOK_GPA const *  Hook,
QWORD  Address,
INTRO_ACTION Action 
)
static

Handles writes done over the HAL interrupt controller.

This is the EPT write hook set by IntWinHalProtectHalIntCtrl.

Parameters
[in]ContextThe context set by IntWinHalProtectHalIntCtrl. This will be the hal.dll KERNEL_DRIVER.
[in]HookThe hook for which this callback was invoked.
[in]AddressThe accessed physical address.
[out]ActionThe action to be taken.
Return values
INT_STATUS_SUCCESSin case of success.
INT_STATUS_INVALID_PARAMETER_1if Context is NULL.

Definition at line 70 of file winhal.c.

Referenced by IntWinHalProtectHalIntCtrl().

◆ IntWinHalIsIntController()

static BOOLEAN IntWinHalIsIntController ( QWORD  CheckedAddress,
QWORD  HalHeap 
)
static

Checks if a guest memory range is the HAL interrupt controller.

The check is done based on invariants:

  • the area starts with a list, with the next element pointing in the HAL heap as well
  • starting with the 4th guest pointer, all the following pointers are either NULL, or point inside the HAL heap
  • the type must be 2
Parameters
[in]CheckedAddressThe guest virtual address to check.
[in]HalHeapThe Hal Heap address.
Returns
True if CheckedAddress points to the HAL interrupt controller; False if it does not.

Definition at line 833 of file winhal.c.

Referenced by IntWinHalFindInterruptController().

◆ IntWinHalProtectHalDispatchTable()

INTSTATUS IntWinHalProtectHalDispatchTable ( void  )

Activates the HAL dispatch table protection.

Will set IntWinHalHandleDispatchTableWrite as the EPT hook handler.

Returns
INT_STATUS_SUCCESS if successful, or an appropriate INTSTATUS error value

Definition at line 758 of file winhal.c.

Referenced by IntWinHalCreateHalData(), and IntWinHalUpdateProtection().

◆ IntWinHalProtectHalHeapExecs()

INTSTATUS IntWinHalProtectHalHeapExecs ( void  )

Hooks the HAL heap against execution.

This will protect the first 16 pages from the HAL heap. Based on the Windows version, some of them already have the NX bit set inside the guest page tables. IntWinHalHandleHalHeapExec will be set as the EPT hook handler. Pages that translate to physical address 0 or that are not present are not hooked.

Return values
INT_STATUS_SUCCESSin case of success.
INT_STATUS_ALREADY_INITIALIZED_HINTif the HAL heap is already protected.
INT_STATUS_NOT_NEEDED_HINTif the HAL heap is not yet initialized.

Definition at line 562 of file winhal.c.

Referenced by IntWinHalCreateHalData(), and IntWinHalUpdateProtection().

◆ IntWinHalProtectHalIntCtrl()

INTSTATUS IntWinHalProtectHalIntCtrl ( void  )

Protects the HAL interrupt controller against writes.

Will set IntWinHalHandleHalIntCtrlWrite as the EPT hook callback.

Returns
INT_STATUS_SUCCESS if successful, or an appropriate INTSTATUS error value

Definition at line 681 of file winhal.c.

Referenced by IntWinHalCreateHalData(), and IntWinHalUpdateProtection().

◆ IntWinHalSendAlert()

static void IntWinHalSendAlert ( EXCEPTION_VICTIM_ZONE const *  Victim,
EXCEPTION_KM_ORIGINATOR const *  Originator,
INTRO_ACTION  Action,
INTRO_ACTION_REASON  Reason 
)
static

Sends an introEventEptViolation for HAL alerts.

Parameters
[in]VictimVictim information.
[in]OriginatorOriginator information.
[in]ActionThe action taken.
[in]ReasonThe reason for which Action was taken.

Definition at line 19 of file winhal.c.

Referenced by IntWinHalHandleHalIntCtrlWrite().

◆ IntWinHalUninit()

void IntWinHalUninit ( void  )

Frees any resources held by gHalData and removes all the HAL protections.

Definition at line 1445 of file winhal.c.

Referenced by IntWinGuestUninit().

◆ IntWinHalUnprotectHalDispatchTable()

INTSTATUS IntWinHalUnprotectHalDispatchTable ( void  )

Deactivates the HAL dispatch table protection.

Returns
INT_STATUS_SUCCESS if successful, or an appropriate INTSTATUS error value

Definition at line 801 of file winhal.c.

Referenced by IntWinHalUninit(), and IntWinHalUpdateProtection().

◆ IntWinHalUnprotectHalHeapExecs()

INTSTATUS IntWinHalUnprotectHalHeapExecs ( void  )

Deactivates the HAL heap execution protection.

Returns
INT_STATUS_SUCCESS if successful, or an appropriate INTSTATUS error value

Definition at line 656 of file winhal.c.

Referenced by IntWinHalUninit(), and IntWinHalUpdateProtection().

◆ IntWinHalUnprotectHalIntCtrl()

INTSTATUS IntWinHalUnprotectHalIntCtrl ( void  )

Deactivates the HAL interrupt controller write protection.

Returns
INT_STATUS_SUCCESS if successful, or an appropriate INTSTATUS error value

Definition at line 733 of file winhal.c.

Referenced by IntWinHalUninit(), and IntWinHalUpdateProtection().

◆ IntWinHalUpdateProtection()

INTSTATUS IntWinHalUpdateProtection ( void  )

Updates any of the HAL protections.

If any of the INTRO_OPT_PROT_KM_HAL_DISP_TABLE, INTRO_OPT_PROT_KM_HAL_HEAP_EXEC, or INTRO_OPT_PROT_KM_HAL_INT_CTRL option is changed, the protection is enabled, or disabled, based on the new value.

Returns
INT_STATUS_SUCCESS if successful, or an appropriate INTSTATUS error value

Definition at line 1385 of file winhal.c.

Referenced by IntGuestUpdateCoreOptions().

Variable Documentation

◆ gHalData

WIN_HAL_DATA gHalData = { 0 }
static

The HAL information.

Definition at line 15 of file winhal.c.