Bitdefender Hypervisor Memory Introspection
winumcrash.c File Reference
#include "winumcrash.h"
#include "alerts.h"
#include "guests.h"
#include "shellcode.h"
#include "winprocesshp.h"
#include "winthread.h"

Go to the source code of this file.

Macros

#define STILL_ACTIVE   0x00000103L
 
#define EXCEPTION_ACCESS_VIOLATION   0xC0000005L
 
#define EXCEPTION_DATATYPE_MISALIGNMENT   0x80000002L
 
#define EXCEPTION_BREAKPOINT   0x80000003L
 
#define EXCEPTION_SINGLE_STEP   0x80000004L
 
#define EXCEPTION_ARRAY_BOUNDS_EXCEEDED   0xC000008CL
 
#define EXCEPTION_FLT_DENORMAL_OPERAND   0xC000008DL
 
#define EXCEPTION_FLT_DIVIDE_BY_ZERO   0xC000008EL
 
#define EXCEPTION_FLT_INEXACT_RESULT   0xC000008FL
 
#define EXCEPTION_FLT_INVALID_OPERATION   0xC0000090L
 
#define EXCEPTION_FLT_OVERFLOW   0xC0000091L
 
#define EXCEPTION_FLT_STACK_CHECK   0xC0000092L
 
#define EXCEPTION_FLT_UNDERFLOW   0xC0000093L
 
#define EXCEPTION_INT_DIVIDE_BY_ZERO   0xC0000094L
 
#define EXCEPTION_INT_OVERFLOW   0xC0000095L
 
#define EXCEPTION_PRIV_INSTRUCTION   0xC0000096L
 
#define EXCEPTION_IN_PAGE_ERROR   0xC0000006L
 
#define EXCEPTION_ILLEGAL_INSTRUCTION   0xC000001DL
 
#define EXCEPTION_NONCONTINUABLE_EXCEPTION   0xC0000025L
 
#define EXCEPTION_STACK_OVERFLOW   0xC00000FDL
 
#define EXCEPTION_INVALID_DISPOSITION   0xC0000026L
 
#define EXCEPTION_GUARD_PAGE   0x80000001L
 
#define EXCEPTION_INVALID_HANDLE   0xC0000008L
 
#define EXCEPTION_POSSIBLE_DEADLOCK   0xC0000194L
 
#define CONTROL_C_EXIT   0xC000013AL
 
#define KI_EXCEPTION_INTERNAL   0x10000000
 
#define KI_EXCEPTION_GP_FAULT   ((INTSTATUS)(KI_EXCEPTION_INTERNAL | 0x01))
 General protection fault. More...
 
#define KI_EXCEPTION_INVALID_OP   ((INTSTATUS)(KI_EXCEPTION_INTERNAL | 0x02))
 Invalid opcode exceptions. More...
 
#define KI_EXCEPTION_INTEGER_DIVIDE_BY_ZERO   ((INTSTATUS)(KI_EXCEPTION_INTERNAL | 0x03))
 Divide error. More...
 
#define KI_EXCEPTION_ACCESS_VIOLATION   ((INTSTATUS)(KI_EXCEPTION_INTERNAL | 0x04))
 Page fault. More...
 
#define KERNEL_MODE   0
 The event was triggered inside the kernel space. More...
 
#define USER_MODE   1
 The event was triggered inside the user space. More...
 
#define FLG_CONTINUABLE   0
 
#define FLG_NON_CONTINUABLE   1
 
#define IS_DEP_FAULT(Er)
 Checks if a fault is an access violation caused by DEP. More...
 
#define CODE_SEG_UM_32   0x20
 32-bit user mode code selector More...
 
#define CODE_SEG_UM_64   0x30
 64-bit user mode code selector More...
 

Enumerations

enum  ACCESS_VIOLATION_EVENT { PARAM1_READ = 0, PARAM1_WRITE = 1, PARAM1_DEP = 8 }
 The type of event that caused the access violation. More...
 

Functions

static BOOLEAN IntWinPreProcessException (DWORD ExceptionCode, DWORD *Status)
 Translates an internal kernel exception code to an exception status known by used mode applications, which is usually a NTSTATUS value. More...
 
static void IntWinFillRegsFromExceptionInfo (void const *TrapFrame, KEXCEPTION_FRAME64 const *ExFrame, IG_ARCH_REGS *Regs)
 Reads the guest registers available inside the guest exception information structures. More...
 
static INTSTATUS IntWinCrashHandleDepViolation (void const *ExceptionRecord, QWORD ExceptionFrameGva, QWORD TrapFrameGva)
 Handles a crash generated by a DEP violation. More...
 
static INTSTATUS IntWinSetUmExceptionEvent (void const *ExceptionRecord)
 Sets the last exception triggered by a process. More...
 
