Bitdefender Hypervisor Memory Introspection
winintobj.c File Reference

This file contains detection logic for interrupt objects in KPRCB, which are used in order to set handlers for unexpected exceptions on most of Windows versions. More...

#include "winintobj.h"
#include "integrity.h"
#include "exceptions.h"
#include "alerts.h"
#include "kernvm.h"

Go to the source code of this file.

Data Structures

struct  _INTOBJ_PROT_DESCRIPTOR
 Structure describing a protected interrupt object. More...
 
struct  _INTOBJ_PERPROC_DESCRIPTOR
 Structure describing the protected InterruptObject array for a KPRCB associated with a CPU. More...
 

Macros

#define INTERRUPT_OBJECT_COUNT   0x20
 The number of protected interrupt objects. More...
 
#define DISPATCH_OFFSET
 Helper macro for computing the offset of DispatchAddress inside the nt!_KINTERRUPT structure. More...
 
#define SERVICE_OFFSET
 Helper macro for computing the offset of ServiceRoutine inside the nt!_KINTERRUPT structure. More...
 

Typedefs

typedef struct _INTOBJ_PROT_DESCRIPTOR INTOBJ_PROT_DESCRIPTOR
 Structure describing a protected interrupt object. More...
 
typedef struct _INTOBJ_PROT_DESCRIPTORPINTOBJ_PROT_DESCRIPTOR
 
typedef struct _INTOBJ_PERPROC_DESCRIPTOR INTOBJ_PERPROC_DESCRIPTOR
 Structure describing the protected InterruptObject array for a KPRCB associated with a CPU. More...
 
typedef struct _INTOBJ_PERPROC_DESCRIPTORPINTOBJ_PERPROC_DESCRIPTOR
 

Functions

static INTSTATUS IntWinIntObjSendIntegrityAlert (INTOBJ_PROT_DESCRIPTOR *Descriptor, EXCEPTION_VICTIM_ZONE *Victim, EXCEPTION_KM_ORIGINATOR *Originator, INTRO_ACTION Action, INTRO_ACTION_REASON Reason)
 Sends an introEventIntegrityViolation alert for a modified Interrupt Object entry. More...
 
static INTSTATUS IntWinIntObjHandleModification (INTOBJ_PROT_DESCRIPTOR *Descriptor, QWORD ObjectGva, INTRO_ACTION *Action)
 Handles the modification of an interrupt object. More...
 
static INTSTATUS IntWinIntObjHandleObjectModification (INTEGRITY_REGION *IntegrityRegion)
 Integrity callback for modifications detected inside protected objects. More...
 
static INTSTATUS IntWinIntObjHandleArrayModification (INTEGRITY_REGION *IntegrityRegion)
 Integrity callback for modifications detected inside the array containing the protected objects. More...
 
INTSTATUS IntWinIntObjProtect (void)
 Protects the interrupt objects which are present in the KPRCB's InterruptObject array. More...
 
INTSTATUS IntWinIntObjUnprotect (void)
 Uninitializes the interrupt objects protection. More...
 

Variables

INTOBJ_PERPROC_DESCRIPTORgDescriptors
 Global array containing the per CPU protection descriptors for each InterruptObject array. More...
 

Detailed Description

This file contains detection logic for interrupt objects in KPRCB, which are used in order to set handlers for unexpected exceptions on most of Windows versions.

As observed, for some exceptions (for example int 0x15), the control is given to KiIsrLinkage, where the kernel consults KPRCB.InterruptObject[InterruptCode]. If there is no such object associated to the interrupt code, the kernel just dispatches the exception as being unhandled. However, if a KINTERRUPT object is in the given array, the kernel will call DispatchAddress from the given object, which in turn would need to handle the interrupt exit and would pass the control to ServiceRoutine from the given object. Since interrupts can be issued from everywhere, one can forge some object for an unexpected exception in order to gain privileged execution in kernel-mode. For this purpose, we will monitor for the first 0x20 objects in the InterruptObject array from each KPRCB in order to verify relocations or new objects being added when these actions occur. Moreover, the introcore engine will monitor the DispatchAddress and ServiceRoutine fields for each object in the first 0x20, in order to detect and block possible modifications being done with the purpose of detouring the execution when an exception takes place.