INTSTATUS IntWinHandleException (void *Detour)
 Handles a hardware exception triggered inside the guestThis is the detour handler for the guest KiDispatchException function: More...
 

Macro Definition Documentation

◆ CODE_SEG_UM_32

#define CODE_SEG_UM_32   0x20

32-bit user mode code selector

Definition at line 85 of file winumcrash.c.

Referenced by IntWinCrashHandleDepViolation().

◆ CODE_SEG_UM_64

#define CODE_SEG_UM_64   0x30

64-bit user mode code selector

Definition at line 86 of file winumcrash.c.

Referenced by IntWinCrashHandleDepViolation().

◆ CONTROL_C_EXIT

#define CONTROL_C_EXIT   0xC000013AL

Definition at line 40 of file winumcrash.c.

Referenced by IntWinPreProcessException().

◆ EXCEPTION_ACCESS_VIOLATION

#define EXCEPTION_ACCESS_VIOLATION   0xC0000005L

Definition at line 17 of file winumcrash.c.

Referenced by IntWinPreProcessException().

◆ EXCEPTION_ARRAY_BOUNDS_EXCEEDED

#define EXCEPTION_ARRAY_BOUNDS_EXCEEDED   0xC000008CL

Definition at line 21 of file winumcrash.c.

Referenced by IntWinPreProcessException().

◆ EXCEPTION_BREAKPOINT

#define EXCEPTION_BREAKPOINT   0x80000003L

Definition at line 19 of file winumcrash.c.

Referenced by IntWinPreProcessException().

◆ EXCEPTION_DATATYPE_MISALIGNMENT

#define EXCEPTION_DATATYPE_MISALIGNMENT   0x80000002L

Definition at line 18 of file winumcrash.c.

Referenced by IntWinPreProcessException().

◆ EXCEPTION_FLT_DENORMAL_OPERAND

#define EXCEPTION_FLT_DENORMAL_OPERAND   0xC000008DL

Definition at line 22 of file winumcrash.c.

Referenced by IntWinPreProcessException().

◆ EXCEPTION_FLT_DIVIDE_BY_ZERO

#define EXCEPTION_FLT_DIVIDE_BY_ZERO   0xC000008EL

Definition at line 23 of file winumcrash.c.

Referenced by IntWinPreProcessException().

◆ EXCEPTION_FLT_INEXACT_RESULT

#define EXCEPTION_FLT_INEXACT_RESULT   0xC000008FL

Definition at line 24 of file winumcrash.c.

Referenced by IntWinPreProcessException().

◆ EXCEPTION_FLT_INVALID_OPERATION

#define EXCEPTION_FLT_INVALID_OPERATION   0xC0000090L

Definition at line 25 of file winumcrash.c.

Referenced by IntWinPreProcessException().

◆ EXCEPTION_FLT_OVERFLOW

#define EXCEPTION_FLT_OVERFLOW   0xC0000091L

Definition at line 26 of file winumcrash.c.

Referenced by IntWinPreProcessException().

◆ EXCEPTION_FLT_STACK_CHECK

#define EXCEPTION_FLT_STACK_CHECK   0xC0000092L

Definition at line 27 of file winumcrash.c.

Referenced by IntWinPreProcessException().

◆ EXCEPTION_FLT_UNDERFLOW

#define EXCEPTION_FLT_UNDERFLOW   0xC0000093L

Definition at line 28 of file winumcrash.c.

Referenced by IntWinPreProcessException().

◆ EXCEPTION_GUARD_PAGE

#define EXCEPTION_GUARD_PAGE   0x80000001L

Definition at line 37 of file winumcrash.c.

Referenced by IntWinPreProcessException().

◆ EXCEPTION_ILLEGAL_INSTRUCTION

#define EXCEPTION_ILLEGAL_INSTRUCTION   0xC000001DL

Definition at line 33 of file winumcrash.c.

Referenced by IntWinPreProcessException().

◆ EXCEPTION_IN_PAGE_ERROR

#define EXCEPTION_IN_PAGE_ERROR   0xC0000006L

Definition at line 32 of file winumcrash.c.

Referenced by IntWinPreProcessException().

◆ EXCEPTION_INT_DIVIDE_BY_ZERO

#define EXCEPTION_INT_DIVIDE_BY_ZERO   0xC0000094L

Definition at line 29 of file winumcrash.c.

Referenced by IntWinHandleException(), and IntWinPreProcessException().

◆ EXCEPTION_INT_OVERFLOW

#define EXCEPTION_INT_OVERFLOW   0xC0000095L

Definition at line 30 of file winumcrash.c.

Referenced by IntWinPreProcessException().

◆ EXCEPTION_INVALID_DISPOSITION

#define EXCEPTION_INVALID_DISPOSITION   0xC0000026L

Definition at line 36 of file winumcrash.c.