Definition in file winintobj.c.

Macro Definition Documentation

◆ DISPATCH_OFFSET

#define DISPATCH_OFFSET
Value:
FIELD_OFFSET(KINTERRUPT_COMMON32, DispatchAddress))
BOOLEAN Guest64
True if this is a 64-bit guest, False if it is a 32-bit guest.
Definition: guests.h:290
The common part of nt!_KINTERRUPT on all x86 Windows versions.
Definition: wddefs.h:1961
GUEST_STATE gGuest
The current guest state.
Definition: guests.c:50
#define FIELD_OFFSET(type, field)
Definition: introdefs.h:239
The common part of nt!_KINTERRUPT on all x64 Windows versions.
Definition: wddefs.h:1984

Helper macro for computing the offset of DispatchAddress inside the nt!_KINTERRUPT structure.

Definition at line 40 of file winintobj.c.

Referenced by IntWinIntObjHandleArrayModification(), IntWinIntObjHandleModification(), and IntWinIntObjProtect().

◆ INTERRUPT_OBJECT_COUNT

#define INTERRUPT_OBJECT_COUNT   0x20

The number of protected interrupt objects.

Definition at line 35 of file winintobj.c.

Referenced by IntWinIntObjHandleArrayModification(), IntWinIntObjProtect(), and IntWinIntObjUnprotect().

◆ SERVICE_OFFSET

#define SERVICE_OFFSET
Value:
BOOLEAN Guest64
True if this is a 64-bit guest, False if it is a 32-bit guest.
Definition: guests.h:290
The common part of nt!_KINTERRUPT on all x86 Windows versions.
Definition: wddefs.h:1961
GUEST_STATE gGuest
The current guest state.
Definition: guests.c:50
#define FIELD_OFFSET(type, field)
Definition: introdefs.h:239
The common part of nt!_KINTERRUPT on all x64 Windows versions.
Definition: wddefs.h:1984

Helper macro for computing the offset of ServiceRoutine inside the nt!_KINTERRUPT structure.

Definition at line 45 of file winintobj.c.

Referenced by IntWinIntObjHandleArrayModification(), IntWinIntObjHandleModification(), and IntWinIntObjProtect().

Typedef Documentation

◆ INTOBJ_PERPROC_DESCRIPTOR

Structure describing the protected InterruptObject array for a KPRCB associated with a CPU.

◆ INTOBJ_PROT_DESCRIPTOR

Structure describing a protected interrupt object.

◆ PINTOBJ_PERPROC_DESCRIPTOR

◆ PINTOBJ_PROT_DESCRIPTOR

Function Documentation

◆ IntWinIntObjHandleArrayModification()

static INTSTATUS IntWinIntObjHandleArrayModification ( INTEGRITY_REGION IntegrityRegion)
static

Integrity callback for modifications detected inside the array containing the protected objects.

This function is used for monitoring relocations of objects inside the KPRCB's InterruptObject array. Based on the objects that are relocated, a detection can be made, for example, when a fake object is overwritten in the array. This function will handle the logic of enforcing the decided action from IntWinIntObjHandleModification, by either protecting the new object, if the relocation is deemed legitimate, or overwriting the old object if not.

Parameters
[in,out]IntegrityRegionThe integrity region associated with the monitorized array.
Returns
INT_STATUS_SUCCESS if successful, or an appropriate INTSTATUS error value.

Definition at line 331 of file winintobj.c.

Referenced by IntWinIntObjProtect().

◆ IntWinIntObjHandleModification()

static INTSTATUS IntWinIntObjHandleModification ( INTOBJ_PROT_DESCRIPTOR Descriptor,
QWORD  ObjectGva,
INTRO_ACTION Action 
)
static

Handles the modification of an interrupt object.

This function handles the detected modification and takes an action after consulting the exception mechanism. Note that this function can be called either when an object has been relocated, or when the object has been modified.

Parameters
[in]DescriptorThe INTOBJ_PROT_DESCRIPTOR descriptor associated with the modified object.
[in]ObjectGvaThe virtual address of the object. Note that, when an object is relocated, this will contain a different address than what is protected through the integrity objects associated in the given descriptor.
[out]ActionThe action that is going to be decided by this function.
Returns
INT_STATUS_SUCCESS if successful, or an appropriate INTSTATUS error value.

Definition at line 137 of file winintobj.c.

Referenced by IntWinIntObjHandleArrayModification(), and IntWinIntObjHandleObjectModification().

◆ IntWinIntObjHandleObjectModification()

static INTSTATUS IntWinIntObjHandleObjectModification ( INTEGRITY_REGION IntegrityRegion)
static

Integrity callback for modifications detected inside protected objects.

This function will be called whenever a modification is detected over the DispatchAddress or ServiceRoutine fields of the protected KINTERRUPT structure in the InterruptObject array. Note that this function will handle the logic of enforcing the action which was decided by IntWinIntObjHandleModification.

Parameters
[in,out]IntegrityRegionThe integrity region associated with the protected field.
Returns
INT_STATUS_SUCCESS if successful, or an appropriate INTSTATUS error value.

Definition at line 276 of file winintobj.c.

Referenced by IntWinIntObjHandleArrayModification(), and IntWinIntObjProtect().

◆ IntWinIntObjProtect()

INTSTATUS IntWinIntObjProtect ( void  )

Protects the interrupt objects which are present in the KPRCB's InterruptObject array.

This will create an integrity region for the array on each CPU's KPRCB, in order to monitor it, through IntWinIntObjHandleArrayModification, so that the introspection engine can be notified whenever an interrupt object relocation takes place. The DispatchAddress and ServiceRoutine fields are protected in each interrupt object, for which IntWinIntObjHandleObjectModification will be called whenever a modification is detected.

Return values
INT_STATUS_SUCCESSOn success.
INT_STATUS_NOT_INITIALIZEDIf there is no CPU for which protection can be enforced.
INT_STATUS_NOT_NEEDED_HINTIf the guest is not 64 bits or if the KPRCB does not have an InterruptObject associated.
INT_STATUS_INSUFFICIENT_RESOURCESIf there are not enough resources for the protection to be enforced.

Definition at line 473 of file winintobj.c.

Referenced by IntGuestUpdateCoreOptions(), and IntWinGuestActivateProtection().

◆ IntWinIntObjSendIntegrityAlert()

static INTSTATUS IntWinIntObjSendIntegrityAlert ( INTOBJ_PROT_DESCRIPTOR Descriptor,
EXCEPTION_VICTIM_ZONE Victim,
EXCEPTION_KM_ORIGINATOR Originator,
INTRO_ACTION  Action,
INTRO_ACTION_REASON  Reason 
)
static

Sends an introEventIntegrityViolation alert for a modified Interrupt Object entry.

Parameters
[in]DescriptorThe INTOBJ_PROT_DESCRIPTOR descriptor associated with the modified object.
[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 75 of file winintobj.c.

Referenced by IntWinIntObjHandleModification().

◆ IntWinIntObjUnprotect()

INTSTATUS IntWinIntObjUnprotect ( void  )

Uninitializes the interrupt objects protection.

This function will remove all integrity regions associated with protected interrupt object fields, as well as the integrity regions used for monitoring the InterrupObject array.

Return values
INT_STATUS_SUCCESSOn success.
INT_STATUS_NOT_INITIALIZEDIf the protection was not initialized beforehand.

Definition at line 609 of file winintobj.c.

Referenced by IntGuestUpdateCoreOptions(), and IntWinIntObjProtect().

Variable Documentation

◆ gDescriptors

Global array containing the per CPU protection descriptors for each InterruptObject array.

Definition at line 71 of file winintobj.c.