Referenced by IntWinPreProcessException().

◆ EXCEPTION_INVALID_HANDLE

#define EXCEPTION_INVALID_HANDLE   0xC0000008L

Definition at line 38 of file winumcrash.c.

Referenced by IntWinPreProcessException().

◆ EXCEPTION_NONCONTINUABLE_EXCEPTION

#define EXCEPTION_NONCONTINUABLE_EXCEPTION   0xC0000025L

Definition at line 34 of file winumcrash.c.

Referenced by IntWinPreProcessException().

◆ EXCEPTION_POSSIBLE_DEADLOCK

#define EXCEPTION_POSSIBLE_DEADLOCK   0xC0000194L

Definition at line 39 of file winumcrash.c.

Referenced by IntWinPreProcessException().

◆ EXCEPTION_PRIV_INSTRUCTION

#define EXCEPTION_PRIV_INSTRUCTION   0xC0000096L

Definition at line 31 of file winumcrash.c.

Referenced by IntWinPreProcessException().

◆ EXCEPTION_SINGLE_STEP

#define EXCEPTION_SINGLE_STEP   0x80000004L

Definition at line 20 of file winumcrash.c.

Referenced by IntWinPreProcessException().

◆ EXCEPTION_STACK_OVERFLOW

#define EXCEPTION_STACK_OVERFLOW   0xC00000FDL

Definition at line 35 of file winumcrash.c.

Referenced by IntWinPreProcessException().

◆ FLG_CONTINUABLE

#define FLG_CONTINUABLE   0

Definition at line 58 of file winumcrash.c.

◆ FLG_NON_CONTINUABLE

#define FLG_NON_CONTINUABLE   1

Definition at line 59 of file winumcrash.c.

Referenced by IntWinSetUmExceptionEvent().

◆ IS_DEP_FAULT

#define IS_DEP_FAULT (   Er)
Value:
((EXCEPTION_ACCESS_VIOLATION == (Er).ExceptionCode) && \
!IS_KERNEL_POINTER_WIN(gGuest.Guest64, (Er).ExceptionAddress) && \
(PARAM1_DEP == (Er).ExceptionInformation[0]))
A user-mode data execution prevention (DEP) violation.
Definition: winumcrash.c:71
#define EXCEPTION_ACCESS_VIOLATION
Definition: winumcrash.c:17
BOOLEAN Guest64
True if this is a 64-bit guest, False if it is a 32-bit guest.
Definition: guests.h:290
#define IS_KERNEL_POINTER_WIN(is64, p)
Checks if a guest virtual address resides inside the Windows kernel address space.
Definition: wddefs.h:76
GUEST_STATE gGuest
The current guest state.
Definition: guests.c:50

Checks if a fault is an access violation caused by DEP.

Parameters
[in]ErThe exception record structure. Either a EXCEPTION_RECORD32 or a EXCEPTION_RECORD64
Returns
True if this is an access violation caused by DEP, False if it is not

Definition at line 81 of file winumcrash.c.

Referenced by IntWinHandleException().

◆ KERNEL_MODE

#define KERNEL_MODE   0

The event was triggered inside the kernel space.

Definition at line 54 of file winumcrash.c.

Referenced by IntWinHandleException().

◆ KI_EXCEPTION_ACCESS_VIOLATION

#define KI_EXCEPTION_ACCESS_VIOLATION   ((INTSTATUS)(KI_EXCEPTION_INTERNAL | 0x04))

Page fault.

Definition at line 52 of file winumcrash.c.

Referenced by IntWinPreProcessException().

◆ KI_EXCEPTION_GP_FAULT

#define KI_EXCEPTION_GP_FAULT   ((INTSTATUS)(KI_EXCEPTION_INTERNAL | 0x01))

General protection fault.

Definition at line 46 of file winumcrash.c.

Referenced by IntWinPreProcessException().

◆ KI_EXCEPTION_INTEGER_DIVIDE_BY_ZERO

#define KI_EXCEPTION_INTEGER_DIVIDE_BY_ZERO   ((INTSTATUS)(KI_EXCEPTION_INTERNAL | 0x03))

Divide error.

Definition at line 50 of file winumcrash.c.

Referenced by IntWinPreProcessException().

◆ KI_EXCEPTION_INTERNAL

#define KI_EXCEPTION_INTERNAL   0x10000000

Definition at line 44 of file winumcrash.c.

◆ KI_EXCEPTION_INVALID_OP

#define KI_EXCEPTION_INVALID_OP   ((INTSTATUS)(KI_EXCEPTION_INTERNAL | 0x02))

Invalid opcode exceptions.

Definition at line 48 of file winumcrash.c.

Referenced by IntWinPreProcessException().

◆ STILL_ACTIVE

#define STILL_ACTIVE   0x00000103L

Definition at line 16 of file winumcrash.c.

Referenced by IntWinPreProcessException().

◆ USER_MODE

#define USER_MODE   1

The event was triggered inside the user space.

Definition at line 55 of file winumcrash.c.

Enumeration Type Documentation

◆ ACCESS_VIOLATION_EVENT

The type of event that caused the access violation.

The first element of the ExceptionInformation array of an exception record indicates the type of operation that caused the access violation.

Enumerator
PARAM1_READ 

Attempt to read inaccessible data.

PARAM1_WRITE 

Attempt to write inaccessible data.

PARAM1_DEP 

A user-mode data execution prevention (DEP) violation.

Definition at line 67 of file winumcrash.c.

Function Documentation

◆ IntWinCrashHandleDepViolation()

static INTSTATUS IntWinCrashHandleDepViolation ( void const *  ExceptionRecord,
QWORD  ExceptionFrameGva,
QWORD  TrapFrameGva 
)
static

Handles a crash generated by a DEP violation.

For processes that opt-out of DEP, the stack and heap may be created as executable from the start. In those cases, if they are protected with PROC_OPT_PROT_EXPLOIT, introcore enforces DEP for them using IntWinProcEnforceProcessDep. In those cases, even if introcore hooks the stack and the heap against executions, a page fault will be triggered in guest, and that will be delivered before the EPT violation will be triggered. We still want to send an alert in those cases, so we intercept it and convert it to an introEventEptViolation. Note that in this cases the action taken by introcore is not relevant, as the action will be blocked directly by the OS page fault handler, so the action set in the event will always be introGuestNotAllowed. We consult the exceptions mechanism, but if an exception matches we will not send an alert, but the process will probably be killed by the OS. The conversion is slightly more complicated than it sounds, as we are in the context of the kernel, trying to reconstruct the context of the user mode application at the time it triggered the DEP violation. Some information may no longer be available, or it may have changed.

Parameters
[in]ExceptionRecordThe exception record obtained from the guest. Pointer to a EXCEPTION_RECORD64 structure for 64-bit kernels, and a EXCEPTION_RECORD32 structure for 32-bit kernels
[in]ExceptionFrameGvaThe guest virtual address at which the exception frame starts. Used only for 64-bit kernels
[in]TrapFrameGvaThe guest virtual address at which the _KTRAP_FRAME structure is located
Returns
INT_STATUS_SUCCESS if successful, or an appropriate INTSTATUS error value

Definition at line 220 of file winumcrash.c.

Referenced by IntWinHandleException().

◆ IntWinFillRegsFromExceptionInfo()

static void IntWinFillRegsFromExceptionInfo ( void const *  TrapFrame,
KEXCEPTION_FRAME64 const *  ExFrame,
IG_ARCH_REGS Regs 
)
static

Reads the guest registers available inside the guest exception information structures.

Parameters
[in]TrapFrameThe guest trap frame. KTRAP_FRAME64 for 64-bit kernels, KTRAP_FRAME32 for 32-bit kernels
[in]ExFrameThe exception frame structure. Needed only for 64-bit kernels.
[out]RegsThe reigster values

Definition at line 161 of file winumcrash.c.

Referenced by IntWinCrashHandleDepViolation().

◆ IntWinPreProcessException()

static BOOLEAN IntWinPreProcessException ( DWORD  ExceptionCode,
DWORD Status 
)
static

Translates an internal kernel exception code to an exception status known by used mode applications, which is usually a NTSTATUS value.

Some of the conversions done here are based on what the KiPreprocessFault Windows kernel function is doing.

Parameters
[in]ExceptionCodeThe kernel exception code to be converted. This is the code extracted from the exception record read from the kernel
[out]StatusOn success, the exception status
Return values
Trueif ExceptionCode was known
Falseif it was not known and no conversion was possible

Definition at line 91 of file winumcrash.c.

Referenced by IntWinHandleException().

◆ IntWinSetUmExceptionEvent()

static INTSTATUS IntWinSetUmExceptionEvent ( void const *  ExceptionRecord)
static

Sets the last exception triggered by a process.

This is used when the INTRO_OPT_EVENT_PROCESS_CRASH option is set. We won't send an event every time a process triggers an exception, as some processes may trigger a lot of exceptions and that will cause a performance impact. Instead, we save the last one, the assumption being that if the process crashes, the last exception may have something to do with it.

Parameters
[in]ExceptionRecordThe exception record structure. Points to a EXCEPTION_RECORD64 structure on 64-bit guests, and to a EXCEPTION_RECORD32 structure on 32-bit guests
Return values
INT_STATUS_SUCCESSin case of success
INT_STATUS_INVALID_PARAMETER_1if ExceptionRecord is NULL
INT_STATUS_NOT_FOUNDis no process is found

Definition at line 476 of file winumcrash.c.

Referenced by IntWinHandleException().