2020-04-13 23:33:12 -07:00
/**
* @ file Debugger . c
2022-01-18 22:38:56 +03:30
* @ author Sina Karvandi ( sina @ hyperdbg . org )
2020-05-12 13:12:21 -07:00
* @ brief Implementation of Debugger functions
2020-04-13 23:33:12 -07:00
* @ details
2022-06-28 09:52:24 -07:00
*
2020-04-13 23:33:12 -07:00
* @ version 0.1
* @ date 2020 - 04 - 13
2022-06-28 09:52:24 -07:00
*
2020-04-13 23:33:12 -07:00
* @ copyright This project is released under the GNU Public License v3 .
2022-06-28 09:52:24 -07:00
*
2020-04-13 23:33:12 -07:00
*/
2022-05-04 16:38:21 -07:00
# include "pch.h"
2020-10-25 10:09:52 -07:00
2021-03-11 16:27:30 +03:30
/**
* @ brief A wrapper for GetRegValue ( ) in script - engine
2022-06-28 09:52:24 -07:00
*
2021-03-11 16:27:30 +03:30
* @ return BOOLEAN Value of register
*/
UINT64
DebuggerGetRegValueWrapper ( PGUEST_REGS GuestRegs , UINT32 /* REGS_ENUM */ RegId )
{
return GetRegValue ( GuestRegs , RegId ) ;
}
2021-11-13 01:04:20 +03:30
/**
* @ brief Debugger get the last error
2022-06-28 09:52:24 -07:00
*
2021-11-13 01:04:20 +03:30
* @ return UINT32 Error value
*/
UINT32
DebuggerGetLastError ( )
{
return g_LastError ;
}
/**
* @ brief Debugger set the last error
* @ param LastError The value of last error
2022-06-28 09:52:24 -07:00
*
2021-11-13 01:04:20 +03:30
* @ return VOID
*/
2023-03-22 17:45:52 +09:00
VOID
DebuggerSetLastError ( UINT32 LastError )
2021-11-13 01:04:20 +03:30
{
g_LastError = LastError ;
}
2020-08-28 04:03:12 -07:00
/**
2026-06-04 00:06:41 +02:00
* @ brief Initialize script engine global variables and per - core stack buffers
2022-06-28 09:52:24 -07:00
*
* @ return BOOLEAN Shows whether the initialization process was successful
2020-08-28 04:03:12 -07:00
* or not
*/
2020-04-13 23:33:12 -07:00
BOOLEAN
2026-06-04 00:06:41 +02:00
DebuggerInitializeScriptEngine ( )
2020-04-13 23:33:12 -07:00
{
2024-03-03 16:27:16 +09:00
ULONG ProcessorsCount = KeQueryActiveProcessorCount ( 0 ) ;
2023-03-22 17:45:52 +09:00
PROCESSOR_DEBUGGING_STATE * CurrentDebuggerState = NULL ;
2021-10-26 22:28:32 +03:30
2023-01-15 06:58:56 +09:00
//
2026-06-04 00:06:41 +02:00
// Initialize script engines global variables holder
2023-01-15 06:58:56 +09:00
//
2026-06-04 00:06:41 +02:00
if ( ! g_ScriptGlobalVariables )
2023-03-22 17:45:52 +09:00
{
2026-06-04 00:06:41 +02:00
g_ScriptGlobalVariables = PlatformMemAllocateNonPagedPool ( MAX_VAR_COUNT * sizeof ( UINT64 ) ) ;
2023-01-15 06:58:56 +09:00
}
2026-06-04 00:06:41 +02:00
if ( ! g_ScriptGlobalVariables )
2023-03-22 17:45:52 +09:00
{
2026-06-04 00:06:41 +02:00
//
// Out of resource, initialization of script engine's global variable holders failed
//
2020-05-14 14:59:56 -07:00
return FALSE ;
2023-01-15 03:58:26 +09:00
}
//
2026-06-04 00:06:41 +02:00
// Zero the global variables memory
2023-01-15 03:58:26 +09:00
//
2026-06-04 00:06:41 +02:00
RtlZeroMemory ( g_ScriptGlobalVariables , MAX_VAR_COUNT * sizeof ( UINT64 ) ) ;
//
// Initialize the local and temp variables
//
for ( SIZE_T i = 0 ; i < ProcessorsCount ; i + + )
2023-03-22 17:45:52 +09:00
{
2026-06-04 00:06:41 +02:00
CurrentDebuggerState = & g_DbgState [ i ] ;
if ( ! CurrentDebuggerState - > ScriptEngineCoreSpecificStackBuffer )
{
CurrentDebuggerState - > ScriptEngineCoreSpecificStackBuffer = PlatformMemAllocateNonPagedPool ( MAX_STACK_BUFFER_COUNT * sizeof ( UINT64 ) ) ;
}
if ( ! CurrentDebuggerState - > ScriptEngineCoreSpecificStackBuffer )
{
//
// Out of resource, initialization of script engine's stack buffer holders failed
//
return FALSE ;
}
//
// Zero stack buffer memory
//
RtlZeroMemory ( CurrentDebuggerState - > ScriptEngineCoreSpecificStackBuffer , MAX_STACK_BUFFER_COUNT * sizeof ( UINT64 ) ) ;
2023-01-15 03:58:26 +09:00
}
2020-04-13 23:33:12 -07:00
2026-06-04 00:06:41 +02:00
return TRUE ;
}
/**
* @ brief Initialize trap flag state and breakpoint related structures
*
* @ return BOOLEAN Shows whether the initialization process was successful
* or not
*/
BOOLEAN
DebuggerInitializeTrapsAndBreakpoints ( )
{
//
// Zero the TRAP FLAG state memory
//
RtlZeroMemory ( & g_TrapFlagState , sizeof ( DEBUGGER_TRAP_FLAG_STATE ) ) ;
//
// Request pages for breakpoint detail
//
PoolManagerRequestAllocation ( sizeof ( DEBUGGEE_BP_DESCRIPTOR ) ,
MAXIMUM_BREAKPOINTS_WITHOUT_CONTINUE ,
BREAKPOINT_DEFINITION_STRUCTURE ) ;
//
// Initialize list of breakpoints and breakpoint id
//
g_MaximumBreakpointId = 0 ;
InitializeListHead ( & g_BreakpointsListHead ) ;
return TRUE ;
}
/**
2026-06-04 00:55:05 +02:00
* @ brief Initialize VMM operations ( events and related operations )
2026-06-04 00:06:41 +02:00
*
* @ return BOOLEAN Shows whether the initialization process was successful
* or not
*/
BOOLEAN
2026-06-04 00:55:05 +02:00
DebuggerInitializeVmmOperations ( )
2026-06-04 00:06:41 +02:00
{
2020-04-13 23:33:12 -07:00
//
// Initialize lists relating to the debugger events store
//
2020-06-22 16:26:44 -07:00
InitializeListHead ( & g_Events - > EptHookExecCcEventsHead ) ;
2023-07-07 01:21:07 +09:00
InitializeListHead ( & g_Events - > HiddenHookReadAndWriteAndExecuteEventsHead ) ;
2020-06-22 16:26:44 -07:00
InitializeListHead ( & g_Events - > HiddenHookReadAndWriteEventsHead ) ;
2023-07-07 01:21:07 +09:00
InitializeListHead ( & g_Events - > HiddenHookReadAndExecuteEventsHead ) ;
InitializeListHead ( & g_Events - > HiddenHookWriteAndExecuteEventsHead ) ;
2020-06-22 16:26:44 -07:00
InitializeListHead ( & g_Events - > HiddenHookReadEventsHead ) ;
InitializeListHead ( & g_Events - > HiddenHookWriteEventsHead ) ;
2023-07-07 01:21:07 +09:00
InitializeListHead ( & g_Events - > HiddenHookExecuteEventsHead ) ;
2020-06-22 13:59:21 -07:00
InitializeListHead ( & g_Events - > EptHook2sExecDetourEventsHead ) ;
2020-05-14 14:59:56 -07:00
InitializeListHead ( & g_Events - > SyscallHooksEferSyscallEventsHead ) ;
InitializeListHead ( & g_Events - > SyscallHooksEferSysretEventsHead ) ;
2020-05-30 07:20:06 -07:00
InitializeListHead ( & g_Events - > CpuidInstructionExecutionEventsHead ) ;
InitializeListHead ( & g_Events - > RdmsrInstructionExecutionEventsHead ) ;
InitializeListHead ( & g_Events - > WrmsrInstructionExecutionEventsHead ) ;
InitializeListHead ( & g_Events - > ExceptionOccurredEventsHead ) ;
2020-06-02 11:41:37 -07:00
InitializeListHead ( & g_Events - > TscInstructionExecutionEventsHead ) ;
2020-06-02 15:17:03 -07:00
InitializeListHead ( & g_Events - > PmcInstructionExecutionEventsHead ) ;
2020-06-12 16:01:10 -07:00
InitializeListHead ( & g_Events - > InInstructionExecutionEventsHead ) ;
InitializeListHead ( & g_Events - > OutInstructionExecutionEventsHead ) ;
InitializeListHead ( & g_Events - > DebugRegistersAccessedEventsHead ) ;
InitializeListHead ( & g_Events - > ExternalInterruptOccurredEventsHead ) ;
2020-07-03 04:50:48 -07:00
InitializeListHead ( & g_Events - > VmcallInstructionExecutionEventsHead ) ;
2023-11-02 15:27:51 +09:00
InitializeListHead ( & g_Events - > TrapExecutionModeChangedEventsHead ) ;
2023-11-03 14:51:21 +09:00
InitializeListHead ( & g_Events - > TrapExecutionInstructionTraceEventsHead ) ;
2023-09-15 18:00:01 +09:00
InitializeListHead ( & g_Events - > ControlRegister3ModifiedEventsHead ) ;
2022-07-08 01:19:41 +02:00
InitializeListHead ( & g_Events - > ControlRegisterModifiedEventsHead ) ;
2025-08-21 00:17:26 +02:00
InitializeListHead ( & g_Events - > XsetbvInstructionExecutionEventsHead ) ;
2020-04-19 11:53:03 -07:00
2020-04-15 14:11:54 -07:00
//
2026-06-04 00:06:41 +02:00
// Initialize NMI broadcasting mechanism
2020-04-15 14:11:54 -07:00
//
2026-06-04 00:06:41 +02:00
VmFuncVmxBroadcastInitialize ( ) ;
2020-04-15 14:11:54 -07:00
2020-08-28 04:03:12 -07:00
//
// Set initial state of triggering events for VMCALLs
//
2023-01-19 21:34:45 +09:00
VmFuncSetTriggerEventForVmcalls ( FALSE ) ;
2020-08-28 04:03:12 -07:00
//
2026-06-04 00:06:41 +02:00
// Set initial state of triggering events for CPUIDs
2020-08-28 04:03:12 -07:00
//
2023-01-19 21:34:45 +09:00
VmFuncSetTriggerEventForCpuids ( FALSE ) ;
2020-08-28 04:03:12 -07:00
2026-07-19 19:39:33 +02:00
//
2026-06-09 19:34:58 +02:00
// Pre-allocate pools for possible EPT hooks
//
ConfigureEptHookReservePreallocatedPoolsForEptHooks ( MAXIMUM_NUMBER_OF_INITIAL_PREALLOCATED_EPT_HOOKS ) ;
if ( ! PoolManagerCheckAndPerformAllocationAndDeallocation ( ) )
{
LogWarning ( " Warning, cannot allocate the pre-allocated pools for EPT hooks " ) ;
//
// BTW, won't fail the starting phase because of this
//
}
2021-05-07 16:30:26 +04:30
//
2026-06-04 00:06:41 +02:00
// Enabled Debugger VMX Events
2021-05-07 16:30:26 +04:30
//
2026-06-04 00:06:41 +02:00
g_EnableDebuggerVmxEvents = TRUE ;
2021-05-07 16:30:26 +04:30
2026-06-04 00:06:41 +02:00
return TRUE ;
}
2026-06-04 00:55:05 +02:00
/**
* @ brief Initialize Debugger Structures and Routines
*
* @ return BOOLEAN Shows whether the initialization process was successful
* or not
*/
2026-06-04 00:06:41 +02:00
BOOLEAN
DebuggerInitialize ( )
{
ULONG ProcessorsCount = KeQueryActiveProcessorCount ( 0 ) ;
2021-05-07 16:30:26 +04:30
//
2026-06-04 00:06:41 +02:00
// Also allocate the debugging state
2021-05-07 16:30:26 +04:30
//
2026-06-04 00:06:41 +02:00
if ( ! GlobalDebuggingStateAllocateZeroedMemory ( ) )
{
return FALSE ;
}
2021-05-07 16:30:26 +04:30
2023-07-21 21:51:56 +09:00
//
2026-06-04 00:06:41 +02:00
// Allocate buffer for saving events
2023-07-21 21:51:56 +09:00
//
2026-06-04 00:06:41 +02:00
if ( GlobalEventsAllocateZeroedMemory ( ) = = FALSE )
2023-03-22 17:45:52 +09:00
{
2026-06-04 00:06:41 +02:00
return FALSE ;
2021-10-26 22:28:32 +03:30
}
2023-07-21 21:51:56 +09:00
2021-10-26 22:28:32 +03:30
//
2026-06-04 00:06:41 +02:00
// Set the core's IDs
2021-10-26 22:28:32 +03:30
//
2026-06-04 00:06:41 +02:00
for ( UINT32 i = 0 ; i < ProcessorsCount ; i + + )
2023-03-22 17:45:52 +09:00
{
2026-06-04 00:06:41 +02:00
g_DbgState [ i ] . CoreId = i ;
2021-10-26 22:28:32 +03:30
}
2025-06-28 10:06:30 +02:00
//
2026-06-04 00:06:41 +02:00
// Initialize Pool Manager
2025-06-28 10:06:30 +02:00
//
2026-06-04 00:06:41 +02:00
if ( ! PoolManagerInitialize ( ) )
{
LogError ( " Err, could not initialize pool manager " ) ;
return FALSE ;
}
2025-06-28 10:06:30 +02:00
//
2026-06-04 00:06:41 +02:00
// Initialize script engine global variables and per-core stack buffers
2025-06-28 10:06:30 +02:00
//
2026-06-04 00:06:41 +02:00
if ( ! DebuggerInitializeScriptEngine ( ) )
{
return FALSE ;
}
2025-06-28 10:06:30 +02:00
2022-04-24 20:57:08 +04:30
//
2026-06-04 00:06:41 +02:00
// Initialize trap flag state and breakpoint related structures
2022-04-24 20:57:08 +04:30
//
2026-06-04 00:06:41 +02:00
if ( ! DebuggerInitializeTrapsAndBreakpoints ( ) )
2023-03-22 17:45:52 +09:00
{
2022-02-15 23:37:49 +03:30
return FALSE ;
}
2022-04-24 20:57:08 +04:30
2022-02-15 23:37:49 +03:30
//
// Initialize attaching mechanism,
// we'll use the functionalities of the attaching in reading modules
// of user mode applications (other than attaching mechanism itself)
//
2023-03-22 17:45:52 +09:00
if ( ! AttachingInitialize ( ) )
{
2022-02-15 23:37:49 +03:30
return FALSE ;
}
2020-04-13 23:33:12 -07:00
return TRUE ;
}
2020-09-05 08:09:04 -07:00
/**
2026-06-04 00:55:05 +02:00
* @ brief Uninitialize Debugger VMM Operations ( Events and other related operations )
2022-06-28 09:52:24 -07:00
*
2026-06-04 00:55:05 +02:00
* @ return VOID
2020-09-05 08:09:04 -07:00
*/
2023-03-22 17:45:52 +09:00
VOID
2026-06-04 00:55:05 +02:00
DebuggerUninitializeVmmOperations ( )
2020-09-05 08:09:04 -07:00
{
//
// *** Disable, terminate and clear all the events ***
//
//
// Because we want to delete all the objects and buffers (pools)
// after we finished termination, the debugger might still use
// the buffers for events and action, for solving this problem
// we first disable the tag(s) and this way the debugger no longer
// use that event and this way we can safely remove and deallocate
// the buffers later after termination
//
2023-07-06 16:12:28 +09:00
//
// Disable triggering events
//
2026-06-04 00:06:41 +02:00
g_EnableDebuggerVmxEvents = FALSE ;
2023-07-06 16:12:28 +09:00
2020-09-05 08:09:04 -07:00
//
2023-10-22 01:14:36 +09:00
// Clear all events (Check if the kernel debugger is enable
// and whether the instant event mechanism is working or not)
2020-09-05 08:09:04 -07:00
//
2023-10-22 01:14:36 +09:00
if ( g_KernelDebuggerState & & EnableInstantEventMechanism )
{
2023-10-22 03:10:48 +09:00
DebuggerClearAllEvents ( FALSE , TRUE ) ;
2023-10-22 01:14:36 +09:00
}
else
{
2023-10-22 03:10:48 +09:00
DebuggerClearAllEvents ( FALSE , FALSE ) ;
2023-10-22 01:14:36 +09:00
}
2021-01-28 06:14:55 -08:00
//
// Uninitialize kernel debugger
//
KdUninitializeKernelDebugger ( ) ;
2022-01-05 22:16:25 +03:30
//
2022-01-11 01:57:13 +03:30
// Uninitialize user debugger
2022-01-05 22:16:25 +03:30
//
2022-01-11 01:57:13 +03:30
UdUninitializeUserDebugger ( ) ;
2022-04-24 20:57:08 +04:30
//
2023-01-26 17:42:26 +09:00
// Uninitialize NMI broadcasting mechanism
2022-04-24 20:57:08 +04:30
//
2023-01-26 17:42:26 +09:00
VmFuncVmxBroadcastUninitialize ( ) ;
2026-06-04 00:55:05 +02:00
}
/**
* @ brief Uninitialize Debugger Structures and Routines
*
* @ return VOID
*/
VOID
DebuggerUninitialize ( )
{
ULONG ProcessorsCount ;
PROCESSOR_DEBUGGING_STATE * CurrentDebuggerState = NULL ;
ProcessorsCount = KeQueryActiveProcessorCount ( 0 ) ;
2026-06-04 00:06:41 +02:00
//
// Free the Pool manager
//
PoolManagerUninitialize ( ) ;
2023-01-15 15:36:09 +09:00
//
// Free g_Events
//
GlobalEventsFreeMemory ( ) ;
//
// Free g_ScriptGlobalVariables
//
2023-03-22 17:45:52 +09:00
if ( g_ScriptGlobalVariables ! = NULL )
{
2024-05-11 20:22:52 +09:00
PlatformMemFreePool ( g_ScriptGlobalVariables ) ;
2023-07-06 16:12:28 +09:00
g_ScriptGlobalVariables = NULL ;
2023-01-15 15:36:09 +09:00
}
//
// Free core specific local and temp variables
//
2024-03-03 16:27:16 +09:00
for ( SIZE_T i = 0 ; i < ProcessorsCount ; i + + )
2023-03-22 17:45:52 +09:00
{
2023-01-15 15:36:09 +09:00
CurrentDebuggerState = & g_DbgState [ i ] ;
2024-06-15 02:10:03 +08:00
if ( CurrentDebuggerState - > ScriptEngineCoreSpecificStackBuffer ! = NULL )
{
PlatformMemFreePool ( CurrentDebuggerState - > ScriptEngineCoreSpecificStackBuffer ) ;
CurrentDebuggerState - > ScriptEngineCoreSpecificStackBuffer = NULL ;
}
2023-01-15 15:36:09 +09:00
}
//
// Free g_DbgState
//
GlobalDebuggingStateFreeMemory ( ) ;
2020-09-05 08:09:04 -07:00
}
2020-08-28 04:03:12 -07:00
/**
* @ brief Create an Event Object
2022-06-28 09:52:24 -07:00
*
2020-08-28 04:03:12 -07:00
* @ details should NOT be called in vmx - root
2022-06-28 09:52:24 -07:00
*
2020-08-28 04:03:12 -07:00
* @ param Enabled Is the event enabled or disabled
* @ param CoreId The core id that this event is allowed to run
* @ param ProcessId The process id that this event is allowed to run
* @ param EventType The type of event
* @ param Tag User - mode generated unique tag ( id ) of the event
2023-10-17 16:50:28 +09:00
* @ param Options Optional parameters for the event
2020-08-28 04:03:12 -07:00
* @ param ConditionsBufferSize Size of condition code buffer ( if any )
* @ param ConditionBuffer Address of condition code buffer ( if any )
2023-10-17 16:50:28 +09:00
* @ param ResultsToReturn Result buffer that should be returned to
* the user - mode
* @ param InputFromVmxRoot Whether the input comes from VMX root - mode or IOCTL
*
2020-08-28 04:03:12 -07:00
* @ return PDEBUGGER_EVENT Returns null in the case of error and event
* object address when it ' s successful
*/
2020-04-13 23:33:12 -07:00
PDEBUGGER_EVENT
2023-10-17 16:50:28 +09:00
DebuggerCreateEvent ( BOOLEAN Enabled ,
UINT32 CoreId ,
UINT32 ProcessId ,
VMM_EVENT_TYPE_ENUM EventType ,
UINT64 Tag ,
DEBUGGER_EVENT_OPTIONS * Options ,
UINT32 ConditionsBufferSize ,
PVOID ConditionBuffer ,
PDEBUGGER_EVENT_AND_ACTION_RESULT ResultsToReturn ,
BOOLEAN InputFromVmxRoot )
2020-04-13 23:33:12 -07:00
{
2023-10-17 16:50:28 +09:00
PDEBUGGER_EVENT Event = NULL ;
UINT32 EventBufferSize = sizeof ( DEBUGGER_EVENT ) + ConditionsBufferSize ;
2020-04-13 23:33:12 -07:00
//
// Initialize the event structure
//
2023-10-17 16:50:28 +09:00
if ( InputFromVmxRoot )
{
//
// *** The buffer is coming from VMX-root mode ***
//
//
2023-10-17 18:20:21 +09:00
// If the buffer is smaller than regular instant events
2023-10-17 16:50:28 +09:00
//
if ( REGULAR_INSTANT_EVENT_CONDITIONAL_BUFFER > = EventBufferSize )
{
//
// The buffer fits into a regular instant event
//
2024-03-01 15:59:58 +09:00
Event = ( DEBUGGER_EVENT * ) PoolManagerRequestPool ( INSTANT_REGULAR_EVENT_BUFFER , TRUE , REGULAR_INSTANT_EVENT_CONDITIONAL_BUFFER ) ;
2023-10-17 16:50:28 +09:00
if ( ! Event )
{
//
// Here we try again to see if we could store it into a big instant event instead
//
2024-03-01 15:59:58 +09:00
Event = ( DEBUGGER_EVENT * ) PoolManagerRequestPool ( INSTANT_BIG_EVENT_BUFFER , TRUE , BIG_INSTANT_EVENT_CONDITIONAL_BUFFER ) ;
2023-10-17 16:50:28 +09:00
if ( ! Event )
{
//
// Set the error
//
ResultsToReturn - > IsSuccessful = FALSE ;
ResultsToReturn - > Error = DEBUGGER_ERROR_INSTANT_EVENT_REGULAR_PREALLOCATED_BUFFER_NOT_FOUND ;
//
// There is a problem with allocating event
//
return NULL ;
}
}
}
else if ( BIG_INSTANT_EVENT_CONDITIONAL_BUFFER > = EventBufferSize )
{
//
// The buffer fits into a big instant event
//
2024-03-01 15:59:58 +09:00
Event = ( DEBUGGER_EVENT * ) PoolManagerRequestPool ( INSTANT_BIG_EVENT_BUFFER , TRUE , BIG_INSTANT_EVENT_CONDITIONAL_BUFFER ) ;
2023-10-17 16:50:28 +09:00
if ( ! Event )
{
//
// Set the error
//
ResultsToReturn - > IsSuccessful = FALSE ;
ResultsToReturn - > Error = DEBUGGER_ERROR_INSTANT_EVENT_BIG_PREALLOCATED_BUFFER_NOT_FOUND ;
//
// There is a problem with allocating event
//
return NULL ;
}
}
else
{
//
// The buffer doesn't fit into any of the regular or big event's preallocated buffers
//
//
// Set the error
//
ResultsToReturn - > IsSuccessful = FALSE ;
2024-03-17 18:17:38 +09:00
ResultsToReturn - > Error = DEBUGGER_ERROR_INSTANT_EVENT_PREALLOCATED_BUFFER_IS_NOT_ENOUGH_FOR_EVENT_AND_CONDITIONALS ;
2023-09-11 21:53:11 +09:00
2023-10-17 16:50:28 +09:00
return NULL ;
}
}
else
2023-03-22 17:45:52 +09:00
{
2020-04-15 10:47:18 -07:00
//
2023-10-17 16:50:28 +09:00
// If it's not coming from the VMX-root mode then we're allocating it from the OS buffers
2020-04-15 10:47:18 -07:00
//
2024-05-11 20:22:52 +09:00
Event = PlatformMemAllocateZeroedNonPagedPool ( EventBufferSize ) ;
2023-10-17 16:50:28 +09:00
if ( ! Event )
{
//
// Set the error
//
ResultsToReturn - > IsSuccessful = FALSE ;
ResultsToReturn - > Error = DEBUGGER_ERROR_UNABLE_TO_CREATE_EVENT ;
//
// There is a problem with allocating event
//
return NULL ;
}
2020-04-15 10:47:18 -07:00
}
2023-03-22 17:45:52 +09:00
Event - > CoreId = CoreId ;
Event - > ProcessId = ProcessId ;
Event - > Enabled = Enabled ;
Event - > EventType = EventType ;
Event - > Tag = Tag ;
2020-04-15 10:47:18 -07:00
Event - > CountOfActions = 0 ; // currently there is no action
2023-10-14 21:28:08 +09:00
//
// Copy Options
//
2023-10-14 23:29:16 +09:00
memcpy ( & Event - > InitOptions , Options , sizeof ( DEBUGGER_EVENT_OPTIONS ) ) ;
2020-04-13 23:33:12 -07:00
//
2020-04-15 10:47:18 -07:00
// check if this event is conditional or not
2020-04-13 23:33:12 -07:00
//
2023-03-22 17:45:52 +09:00
if ( ConditionBuffer ! = 0 )
{
2020-04-15 10:47:18 -07:00
//
2024-03-17 18:17:38 +09:00
// It's conditional
2020-04-15 10:47:18 -07:00
//
2023-03-22 17:45:52 +09:00
Event - > ConditionsBufferSize = ConditionsBufferSize ;
2024-03-01 15:59:58 +09:00
Event - > ConditionBufferAddress = ( PVOID ) ( ( UINT64 ) Event + sizeof ( DEBUGGER_EVENT ) ) ;
2020-04-15 10:47:18 -07:00
//
2024-03-17 18:17:38 +09:00
// copy the condition buffer to the end of the buffer of the event
2020-04-15 10:47:18 -07:00
//
memcpy ( Event - > ConditionBufferAddress , ConditionBuffer , ConditionsBufferSize ) ;
2023-03-22 17:45:52 +09:00
}
else
{
2020-04-15 10:47:18 -07:00
//
// It's unconditioanl
//
Event - > ConditionsBufferSize = 0 ;
}
2020-04-13 23:33:12 -07:00
2020-04-15 12:37:24 -07:00
//
// Make the action lists ready
//
InitializeListHead ( & Event - > ActionsListHead ) ;
2020-04-13 23:33:12 -07:00
//
// Return our event
//
return Event ;
}
2023-10-17 21:01:30 +09:00
/**
* @ brief Allocates buffer for requested safe buffer
*
* @ param SizeOfRequestedSafeBuffer The size of the requested safe buffer
* @ param ResultsToReturn The buffer address that should be returned
* to the user - mode as the result
* @ param InputFromVmxRoot Whether the input comes from VMX root - mode or IOCTL
*
* @ return PVOID
*/
PVOID
DebuggerAllocateSafeRequestedBuffer ( SIZE_T SizeOfRequestedSafeBuffer ,
PDEBUGGER_EVENT_AND_ACTION_RESULT ResultsToReturn ,
BOOLEAN InputFromVmxRoot )
{
PVOID RequestedBuffer = NULL ;
//
// Check whether the buffer comes from VMX-root mode or non-root mode
//
if ( InputFromVmxRoot )
{
//
// *** The buffer is coming from VMX-root mode ***
//
//
// If the requested safe buffer is smaller than regular safe buffers
//
if ( REGULAR_INSTANT_EVENT_REQUESTED_SAFE_BUFFER > = SizeOfRequestedSafeBuffer )
{
//
// The buffer fits into a regular safe requested buffer
//
2024-03-01 15:59:58 +09:00
RequestedBuffer = ( PVOID ) PoolManagerRequestPool ( INSTANT_REGULAR_SAFE_BUFFER_FOR_EVENTS , TRUE , REGULAR_INSTANT_EVENT_REQUESTED_SAFE_BUFFER ) ;
2023-10-17 21:01:30 +09:00
if ( ! RequestedBuffer )
{
//
// Here we try again to see if we could store it into a big instant event safe requested buffer instead
//
2024-03-01 15:59:58 +09:00
RequestedBuffer = ( PVOID ) PoolManagerRequestPool ( INSTANT_BIG_SAFE_BUFFER_FOR_EVENTS , TRUE , BIG_INSTANT_EVENT_REQUESTED_SAFE_BUFFER ) ;
2023-10-17 21:01:30 +09:00
if ( ! RequestedBuffer )
{
//
// Set the error
//
ResultsToReturn - > IsSuccessful = FALSE ;
ResultsToReturn - > Error = DEBUGGER_ERROR_INSTANT_EVENT_REGULAR_REQUESTED_SAFE_BUFFER_NOT_FOUND ;
//
// There is a problem with allocating requested safe buffer
//
return NULL ;
}
}
}
else if ( BIG_INSTANT_EVENT_REQUESTED_SAFE_BUFFER > = SizeOfRequestedSafeBuffer )
{
//
// The buffer fits into a big instant requested safe buffer
//
2024-03-01 15:59:58 +09:00
RequestedBuffer = ( PVOID ) PoolManagerRequestPool ( INSTANT_BIG_SAFE_BUFFER_FOR_EVENTS , TRUE , BIG_INSTANT_EVENT_REQUESTED_SAFE_BUFFER ) ;
2023-10-17 21:01:30 +09:00
if ( ! RequestedBuffer )
{
//
// Set the error
//
ResultsToReturn - > IsSuccessful = FALSE ;
ResultsToReturn - > Error = DEBUGGER_ERROR_INSTANT_EVENT_BIG_REQUESTED_SAFE_BUFFER_NOT_FOUND ;
//
// There is a problem with allocating event
//
return NULL ;
}
}
else
{
//
// The buffer doesn't fit into any of the regular or big safe requested buffers
//
//
// Set the error
//
ResultsToReturn - > IsSuccessful = FALSE ;
ResultsToReturn - > Error = DEBUGGER_ERROR_INSTANT_EVENT_PREALLOCATED_BUFFER_IS_NOT_ENOUGH_FOR_REQUESTED_SAFE_BUFFER ;
return NULL ;
}
}
else
{
2024-05-11 20:22:52 +09:00
RequestedBuffer = PlatformMemAllocateZeroedNonPagedPool ( SizeOfRequestedSafeBuffer ) ;
2023-10-17 21:01:30 +09:00
if ( ! RequestedBuffer )
{
ResultsToReturn - > IsSuccessful = FALSE ;
ResultsToReturn - > Error = DEBUGGER_ERROR_UNABLE_TO_ALLOCATE_REQUESTED_SAFE_BUFFER ;
return NULL ;
}
}
return RequestedBuffer ;
}
2020-08-28 04:03:12 -07:00
/**
* @ brief Create an action and add the action to an event
2022-06-28 09:52:24 -07:00
*
2020-08-28 04:03:12 -07:00
* @ param Event Target event object
* @ param ActionType Type of action
* @ param SendTheResultsImmediately whether the results should be received
* by the user - mode immediately
* @ param InTheCaseOfCustomCode Custom code structure ( if any )
2020-10-08 01:16:51 -07:00
* @ param InTheCaseOfRunScript Run script structure ( if any )
2023-10-17 18:20:21 +09:00
* @ param ResultsToReturn The buffer address that should be returned
* to the user - mode as the result
* @ param InputFromVmxRoot Whether the input comes from VMX root - mode or IOCTL
*
2022-06-28 09:52:24 -07:00
* @ return PDEBUGGER_EVENT_ACTION
2020-08-28 04:03:12 -07:00
*/
2020-05-14 08:28:28 -07:00
PDEBUGGER_EVENT_ACTION
2023-03-22 17:45:52 +09:00
DebuggerAddActionToEvent ( PDEBUGGER_EVENT Event ,
DEBUGGER_EVENT_ACTION_TYPE_ENUM ActionType ,
BOOLEAN SendTheResultsImmediately ,
PDEBUGGER_EVENT_REQUEST_CUSTOM_CODE InTheCaseOfCustomCode ,
2023-10-17 18:20:21 +09:00
PDEBUGGER_EVENT_ACTION_RUN_SCRIPT_CONFIGURATION InTheCaseOfRunScript ,
PDEBUGGER_EVENT_AND_ACTION_RESULT ResultsToReturn ,
BOOLEAN InputFromVmxRoot )
2020-04-13 23:33:12 -07:00
{
2020-04-15 12:37:24 -07:00
PDEBUGGER_EVENT_ACTION Action ;
2023-10-17 18:20:21 +09:00
SIZE_T ActionBufferSize ;
2023-10-17 21:01:30 +09:00
PVOID RequestedBuffer = NULL ;
2020-04-13 23:33:12 -07:00
//
2020-04-15 10:47:18 -07:00
// Allocate action + allocate code for custom code
2020-04-13 23:33:12 -07:00
//
2020-04-15 10:47:18 -07:00
2023-03-22 17:45:52 +09:00
if ( InTheCaseOfCustomCode ! = NULL )
{
2020-04-15 10:47:18 -07:00
//
2020-10-22 08:14:59 -07:00
// We should allocate extra buffer for custom code
2020-04-15 10:47:18 -07:00
//
2023-10-17 18:20:21 +09:00
ActionBufferSize = sizeof ( DEBUGGER_EVENT_ACTION ) + InTheCaseOfCustomCode - > CustomCodeBufferSize ;
2023-03-22 17:45:52 +09:00
}
else if ( InTheCaseOfRunScript ! = NULL )
{
2020-10-22 08:14:59 -07:00
//
// We should allocate extra buffer for script
//
2023-10-17 18:20:21 +09:00
ActionBufferSize = sizeof ( DEBUGGER_EVENT_ACTION ) + InTheCaseOfRunScript - > ScriptLength ;
2023-03-22 17:45:52 +09:00
}
else
{
2020-04-15 12:37:24 -07:00
//
2020-10-22 08:14:59 -07:00
// We shouldn't allocate extra buffer as there is no custom code
2020-04-15 12:37:24 -07:00
//
2023-10-17 18:20:21 +09:00
ActionBufferSize = sizeof ( DEBUGGER_EVENT_ACTION ) ;
2020-08-28 04:03:12 -07:00
}
2020-04-15 10:47:18 -07:00
2023-10-17 18:20:21 +09:00
//
// Allocate buffer for storing the action
//
if ( InputFromVmxRoot )
{
//
// *** The buffer is coming from VMX-root mode ***
//
//
// If the buffer is smaller than regular instant events's action
//
if ( REGULAR_INSTANT_EVENT_ACTION_BUFFER > = ActionBufferSize )
{
//
// The buffer fits into a regular instant event's action
//
2024-03-01 15:59:58 +09:00
Action = ( DEBUGGER_EVENT_ACTION * ) PoolManagerRequestPool ( INSTANT_REGULAR_EVENT_ACTION_BUFFER , TRUE , REGULAR_INSTANT_EVENT_ACTION_BUFFER ) ;
2023-10-17 18:20:21 +09:00
if ( ! Action )
{
//
// Here we try again to see if we could store it into a big instant event's action buffer instead
//
2024-03-01 15:59:58 +09:00
Action = ( DEBUGGER_EVENT_ACTION * ) PoolManagerRequestPool ( INSTANT_BIG_EVENT_ACTION_BUFFER , TRUE , BIG_INSTANT_EVENT_ACTION_BUFFER ) ;
2023-10-17 18:20:21 +09:00
if ( ! Action )
{
//
// Set the error
//
ResultsToReturn - > IsSuccessful = FALSE ;
ResultsToReturn - > Error = DEBUGGER_ERROR_INSTANT_EVENT_ACTION_REGULAR_PREALLOCATED_BUFFER_NOT_FOUND ;
//
// There is a problem with allocating event's action
//
return NULL ;
}
}
}
else if ( BIG_INSTANT_EVENT_ACTION_BUFFER > = ActionBufferSize )
{
//
// The buffer fits into a big instant event's action buffer
//
2024-03-01 15:59:58 +09:00
Action = ( DEBUGGER_EVENT_ACTION * ) PoolManagerRequestPool ( INSTANT_BIG_EVENT_ACTION_BUFFER , TRUE , BIG_INSTANT_EVENT_ACTION_BUFFER ) ;
2023-10-17 18:20:21 +09:00
if ( ! Action )
{
//
// Set the error
//
ResultsToReturn - > IsSuccessful = FALSE ;
ResultsToReturn - > Error = DEBUGGER_ERROR_INSTANT_EVENT_ACTION_BIG_PREALLOCATED_BUFFER_NOT_FOUND ;
//
// There is a problem with allocating event's action buffer
//
return NULL ;
}
}
else
{
//
// The buffer doesn't fit into any of the regular or big event's action preallocated buffers
//
//
// Set the error
//
ResultsToReturn - > IsSuccessful = FALSE ;
ResultsToReturn - > Error = DEBUGGER_ERROR_INSTANT_EVENT_PREALLOCATED_BUFFER_IS_NOT_ENOUGH_FOR_ACTION_BUFFER ;
2020-04-15 12:37:24 -07:00
2023-10-17 18:20:21 +09:00
return NULL ;
}
}
else
2023-03-22 17:45:52 +09:00
{
2020-08-28 04:03:12 -07:00
//
2023-10-17 18:20:21 +09:00
// If it's not coming from the VMX-root mode then we're allocating it from the OS buffers
2020-08-28 04:03:12 -07:00
//
2024-05-11 20:22:52 +09:00
Action = PlatformMemAllocateZeroedNonPagedPool ( ActionBufferSize ) ;
2023-10-17 18:20:21 +09:00
if ( Action = = NULL )
{
//
// Set the appropriate error
//
ResultsToReturn - > IsSuccessful = FALSE ;
ResultsToReturn - > Error = DEBUGGER_ERROR_UNABLE_TO_CREATE_ACTION_CANNOT_ALLOCATE_BUFFER ;
//
// There was an error in allocation
//
return NULL ;
}
2020-04-15 12:37:24 -07:00
}
2020-04-13 23:33:12 -07:00
//
2020-04-15 10:47:18 -07:00
// If the user needs a buffer to be passed to the debugger then
// we should allocate it here (Requested buffer is only available for custom code types)
2020-04-13 23:33:12 -07:00
//
2024-03-01 22:27:09 +09:00
if ( ActionType = = RUN_CUSTOM_CODE & &
InTheCaseOfCustomCode ! = NULL & &
InTheCaseOfCustomCode - > OptionalRequestedBufferSize ! = 0 )
2023-03-22 17:45:52 +09:00
{
2020-04-13 23:33:12 -07:00
//
2020-04-15 10:47:18 -07:00
// Check if the optional buffer is not more that the size
// we can send to usermode
2020-04-13 23:33:12 -07:00
//
2023-03-22 17:45:52 +09:00
if ( InTheCaseOfCustomCode - > OptionalRequestedBufferSize > = MaximumPacketsCapacity )
{
2020-10-22 08:14:59 -07:00
//
// There was an error
//
2023-10-17 21:01:30 +09:00
if ( InputFromVmxRoot )
{
2024-03-01 18:11:24 +09:00
PoolManagerFreePool ( ( UINT64 ) Action ) ;
2023-10-17 21:01:30 +09:00
}
else
{
2024-05-11 20:22:52 +09:00
PlatformMemFreePool ( Action ) ;
2023-10-17 21:01:30 +09:00
}
//
// Set the appropriate error
//
ResultsToReturn - > IsSuccessful = FALSE ;
ResultsToReturn - > Error = DEBUGGER_ERROR_INSTANT_EVENT_REQUESTED_OPTIONAL_BUFFER_IS_BIGGER_THAN_DEBUGGERS_SEND_RECEIVE_STACK ;
2023-10-17 18:20:21 +09:00
2020-05-14 08:28:28 -07:00
return NULL ;
2020-04-15 10:47:18 -07:00
}
2020-04-13 23:33:12 -07:00
//
2020-04-15 10:47:18 -07:00
// User needs a buffer to play with
2020-04-13 23:33:12 -07:00
//
2023-10-17 21:01:30 +09:00
RequestedBuffer = DebuggerAllocateSafeRequestedBuffer ( InTheCaseOfCustomCode - > OptionalRequestedBufferSize , ResultsToReturn , InputFromVmxRoot ) ;
2020-04-13 23:33:12 -07:00
2023-03-22 17:45:52 +09:00
if ( ! RequestedBuffer )
{
2020-04-15 10:47:18 -07:00
//
// There was an error in allocation
//
2023-10-17 21:01:30 +09:00
if ( InputFromVmxRoot )
{
2024-03-01 18:11:24 +09:00
PoolManagerFreePool ( ( UINT64 ) Action ) ;
2023-10-17 21:01:30 +09:00
}
else
{
2024-05-11 20:22:52 +09:00
PlatformMemFreePool ( Action ) ;
2023-10-17 21:01:30 +09:00
}
2023-10-17 18:20:21 +09:00
2023-10-17 21:01:30 +09:00
//
// Not need to set error as the above function already adjust the error
//
2020-05-14 08:28:28 -07:00
return NULL ;
2020-04-13 23:33:12 -07:00
}
2021-10-05 21:43:07 +03:30
2020-04-15 10:47:18 -07:00
//
// Add it to the action
//
Action - > RequestedBuffer . EnabledRequestBuffer = TRUE ;
2023-03-22 17:45:52 +09:00
Action - > RequestedBuffer . RequestBufferSize = InTheCaseOfCustomCode - > OptionalRequestedBufferSize ;
2024-02-29 19:26:14 +09:00
Action - > RequestedBuffer . RequstBufferAddress = ( UINT64 ) RequestedBuffer ;
2020-04-15 10:47:18 -07:00
}
2020-10-22 08:14:59 -07:00
//
// If the user needs a buffer to be passed to the debugger script then
// we should allocate it here (Requested buffer is only available for custom code types)
//
2024-03-01 23:20:18 +09:00
if ( ActionType = = RUN_SCRIPT & &
InTheCaseOfRunScript ! = NULL & &
InTheCaseOfRunScript - > OptionalRequestedBufferSize ! = 0 )
2023-03-22 17:45:52 +09:00
{
2020-10-22 08:14:59 -07:00
//
// Check if the optional buffer is not more that the size
// we can send to usermode
//
2023-03-22 17:45:52 +09:00
if ( InTheCaseOfRunScript - > OptionalRequestedBufferSize > = MaximumPacketsCapacity )
{
2020-10-22 08:14:59 -07:00
//
// There was an error
//
2023-10-17 21:01:30 +09:00
if ( InputFromVmxRoot )
{
2024-03-01 18:11:24 +09:00
PoolManagerFreePool ( ( UINT64 ) Action ) ;
2023-10-17 21:01:30 +09:00
}
else
{
2024-05-11 20:22:52 +09:00
PlatformMemFreePool ( Action ) ;
2023-10-17 21:01:30 +09:00
}
//
// Set the appropriate error
//
ResultsToReturn - > IsSuccessful = FALSE ;
ResultsToReturn - > Error = DEBUGGER_ERROR_INSTANT_EVENT_REQUESTED_OPTIONAL_BUFFER_IS_BIGGER_THAN_DEBUGGERS_SEND_RECEIVE_STACK ;
2023-10-17 18:20:21 +09:00
2020-10-22 08:14:59 -07:00
return NULL ;
}
//
// User needs a buffer to play with
//
2023-10-17 21:01:30 +09:00
RequestedBuffer = DebuggerAllocateSafeRequestedBuffer ( InTheCaseOfRunScript - > OptionalRequestedBufferSize , ResultsToReturn , InputFromVmxRoot ) ;
2020-10-22 08:14:59 -07:00
2023-03-22 17:45:52 +09:00
if ( ! RequestedBuffer )
{
2020-10-22 08:14:59 -07:00
//
// There was an error in allocation
//
2023-10-17 21:01:30 +09:00
if ( InputFromVmxRoot )
{
2024-03-01 18:11:24 +09:00
PoolManagerFreePool ( ( UINT64 ) Action ) ;
2023-10-17 21:01:30 +09:00
}
else
{
2024-05-11 20:22:52 +09:00
PlatformMemFreePool ( Action ) ;
2023-10-17 21:01:30 +09:00
}
2023-10-17 18:20:21 +09:00
2023-10-17 21:01:30 +09:00
//
// Not need to set error as the above function already adjust the error
//
2020-10-22 08:14:59 -07:00
return NULL ;
}
2021-10-05 21:43:07 +03:30
2020-10-22 08:14:59 -07:00
//
// Add it to the action
//
Action - > RequestedBuffer . EnabledRequestBuffer = TRUE ;
2023-03-22 17:45:52 +09:00
Action - > RequestedBuffer . RequestBufferSize = InTheCaseOfRunScript - > OptionalRequestedBufferSize ;
2024-02-29 19:26:14 +09:00
Action - > RequestedBuffer . RequstBufferAddress = ( UINT64 ) RequestedBuffer ;
2020-10-22 08:14:59 -07:00
}
2024-03-01 23:20:18 +09:00
if ( ActionType = = RUN_CUSTOM_CODE & & InTheCaseOfCustomCode ! = NULL )
2023-03-22 17:45:52 +09:00
{
2020-04-15 10:47:18 -07:00
//
// Check if it's a Custom code without custom code buffer which is invalid
//
2024-03-01 22:27:09 +09:00
if ( InTheCaseOfCustomCode ! = NULL & & InTheCaseOfCustomCode - > CustomCodeBufferSize = = 0 )
2023-03-22 17:45:52 +09:00
{
2020-10-22 08:14:59 -07:00
//
// There was an error
//
2023-10-17 21:01:30 +09:00
if ( InputFromVmxRoot )
{
2024-03-01 18:11:24 +09:00
PoolManagerFreePool ( ( UINT64 ) Action ) ;
2023-10-17 21:01:30 +09:00
if ( RequestedBuffer ! = NULL )
{
2024-03-01 15:59:58 +09:00
PoolManagerFreePool ( ( UINT64 ) RequestedBuffer ) ;
2023-10-17 21:01:30 +09:00
}
}
else
{
2024-05-11 20:22:52 +09:00
PlatformMemFreePool ( Action ) ;
2023-10-17 21:01:30 +09:00
if ( RequestedBuffer ! = NULL )
{
2024-05-11 20:22:52 +09:00
PlatformMemFreePool ( RequestedBuffer ) ;
2023-10-17 21:01:30 +09:00
}
}
ResultsToReturn - > IsSuccessful = FALSE ;
ResultsToReturn - > Error = DEBUGGER_ERROR_ACTION_BUFFER_SIZE_IS_ZERO ;
2020-05-14 08:28:28 -07:00
return NULL ;
2020-10-22 08:14:59 -07:00
}
2020-04-15 10:47:18 -07:00
//
// Move the custom code buffer to the end of the action
//
2023-03-22 17:45:52 +09:00
Action - > CustomCodeBufferSize = InTheCaseOfCustomCode - > CustomCodeBufferSize ;
2024-03-01 15:59:58 +09:00
Action - > CustomCodeBufferAddress = ( PVOID ) ( ( UINT64 ) Action + sizeof ( DEBUGGER_EVENT_ACTION ) ) ;
2020-04-13 23:33:12 -07:00
2020-04-15 10:47:18 -07:00
//
// copy the custom code buffer to the end of the buffer of the action
//
2020-04-15 12:37:24 -07:00
memcpy ( Action - > CustomCodeBufferAddress , InTheCaseOfCustomCode - > CustomCodeBufferAddress , InTheCaseOfCustomCode - > CustomCodeBufferSize ) ;
}
//
2020-10-08 01:16:51 -07:00
// If it's run script action type
2020-04-15 12:37:24 -07:00
//
2024-03-01 23:20:18 +09:00
else if ( ActionType = = RUN_SCRIPT & & InTheCaseOfRunScript ! = NULL )
2023-03-22 17:45:52 +09:00
{
2020-10-22 08:14:59 -07:00
//
// Check the buffers of run script
//
2024-03-03 15:15:38 +09:00
if ( InTheCaseOfRunScript - > ScriptBuffer = = NULL64_ZERO | | InTheCaseOfRunScript - > ScriptLength = = NULL_ZERO )
2023-03-22 17:45:52 +09:00
{
2020-10-22 08:14:59 -07:00
//
2023-10-17 21:01:30 +09:00
// There was an error
2020-10-22 08:14:59 -07:00
//
2023-10-17 21:01:30 +09:00
if ( InputFromVmxRoot )
{
2024-03-01 18:11:24 +09:00
PoolManagerFreePool ( ( UINT64 ) Action ) ;
2023-10-17 21:01:30 +09:00
if ( RequestedBuffer ! = 0 )
{
2024-03-01 15:59:58 +09:00
PoolManagerFreePool ( ( UINT64 ) RequestedBuffer ) ;
2023-10-17 21:01:30 +09:00
}
}
else
{
2024-05-11 20:22:52 +09:00
PlatformMemFreePool ( Action ) ;
2023-10-17 21:01:30 +09:00
if ( RequestedBuffer ! = 0 )
{
2024-05-11 20:22:52 +09:00
PlatformMemFreePool ( RequestedBuffer ) ;
2023-10-17 21:01:30 +09:00
}
}
ResultsToReturn - > IsSuccessful = FALSE ;
ResultsToReturn - > Error = DEBUGGER_ERROR_ACTION_BUFFER_SIZE_IS_ZERO ;
2023-10-17 18:20:21 +09:00
2020-10-22 08:14:59 -07:00
return NULL ;
}
//
// Allocate the buffer from a non-page pool on the script
//
2024-03-01 15:59:58 +09:00
Action - > ScriptConfiguration . ScriptBuffer = ( UINT64 ) ( ( BYTE * ) Action + sizeof ( DEBUGGER_EVENT_ACTION ) ) ;
2020-10-22 08:14:59 -07:00
//
// Copy the memory of script to our non-paged pool
//
2026-05-31 18:59:52 +02:00
RtlCopyMemory ( ( PVOID ) Action - > ScriptConfiguration . ScriptBuffer , ( const PVOID ) InTheCaseOfRunScript - > ScriptBuffer , InTheCaseOfRunScript - > ScriptLength ) ;
2020-10-22 08:14:59 -07:00
//
// Set other fields
//
2023-03-22 17:45:52 +09:00
Action - > ScriptConfiguration . ScriptLength = InTheCaseOfRunScript - > ScriptLength ;
Action - > ScriptConfiguration . ScriptPointer = InTheCaseOfRunScript - > ScriptPointer ;
2020-10-22 08:14:59 -07:00
Action - > ScriptConfiguration . OptionalRequestedBufferSize = InTheCaseOfRunScript - > OptionalRequestedBufferSize ;
2020-04-13 23:33:12 -07:00
}
2020-04-15 10:47:18 -07:00
//
// Create an order code for the current action
// and also increase the Count of action in event
//
Event - > CountOfActions + + ;
Action - > ActionOrderCode = Event - > CountOfActions ;
//
// Fill other parts of the action
//
Action - > ImmediatelySendTheResults = SendTheResultsImmediately ;
2023-03-22 17:45:52 +09:00
Action - > ActionType = ActionType ;
Action - > Tag = Event - > Tag ;
2020-04-15 10:47:18 -07:00
2020-04-15 12:37:24 -07:00
//
// Now we should add the action to the event's LIST_ENTRY of actions
//
InsertHeadList ( & Event - > ActionsListHead , & ( Action - > ActionsList ) ) ;
2020-05-14 08:28:28 -07:00
return Action ;
2020-04-15 10:47:18 -07:00
}
2020-08-28 04:03:12 -07:00
/**
* @ brief Register an event to a list of active events
2022-06-28 09:52:24 -07:00
*
2020-08-28 04:03:12 -07:00
* @ param Event Event structure
* @ return BOOLEAN TRUE if it successfully registered and FALSE if not registered
*/
2020-04-15 10:47:18 -07:00
BOOLEAN
DebuggerRegisterEvent ( PDEBUGGER_EVENT Event )
{
2023-01-10 21:47:06 +09:00
PLIST_ENTRY TargetEventList = NULL ;
2020-04-13 23:33:12 -07:00
//
// Register the event
//
2023-01-10 21:47:06 +09:00
TargetEventList = DebuggerGetEventListByEventType ( Event - > EventType ) ;
2023-03-22 17:45:52 +09:00
if ( TargetEventList ! = NULL )
{
2023-01-10 21:47:06 +09:00
InsertHeadList ( TargetEventList , & ( Event - > EventsOfSameTypeList ) ) ;
2020-08-28 04:03:12 -07:00
2023-01-10 21:47:06 +09:00
return TRUE ;
2023-03-22 17:45:52 +09:00
}
else
{
2020-04-15 17:08:13 -07:00
return FALSE ;
}
2020-04-13 23:33:12 -07:00
}
2020-08-28 04:03:12 -07:00
/**
* @ brief Trigger events of a special type to be managed by debugger
2022-06-28 09:52:24 -07:00
*
2020-08-28 04:03:12 -07:00
* @ param EventType Type of events
2022-09-22 13:19:37 +09:00
* @ param CallingStage Stage of calling ( pre - event or post - event )
2020-08-28 04:03:12 -07:00
* @ param Context An optional parameter ( different in each event )
2022-09-22 13:19:37 +09:00
* @ param PostEventRequired Whether the caller is requested to
* trigger a post - event event
2022-12-09 14:49:25 +09:00
* @ param Regs Guest gp - registers
*
2024-03-17 18:17:38 +09:00
* @ return VMM_CALLBACK_TRIGGERING_EVENT_STATUS_TYPE returns the status
2022-06-15 12:55:44 +04:30
* of handling events
2020-08-28 04:03:12 -07:00
*/
2023-01-29 04:06:01 +09:00
VMM_CALLBACK_TRIGGERING_EVENT_STATUS_TYPE
2023-03-22 17:45:52 +09:00
DebuggerTriggerEvents ( VMM_EVENT_TYPE_ENUM EventType ,
VMM_CALLBACK_EVENT_CALLING_STAGE_TYPE CallingStage ,
PVOID Context ,
BOOLEAN * PostEventRequired ,
GUEST_REGS * Regs )
2020-04-13 23:33:12 -07:00
{
2024-07-08 17:50:40 +09:00
PROCESSOR_DEBUGGING_STATE * DbgState = NULL ;
2023-08-07 17:08:15 +09:00
DebuggerCheckForCondition * ConditionFunc ;
2024-03-01 18:11:24 +09:00
DEBUGGER_TRIGGERED_EVENT_DETAILS EventTriggerDetail = { 0 } ;
2024-01-31 15:46:45 +09:00
PEPT_HOOKS_CONTEXT EptContext ;
2024-07-08 17:50:40 +09:00
PLIST_ENTRY TempList = 0 ;
PLIST_ENTRY TempList2 = 0 ;
const PVOID OriginalContext = Context ;
2022-12-09 14:49:25 +09:00
2020-04-16 10:40:20 -07:00
//
// Check if triggering debugging actions are allowed or not
//
2026-06-04 00:06:41 +02:00
if ( ! g_EnableDebuggerVmxEvents | | g_InterceptBreakpointsAndEventsForCommandsInRemoteComputer )
2023-03-22 17:45:52 +09:00
{
2020-04-16 10:40:20 -07:00
//
// Debugger is not enabled
//
2023-01-29 04:06:01 +09:00
return VMM_CALLBACK_TRIGGERING_EVENT_STATUS_DEBUGGER_NOT_ENABLED ;
2020-04-16 10:40:20 -07:00
}
2023-01-29 07:12:19 +09:00
//
// Find the debugging state structure
//
2023-09-05 18:04:21 +09:00
DbgState = & g_DbgState [ KeGetCurrentProcessorNumberEx ( NULL ) ] ;
2023-01-29 07:12:19 +09:00
2020-04-15 17:08:13 -07:00
//
// Find the debugger events list base on the type of the event
//
2023-03-22 17:45:52 +09:00
TempList = DebuggerGetEventListByEventType ( EventType ) ;
2023-01-10 21:47:06 +09:00
TempList2 = TempList ;
2022-06-15 12:55:44 +04:30
2023-03-22 17:45:52 +09:00
if ( TempList = = NULL )
{
2023-01-29 04:06:01 +09:00
return VMM_CALLBACK_TRIGGERING_EVENT_STATUS_INVALID_EVENT_TYPE ;
2020-04-16 06:21:50 -07:00
}
2020-04-13 23:33:12 -07:00
2023-03-22 17:45:52 +09:00
while ( TempList2 ! = TempList - > Flink )
{
TempList = TempList - > Flink ;
2020-04-16 06:21:50 -07:00
PDEBUGGER_EVENT CurrentEvent = CONTAINING_RECORD ( TempList , DEBUGGER_EVENT , EventsOfSameTypeList ) ;
2020-05-14 14:59:56 -07:00
2020-04-16 06:21:50 -07:00
//
// check if the event is enabled or not
//
2023-03-22 17:45:52 +09:00
if ( ! CurrentEvent - > Enabled )
{
2020-04-16 06:21:50 -07:00
continue ;
2020-04-15 17:08:13 -07:00
}
2020-04-16 06:21:50 -07:00
2020-05-14 14:59:56 -07:00
//
// Check if this event is for this core or not
//
2023-03-22 17:45:52 +09:00
if ( CurrentEvent - > CoreId ! = DEBUGGER_EVENT_APPLY_TO_ALL_CORES & & CurrentEvent - > CoreId ! = DbgState - > CoreId )
{
2020-05-14 14:59:56 -07:00
//
// This event is not related to either or core or all cores
//
continue ;
}
2020-05-29 15:24:00 -07:00
//
// Check if this event is for this process or not
//
2024-03-01 23:02:03 +09:00
if ( CurrentEvent - > ProcessId ! = DEBUGGER_EVENT_APPLY_TO_ALL_PROCESSES & & CurrentEvent - > ProcessId ! = HANDLE_TO_UINT32 ( PsGetCurrentProcessId ( ) ) )
2023-03-22 17:45:52 +09:00
{
2020-05-29 15:24:00 -07:00
//
// This event is not related to either our process or all processes
//
continue ;
}
2020-06-12 16:01:10 -07:00
//
2025-08-21 19:48:37 +02:00
// Check event type specific conditions, if the event is not mentioned
// here, it means that it doesn't have any special condition
2020-06-12 16:01:10 -07:00
//
2023-03-22 17:45:52 +09:00
switch ( CurrentEvent - > EventType )
{
2020-06-13 03:12:44 -07:00
case EXTERNAL_INTERRUPT_OCCURRED :
2022-09-22 13:19:37 +09:00
2020-06-13 03:12:44 -07:00
//
// For external interrupt exiting events we check whether the
// vector match the event's vector or not
2020-06-12 16:01:10 -07:00
//
// Context is the physical address
//
2024-03-01 15:59:58 +09:00
if ( ( UINT64 ) Context ! = CurrentEvent - > Options . OptionalParam1 )
2023-03-22 17:45:52 +09:00
{
2020-06-12 16:01:10 -07:00
//
// The interrupt is not for this event
//
continue ;
}
2022-09-22 13:19:37 +09:00
2020-06-13 03:12:44 -07:00
break ;
2021-07-19 17:31:59 +04:30
2023-07-07 01:21:07 +09:00
case HIDDEN_HOOK_READ_AND_WRITE_AND_EXECUTE :
2020-06-13 03:12:44 -07:00
case HIDDEN_HOOK_READ_AND_WRITE :
2023-07-07 01:21:07 +09:00
case HIDDEN_HOOK_READ_AND_EXECUTE :
case HIDDEN_HOOK_WRITE_AND_EXECUTE :
2020-06-13 03:12:44 -07:00
case HIDDEN_HOOK_READ :
case HIDDEN_HOOK_WRITE :
2023-07-07 01:21:07 +09:00
case HIDDEN_HOOK_EXECUTE :
2022-09-22 13:19:37 +09:00
2020-06-13 03:12:44 -07:00
//
2023-07-07 01:21:07 +09:00
// For hidden hook read/write/execute we check whether the address
2020-06-13 03:12:44 -07:00
// is in the range of what user specified or not, this is because
// we get the events for all hidden hooks in a page granularity
//
2020-06-12 16:01:10 -07:00
2024-07-08 17:50:40 +09:00
//
// Here the OriginalContext is used because the context
// might be changed but the OriginalContext is constant
//
EptContext = ( PEPT_HOOKS_CONTEXT ) OriginalContext ;
2024-01-31 15:46:45 +09:00
2020-05-20 11:38:07 -07:00
//
2024-07-08 17:50:40 +09:00
// EPT context should be checked with hooking tag
2024-01-31 20:33:29 +09:00
// The hooking tag is same as the event tag if both
// of them match together
2020-05-20 11:38:07 -07:00
//
2024-01-31 20:33:29 +09:00
if ( EptContext - > HookingTag ! = CurrentEvent - > Tag )
2023-03-22 17:45:52 +09:00
{
2020-05-20 11:38:07 -07:00
//
2024-03-17 18:17:38 +09:00
// The value is not within our expected range
2020-05-20 11:38:07 -07:00
//
continue ;
2023-03-22 17:45:52 +09:00
}
else
{
2021-12-14 03:46:00 +03:30
//
// Fix the context to virtual address
//
2024-03-01 15:59:58 +09:00
Context = ( PVOID ) EptContext - > VirtualAddress ;
2021-12-14 03:46:00 +03:30
}
2020-06-13 03:12:44 -07:00
break ;
2021-07-19 17:31:59 +04:30
2020-07-10 13:33:43 -07:00
case HIDDEN_HOOK_EXEC_CC :
2021-12-14 13:38:09 +03:30
//
// Here we check if it's HIDDEN_HOOK_EXEC_CC then it means
// so we have to make sure to perform its actions only if
// the hook is triggered for the address described in
// event, note that address in event is a virtual address
2020-05-29 15:24:00 -07:00
//
2024-03-01 15:59:58 +09:00
if ( ( UINT64 ) Context ! = CurrentEvent - > Options . OptionalParam1 )
2023-03-22 17:45:52 +09:00
{
2021-12-14 13:38:09 +03:30
//
// Context is the virtual address
//
//
// The hook is not for this (virtual) address
//
continue ;
}
break ;
case HIDDEN_HOOK_EXEC_DETOURS :
2024-07-08 17:50:40 +09:00
//
// Here the OriginalContext is used because the context
// might be changed but the OriginalContext is constant
//
EptContext = ( PEPT_HOOKS_CONTEXT ) OriginalContext ;
2020-06-13 03:12:44 -07:00
//
2021-12-14 13:38:09 +03:30
// Here we check if it's HIDDEN_HOOK_EXEC_DETOURS
// then it means that it's detours hidden hook exec so we have
// to make sure to perform its actions, only if the hook is triggered
// for the address described in event, note that address in event is
// a physical address and the address that the function that triggers
// these events and sent here as the context is also converted to its
// physical form
2020-06-13 03:12:44 -07:00
// This way we are sure that no one can bypass our hook by remapping
// address to another virtual address as everything is physical
2020-05-29 15:24:00 -07:00
//
2024-07-08 17:50:40 +09:00
if ( EptContext - > PhysicalAddress ! = CurrentEvent - > Options . OptionalParam1 )
2023-03-22 17:45:52 +09:00
{
2020-06-13 03:12:44 -07:00
//
// Context is the physical address
//
2020-06-02 07:20:06 -07:00
2020-06-13 03:12:44 -07:00
//
// The hook is not for this (physical) address
//
continue ;
2023-03-22 17:45:52 +09:00
}
else
{
2021-12-14 13:38:09 +03:30
//
// Convert it to virtual address
//
2024-07-08 17:50:40 +09:00
Context = ( PVOID ) ( EptContext - > VirtualAddress ) ;
2021-12-14 13:38:09 +03:30
}
2020-06-13 03:12:44 -07:00
break ;
2021-07-19 17:31:59 +04:30
2020-06-13 03:12:44 -07:00
case RDMSR_INSTRUCTION_EXECUTION :
case WRMSR_INSTRUCTION_EXECUTION :
2022-09-22 13:19:37 +09:00
2020-06-02 07:20:06 -07:00
//
2020-06-13 03:12:44 -07:00
// check if MSR exit is what we want or not
2020-06-02 07:20:06 -07:00
//
2024-03-01 15:59:58 +09:00
if ( CurrentEvent - > Options . OptionalParam1 ! = DEBUGGER_EVENT_MSR_READ_OR_WRITE_ALL_MSRS & & CurrentEvent - > Options . OptionalParam1 ! = ( UINT64 ) Context )
2023-03-22 17:45:52 +09:00
{
2020-05-29 15:24:00 -07:00
//
2020-06-02 07:20:06 -07:00
// The msr is not what we want
2020-05-29 15:24:00 -07:00
//
continue ;
}
2022-09-22 13:19:37 +09:00
2020-06-13 03:12:44 -07:00
break ;
2021-07-19 17:31:59 +04:30
2020-06-13 03:12:44 -07:00
case EXCEPTION_OCCURRED :
2022-09-22 13:19:37 +09:00
2020-06-13 03:12:44 -07:00
//
// check if exception is what we need or not
//
2024-03-01 15:59:58 +09:00
if ( CurrentEvent - > Options . OptionalParam1 ! = DEBUGGER_EVENT_EXCEPTIONS_ALL_FIRST_32_ENTRIES & & CurrentEvent - > Options . OptionalParam1 ! = ( UINT64 ) Context )
2023-03-22 17:45:52 +09:00
{
2020-06-03 06:59:28 -07:00
//
// The exception is not what we want
//
continue ;
}
2022-09-22 13:19:37 +09:00
2020-06-13 03:12:44 -07:00
break ;
2021-07-19 17:31:59 +04:30
2020-06-13 03:12:44 -07:00
case IN_INSTRUCTION_EXECUTION :
case OUT_INSTRUCTION_EXECUTION :
2022-09-22 13:19:37 +09:00
2020-06-13 03:12:44 -07:00
//
// check if I/O port is what we want or not
//
2024-03-01 15:59:58 +09:00
if ( CurrentEvent - > Options . OptionalParam1 ! = DEBUGGER_EVENT_ALL_IO_PORTS & & CurrentEvent - > Options . OptionalParam1 ! = ( UINT64 ) Context )
2023-03-22 17:45:52 +09:00
{
2020-06-13 03:12:44 -07:00
//
// The port is not what we want
//
continue ;
}
2022-09-22 13:19:37 +09:00
2020-06-13 03:12:44 -07:00
break ;
2021-07-19 17:31:59 +04:30
2020-06-13 22:39:53 -07:00
case SYSCALL_HOOK_EFER_SYSCALL :
//
// case SYSCALL_HOOK_EFER_SYSRET:
//
// I don't know how to find syscall number when sysret is executed so
// that's why we don't support extra argument for sysret
2022-09-22 13:19:37 +09:00
//
2020-06-13 22:39:53 -07:00
//
// check syscall number
//
2024-03-01 15:59:58 +09:00
if ( CurrentEvent - > Options . OptionalParam1 ! = DEBUGGER_EVENT_SYSCALL_ALL_SYSRET_OR_SYSCALLS & & CurrentEvent - > Options . OptionalParam1 ! = ( UINT64 ) Context )
2023-03-22 17:45:52 +09:00
{
2020-06-13 22:39:53 -07:00
//
// The syscall number is not what we want
//
continue ;
}
2021-07-19 17:31:59 +04:30
2020-06-13 22:39:53 -07:00
break ;
2021-07-19 17:31:59 +04:30
2023-05-11 17:55:47 +09:00
case CPUID_INSTRUCTION_EXECUTION :
//
// check if CPUID is what we want or not
//
2024-03-01 15:59:58 +09:00
if ( CurrentEvent - > Options . OptionalParam1 ! = ( UINT64 ) NULL /*FALSE*/ & & CurrentEvent - > Options . OptionalParam2 ! = ( UINT64 ) Context )
2023-05-11 17:55:47 +09:00
{
//
// The CPUID is not what we want (and the user didn't intend to get all CPUIDs)
//
continue ;
}
break ;
2022-07-08 01:19:41 +02:00
case CONTROL_REGISTER_MODIFIED :
2022-09-22 13:19:37 +09:00
//
2022-07-08 01:19:41 +02:00
// check if CR exit is what we want or not
//
2024-03-01 15:59:58 +09:00
if ( CurrentEvent - > Options . OptionalParam1 ! = ( UINT64 ) Context )
2023-03-22 17:45:52 +09:00
{
2022-09-22 13:19:37 +09:00
//
2022-07-08 01:19:41 +02:00
// The CR is not what we want
//
continue ;
}
2022-09-22 13:19:37 +09:00
2022-07-08 01:19:41 +02:00
break ;
2023-11-03 14:51:21 +09:00
case TRAP_EXECUTION_MODE_CHANGED :
2023-09-18 19:47:13 +09:00
//
// check if the debugger needs user-to-kernel or kernel-to-user events
//
2023-10-14 21:28:08 +09:00
if ( CurrentEvent - > Options . OptionalParam1 ! = DEBUGGER_EVENT_MODE_TYPE_USER_MODE_AND_KERNEL_MODE )
2023-09-18 19:47:13 +09:00
{
2023-10-14 21:28:08 +09:00
if ( ( CurrentEvent - > Options . OptionalParam1 = = DEBUGGER_EVENT_MODE_TYPE_USER_MODE & &
2024-03-01 23:02:03 +09:00
Context = = ( PVOID ) DEBUGGER_EVENT_MODE_TYPE_KERNEL_MODE ) | |
2023-10-14 21:28:08 +09:00
( CurrentEvent - > Options . OptionalParam1 = = DEBUGGER_EVENT_MODE_TYPE_KERNEL_MODE & &
2024-03-01 23:02:03 +09:00
Context = = ( PVOID ) DEBUGGER_EVENT_MODE_TYPE_USER_MODE ) )
2023-09-18 19:47:13 +09:00
{
continue ;
}
}
break ;
2025-08-21 00:17:26 +02:00
case XSETBV_INSTRUCTION_EXECUTION :
//
// check if XSETBV is what we want or not
//
if ( CurrentEvent - > Options . OptionalParam1 ! = ( UINT64 ) NULL /*FALSE*/ & & CurrentEvent - > Options . OptionalParam2 ! = ( UINT64 ) Context )
{
//
// The XCR is not what we want (and the user didn't intend to get all XSETBVs)
//
continue ;
}
break ;
2025-08-21 19:48:37 +02:00
default : // All other events that don't have conditions
2020-06-13 03:12:44 -07:00
break ;
2020-06-03 06:59:28 -07:00
}
2022-09-22 13:19:37 +09:00
//
2023-07-30 22:43:51 +09:00
// Check the stage of calling (pre, all, or post event)
2022-09-22 13:19:37 +09:00
//
2023-07-30 22:43:51 +09:00
if ( CallingStage = = VMM_CALLBACK_CALLING_STAGE_PRE_EVENT_EMULATION & &
( CurrentEvent - > EventMode = = VMM_CALLBACK_CALLING_STAGE_ALL_EVENT_EMULATION | |
CurrentEvent - > EventMode = = VMM_CALLBACK_CALLING_STAGE_POST_EVENT_EMULATION ) )
2023-03-22 17:45:52 +09:00
{
2022-09-22 13:19:37 +09:00
//
2023-07-30 22:43:51 +09:00
// Here it means that the current event is a post, or all event event
// and the current stage of calling is for the pre-event events, thus
2024-03-17 01:01:22 +09:00
// this event is not supposed to be ran at the current stage.
2022-09-22 13:19:37 +09:00
// However, we'll set a flag so the caller will know that there is
// a valid post-event available for the parameters related to this
// event.
// This mechanism notifies the caller to trigger the event after
// emulation, we implement it in a way that the caller knows when
// to trigger a post-event thus it optimizes the number of times
// that the caller triggers the events and avoid unnecessary triggering
// of the event (for post-event) but at the same time we have the
// flexibility of having both pre-event and post-event concepts
//
* PostEventRequired = TRUE ;
2023-07-30 22:43:51 +09:00
if ( CurrentEvent - > EventMode = = VMM_CALLBACK_CALLING_STAGE_POST_EVENT_EMULATION )
{
//
// If it's not an 'all' event and it is only the 'post' event,
// then we ignore the trigger stage
//
continue ;
}
2022-09-22 13:19:37 +09:00
}
2020-04-20 06:49:34 -07:00
//
2024-03-17 18:17:38 +09:00
// Check if condition is met or not , if the condition
2020-04-20 06:49:34 -07:00
// is not met then we have to avoid performing the actions
//
2023-03-22 17:45:52 +09:00
if ( CurrentEvent - > ConditionsBufferSize ! = 0 )
{
2020-04-20 06:49:34 -07:00
//
// Means that there is some conditions
//
2024-03-01 22:27:09 +09:00
ConditionFunc = ( DebuggerCheckForCondition * ) CurrentEvent - > ConditionBufferAddress ;
2020-04-20 06:49:34 -07:00
//
// Run and check for results
//
2020-07-06 11:51:56 -07:00
// Because the user might change the nonvolatile registers, we save fastcall nonvolatile registers
//
2026-07-19 19:39:33 +02:00
if ( AsmDebuggerConditionCodeHandler ( ( UINT64 ) Regs , ( UINT64 ) Context , ( UINT64 ) ConditionFunc ) = = 0 )
2023-03-22 17:45:52 +09:00
{
2020-04-20 06:49:34 -07:00
//
// The condition function returns null, mean that the
// condition didn't met, we can ignore this event
//
continue ;
}
}
2022-06-15 12:55:44 +04:30
//
2023-07-13 16:05:42 +09:00
// Reset the event ignorance mechanism (apply 'sc on/off' to the events)
2022-06-15 12:55:44 +04:30
//
2023-06-07 19:24:47 +09:00
DbgState - > ShortCircuitingEvent = CurrentEvent - > EnableShortCircuiting ;
2022-06-15 12:55:44 +04:30
2023-07-30 22:43:51 +09:00
//
2023-08-07 17:08:15 +09:00
// Setup event trigger detail
2023-07-30 22:43:51 +09:00
//
2023-08-07 17:08:15 +09:00
EventTriggerDetail . Context = Context ;
EventTriggerDetail . Tag = CurrentEvent - > Tag ;
EventTriggerDetail . Stage = CallingStage ;
2023-07-30 22:43:51 +09:00
2020-04-15 17:08:13 -07:00
//
2020-04-16 06:21:50 -07:00
// perform the actions
2020-04-15 17:08:13 -07:00
//
2026-07-19 19:39:33 +02:00
DebuggerPerformActions ( DbgState , CurrentEvent , & EventTriggerDetail , Regs ) ;
2020-04-15 17:08:13 -07:00
}
2022-06-15 12:55:44 +04:30
//
// Check if the event should be ignored or not
//
2023-03-22 17:45:52 +09:00
if ( DbgState - > ShortCircuitingEvent )
{
2023-05-11 23:13:44 +09:00
//
2023-07-13 16:05:42 +09:00
// Reset the event ignorance (short-circuit) mechanism
2023-05-11 23:13:44 +09:00
//
DbgState - > ShortCircuitingEvent = FALSE ;
2022-06-15 12:55:44 +04:30
//
// Event should be ignored
//
2023-01-29 04:06:01 +09:00
return VMM_CALLBACK_TRIGGERING_EVENT_STATUS_SUCCESSFUL_IGNORE_EVENT ;
2023-03-22 17:45:52 +09:00
}
else
{
2022-06-15 12:55:44 +04:30
//
// Event shouldn't be ignored
//
2023-01-29 04:06:01 +09:00
return VMM_CALLBACK_TRIGGERING_EVENT_STATUS_SUCCESSFUL ;
2022-06-15 12:55:44 +04:30
}
2020-04-15 17:08:13 -07:00
}
2020-08-28 04:03:12 -07:00
/**
* @ brief Run a special event ' s action ( s )
2022-06-28 09:52:24 -07:00
*
2022-12-09 14:49:25 +09:00
* @ param DbgState The state of the debugger on the current core
2020-08-28 04:03:12 -07:00
* @ param Event Event Object
2023-08-07 17:08:15 +09:00
* @ param EventTriggerDetail Event trigger details
2026-07-19 19:39:33 +02:00
* @ param Regs Registers
2023-08-07 17:08:15 +09:00
*
2022-06-28 09:52:24 -07:00
* @ return VOID
2020-08-28 04:03:12 -07:00
*/
2023-03-22 17:45:52 +09:00
VOID
2023-08-07 17:08:15 +09:00
DebuggerPerformActions ( PROCESSOR_DEBUGGING_STATE * DbgState ,
DEBUGGER_EVENT * Event ,
2026-07-19 19:39:33 +02:00
DEBUGGER_TRIGGERED_EVENT_DETAILS * EventTriggerDetail ,
GUEST_REGS * Regs )
2020-04-15 17:08:13 -07:00
{
2020-04-16 10:40:20 -07:00
PLIST_ENTRY TempList = 0 ;
//
// Find and run all the actions in this Event
//
TempList = & Event - > ActionsListHead ;
2023-03-22 17:45:52 +09:00
while ( & Event - > ActionsListHead ! = TempList - > Flink )
{
TempList = TempList - > Flink ;
2020-04-16 10:40:20 -07:00
PDEBUGGER_EVENT_ACTION CurrentAction = CONTAINING_RECORD ( TempList , DEBUGGER_EVENT_ACTION , ActionsList ) ;
//
// Perform the action
//
2023-03-22 17:45:52 +09:00
switch ( CurrentAction - > ActionType )
{
2020-04-16 10:40:20 -07:00
case BREAK_TO_DEBUGGER :
2023-08-07 17:08:15 +09:00
2026-07-19 19:39:33 +02:00
DebuggerPerformBreakToDebugger ( DbgState , CurrentAction , EventTriggerDetail , Regs ) ;
2023-08-07 17:08:15 +09:00
2020-04-16 10:40:20 -07:00
break ;
2023-08-07 17:08:15 +09:00
2020-10-08 01:16:51 -07:00
case RUN_SCRIPT :
2023-08-07 17:08:15 +09:00
2026-07-19 19:39:33 +02:00
DebuggerPerformRunScript ( DbgState , CurrentAction , NULL , EventTriggerDetail , Regs ) ;
2023-08-07 17:08:15 +09:00
2020-04-16 10:40:20 -07:00
break ;
2023-08-07 17:08:15 +09:00
2020-04-16 10:40:20 -07:00
case RUN_CUSTOM_CODE :
2023-08-07 17:08:15 +09:00
2026-07-19 19:39:33 +02:00
DebuggerPerformRunTheCustomCode ( DbgState , CurrentAction , EventTriggerDetail , Regs ) ;
2023-08-07 17:08:15 +09:00
2020-04-16 10:40:20 -07:00
break ;
2023-08-07 17:08:15 +09:00
2020-04-16 10:40:20 -07:00
default :
2022-04-24 20:57:08 +04:30
2020-04-16 10:40:20 -07:00
//
// Invalid action type
//
break ;
}
}
2020-04-15 17:08:13 -07:00
}
2020-08-28 04:03:12 -07:00
/**
2020-10-08 01:16:51 -07:00
* @ brief Managing run script action
2022-06-28 09:52:24 -07:00
*
2022-12-09 14:49:25 +09:00
* @ param DbgState The state of the debugger on the current core
2020-08-28 04:03:12 -07:00
* @ param Action Action object
2023-08-07 17:08:15 +09:00
* @ param ScriptDetails Details of script
* @ param EventTriggerDetail Event trigger detail
2026-07-19 19:39:33 +02:00
* @ param Regs registers
*
2022-06-28 09:52:24 -07:00
* @ return BOOLEAN
2020-08-28 04:03:12 -07:00
*/
2021-02-04 08:37:49 -08:00
BOOLEAN
2023-08-07 17:08:15 +09:00
DebuggerPerformRunScript ( PROCESSOR_DEBUGGING_STATE * DbgState ,
DEBUGGER_EVENT_ACTION * Action ,
DEBUGGEE_SCRIPT_PACKET * ScriptDetails ,
2026-07-19 19:39:33 +02:00
DEBUGGER_TRIGGERED_EVENT_DETAILS * EventTriggerDetail ,
GUEST_REGS * Regs )
2020-04-16 11:17:42 -07:00
{
2024-07-24 21:25:55 +08:00
SYMBOL_BUFFER CodeBuffer = { 0 } ;
ACTION_BUFFER ActionBuffer = { 0 } ;
SYMBOL ErrorSymbol = { 0 } ;
SCRIPT_ENGINE_GENERAL_REGISTERS ScriptGeneralRegisters = { 0 } ;
2021-01-14 02:33:38 -08:00
2023-03-22 17:45:52 +09:00
if ( Action ! = NULL )
{
2023-08-07 17:08:15 +09:00
//
// Fill the action buffer's calling stage
//
if ( EventTriggerDetail - > Stage = = VMM_CALLBACK_CALLING_STAGE_POST_EVENT_EMULATION )
{
ActionBuffer . CallingStage = 1 ;
}
else
{
ActionBuffer . CallingStage = 0 ;
}
2021-02-04 08:37:49 -08:00
//
// Fill the action buffer
//
2024-03-01 21:02:52 +09:00
ActionBuffer . Context = ( UINT64 ) EventTriggerDetail - > Context ;
2023-08-07 17:08:15 +09:00
ActionBuffer . Tag = EventTriggerDetail - > Tag ;
2021-02-04 08:37:49 -08:00
ActionBuffer . ImmediatelySendTheResults = Action - > ImmediatelySendTheResults ;
2024-03-01 21:02:52 +09:00
ActionBuffer . CurrentAction = ( UINT64 ) Action ;
2020-11-04 06:58:04 -08:00
2021-02-04 08:37:49 -08:00
//
// Context point to the registers
//
2024-03-01 21:02:52 +09:00
CodeBuffer . Head = ( PSYMBOL ) Action - > ScriptConfiguration . ScriptBuffer ;
2023-03-22 17:45:52 +09:00
CodeBuffer . Size = Action - > ScriptConfiguration . ScriptLength ;
2021-02-04 08:37:49 -08:00
CodeBuffer . Pointer = Action - > ScriptConfiguration . ScriptPointer ;
2023-03-22 17:45:52 +09:00
}
else if ( ScriptDetails ! = NULL )
{
2023-08-07 17:08:15 +09:00
//
// Fill the action buffer's calling stage
//
if ( EventTriggerDetail - > Stage = = VMM_CALLBACK_CALLING_STAGE_POST_EVENT_EMULATION )
{
ActionBuffer . CallingStage = 1 ;
}
else
{
ActionBuffer . CallingStage = 0 ;
}
2021-02-04 08:37:49 -08:00
//
// Fill the action buffer
//
2024-03-01 21:02:52 +09:00
ActionBuffer . Context = ( UINT64 ) EventTriggerDetail - > Context ;
2023-08-07 17:08:15 +09:00
ActionBuffer . Tag = EventTriggerDetail - > Tag ;
2021-02-04 08:37:49 -08:00
ActionBuffer . ImmediatelySendTheResults = TRUE ;
2024-03-01 21:02:52 +09:00
ActionBuffer . CurrentAction = ( UINT64 ) NULL ;
2021-02-04 08:37:49 -08:00
//
// Context point to the registers
//
2024-03-01 21:02:52 +09:00
CodeBuffer . Head = ( SYMBOL * ) ( ( CHAR * ) ScriptDetails + sizeof ( DEBUGGEE_SCRIPT_PACKET ) ) ;
2023-03-22 17:45:52 +09:00
CodeBuffer . Size = ScriptDetails - > ScriptBufferSize ;
2021-02-04 08:37:49 -08:00
CodeBuffer . Pointer = ScriptDetails - > ScriptBufferPointer ;
2023-03-22 17:45:52 +09:00
}
else
{
2021-02-04 08:37:49 -08:00
//
// The parameters are wrong !
//
return FALSE ;
}
2020-10-25 10:09:52 -07:00
2021-10-26 22:28:32 +03:30
//
2024-07-24 21:25:55 +08:00
// Fill the stack buffer for this run
2021-10-26 22:28:32 +03:30
//
2024-07-24 21:25:55 +08:00
ScriptGeneralRegisters . StackBuffer = DbgState - > ScriptEngineCoreSpecificStackBuffer ;
ScriptGeneralRegisters . GlobalVariablesList = g_ScriptGlobalVariables ;
2024-08-23 22:33:36 +08:00
RtlZeroMemory ( ScriptGeneralRegisters . StackBuffer , MAX_STACK_BUFFER_COUNT * sizeof ( UINT64 ) ) ;
2024-06-15 02:10:03 +08:00
2024-07-20 11:58:17 +08:00
UINT64 EXECUTENUMBER = 0 ;
2024-06-15 02:10:03 +08:00
2024-03-01 21:02:52 +09:00
for ( UINT64 i = 0 ; i < CodeBuffer . Pointer ; )
2023-03-22 17:45:52 +09:00
{
2021-02-07 08:18:00 -08:00
//
// If has error, show error message and abort.
//
2023-07-12 21:09:14 +09:00
2026-07-19 19:39:33 +02:00
if ( ScriptEngineExecute ( Regs ,
2023-03-22 17:45:52 +09:00
& ActionBuffer ,
2024-07-24 21:25:55 +08:00
& ScriptGeneralRegisters ,
2023-03-22 17:45:52 +09:00
& CodeBuffer ,
& i ,
2024-07-24 21:25:55 +08:00
& ErrorSymbol ) = = TRUE )
2023-03-22 17:45:52 +09:00
{
2025-01-25 18:37:54 +01:00
LogInfo ( " Err, ScriptEngineExecute, function = % s \n " ,
2024-07-19 19:17:46 +08:00
FunctionNames [ ErrorSymbol . Value ] ) ;
break ;
}
2024-07-24 21:25:55 +08:00
else if ( ScriptGeneralRegisters . StackIndx > = MAX_STACK_BUFFER_COUNT )
2024-07-19 19:17:46 +08:00
{
2025-01-25 18:37:54 +01:00
LogInfo ( " Err, stack buffer overflow (more information: https://docs.hyperdbg.org/tips-and-tricks/misc/customize-build/change-script-engine-limitations) \n " ) ;
2021-02-07 08:18:00 -08:00
break ;
}
2024-07-20 11:58:17 +08:00
else if ( EXECUTENUMBER > = MAX_EXECUTION_COUNT )
{
2025-01-25 18:37:54 +01:00
LogInfo ( " Err, exceeding the max execution count (more information: https://docs.hyperdbg.org/tips-and-tricks/misc/customize-build/change-script-engine-limitations) \n " ) ;
2024-07-20 11:58:17 +08:00
break ;
}
EXECUTENUMBER + + ;
2020-10-25 10:09:52 -07:00
}
2021-02-04 08:37:49 -08:00
return TRUE ;
2020-04-16 11:17:42 -07:00
}
2020-04-16 10:40:20 -07:00
2020-08-28 04:03:12 -07:00
/**
* @ brief Manage running the custom code action
2022-06-28 09:52:24 -07:00
*
2022-12-09 14:49:25 +09:00
* @ param DbgState The state of the debugger on the current core
2020-08-28 04:03:12 -07:00
* @ param Action Action object
2023-08-07 17:08:15 +09:00
* @ param EventTriggerDetail Event trigger detail
2026-07-19 19:39:33 +02:00
* @ param Reg Registers
2023-08-07 17:08:15 +09:00
*
2022-06-28 09:52:24 -07:00
* @ return VOID
2020-08-28 04:03:12 -07:00
*/
2023-03-22 17:45:52 +09:00
VOID
2023-08-07 17:08:15 +09:00
DebuggerPerformRunTheCustomCode ( PROCESSOR_DEBUGGING_STATE * DbgState ,
DEBUGGER_EVENT_ACTION * Action ,
2026-07-19 19:39:33 +02:00
DEBUGGER_TRIGGERED_EVENT_DETAILS * EventTriggerDetail ,
GUEST_REGS * Regs )
2020-04-15 17:08:13 -07:00
{
2026-07-19 19:39:33 +02:00
UNREFERENCED_PARAMETER ( DbgState ) ;
2023-03-22 17:45:52 +09:00
if ( Action - > CustomCodeBufferSize = = 0 )
{
2020-04-19 11:53:03 -07:00
//
// Sth went wrong ! the buffer size for custom code shouldn't be zero
//
return ;
}
2020-05-12 15:43:34 -07:00
//
// -----------------------------------------------------------------------------------------------------
2023-07-31 15:05:14 +09:00
// Test
2020-05-12 15:43:34 -07:00
//
2021-08-30 17:23:17 +04:30
// LogInfo("%X Called from : %llx", Tag, Context);
2020-06-14 02:47:22 -07:00
//
2021-02-04 08:37:49 -08:00
//
// LogInfo("Process Id : %x , Rax : %llx , R8 : %llx , Context : 0x%llx ", PsGetCurrentProcessId(), Regs->rax, Regs->r8, Context);
// return;
2020-05-12 15:43:34 -07:00
//
// -----------------------------------------------------------------------------------------------------
//
2020-04-19 11:53:03 -07:00
//
// Run the custom code
//
2023-03-22 17:45:52 +09:00
if ( Action - > RequestedBuffer . RequestBufferSize = = 0 )
{
2020-04-19 11:53:03 -07:00
//
2020-07-06 11:51:56 -07:00
// Because the user might change the nonvolatile registers, we save fastcall nonvolatile registers
2020-04-19 11:53:03 -07:00
//
2024-03-01 22:27:09 +09:00
AsmDebuggerCustomCodeHandler ( ( UINT64 ) NULL ,
2026-07-19 19:39:33 +02:00
( UINT64 ) Regs ,
2024-03-01 22:27:09 +09:00
( UINT64 ) EventTriggerDetail - > Context ,
( UINT64 ) Action - > CustomCodeBufferAddress ) ;
2023-03-22 17:45:52 +09:00
}
else
{
2020-04-19 11:53:03 -07:00
//
2020-07-06 11:51:56 -07:00
// Because the user might change the nonvolatile registers, we save fastcall nonvolatile registers
2020-04-19 11:53:03 -07:00
//
2024-03-01 22:27:09 +09:00
AsmDebuggerCustomCodeHandler ( ( UINT64 ) Action - > RequestedBuffer . RequstBufferAddress ,
2026-07-19 19:39:33 +02:00
( UINT64 ) Regs ,
2024-03-01 22:27:09 +09:00
( UINT64 ) EventTriggerDetail - > Context ,
( UINT64 ) Action - > CustomCodeBufferAddress ) ;
2020-04-19 11:53:03 -07:00
}
2020-04-15 17:08:13 -07:00
}
2021-02-04 08:37:49 -08:00
/**
* @ brief Manage breaking to the debugger action
2022-06-28 09:52:24 -07:00
*
2022-12-09 14:49:25 +09:00
* @ param DbgState The state of the debugger on the current core
2021-02-04 08:37:49 -08:00
* @ param Tag Tag of event
* @ param Action Action object
2023-08-07 17:08:15 +09:00
* @ param EventTriggerDetail Event trigger detail
2026-07-19 19:39:33 +02:00
* @ param Regs Registers
2022-12-05 15:31:56 +09:00
*
2022-06-28 09:52:24 -07:00
* @ return VOID
2021-02-04 08:37:49 -08:00
*/
2023-03-22 17:45:52 +09:00
VOID
2023-08-07 17:08:15 +09:00
DebuggerPerformBreakToDebugger ( PROCESSOR_DEBUGGING_STATE * DbgState ,
DEBUGGER_EVENT_ACTION * Action ,
2026-07-19 19:39:33 +02:00
DEBUGGER_TRIGGERED_EVENT_DETAILS * EventTriggerDetail ,
GUEST_REGS * Regs )
2021-02-04 08:37:49 -08:00
{
2024-03-01 18:11:24 +09:00
UNREFERENCED_PARAMETER ( Action ) ;
2023-03-22 17:45:52 +09:00
if ( VmFuncVmxGetCurrentExecutionMode ( ) = = TRUE )
{
2021-02-17 11:37:23 -08:00
//
// The guest is already in vmx-root mode
// Halt other cores
//
KdHandleBreakpointAndDebugBreakpoints (
2022-12-09 18:26:38 +09:00
DbgState ,
2021-02-17 11:37:23 -08:00
DEBUGGEE_PAUSING_REASON_DEBUGGEE_EVENT_TRIGGERED ,
2023-08-07 17:08:15 +09:00
EventTriggerDetail ) ;
2023-03-22 17:45:52 +09:00
}
else
{
2021-02-17 11:37:23 -08:00
//
2023-08-07 18:41:37 +09:00
// The guest is on vmx non-root mode and this is an event
2021-02-17 11:37:23 -08:00
//
2024-03-01 18:11:24 +09:00
VmFuncVmxVmcall ( DEBUGGER_VMCALL_VM_EXIT_HALT_SYSTEM_AS_A_RESULT_OF_TRIGGERING_EVENT ,
( UINT64 ) EventTriggerDetail ,
2026-07-19 19:39:33 +02:00
( UINT64 ) Regs ,
2024-03-01 21:02:52 +09:00
( UINT64 ) NULL ) ;
2021-02-17 11:37:23 -08:00
}
2021-02-04 08:37:49 -08:00
}
2026-07-19 19:39:33 +02:00
/**
* @ brief Manage breaking to the debugger action by core id
*
* @ param CoreId
* @ param Tag Tag of event
* @ param Action Action object
* @ param EventTriggerDetail Event trigger detail
* @ param Regs Registers
*
* @ return VOID
*/
VOID
DebuggerPerformBreakToDebuggerByCoreId ( UINT32 CoreId ,
DEBUGGER_EVENT_ACTION * Action ,
DEBUGGER_TRIGGERED_EVENT_DETAILS * EventTriggerDetail ,
GUEST_REGS * Regs )
{
PROCESSOR_DEBUGGING_STATE * DbgState = & g_DbgState [ CoreId ] ;
DebuggerPerformBreakToDebugger ( DbgState , Action , EventTriggerDetail , Regs ) ;
}
2020-08-28 04:03:12 -07:00
/**
* @ brief Find event object by tag
2022-06-28 09:52:24 -07:00
*
2020-08-28 04:03:12 -07:00
* @ param Tag Tag of event
* @ return PDEBUGGER_EVENT Returns null if not found and event object if found
*/
2020-05-14 08:28:28 -07:00
PDEBUGGER_EVENT
DebuggerGetEventByTag ( UINT64 Tag )
2020-04-15 17:08:13 -07:00
{
2023-03-22 17:45:52 +09:00
PLIST_ENTRY TempList = 0 ;
2020-05-14 08:28:28 -07:00
PLIST_ENTRY TempList2 = 0 ;
2020-04-13 23:33:12 -07:00
//
2020-05-14 14:59:56 -07:00
// We have to iterate through all events
2020-04-13 23:33:12 -07:00
//
2026-05-31 18:59:52 +02:00
for ( SIZE_T i = 0 ; i < sizeof ( DEBUGGER_CORE_EVENTS ) / sizeof ( LIST_ENTRY ) ; i + + )
2023-03-22 17:45:52 +09:00
{
TempList = ( PLIST_ENTRY ) ( ( UINT64 ) ( g_Events ) + ( i * sizeof ( LIST_ENTRY ) ) ) ;
2020-05-14 14:59:56 -07:00
TempList2 = TempList ;
2023-03-22 17:45:52 +09:00
while ( TempList2 ! = TempList - > Flink )
{
TempList = TempList - > Flink ;
2020-05-14 14:59:56 -07:00
PDEBUGGER_EVENT CurrentEvent = CONTAINING_RECORD ( TempList , DEBUGGER_EVENT , EventsOfSameTypeList ) ;
2020-05-14 08:28:28 -07:00
2020-05-14 14:59:56 -07:00
//
// Check if we find the event or not
//
2023-03-22 17:45:52 +09:00
if ( CurrentEvent - > Tag = = Tag )
{
2020-05-14 14:59:56 -07:00
return CurrentEvent ;
2020-05-14 08:28:28 -07:00
}
}
}
//
// We didn't find anything, so return null
//
return NULL ;
2020-04-13 23:33:12 -07:00
}
2020-08-28 04:03:12 -07:00
/**
* @ brief Enable or disable all events from all the types
2022-06-28 09:52:24 -07:00
*
* @ param IsEnable If you want to enable then true and if
2020-08-28 04:03:12 -07:00
* you want to disable then false
* @ return BOOLEAN if at least one event enabled / disabled then
* it returns true , and otherwise false
*/
BOOLEAN
DebuggerEnableOrDisableAllEvents ( BOOLEAN IsEnable )
{
2023-03-22 17:45:52 +09:00
BOOLEAN FindAtLeastOneEvent = FALSE ;
PLIST_ENTRY TempList = 0 ;
PLIST_ENTRY TempList2 = 0 ;
2020-08-28 04:03:12 -07:00
//
// We have to iterate through all events
//
2026-05-31 18:59:52 +02:00
for ( SIZE_T i = 0 ; i < sizeof ( DEBUGGER_CORE_EVENTS ) / sizeof ( LIST_ENTRY ) ; i + + )
2023-03-22 17:45:52 +09:00
{
TempList = ( PLIST_ENTRY ) ( ( UINT64 ) ( g_Events ) + ( i * sizeof ( LIST_ENTRY ) ) ) ;
2020-08-28 04:03:12 -07:00
TempList2 = TempList ;
2023-03-22 17:45:52 +09:00
while ( TempList2 ! = TempList - > Flink )
{
TempList = TempList - > Flink ;
2020-08-28 04:03:12 -07:00
PDEBUGGER_EVENT CurrentEvent = CONTAINING_RECORD ( TempList , DEBUGGER_EVENT , EventsOfSameTypeList ) ;
//
// Check if we find at least one event or not
//
2023-03-22 17:45:52 +09:00
if ( ! FindAtLeastOneEvent )
{
2020-08-28 04:03:12 -07:00
FindAtLeastOneEvent = TRUE ;
}
//
// Enable or disable event
2023-11-02 13:48:56 +09:00
// (We could directly modify the "enabled" flag here, however
// in the case of any possible callback for enabling/disabling let's
// modify the state of being enable all of them in a single place)
2020-08-28 04:03:12 -07:00
//
2023-11-02 13:48:56 +09:00
if ( IsEnable )
{
DebuggerEnableEvent ( CurrentEvent - > Tag ) ;
}
else
{
DebuggerDisableEvent ( CurrentEvent - > Tag ) ;
}
2020-08-28 04:03:12 -07:00
}
}
return FindAtLeastOneEvent ;
}
/**
* @ brief Terminate effect and configuration to vmx - root
* and non - root for all the events
2022-06-28 09:52:24 -07:00
*
2023-10-14 23:29:16 +09:00
* @ param InputFromVmxRoot Whether the input comes from VMX root - mode or IOCTL
*
2020-08-28 04:03:12 -07:00
* @ return BOOLEAN if at least one event terminated then
* it returns true , and otherwise false
*/
BOOLEAN
2023-10-14 23:29:16 +09:00
DebuggerTerminateAllEvents ( BOOLEAN InputFromVmxRoot )
2020-08-28 04:03:12 -07:00
{
2023-03-22 17:45:52 +09:00
BOOLEAN FindAtLeastOneEvent = FALSE ;
PLIST_ENTRY TempList = 0 ;
PLIST_ENTRY TempList2 = 0 ;
2020-08-28 04:03:12 -07:00
//
// We have to iterate through all events
//
2026-05-31 18:59:52 +02:00
for ( SIZE_T i = 0 ; i < sizeof ( DEBUGGER_CORE_EVENTS ) / sizeof ( LIST_ENTRY ) ; i + + )
2023-03-22 17:45:52 +09:00
{
TempList = ( PLIST_ENTRY ) ( ( UINT64 ) ( g_Events ) + ( i * sizeof ( LIST_ENTRY ) ) ) ;
2020-08-28 04:03:12 -07:00
TempList2 = TempList ;
2023-03-22 17:45:52 +09:00
while ( TempList2 ! = TempList - > Flink )
{
TempList = TempList - > Flink ;
2020-08-28 04:03:12 -07:00
PDEBUGGER_EVENT CurrentEvent = CONTAINING_RECORD ( TempList , DEBUGGER_EVENT , EventsOfSameTypeList ) ;
//
// Check if we find at least one event or not
//
2023-03-22 17:45:52 +09:00
if ( ! FindAtLeastOneEvent )
{
2020-08-28 04:03:12 -07:00
FindAtLeastOneEvent = TRUE ;
}
//
// Terminate the current event
//
2023-10-14 23:29:16 +09:00
DebuggerTerminateEvent ( CurrentEvent - > Tag , InputFromVmxRoot ) ;
2020-08-28 04:03:12 -07:00
}
}
return FindAtLeastOneEvent ;
}
/**
* @ brief Remove all the events from all the lists
* and also de - allocate their structures and actions
2022-06-28 09:52:24 -07:00
*
2020-08-28 04:03:12 -07:00
* @ details should not be called from vmx - root mode , also
2022-06-28 09:52:24 -07:00
* it won ' t terminate their effects , so the events should
2020-08-28 04:03:12 -07:00
* be terminated first then we can remove them
2022-06-28 09:52:24 -07:00
*
2023-10-22 03:10:48 +09:00
* @ param PoolManagerAllocatedMemory Whether the pools are allocated from the
* pool manager or original OS pools
2023-10-17 16:50:28 +09:00
*
2020-08-28 04:03:12 -07:00
* @ return BOOLEAN if at least one event removed then
* it returns true , and otherwise false
*/
BOOLEAN
2023-10-22 03:10:48 +09:00
DebuggerRemoveAllEvents ( BOOLEAN PoolManagerAllocatedMemory )
2020-08-28 04:03:12 -07:00
{
2023-03-22 17:45:52 +09:00
BOOLEAN FindAtLeastOneEvent = FALSE ;
PLIST_ENTRY TempList = 0 ;
PLIST_ENTRY TempList2 = 0 ;
2020-08-28 04:03:12 -07:00
//
// We have to iterate through all events
//
2026-05-31 18:59:52 +02:00
for ( SIZE_T i = 0 ; i < sizeof ( DEBUGGER_CORE_EVENTS ) / sizeof ( LIST_ENTRY ) ; i + + )
2023-03-22 17:45:52 +09:00
{
TempList = ( PLIST_ENTRY ) ( ( UINT64 ) ( g_Events ) + ( i * sizeof ( LIST_ENTRY ) ) ) ;
2020-08-28 04:03:12 -07:00
TempList2 = TempList ;
2023-03-22 17:45:52 +09:00
while ( TempList2 ! = TempList - > Flink )
{
TempList = TempList - > Flink ;
2020-08-28 04:03:12 -07:00
PDEBUGGER_EVENT CurrentEvent = CONTAINING_RECORD ( TempList , DEBUGGER_EVENT , EventsOfSameTypeList ) ;
//
// Check if we find at least one event or not
//
2023-03-22 17:45:52 +09:00
if ( ! FindAtLeastOneEvent )
{
2020-08-28 04:03:12 -07:00
FindAtLeastOneEvent = TRUE ;
}
//
// Remove the current event
//
2023-10-22 03:10:48 +09:00
DebuggerRemoveEvent ( CurrentEvent - > Tag , PoolManagerAllocatedMemory ) ;
2020-08-28 04:03:12 -07:00
}
}
return FindAtLeastOneEvent ;
}
/**
* @ brief Count the list of events in a special list
2022-06-28 09:52:24 -07:00
*
2020-08-28 04:03:12 -07:00
* @ param TargetEventList target event list
* @ return UINT32 count of events on the list
*/
UINT32
DebuggerEventListCount ( PLIST_ENTRY TargetEventList )
{
PLIST_ENTRY TempList = 0 ;
2023-03-22 17:45:52 +09:00
UINT32 Counter = 0 ;
2020-08-28 04:03:12 -07:00
//
// We have to iterate through all events of this list
//
TempList = TargetEventList ;
2023-03-22 17:45:52 +09:00
while ( TargetEventList ! = TempList - > Flink )
{
2024-03-01 18:11:24 +09:00
TempList = TempList - > Flink ;
/* PDEBUGGER_EVENT CurrentEvent = CONTAINING_RECORD(TempList, DEBUGGER_EVENT, EventsOfSameTypeList); */
2020-08-28 04:03:12 -07:00
//
// Increase the counter
//
Counter + + ;
}
return Counter ;
}
2023-01-10 21:47:06 +09:00
/**
* @ brief Get List of event based on event type
*
* @ param EventType type of event
* @ return PLIST_ENTRY
*/
PLIST_ENTRY
2023-01-29 04:06:01 +09:00
DebuggerGetEventListByEventType ( VMM_EVENT_TYPE_ENUM EventType )
2023-01-10 21:47:06 +09:00
{
PLIST_ENTRY ResultList = NULL ;
//
// Register the event
//
2023-03-22 17:45:52 +09:00
switch ( EventType )
{
2023-07-07 01:21:07 +09:00
case HIDDEN_HOOK_READ_AND_WRITE_AND_EXECUTE :
ResultList = & g_Events - > HiddenHookReadAndWriteAndExecuteEventsHead ;
break ;
2023-01-10 21:47:06 +09:00
case HIDDEN_HOOK_READ_AND_WRITE :
ResultList = & g_Events - > HiddenHookReadAndWriteEventsHead ;
break ;
2023-07-07 01:21:07 +09:00
case HIDDEN_HOOK_READ_AND_EXECUTE :
ResultList = & g_Events - > HiddenHookReadAndExecuteEventsHead ;
break ;
case HIDDEN_HOOK_WRITE_AND_EXECUTE :
ResultList = & g_Events - > HiddenHookWriteAndExecuteEventsHead ;
break ;
2023-01-10 21:47:06 +09:00
case HIDDEN_HOOK_READ :
ResultList = & g_Events - > HiddenHookReadEventsHead ;
break ;
case HIDDEN_HOOK_WRITE :
ResultList = & g_Events - > HiddenHookWriteEventsHead ;
break ;
2023-07-07 01:21:07 +09:00
case HIDDEN_HOOK_EXECUTE :
ResultList = & g_Events - > HiddenHookExecuteEventsHead ;
break ;
2023-01-10 21:47:06 +09:00
case HIDDEN_HOOK_EXEC_DETOURS :
ResultList = & g_Events - > EptHook2sExecDetourEventsHead ;
break ;
case HIDDEN_HOOK_EXEC_CC :
ResultList = & g_Events - > EptHookExecCcEventsHead ;
break ;
case SYSCALL_HOOK_EFER_SYSCALL :
ResultList = & g_Events - > SyscallHooksEferSyscallEventsHead ;
break ;
case SYSCALL_HOOK_EFER_SYSRET :
ResultList = & g_Events - > SyscallHooksEferSysretEventsHead ;
break ;
case CPUID_INSTRUCTION_EXECUTION :
ResultList = & g_Events - > CpuidInstructionExecutionEventsHead ;
break ;
case RDMSR_INSTRUCTION_EXECUTION :
ResultList = & g_Events - > RdmsrInstructionExecutionEventsHead ;
break ;
case WRMSR_INSTRUCTION_EXECUTION :
ResultList = & g_Events - > WrmsrInstructionExecutionEventsHead ;
break ;
case EXCEPTION_OCCURRED :
ResultList = & g_Events - > ExceptionOccurredEventsHead ;
break ;
case TSC_INSTRUCTION_EXECUTION :
ResultList = & g_Events - > TscInstructionExecutionEventsHead ;
break ;
case PMC_INSTRUCTION_EXECUTION :
ResultList = & g_Events - > PmcInstructionExecutionEventsHead ;
break ;
case IN_INSTRUCTION_EXECUTION :
ResultList = & g_Events - > InInstructionExecutionEventsHead ;
break ;
case OUT_INSTRUCTION_EXECUTION :
ResultList = & g_Events - > OutInstructionExecutionEventsHead ;
break ;
case DEBUG_REGISTERS_ACCESSED :
ResultList = & g_Events - > DebugRegistersAccessedEventsHead ;
break ;
case EXTERNAL_INTERRUPT_OCCURRED :
ResultList = & g_Events - > ExternalInterruptOccurredEventsHead ;
break ;
case VMCALL_INSTRUCTION_EXECUTION :
ResultList = & g_Events - > VmcallInstructionExecutionEventsHead ;
break ;
2023-11-03 14:51:21 +09:00
case TRAP_EXECUTION_MODE_CHANGED :
2023-11-02 15:27:51 +09:00
ResultList = & g_Events - > TrapExecutionModeChangedEventsHead ;
break ;
2023-11-03 14:51:21 +09:00
case TRAP_EXECUTION_INSTRUCTION_TRACE :
ResultList = & g_Events - > TrapExecutionInstructionTraceEventsHead ;
2023-09-15 18:00:01 +09:00
break ;
case CONTROL_REGISTER_3_MODIFIED :
ResultList = & g_Events - > ControlRegister3ModifiedEventsHead ;
2023-09-13 19:59:55 +09:00
break ;
2023-01-10 21:47:06 +09:00
case CONTROL_REGISTER_MODIFIED :
ResultList = & g_Events - > ControlRegisterModifiedEventsHead ;
break ;
2025-08-21 00:17:26 +02:00
case XSETBV_INSTRUCTION_EXECUTION :
ResultList = & g_Events - > XsetbvInstructionExecutionEventsHead ;
break ;
2023-01-10 21:47:06 +09:00
default :
//
// Wrong event type
//
LogError ( " Err, wrong event type is specified " ) ;
ResultList = NULL ;
break ;
}
return ResultList ;
}
2021-10-04 23:47:31 +03:30
/**
* @ brief Count the list of events in a special list that
* are activate on a target core
2022-06-28 09:52:24 -07:00
*
2021-10-04 23:47:31 +03:30
* @ param TargetEventList target event list
* @ param TargetCore target core
* @ return UINT32 count of events on the list which is activated
* on the target core
*/
UINT32
DebuggerEventListCountByCore ( PLIST_ENTRY TargetEventList , UINT32 TargetCore )
{
2022-12-07 15:47:15 +09:00
PLIST_ENTRY TempList = 0 ;
2023-03-22 17:45:52 +09:00
UINT32 Counter = 0 ;
2021-10-04 23:47:31 +03:30
//
// We have to iterate through all events of this list
//
TempList = TargetEventList ;
2023-03-22 17:45:52 +09:00
while ( TargetEventList ! = TempList - > Flink )
{
TempList = TempList - > Flink ;
2021-10-04 23:47:31 +03:30
PDEBUGGER_EVENT CurrentEvent = CONTAINING_RECORD ( TempList , DEBUGGER_EVENT , EventsOfSameTypeList ) ;
2023-03-22 17:45:52 +09:00
if ( CurrentEvent - > CoreId = = DEBUGGER_EVENT_APPLY_TO_ALL_CORES | | CurrentEvent - > CoreId = = TargetCore )
{
2021-10-04 23:47:31 +03:30
//
// Increase the counter
//
Counter + + ;
}
}
return Counter ;
}
2023-01-10 21:47:06 +09:00
/**
* @ brief Count the list of events by a special event type that
* are activate on a target core
*
* @ param EventType target event type
* @ param TargetCore target core
*
* @ return UINT32 count of events on the list which is activated
* on the target core
*/
UINT32
2023-01-29 04:06:01 +09:00
DebuggerEventListCountByEventType ( VMM_EVENT_TYPE_ENUM EventType , UINT32 TargetCore )
2023-01-10 21:47:06 +09:00
{
PLIST_ENTRY TempList = 0 ;
2023-03-22 17:45:52 +09:00
UINT32 Counter = 0 ;
2023-01-10 21:47:06 +09:00
PLIST_ENTRY TargetEventList = DebuggerGetEventListByEventType ( EventType ) ;
//
// We have to iterate through all events of this list
//
TempList = TargetEventList ;
2023-03-22 17:45:52 +09:00
while ( TargetEventList ! = TempList - > Flink )
{
TempList = TempList - > Flink ;
2023-01-10 21:47:06 +09:00
PDEBUGGER_EVENT CurrentEvent = CONTAINING_RECORD ( TempList , DEBUGGER_EVENT , EventsOfSameTypeList ) ;
2023-03-22 17:45:52 +09:00
if ( CurrentEvent - > CoreId = = DEBUGGER_EVENT_APPLY_TO_ALL_CORES | | CurrentEvent - > CoreId = = TargetCore )
{
2023-01-10 21:47:06 +09:00
//
// Increase the counter
//
Counter + + ;
}
}
return Counter ;
}
2021-10-04 23:47:31 +03:30
/**
* @ brief Get the mask related to the ! exception command for the
* target core
2022-06-28 09:52:24 -07:00
*
2021-10-04 23:47:31 +03:30
* @ param CoreIndex The index of core
2022-06-28 09:52:24 -07:00
*
2021-10-04 23:47:31 +03:30
* @ return UINT32 Returns the current mask for the core
*/
UINT32
DebuggerExceptionEventBitmapMask ( UINT32 CoreIndex )
{
2023-03-22 17:45:52 +09:00
PLIST_ENTRY TempList = 0 ;
UINT32 ExceptionMask = 0 ;
2021-10-04 23:47:31 +03:30
//
// We have to iterate through all events of this list
//
TempList = & g_Events - > ExceptionOccurredEventsHead ;
2023-03-22 17:45:52 +09:00
while ( & g_Events - > ExceptionOccurredEventsHead ! = TempList - > Flink )
{
TempList = TempList - > Flink ;
2021-10-04 23:47:31 +03:30
PDEBUGGER_EVENT CurrentEvent = CONTAINING_RECORD ( TempList , DEBUGGER_EVENT , EventsOfSameTypeList ) ;
2023-03-22 17:45:52 +09:00
if ( CurrentEvent - > CoreId = = DEBUGGER_EVENT_APPLY_TO_ALL_CORES | | CurrentEvent - > CoreId = = CoreIndex )
{
2023-10-14 21:28:08 +09:00
ExceptionMask | = CurrentEvent - > Options . OptionalParam1 ;
2021-10-04 23:47:31 +03:30
}
}
return ExceptionMask ;
}
2020-08-28 04:03:12 -07:00
/**
* @ brief Enable an event by tag
2022-06-28 09:52:24 -07:00
*
2020-08-28 04:03:12 -07:00
* @ param Tag Tag of target event
2022-06-28 09:52:24 -07:00
* @ return BOOLEAN TRUE if event enabled and FALSE if event not
2020-08-28 04:03:12 -07:00
* found
*/
2020-04-13 23:33:12 -07:00
BOOLEAN
2020-05-14 08:28:28 -07:00
DebuggerEnableEvent ( UINT64 Tag )
2020-04-13 23:33:12 -07:00
{
2020-05-14 08:28:28 -07:00
PDEBUGGER_EVENT Event ;
//
// Search all the cores for enable this event
//
Event = DebuggerGetEventByTag ( Tag ) ;
2020-04-13 23:33:12 -07:00
//
2020-05-14 08:28:28 -07:00
// Check if tag is valid or not
2020-04-13 23:33:12 -07:00
//
2023-03-22 17:45:52 +09:00
if ( Event = = NULL )
{
2020-05-14 08:28:28 -07:00
return FALSE ;
}
//
// Enable the event
//
Event - > Enabled = TRUE ;
return TRUE ;
2020-04-13 23:33:12 -07:00
}
2020-05-14 08:28:28 -07:00
2021-02-21 15:05:55 -08:00
/**
* @ brief returns whether an event is enabled / disabled by tag
* @ details this function won ' t check for Tag validity and if
* not found then returns false
2022-06-28 09:52:24 -07:00
*
2021-02-21 15:05:55 -08:00
* @ param Tag Tag of target event
2022-06-28 09:52:24 -07:00
* @ return BOOLEAN TRUE if event enabled and FALSE if event not
2021-02-21 15:05:55 -08:00
* found
*/
BOOLEAN
DebuggerQueryStateEvent ( UINT64 Tag )
{
PDEBUGGER_EVENT Event ;
//
// Search all the cores for enable this event
//
Event = DebuggerGetEventByTag ( Tag ) ;
//
// Check if tag is valid or not
//
2023-03-22 17:45:52 +09:00
if ( Event = = NULL )
{
2021-02-21 15:05:55 -08:00
return FALSE ;
}
return Event - > Enabled ;
}
2020-08-28 04:03:12 -07:00
/**
* @ brief Disable an event by tag
2022-06-28 09:52:24 -07:00
*
2020-08-28 04:03:12 -07:00
* @ param Tag Tag of target event
2022-06-28 09:52:24 -07:00
* @ return BOOLEAN TRUE if event enabled and FALSE if event not
2020-08-28 04:03:12 -07:00
* found
*/
2020-04-13 23:33:12 -07:00
BOOLEAN
DebuggerDisableEvent ( UINT64 Tag )
{
2020-05-14 08:28:28 -07:00
PDEBUGGER_EVENT Event ;
2020-08-28 04:03:12 -07:00
2020-05-14 08:28:28 -07:00
//
// Search all the cores for enable this event
//
Event = DebuggerGetEventByTag ( Tag ) ;
//
// Check if tag is valid or not
//
2023-03-22 17:45:52 +09:00
if ( Event = = NULL )
{
2020-05-14 08:28:28 -07:00
return FALSE ;
}
//
// Disable the event
//
Event - > Enabled = FALSE ;
return TRUE ;
}
2023-10-22 01:14:36 +09:00
/**
* @ brief Clear an event by tag
*
* @ param Tag Tag of target event
* @ param InputFromVmxRoot Whether the input comes from VMX root - mode or IOCTL
2023-10-22 03:10:48 +09:00
* @ param PoolManagerAllocatedMemory Whether the pools are allocated from the
* pool manager or original OS pools
2023-10-22 01:14:36 +09:00
*
* @ return BOOLEAN
*
*/
BOOLEAN
2023-10-22 03:10:48 +09:00
DebuggerClearEvent ( UINT64 Tag , BOOLEAN InputFromVmxRoot , BOOLEAN PoolManagerAllocatedMemory )
2023-10-22 01:14:36 +09:00
{
//
// Because we want to delete all the objects and buffers (pools)
// after we finished termination, the debugger might still use
// the buffers for events and action, for solving this problem
// we first disable the tag(s) and this way the debugger no longer
// use that event and this way we can safely remove and deallocate
// the buffers later after termination
//
//
// First, disable just one event
//
DebuggerDisableEvent ( Tag ) ;
//
// Second, terminate it
//
DebuggerTerminateEvent ( Tag , InputFromVmxRoot ) ;
//
// Third, remove it from the list
//
2023-10-22 03:10:48 +09:00
return DebuggerRemoveEvent ( Tag , PoolManagerAllocatedMemory ) ;
2023-10-22 01:14:36 +09:00
}
/**
* @ brief Clear all events
*
* @ param InputFromVmxRoot Whether the input comes from VMX root - mode or IOCTL
2023-10-22 03:10:48 +09:00
* @ param PoolManagerAllocatedMemory Whether the pools are allocated from the
* pool manager or original OS pools
2023-10-22 01:14:36 +09:00
*
* @ return VOID
*/
VOID
2023-10-22 03:10:48 +09:00
DebuggerClearAllEvents ( BOOLEAN InputFromVmxRoot , BOOLEAN PoolManagerAllocatedMemory )
2023-10-22 01:14:36 +09:00
{
//
// Because we want to delete all the objects and buffers (pools)
// after we finished termination, the debugger might still use
// the buffers for events and action, for solving this problem
// we first disable the tag(s) and this way the debugger no longer
// use that event and this way we can safely remove and deallocate
// the buffers later after termination
//
//
// First, disable all events
//
DebuggerEnableOrDisableAllEvents ( FALSE ) ;
//
// Second, terminate all events
//
DebuggerTerminateAllEvents ( InputFromVmxRoot ) ;
//
// Third, remove all events
//
2023-10-22 03:10:48 +09:00
DebuggerRemoveAllEvents ( PoolManagerAllocatedMemory ) ;
2023-10-22 01:14:36 +09:00
}
2020-08-28 04:03:12 -07:00
/**
* @ brief Detect whether the tag exists or not
2022-06-28 09:52:24 -07:00
*
2020-08-28 04:03:12 -07:00
* @ param Tag Tag of target event
* @ return BOOLEAN TRUE if event found and FALSE if event not found
*/
BOOLEAN
DebuggerIsTagValid ( UINT64 Tag )
{
PDEBUGGER_EVENT Event ;
//
// Search this event
//
Event = DebuggerGetEventByTag ( Tag ) ;
//
// Check if tag is valid or not
//
2023-03-22 17:45:52 +09:00
if ( Event = = NULL )
{
2020-08-28 04:03:12 -07:00
return FALSE ;
}
return TRUE ;
}
2023-01-10 21:06:49 +09:00
/**
* @ brief Detect whether the user or kernel debugger
* is active or not
*
* @ return BOOLEAN TRUE if any of the are activated and FALSE if not
*/
BOOLEAN
DebuggerQueryDebuggerStatus ( )
{
2023-03-22 17:45:52 +09:00
if ( g_KernelDebuggerState | | g_UserDebuggerState )
{
2023-01-10 21:06:49 +09:00
return TRUE ;
2023-03-22 17:45:52 +09:00
}
else
{
2023-01-10 21:06:49 +09:00
return FALSE ;
}
}
2020-08-28 04:03:12 -07:00
/**
* @ brief Remove the event from event list by its tag
2022-06-28 09:52:24 -07:00
*
2020-08-28 04:03:12 -07:00
* @ details should not be called from vmx - root mode , also
2022-06-28 09:52:24 -07:00
* it won ' t terminate their effects , so the events should
2020-08-28 04:03:12 -07:00
* be terminated first then we can remove them
2022-06-28 09:52:24 -07:00
*
2020-08-28 04:03:12 -07:00
* @ param Tag Target events tag
* @ return BOOLEAN If the event was removed then TRUE and FALSE
* if not found
*/
2020-05-14 08:28:28 -07:00
BOOLEAN
2020-05-15 10:45:22 -07:00
DebuggerRemoveEventFromEventList ( UINT64 Tag )
2020-05-14 08:28:28 -07:00
{
2023-03-22 17:45:52 +09:00
PLIST_ENTRY TempList = 0 ;
2020-05-14 08:28:28 -07:00
PLIST_ENTRY TempList2 = 0 ;
//
// We have to iterate through all events
//
2026-05-31 18:59:52 +02:00
for ( SIZE_T i = 0 ; i < sizeof ( DEBUGGER_CORE_EVENTS ) / sizeof ( LIST_ENTRY ) ; i + + )
2023-03-22 17:45:52 +09:00
{
TempList = ( PLIST_ENTRY ) ( ( UINT64 ) ( g_Events ) + ( i * sizeof ( LIST_ENTRY ) ) ) ;
2020-05-14 08:28:28 -07:00
TempList2 = TempList ;
2023-03-22 17:45:52 +09:00
while ( TempList2 ! = TempList - > Flink )
{
TempList = TempList - > Flink ;
2020-05-14 08:28:28 -07:00
PDEBUGGER_EVENT CurrentEvent = CONTAINING_RECORD ( TempList , DEBUGGER_EVENT , EventsOfSameTypeList ) ;
//
// Check if we find the event or not
//
2023-03-22 17:45:52 +09:00
if ( CurrentEvent - > Tag = = Tag )
{
2020-05-14 08:28:28 -07:00
//
// We have to remove the event from the list
//
2020-05-15 13:50:41 -07:00
RemoveEntryList ( & CurrentEvent - > EventsOfSameTypeList ) ;
2020-05-14 14:59:56 -07:00
return TRUE ;
2020-05-14 08:28:28 -07:00
}
}
}
2020-04-13 23:33:12 -07:00
//
2020-05-14 08:28:28 -07:00
// We didn't find anything, so return null
2020-04-13 23:33:12 -07:00
//
2020-05-14 08:28:28 -07:00
return FALSE ;
2020-04-13 23:33:12 -07:00
}
2020-08-28 04:03:12 -07:00
/**
2022-06-28 09:52:24 -07:00
* @ brief Remove the actions and de - allocate its buffer
*
2020-08-28 04:03:12 -07:00
* @ details should not be called from vmx - root mode , also
2022-06-28 09:52:24 -07:00
* it won ' t terminate their effects , so the events should
* be terminated first then we can remove them *
*
2020-08-28 04:03:12 -07:00
* @ param Event Event Object
2023-10-22 03:10:48 +09:00
* @ param PoolManagerAllocatedMemory Whether the pools are allocated from the
* pool manager or original OS pools
2023-10-17 16:50:28 +09:00
*
2020-08-28 04:03:12 -07:00
* @ return BOOLEAN TRUE if it was successful and FALSE if not successful
*/
2020-04-13 23:33:12 -07:00
BOOLEAN
2023-10-22 03:10:48 +09:00
DebuggerRemoveAllActionsFromEvent ( PDEBUGGER_EVENT Event , BOOLEAN PoolManagerAllocatedMemory )
2020-04-13 23:33:12 -07:00
{
2023-03-22 17:45:52 +09:00
PLIST_ENTRY TempList = 0 ;
2020-05-14 08:28:28 -07:00
PLIST_ENTRY TempList2 = 0 ;
//
// Remove all actions
//
2026-06-05 14:59:18 +01:00
TempList = Event - > ActionsListHead . Flink ;
TempList2 = & Event - > ActionsListHead ;
2020-05-14 08:28:28 -07:00
2026-06-05 14:59:18 +01:00
while ( TempList ! = TempList2 )
2023-03-22 17:45:52 +09:00
{
2026-06-05 14:59:18 +01:00
PLIST_ENTRY NextList = TempList - > Flink ;
2020-05-14 08:28:28 -07:00
PDEBUGGER_EVENT_ACTION CurrentAction = CONTAINING_RECORD ( TempList , DEBUGGER_EVENT_ACTION , ActionsList ) ;
//
// Check if it has a OptionalRequestedBuffer probably for
// CustomCode
//
2024-03-01 15:59:58 +09:00
if ( CurrentAction - > RequestedBuffer . RequestBufferSize ! = 0 & & CurrentAction - > RequestedBuffer . RequstBufferAddress ! = ( UINT64 ) NULL )
2023-03-22 17:45:52 +09:00
{
2020-05-14 08:28:28 -07:00
//
// There is a buffer
//
2023-10-22 03:10:48 +09:00
if ( PoolManagerAllocatedMemory )
2023-10-17 16:50:28 +09:00
{
PoolManagerFreePool ( CurrentAction - > RequestedBuffer . RequstBufferAddress ) ;
}
else
{
2024-05-11 20:22:52 +09:00
PlatformMemFreePool ( ( PVOID ) CurrentAction - > RequestedBuffer . RequstBufferAddress ) ;
2023-10-17 16:50:28 +09:00
}
2020-05-14 08:28:28 -07:00
}
//
// Remove the action and free the pool,
// if it's a custom buffer then the buffer
// is appended to the Action
//
2026-06-05 14:59:18 +01:00
RemoveEntryList ( & CurrentAction - > ActionsList ) ;
2023-10-22 03:10:48 +09:00
if ( PoolManagerAllocatedMemory )
2023-10-17 16:50:28 +09:00
{
2024-03-01 18:11:24 +09:00
PoolManagerFreePool ( ( UINT64 ) CurrentAction ) ;
2023-10-17 16:50:28 +09:00
}
else
{
2024-05-11 20:22:52 +09:00
PlatformMemFreePool ( CurrentAction ) ;
2023-10-17 16:50:28 +09:00
}
2026-06-05 14:59:18 +01:00
TempList = NextList ;
2020-05-14 08:28:28 -07:00
}
2020-04-13 23:33:12 -07:00
//
// Remember to free the pool
//
2020-05-14 08:28:28 -07:00
return TRUE ;
}
2020-08-28 04:03:12 -07:00
/**
* @ brief Remove the event by its tags and also remove its actions
* and de - allocate their buffers
2022-06-28 09:52:24 -07:00
*
2023-10-17 16:50:28 +09:00
* @ details it won ' t terminate their effects , so the events should
2020-08-28 04:03:12 -07:00
* be terminated first then we can remove them
2022-06-28 09:52:24 -07:00
*
2020-08-28 04:03:12 -07:00
* @ param Tag Target event tag
2023-10-22 03:10:48 +09:00
* @ param PoolManagerAllocatedMemory Whether the pools are allocated from the
* pool manager or original OS pools
2023-10-17 16:50:28 +09:00
*
2020-08-28 04:03:12 -07:00
* @ return BOOLEAN TRUE if it was successful and FALSE if not successful
*/
2020-05-14 08:28:28 -07:00
BOOLEAN
2023-10-22 03:10:48 +09:00
DebuggerRemoveEvent ( UINT64 Tag , BOOLEAN PoolManagerAllocatedMemory )
2020-05-14 08:28:28 -07:00
{
PDEBUGGER_EVENT Event ;
//
// First of all, we disable event
//
2023-03-22 17:45:52 +09:00
if ( ! DebuggerDisableEvent ( Tag ) )
{
2020-05-14 08:28:28 -07:00
//
// Not found, tag is wrong !
//
return FALSE ;
}
//
// When we're here, we are sure that the tag is valid
// because if it was not valid, then we have to return
// for the above function (DebuggerDisableEvent)
//
Event = DebuggerGetEventByTag ( Tag ) ;
//
2020-05-15 10:45:22 -07:00
// Now we get the PDEBUGGER_EVENT so we have to remove
// it from the event list
2020-05-14 08:28:28 -07:00
//
2023-03-22 17:45:52 +09:00
if ( ! DebuggerRemoveEventFromEventList ( Tag ) )
{
2020-05-15 10:45:22 -07:00
return FALSE ;
2020-05-14 08:28:28 -07:00
}
2020-05-15 13:50:41 -07:00
2020-05-14 08:28:28 -07:00
//
// Remove all of the actions and free its pools
//
2023-10-22 03:10:48 +09:00
DebuggerRemoveAllActionsFromEvent ( Event , PoolManagerAllocatedMemory ) ;
2020-05-14 08:28:28 -07:00
//
// Free the pools of Event, when we free the pool,
// ConditionsBufferAddress is also a part of the
// event pool (ConditionBufferAddress and event
// are both allocate in a same pool ) so both of
// them are freed
//
2023-10-22 03:10:48 +09:00
if ( PoolManagerAllocatedMemory )
2023-10-17 16:50:28 +09:00
{
2024-03-01 18:11:24 +09:00
PoolManagerFreePool ( ( UINT64 ) Event ) ;
2023-10-17 16:50:28 +09:00
}
else
{
2024-05-11 20:22:52 +09:00
PlatformMemFreePool ( Event ) ;
2023-10-17 16:50:28 +09:00
}
2020-05-14 08:28:28 -07:00
return TRUE ;
2020-04-13 23:33:12 -07:00
}
2020-04-16 10:40:20 -07:00
2020-05-19 16:18:34 -07:00
/**
2023-10-10 21:46:05 +09:00
* @ brief validating events
2022-06-28 09:52:24 -07:00
*
2020-08-28 04:03:12 -07:00
* @ param EventDetails The structure that describes event that came
2023-10-10 21:46:05 +09:00
* from the user - mode or VMX - root mode
* @ param ResultsToReturn Result buffer that should be returned to
2020-08-28 04:03:12 -07:00
* the user - mode
2023-10-10 21:46:05 +09:00
* @ param InputFromVmxRoot Whether the input comes from VMX root - mode or IOCTL
*
2023-10-10 23:28:31 +09:00
* @ return BOOLEAN TRUE if the event was valid otherwise returns FALSE
2020-05-19 16:18:34 -07:00
*/
BOOLEAN
2023-10-15 00:08:45 +09:00
DebuggerValidateEvent ( PDEBUGGER_GENERAL_EVENT_DETAIL EventDetails ,
PDEBUGGER_EVENT_AND_ACTION_RESULT ResultsToReturn ,
BOOLEAN InputFromVmxRoot )
2020-05-19 16:18:34 -07:00
{
2022-10-17 12:06:12 +09:00
//
// Check whether the event mode (calling stage) to see whether
// short-cicuiting event is used along with the post-event,
// it is because using the short-circuiting mechanism with
// post-events doesn't make sense; it's not supported!
//
2023-07-31 15:05:14 +09:00
if ( ( EventDetails - > EventStage = = VMM_CALLBACK_CALLING_STAGE_POST_EVENT_EMULATION | |
EventDetails - > EventStage = = VMM_CALLBACK_CALLING_STAGE_ALL_EVENT_EMULATION ) & &
2023-07-30 22:43:51 +09:00
EventDetails - > EnableShortCircuiting = = TRUE )
2023-03-22 17:45:52 +09:00
{
2023-10-10 21:46:05 +09:00
ResultsToReturn - > IsSuccessful = FALSE ;
ResultsToReturn - > Error = DEBUGGER_ERROR_USING_SHORT_CIRCUITING_EVENT_WITH_POST_EVENT_MODE_IS_FORBIDDEDN ;
2022-10-17 12:06:12 +09:00
return FALSE ;
}
2020-06-01 14:17:32 -07:00
//
// Check whether the core Id is valid or not, we read cores count
// here because we use it in later parts
//
2023-03-22 17:45:52 +09:00
if ( EventDetails - > CoreId ! = DEBUGGER_EVENT_APPLY_TO_ALL_CORES )
{
2020-06-01 14:17:32 -07:00
//
// Check if the core number is not invalid
//
2023-10-10 23:28:31 +09:00
if ( ! CommonValidateCoreNumber ( EventDetails - > CoreId ) )
2023-03-22 17:45:52 +09:00
{
2020-06-01 14:17:32 -07:00
//
// CoreId is invalid (Set the error)
//
2023-10-10 21:46:05 +09:00
ResultsToReturn - > IsSuccessful = FALSE ;
ResultsToReturn - > Error = DEBUGGER_ERROR_INVALID_CORE_ID ;
2020-06-01 14:17:32 -07:00
return FALSE ;
}
}
2021-11-04 12:47:18 +03:30
//
// Check if process id is valid or not, we won't touch process id here
// because some of the events use the exact value of DEBUGGER_EVENT_APPLY_TO_ALL_PROCESSES
//
2023-03-22 17:45:52 +09:00
if ( EventDetails - > ProcessId ! = DEBUGGER_EVENT_APPLY_TO_ALL_PROCESSES & & EventDetails - > ProcessId ! = 0 )
{
2021-11-04 12:47:18 +03:30
//
2023-10-10 21:46:05 +09:00
// Here we prefer not to validate the process id, if it's applied from VMX-root mode
2021-11-04 12:47:18 +03:30
//
2023-10-10 21:46:05 +09:00
if ( ! InputFromVmxRoot )
2023-03-22 17:45:52 +09:00
{
2023-10-10 21:46:05 +09:00
//
// The used specified a special pid, let's check if it's valid or not
//
if ( ! CommonIsProcessExist ( EventDetails - > ProcessId ) )
{
ResultsToReturn - > IsSuccessful = FALSE ;
ResultsToReturn - > Error = DEBUGGER_ERROR_INVALID_PROCESS_ID ;
return FALSE ;
}
2021-11-04 12:47:18 +03:30
}
}
2023-10-15 16:12:57 +09:00
//
// *** Event specific validations ***
//
switch ( EventDetails - > EventType )
{
case EXCEPTION_OCCURRED :
2023-03-22 17:45:52 +09:00
{
2020-06-03 06:59:28 -07:00
//
2023-10-15 16:12:57 +09:00
// Check if exception parameters are valid
2020-06-03 06:59:28 -07:00
//
2023-10-15 16:12:57 +09:00
if ( ! ValidateEventException ( EventDetails , ResultsToReturn , InputFromVmxRoot ) )
2023-03-22 17:45:52 +09:00
{
2020-06-03 06:59:28 -07:00
//
2023-10-15 16:12:57 +09:00
// Event parameters are not valid, let break the further execution at this stage
2020-06-03 06:59:28 -07:00
//
return FALSE ;
}
2023-10-15 16:12:57 +09:00
break ;
2023-03-22 17:45:52 +09:00
}
2023-10-15 16:12:57 +09:00
case EXTERNAL_INTERRUPT_OCCURRED :
2023-03-22 17:45:52 +09:00
{
2020-06-12 16:01:10 -07:00
//
2023-10-15 16:12:57 +09:00
// Check if interrupt parameters are valid
2020-06-12 16:01:10 -07:00
//
2023-10-15 16:12:57 +09:00
if ( ! ValidateEventInterrupt ( EventDetails , ResultsToReturn , InputFromVmxRoot ) )
2023-03-22 17:45:52 +09:00
{
2020-06-12 16:01:10 -07:00
//
2023-10-15 16:12:57 +09:00
// Event parameters are not valid, let break the further execution at this stage
2020-06-12 16:01:10 -07:00
//
return FALSE ;
}
2023-10-15 16:12:57 +09:00
break ;
2023-03-22 17:45:52 +09:00
}
2023-11-03 14:51:21 +09:00
case TRAP_EXECUTION_MODE_CHANGED :
2023-09-18 19:47:13 +09:00
{
//
2023-11-02 15:27:51 +09:00
// Check if trap exec mode parameters are valid
2023-09-18 19:47:13 +09:00
//
2023-11-02 15:27:51 +09:00
if ( ! ValidateEventTrapExec ( EventDetails , ResultsToReturn , InputFromVmxRoot ) )
2023-09-18 19:47:13 +09:00
{
//
2023-10-15 16:12:57 +09:00
// Event parameters are not valid, let break the further execution at this stage
2023-09-18 19:47:13 +09:00
//
return FALSE ;
}
2023-10-15 16:12:57 +09:00
break ;
2023-09-18 19:47:13 +09:00
}
2023-10-15 16:12:57 +09:00
case HIDDEN_HOOK_EXEC_DETOURS :
case HIDDEN_HOOK_EXEC_CC :
2023-03-22 17:45:52 +09:00
{
2020-05-21 22:52:23 -07:00
//
2023-10-15 16:12:57 +09:00
// Check if EPT hook exec (hidden breakpoint and inline hook) parameters are valid
2023-10-10 21:46:05 +09:00
//
2023-10-15 16:12:57 +09:00
if ( ! ValidateEventEptHookHiddenBreakpointAndInlineHooks ( EventDetails , ResultsToReturn , InputFromVmxRoot ) )
2023-03-22 17:45:52 +09:00
{
2023-10-15 16:12:57 +09:00
//
// Event parameters are not valid, let break the further execution at this stage
//
2020-05-21 22:52:23 -07:00
return FALSE ;
}
2023-10-10 21:46:05 +09:00
2023-10-15 16:12:57 +09:00
break ;
2023-03-22 17:45:52 +09:00
}
2023-10-15 16:12:57 +09:00
case HIDDEN_HOOK_READ_AND_WRITE_AND_EXECUTE :
case HIDDEN_HOOK_READ_AND_WRITE :
case HIDDEN_HOOK_READ_AND_EXECUTE :
case HIDDEN_HOOK_WRITE_AND_EXECUTE :
case HIDDEN_HOOK_READ :
case HIDDEN_HOOK_WRITE :
case HIDDEN_HOOK_EXECUTE :
2023-03-22 17:45:52 +09:00
{
2020-05-20 11:38:07 -07:00
//
2023-10-15 16:12:57 +09:00
// Check if EPT memory monitor hook parameters are valid
2020-05-20 11:38:07 -07:00
//
2023-10-15 16:12:57 +09:00
if ( ! ValidateEventMonitor ( EventDetails , ResultsToReturn , InputFromVmxRoot ) )
2023-03-22 17:45:52 +09:00
{
2023-10-15 16:12:57 +09:00
//
// Event parameters are not valid, let break the further execution at this stage
//
2020-05-20 11:38:07 -07:00
return FALSE ;
}
2023-10-15 16:12:57 +09:00
break ;
}
default :
2023-10-10 21:46:05 +09:00
2020-05-20 11:38:07 -07:00
//
2023-10-15 16:12:57 +09:00
// Other not specified events doesn't have any special validation
2020-05-20 11:38:07 -07:00
//
2023-10-15 16:12:57 +09:00
break ;
2020-05-20 11:38:07 -07:00
}
2023-10-10 21:46:05 +09:00
//
// As we reached, all the checks are passed and it means the event is valid
//
return TRUE ;
}
/**
2023-10-10 23:28:31 +09:00
* @ brief Applying events
2023-10-10 21:46:05 +09:00
*
2023-10-14 23:29:16 +09:00
* @ param Event The created event object
2023-10-10 21:46:05 +09:00
* @ param ResultsToReturn Result buffer that should be returned to
* the user - mode
* @ param InputFromVmxRoot Whether the input comes from VMX root - mode or IOCTL
*
2023-10-10 23:28:31 +09:00
* @ return BOOLEAN TRUE if the event was applied otherwise returns FALSE
2023-10-10 21:46:05 +09:00
*/
BOOLEAN
2023-10-15 00:08:45 +09:00
DebuggerApplyEvent ( PDEBUGGER_EVENT Event ,
PDEBUGGER_EVENT_AND_ACTION_RESULT ResultsToReturn ,
BOOLEAN InputFromVmxRoot )
2023-10-10 21:46:05 +09:00
{
2020-05-19 16:18:34 -07:00
//
// Now we should configure the cpu to generate the events
//
2023-10-14 23:29:16 +09:00
switch ( Event - > EventType )
2023-03-22 17:45:52 +09:00
{
2023-07-07 01:21:07 +09:00
case HIDDEN_HOOK_READ_AND_WRITE_AND_EXECUTE :
2021-10-27 02:43:15 +03:30
case HIDDEN_HOOK_READ_AND_WRITE :
2023-07-07 01:21:07 +09:00
case HIDDEN_HOOK_READ_AND_EXECUTE :
case HIDDEN_HOOK_WRITE_AND_EXECUTE :
2021-10-27 02:43:15 +03:30
case HIDDEN_HOOK_READ :
2023-03-22 17:45:52 +09:00
case HIDDEN_HOOK_WRITE :
2023-07-07 01:21:07 +09:00
case HIDDEN_HOOK_EXECUTE :
2023-03-22 17:45:52 +09:00
{
2021-08-27 14:59:08 +04:30
//
2023-10-15 15:23:15 +09:00
// Apply the monitor memory hook events
2020-05-20 11:38:07 -07:00
//
2023-10-15 15:23:15 +09:00
if ( ! ApplyEventMonitorEvent ( Event , ResultsToReturn , InputFromVmxRoot ) )
2023-03-22 17:45:52 +09:00
{
2021-10-27 02:43:15 +03:30
goto ClearTheEventAfterCreatingEvent ;
}
break ;
2020-05-19 16:18:34 -07:00
}
2023-03-22 17:45:52 +09:00
case HIDDEN_HOOK_EXEC_CC :
{
2020-08-28 04:03:12 -07:00
//
2023-10-15 15:23:15 +09:00
// Apply the EPT hidden hook (hidden breakpoint) events
2020-08-28 04:03:12 -07:00
//
2023-10-15 15:23:15 +09:00
if ( ! ApplyEventEptHookExecCcEvent ( Event , ResultsToReturn , InputFromVmxRoot ) )
2023-10-14 23:29:16 +09:00
{
2021-10-27 02:43:15 +03:30
goto ClearTheEventAfterCreatingEvent ;
}
2020-07-10 13:33:43 -07:00
2021-10-27 02:43:15 +03:30
break ;
2020-07-10 13:33:43 -07:00
}
2023-03-22 17:45:52 +09:00
case HIDDEN_HOOK_EXEC_DETOURS :
{
2020-08-28 04:03:12 -07:00
//
2023-10-15 15:23:15 +09:00
// Apply the EPT hook trampoline (inline hook) events
2020-08-28 04:03:12 -07:00
//
2023-10-15 15:23:15 +09:00
if ( ! ApplyEventEpthookInlineEvent ( Event , ResultsToReturn , InputFromVmxRoot ) )
2023-03-22 17:45:52 +09:00
{
2021-10-27 02:43:15 +03:30
goto ClearTheEventAfterCreatingEvent ;
}
2020-05-29 15:24:00 -07:00
2021-10-27 02:43:15 +03:30
break ;
2020-05-19 16:18:34 -07:00
}
2023-03-22 17:45:52 +09:00
case RDMSR_INSTRUCTION_EXECUTION :
{
2020-06-01 14:17:32 -07:00
//
2023-10-15 15:23:15 +09:00
// Apply the RDMSR execution exiting events
2020-06-02 07:20:06 -07:00
//
2023-10-15 15:23:15 +09:00
ApplyEventRdmsrExecutionEvent ( Event , ResultsToReturn , InputFromVmxRoot ) ;
2021-10-27 02:43:15 +03:30
break ;
2020-06-02 07:20:06 -07:00
}
2023-03-22 17:45:52 +09:00
case WRMSR_INSTRUCTION_EXECUTION :
{
2020-06-02 07:20:06 -07:00
//
2023-10-15 15:23:15 +09:00
// Apply the WRMSR execution exiting events
2020-06-02 07:20:06 -07:00
//
2023-10-15 15:23:15 +09:00
ApplyEventWrmsrExecutionEvent ( Event , ResultsToReturn , InputFromVmxRoot ) ;
2021-10-27 02:43:15 +03:30
break ;
2020-06-01 14:17:32 -07:00
}
2021-10-27 02:43:15 +03:30
case IN_INSTRUCTION_EXECUTION :
2023-03-22 17:45:52 +09:00
case OUT_INSTRUCTION_EXECUTION :
{
2020-06-13 03:12:44 -07:00
//
2023-10-15 15:23:15 +09:00
// Apply the IN/OUT instructions execution exiting events
2020-06-13 03:12:44 -07:00
//
2023-10-15 15:23:15 +09:00
ApplyEventInOutExecutionEvent ( Event , ResultsToReturn , InputFromVmxRoot ) ;
2021-10-27 02:43:15 +03:30
break ;
2020-06-13 03:12:44 -07:00
}
2023-03-22 17:45:52 +09:00
case TSC_INSTRUCTION_EXECUTION :
{
2020-06-02 11:41:37 -07:00
//
2023-10-15 15:23:15 +09:00
// Apply the RDTSC/RDTSCP instructions execution exiting events
2020-06-02 11:41:37 -07:00
//
2023-10-15 15:23:15 +09:00
ApplyEventTscExecutionEvent ( Event , ResultsToReturn , InputFromVmxRoot ) ;
2021-10-27 02:43:15 +03:30
break ;
2020-05-19 16:18:34 -07:00
}
2023-03-22 17:45:52 +09:00
case PMC_INSTRUCTION_EXECUTION :
{
2020-06-02 15:17:03 -07:00
//
2023-10-15 15:23:15 +09:00
// Apply the RDPMC instruction execution exiting events
2020-06-02 15:17:03 -07:00
//
2023-10-15 15:23:15 +09:00
ApplyEventRdpmcExecutionEvent ( Event , ResultsToReturn , InputFromVmxRoot ) ;
2021-10-27 02:43:15 +03:30
break ;
2020-06-02 15:17:03 -07:00
}
2023-03-22 17:45:52 +09:00
case DEBUG_REGISTERS_ACCESSED :
{
2020-06-12 16:01:10 -07:00
//
2023-10-15 15:23:15 +09:00
// Apply the mov 2 debug register exiting events
2020-06-12 16:01:10 -07:00
//
2023-10-15 15:23:15 +09:00
ApplyEventMov2DebugRegExecutionEvent ( Event , ResultsToReturn , InputFromVmxRoot ) ;
2021-10-27 02:43:15 +03:30
break ;
2020-06-12 16:01:10 -07:00
}
2023-03-22 17:45:52 +09:00
case CONTROL_REGISTER_MODIFIED :
{
2022-07-08 01:19:41 +02:00
//
2023-10-15 15:23:15 +09:00
// Apply the control register access exiting events
2022-07-08 01:19:41 +02:00
//
2023-10-15 15:23:15 +09:00
ApplyEventControlRegisterAccessedEvent ( Event , ResultsToReturn , InputFromVmxRoot ) ;
2022-07-08 01:19:41 +02:00
break ;
}
2023-03-22 17:45:52 +09:00
case EXCEPTION_OCCURRED :
{
2020-08-28 04:03:12 -07:00
//
2023-10-15 15:23:15 +09:00
// Apply the exception events
2020-08-28 04:03:12 -07:00
//
2023-10-15 15:23:15 +09:00
ApplyEventExceptionEvent ( Event , ResultsToReturn , InputFromVmxRoot ) ;
2021-10-27 02:43:15 +03:30
break ;
2020-06-03 06:59:28 -07:00
}
2023-03-22 17:45:52 +09:00
case EXTERNAL_INTERRUPT_OCCURRED :
{
2020-08-28 04:03:12 -07:00
//
2023-10-15 15:23:15 +09:00
// Apply the interrupt events
2020-08-28 04:03:12 -07:00
//
2023-10-15 15:23:15 +09:00
ApplyEventInterruptEvent ( Event , ResultsToReturn , InputFromVmxRoot ) ;
2021-10-27 02:43:15 +03:30
break ;
2020-06-12 16:01:10 -07:00
}
2023-03-22 17:45:52 +09:00
case SYSCALL_HOOK_EFER_SYSCALL :
{
2020-06-13 22:39:53 -07:00
//
2023-10-15 15:23:15 +09:00
// Apply the EFER SYSCALL hook events
2020-06-13 22:39:53 -07:00
//
2023-10-15 15:23:15 +09:00
ApplyEventEferSyscallHookEvent ( Event , ResultsToReturn , InputFromVmxRoot ) ;
2021-10-27 02:43:15 +03:30
break ;
2020-05-19 16:18:34 -07:00
}
2023-03-22 17:45:52 +09:00
case SYSCALL_HOOK_EFER_SYSRET :
{
2020-06-13 22:39:53 -07:00
//
2023-10-15 15:23:15 +09:00
// Apply the EFER SYSRET hook events
2020-06-13 22:39:53 -07:00
//
2023-10-15 15:23:15 +09:00
ApplyEventEferSysretHookEvent ( Event , ResultsToReturn , InputFromVmxRoot ) ;
2021-10-27 02:43:15 +03:30
break ;
2020-05-19 16:18:34 -07:00
}
2023-03-22 17:45:52 +09:00
case VMCALL_INSTRUCTION_EXECUTION :
{
2020-08-28 04:03:12 -07:00
//
2023-10-15 15:23:15 +09:00
// Apply the VMCALL instruction interception events
2020-08-28 04:03:12 -07:00
//
2023-10-15 15:23:15 +09:00
ApplyEventVmcallExecutionEvent ( Event , ResultsToReturn , InputFromVmxRoot ) ;
2021-10-27 02:43:15 +03:30
break ;
2020-08-28 04:03:12 -07:00
}
2023-11-03 14:51:21 +09:00
case TRAP_EXECUTION_MODE_CHANGED :
2023-09-13 19:59:55 +09:00
{
2023-09-18 19:47:13 +09:00
//
2023-11-02 13:48:56 +09:00
// Apply the trap mode change and single instruction trace events
2023-09-13 19:59:55 +09:00
//
2023-11-02 15:27:51 +09:00
if ( ! ApplyEventTrapModeChangeEvent ( Event , ResultsToReturn , InputFromVmxRoot ) )
2023-10-25 15:05:29 +09:00
{
goto ClearTheEventAfterCreatingEvent ;
}
2023-09-14 21:17:44 +09:00
2023-09-13 19:59:55 +09:00
break ;
}
2023-03-22 17:45:52 +09:00
case CPUID_INSTRUCTION_EXECUTION :
{
2020-08-28 04:03:12 -07:00
//
2023-10-15 15:23:15 +09:00
// Apply the CPUID instruction execution events
2020-08-28 04:03:12 -07:00
//
2023-10-15 15:23:15 +09:00
ApplyEventCpuidExecutionEvent ( Event , ResultsToReturn , InputFromVmxRoot ) ;
2021-10-27 02:43:15 +03:30
break ;
2020-08-28 04:03:12 -07:00
}
2023-11-03 14:51:21 +09:00
case TRAP_EXECUTION_INSTRUCTION_TRACE :
{
//
// Apply the tracing events
//
ApplyEventTracingEvent ( Event , ResultsToReturn , InputFromVmxRoot ) ;
break ;
}
2025-08-21 00:17:26 +02:00
case XSETBV_INSTRUCTION_EXECUTION :
{
//
// Apply the XSETBV instruction execution events
//
ApplyEventXsetbvExecutionEvent ( Event , ResultsToReturn , InputFromVmxRoot ) ;
break ;
}
2023-03-22 17:45:52 +09:00
default :
{
2020-05-19 16:18:34 -07:00
//
// Set the error
//
2023-10-10 21:46:05 +09:00
ResultsToReturn - > IsSuccessful = FALSE ;
ResultsToReturn - > Error = DEBUGGER_ERROR_EVENT_TYPE_IS_INVALID ;
2021-10-27 02:43:15 +03:30
goto ClearTheEventAfterCreatingEvent ;
break ;
}
2020-05-19 16:18:34 -07:00
}
//
// Set the status
//
2023-10-10 21:46:05 +09:00
ResultsToReturn - > IsSuccessful = TRUE ;
ResultsToReturn - > Error = 0 ;
2020-05-19 16:18:34 -07:00
2021-10-27 02:43:15 +03:30
//
// Event was applied successfully
//
2020-05-19 16:18:34 -07:00
return TRUE ;
2021-10-27 02:43:15 +03:30
ClearTheEventAfterCreatingEvent :
2023-10-10 23:28:31 +09:00
return FALSE ;
}
/**
* @ brief Routine for parsing events
*
* @ param EventDetails The structure that describes event that came
* from the user - mode
* @ param ResultsToReturn Result buffer that should be returned to
* the user - mode
* @ param InputFromVmxRoot Whether the input comes from VMX root - mode or IOCTL
*
2024-03-17 18:17:38 +09:00
* @ return BOOLEAN TRUE if the event was valid and registered without error ,
2023-10-10 23:28:31 +09:00
* otherwise returns FALSE
*/
BOOLEAN
2023-10-15 00:08:45 +09:00
DebuggerParseEvent ( PDEBUGGER_GENERAL_EVENT_DETAIL EventDetails ,
PDEBUGGER_EVENT_AND_ACTION_RESULT ResultsToReturn ,
BOOLEAN InputFromVmxRoot )
2023-10-10 23:28:31 +09:00
{
PDEBUGGER_EVENT Event ;
2021-10-27 02:43:15 +03:30
//
2023-10-10 23:28:31 +09:00
// ----------------------------------------------------------------------------------
// *** Validating the Event's parameters ***
// ----------------------------------------------------------------------------------
2021-10-27 02:43:15 +03:30
//
2023-10-10 23:28:31 +09:00
//
// Validate the event parameters
//
2023-10-14 21:28:08 +09:00
if ( ! DebuggerValidateEvent ( EventDetails , ResultsToReturn , InputFromVmxRoot ) )
2023-03-22 17:45:52 +09:00
{
2023-10-10 23:28:31 +09:00
//
// Input event is not valid
//
return FALSE ;
2021-10-27 02:43:15 +03:30
}
2023-10-10 23:28:31 +09:00
//
// ----------------------------------------------------------------------------------
// *** Create Event ***
// ----------------------------------------------------------------------------------
//
//
// We initialize event with disabled mode as it doesn't have action yet
//
if ( EventDetails - > ConditionBufferSize ! = 0 )
{
//
// Conditional Event
//
Event = DebuggerCreateEvent ( FALSE ,
EventDetails - > CoreId ,
EventDetails - > ProcessId ,
EventDetails - > EventType ,
EventDetails - > Tag ,
2023-10-14 21:28:08 +09:00
& EventDetails - > Options ,
2023-10-10 23:28:31 +09:00
EventDetails - > ConditionBufferSize ,
2024-03-01 23:20:18 +09:00
( PVOID ) ( ( UINT64 ) EventDetails + sizeof ( DEBUGGER_GENERAL_EVENT_DETAIL ) ) ,
2023-10-17 16:50:28 +09:00
ResultsToReturn ,
InputFromVmxRoot ) ;
2023-10-10 23:28:31 +09:00
}
else
{
//
// Unconditional Event
//
Event = DebuggerCreateEvent ( FALSE ,
EventDetails - > CoreId ,
EventDetails - > ProcessId ,
EventDetails - > EventType ,
EventDetails - > Tag ,
2023-10-14 21:28:08 +09:00
& EventDetails - > Options ,
2023-10-10 23:28:31 +09:00
0 ,
2023-10-17 16:50:28 +09:00
NULL ,
ResultsToReturn ,
InputFromVmxRoot ) ;
2023-10-10 23:28:31 +09:00
}
if ( Event = = NULL )
{
//
2023-10-17 16:50:28 +09:00
// Error is already set in the creation function
2023-10-10 23:28:31 +09:00
//
return FALSE ;
}
//
// Register the event
//
DebuggerRegisterEvent ( Event ) ;
//
// ----------------------------------------------------------------------------------
// *** Apply & Enable Event ***
// ----------------------------------------------------------------------------------
//
2023-10-14 23:29:16 +09:00
if ( DebuggerApplyEvent ( Event , ResultsToReturn , InputFromVmxRoot ) )
2023-10-10 23:28:31 +09:00
{
2023-10-14 21:28:08 +09:00
//
// *** Set the short-circuiting state ***
//
Event - > EnableShortCircuiting = EventDetails - > EnableShortCircuiting ;
//
// Set the event stage (pre- post- event)
//
if ( EventDetails - > EventStage = = VMM_CALLBACK_CALLING_STAGE_POST_EVENT_EMULATION )
{
Event - > EventMode = VMM_CALLBACK_CALLING_STAGE_POST_EVENT_EMULATION ;
}
else if ( EventDetails - > EventStage = = VMM_CALLBACK_CALLING_STAGE_ALL_EVENT_EMULATION )
{
Event - > EventMode = VMM_CALLBACK_CALLING_STAGE_ALL_EVENT_EMULATION ;
}
else
{
//
// Any other value results to be pre-event
//
Event - > EventMode = VMM_CALLBACK_CALLING_STAGE_PRE_EVENT_EMULATION ;
}
2023-10-10 23:28:31 +09:00
return TRUE ;
}
else
{
//
2024-03-17 18:17:38 +09:00
// Remove the event as it was not successful
2023-10-22 03:10:48 +09:00
// The same input as of input from VMX-root is
// selected here because we apply it directly in the
// above function and based on this input we can
// conclude whether the pool is allocated from the
// pool manager or not
2023-10-10 23:28:31 +09:00
//
if ( Event ! = NULL )
{
2023-10-17 16:50:28 +09:00
DebuggerRemoveEvent ( Event - > Tag , InputFromVmxRoot ) ;
2023-10-10 23:28:31 +09:00
}
return FALSE ;
}
2020-05-19 16:18:34 -07:00
}
/**
2023-10-17 21:01:30 +09:00
* @ brief Routine for validating and parsing actions that are coming from
2022-06-28 09:52:24 -07:00
* the user - mode
*
2023-10-17 21:01:30 +09:00
* @ param ActionDetails Structure that describes the action that comes from the
2020-08-28 04:03:12 -07:00
* user - mode
2023-10-10 21:46:05 +09:00
* @ param ResultsToReturn The buffer address that should be returned
2020-08-28 04:03:12 -07:00
* to the user - mode as the result
2023-10-14 21:28:08 +09:00
* @ param InputFromVmxRoot Whether the input comes from VMX root - mode or IOCTL
*
2020-08-28 04:03:12 -07:00
* @ return BOOLEAN if action was parsed and added successfully , return TRUE
* otherwise , returns FALSE
2020-05-19 16:18:34 -07:00
*/
BOOLEAN
2023-10-17 18:20:21 +09:00
DebuggerParseAction ( PDEBUGGER_GENERAL_ACTION ActionDetails ,
2023-10-15 00:08:45 +09:00
PDEBUGGER_EVENT_AND_ACTION_RESULT ResultsToReturn ,
BOOLEAN InputFromVmxRoot )
2020-05-19 16:18:34 -07:00
{
2023-10-17 18:20:21 +09:00
DEBUGGER_EVENT_ACTION * Action = NULL ;
2020-05-19 16:18:34 -07:00
//
// Check if Tag is valid or not
//
2023-10-17 18:20:21 +09:00
PDEBUGGER_EVENT Event = DebuggerGetEventByTag ( ActionDetails - > EventTag ) ;
2020-05-19 16:18:34 -07:00
2023-03-22 17:45:52 +09:00
if ( Event = = NULL )
{
2020-05-19 16:18:34 -07:00
//
// Set the appropriate error
//
2023-10-10 21:46:05 +09:00
ResultsToReturn - > IsSuccessful = FALSE ;
ResultsToReturn - > Error = DEBUGGER_ERROR_TAG_NOT_EXISTS ;
2020-05-19 16:18:34 -07:00
//
// Show that the
//
return FALSE ;
}
2023-10-17 18:20:21 +09:00
if ( ActionDetails - > ActionType = = RUN_CUSTOM_CODE )
2023-03-22 17:45:52 +09:00
{
2020-05-19 16:18:34 -07:00
//
// Check if buffer is not invalid
//
2023-10-17 18:20:21 +09:00
if ( ActionDetails - > CustomCodeBufferSize = = 0 )
2023-03-22 17:45:52 +09:00
{
2020-05-19 16:18:34 -07:00
//
// Set the appropriate error
//
2023-10-10 21:46:05 +09:00
ResultsToReturn - > IsSuccessful = FALSE ;
ResultsToReturn - > Error = DEBUGGER_ERROR_ACTION_BUFFER_SIZE_IS_ZERO ;
2020-05-19 16:18:34 -07:00
//
// Show that the
//
return FALSE ;
}
2020-10-22 08:14:59 -07:00
2020-05-19 16:18:34 -07:00
//
// Add action for RUN_CUSTOM_CODE
//
2023-03-22 17:45:52 +09:00
DEBUGGER_EVENT_REQUEST_CUSTOM_CODE CustomCode = { 0 } ;
2020-05-19 16:18:34 -07:00
2023-10-17 18:20:21 +09:00
CustomCode . CustomCodeBufferSize = ActionDetails - > CustomCodeBufferSize ;
2024-03-01 15:59:58 +09:00
CustomCode . CustomCodeBufferAddress = ( PVOID ) ( ( UINT64 ) ActionDetails + sizeof ( DEBUGGER_GENERAL_ACTION ) ) ;
2023-10-17 18:20:21 +09:00
CustomCode . OptionalRequestedBufferSize = ActionDetails - > PreAllocatedBuffer ;
2020-05-19 16:18:34 -07:00
//
// Add action to event
//
2023-10-17 18:20:21 +09:00
Action = DebuggerAddActionToEvent ( Event ,
RUN_CUSTOM_CODE ,
ActionDetails - > ImmediateMessagePassing ,
& CustomCode ,
NULL ,
ResultsToReturn ,
InputFromVmxRoot ) ;
2020-05-19 16:18:34 -07:00
2023-10-17 18:20:21 +09:00
if ( ! Action )
{
//
// Show that there was an error (error is set by the above function)
//
return FALSE ;
}
2023-03-22 17:45:52 +09:00
}
2023-10-17 18:20:21 +09:00
else if ( ActionDetails - > ActionType = = RUN_SCRIPT )
2023-03-22 17:45:52 +09:00
{
2020-10-22 08:14:59 -07:00
//
// Check if buffer is not invalid
//
2023-10-17 18:20:21 +09:00
if ( ActionDetails - > ScriptBufferSize = = 0 )
2023-03-22 17:45:52 +09:00
{
2020-10-22 08:14:59 -07:00
//
// Set the appropriate error
//
2023-10-10 21:46:05 +09:00
ResultsToReturn - > IsSuccessful = FALSE ;
ResultsToReturn - > Error = DEBUGGER_ERROR_ACTION_BUFFER_SIZE_IS_ZERO ;
2020-10-22 08:14:59 -07:00
//
// Show that the
//
return FALSE ;
}
//
// Add action for RUN_SCRIPT
//
2023-03-22 17:45:52 +09:00
DEBUGGER_EVENT_ACTION_RUN_SCRIPT_CONFIGURATION UserScriptConfig = { 0 } ;
2023-10-17 18:20:21 +09:00
UserScriptConfig . ScriptBuffer = ( UINT64 ) ActionDetails + sizeof ( DEBUGGER_GENERAL_ACTION ) ;
UserScriptConfig . ScriptLength = ActionDetails - > ScriptBufferSize ;
UserScriptConfig . ScriptPointer = ActionDetails - > ScriptBufferPointer ;
UserScriptConfig . OptionalRequestedBufferSize = ActionDetails - > PreAllocatedBuffer ;
Action = DebuggerAddActionToEvent ( Event ,
RUN_SCRIPT ,
ActionDetails - > ImmediateMessagePassing ,
NULL ,
& UserScriptConfig ,
ResultsToReturn ,
InputFromVmxRoot ) ;
if ( ! Action )
{
//
// Show that there was an error (error is set by the above function)
//
return FALSE ;
}
2023-03-22 17:45:52 +09:00
}
2023-10-17 18:20:21 +09:00
else if ( ActionDetails - > ActionType = = BREAK_TO_DEBUGGER )
2023-03-22 17:45:52 +09:00
{
2020-10-22 08:14:59 -07:00
//
// Add action BREAK_TO_DEBUGGER to event
//
2023-10-17 18:20:21 +09:00
Action = DebuggerAddActionToEvent ( Event ,
BREAK_TO_DEBUGGER ,
ActionDetails - > ImmediateMessagePassing ,
NULL ,
NULL ,
ResultsToReturn ,
InputFromVmxRoot ) ;
2020-10-22 08:14:59 -07:00
2023-10-17 18:20:21 +09:00
if ( ! Action )
{
//
// Show that there was an error (error is set by the above function)
//
return FALSE ;
}
2023-03-22 17:45:52 +09:00
}
else
{
2020-05-19 16:18:34 -07:00
//
// Set the appropriate error
//
2023-10-10 21:46:05 +09:00
ResultsToReturn - > IsSuccessful = FALSE ;
ResultsToReturn - > Error = DEBUGGER_ERROR_INVALID_ACTION_TYPE ;
2020-05-19 16:18:34 -07:00
//
2023-10-17 18:20:21 +09:00
// Show that there was an error
2020-05-19 16:18:34 -07:00
//
return FALSE ;
}
2023-10-17 18:20:21 +09:00
//
// Enable the event
//
DebuggerEnableEvent ( Event - > Tag ) ;
2023-10-10 21:46:05 +09:00
ResultsToReturn - > IsSuccessful = TRUE ;
ResultsToReturn - > Error = 0 ;
2020-05-19 16:18:34 -07:00
return TRUE ;
}
2020-08-28 04:03:12 -07:00
/**
* @ brief Terminate one event ' s effect by its tag
2022-06-28 09:52:24 -07:00
*
2020-08-28 04:03:12 -07:00
* @ details This function won ' t remove the event from
* the lists of event or de - allocated them , this should
* be called BEFORE the removing function
2022-06-28 09:52:24 -07:00
*
2020-08-28 04:03:12 -07:00
* @ param Tag Target event ' s tag
2023-10-14 23:29:16 +09:00
* @ param InputFromVmxRoot Whether the input comes from VMX root - mode or IOCTL
*
2020-08-28 04:03:12 -07:00
* @ return BOOLEAN if it was found and terminated without error
* then it returns TRUE , otherwise FALSE
*/
BOOLEAN
2023-10-14 23:29:16 +09:00
DebuggerTerminateEvent ( UINT64 Tag , BOOLEAN InputFromVmxRoot )
2020-08-28 04:03:12 -07:00
{
PDEBUGGER_EVENT Event ;
2024-03-01 23:20:18 +09:00
BOOLEAN Result = FALSE ;
2020-08-28 04:03:12 -07:00
//
// Find the event by its tag
//
Event = DebuggerGetEventByTag ( Tag ) ;
2023-03-22 17:45:52 +09:00
if ( Event = = NULL )
{
2020-08-28 04:03:12 -07:00
//
// event, not found
//
return FALSE ;
}
//
// Check the event type of our specific tag
//
2023-03-22 17:45:52 +09:00
switch ( Event - > EventType )
{
case EXTERNAL_INTERRUPT_OCCURRED :
{
2020-08-28 04:03:12 -07:00
//
// Call external interrupt terminator
//
2023-10-14 23:29:16 +09:00
TerminateExternalInterruptEvent ( Event , InputFromVmxRoot ) ;
2024-03-01 23:20:18 +09:00
Result = TRUE ;
2020-08-28 04:03:12 -07:00
break ;
}
2023-07-07 01:21:07 +09:00
case HIDDEN_HOOK_READ_AND_WRITE_AND_EXECUTE :
2020-08-28 04:03:12 -07:00
case HIDDEN_HOOK_READ_AND_WRITE :
2023-07-07 01:21:07 +09:00
case HIDDEN_HOOK_READ_AND_EXECUTE :
case HIDDEN_HOOK_WRITE_AND_EXECUTE :
2020-08-28 04:03:12 -07:00
case HIDDEN_HOOK_READ :
2023-03-22 17:45:52 +09:00
case HIDDEN_HOOK_WRITE :
2023-07-07 01:21:07 +09:00
case HIDDEN_HOOK_EXECUTE :
2023-03-22 17:45:52 +09:00
{
2020-08-28 04:03:12 -07:00
//
2023-07-07 01:21:07 +09:00
// Call read and write and execute ept hook terminator
2020-08-28 04:03:12 -07:00
//
2023-10-14 23:29:16 +09:00
TerminateHiddenHookReadAndWriteAndExecuteEvent ( Event , InputFromVmxRoot ) ;
2024-03-01 23:20:18 +09:00
Result = TRUE ;
2020-08-28 04:03:12 -07:00
break ;
}
2023-03-22 17:45:52 +09:00
case HIDDEN_HOOK_EXEC_CC :
{
2020-08-28 04:03:12 -07:00
//
// Call ept hook (hidden breakpoint) terminator
//
2023-10-14 23:29:16 +09:00
TerminateHiddenHookExecCcEvent ( Event , InputFromVmxRoot ) ;
2024-03-01 23:20:18 +09:00
Result = TRUE ;
2020-08-28 04:03:12 -07:00
break ;
}
2023-03-22 17:45:52 +09:00
case HIDDEN_HOOK_EXEC_DETOURS :
{
2020-08-28 04:03:12 -07:00
//
// Call ept hook (hidden inline hook) terminator
//
2023-10-14 23:29:16 +09:00
TerminateHiddenHookExecDetoursEvent ( Event , InputFromVmxRoot ) ;
2024-03-01 23:20:18 +09:00
Result = TRUE ;
2020-08-28 04:03:12 -07:00
break ;
}
2023-03-22 17:45:52 +09:00
case RDMSR_INSTRUCTION_EXECUTION :
{
2020-08-28 04:03:12 -07:00
//
// Call rdmsr execution event terminator
//
2023-10-14 23:29:16 +09:00
TerminateRdmsrExecutionEvent ( Event , InputFromVmxRoot ) ;
2024-03-01 23:20:18 +09:00
Result = TRUE ;
2020-08-28 04:03:12 -07:00
break ;
}
2023-03-22 17:45:52 +09:00
case WRMSR_INSTRUCTION_EXECUTION :
{
2020-08-28 04:03:12 -07:00
//
// Call wrmsr execution event terminator
//
2023-10-14 23:29:16 +09:00
TerminateWrmsrExecutionEvent ( Event , InputFromVmxRoot ) ;
2024-03-01 23:20:18 +09:00
Result = TRUE ;
2020-08-28 04:03:12 -07:00
break ;
}
2023-03-22 17:45:52 +09:00
case EXCEPTION_OCCURRED :
{
2020-08-28 04:03:12 -07:00
//
// Call exception events terminator
//
2023-10-14 23:29:16 +09:00
TerminateExceptionEvent ( Event , InputFromVmxRoot ) ;
2024-03-01 23:20:18 +09:00
Result = TRUE ;
2020-08-28 04:03:12 -07:00
break ;
}
2023-03-22 17:45:52 +09:00
case IN_INSTRUCTION_EXECUTION :
{
2020-08-28 04:03:12 -07:00
//
// Call IN instruction execution event terminator
//
2023-10-14 23:29:16 +09:00
TerminateInInstructionExecutionEvent ( Event , InputFromVmxRoot ) ;
2024-03-01 23:20:18 +09:00
Result = TRUE ;
2020-08-28 04:03:12 -07:00
break ;
}
2023-03-22 17:45:52 +09:00
case OUT_INSTRUCTION_EXECUTION :
{
2020-08-28 04:03:12 -07:00
//
// Call OUT instruction execution event terminator
//
2023-10-14 23:29:16 +09:00
TerminateOutInstructionExecutionEvent ( Event , InputFromVmxRoot ) ;
2024-03-01 23:20:18 +09:00
Result = TRUE ;
2020-08-28 04:03:12 -07:00
break ;
}
2023-03-22 17:45:52 +09:00
case SYSCALL_HOOK_EFER_SYSCALL :
{
2020-08-28 04:03:12 -07:00
//
// Call syscall hook event terminator
//
2023-10-14 23:29:16 +09:00
TerminateSyscallHookEferEvent ( Event , InputFromVmxRoot ) ;
2024-03-01 23:20:18 +09:00
Result = TRUE ;
2020-08-28 04:03:12 -07:00
break ;
}
2023-03-22 17:45:52 +09:00
case SYSCALL_HOOK_EFER_SYSRET :
{
2020-08-28 04:03:12 -07:00
//
// Call sysret hook event terminator
//
2023-10-14 23:29:16 +09:00
TerminateSysretHookEferEvent ( Event , InputFromVmxRoot ) ;
2024-03-01 23:20:18 +09:00
Result = TRUE ;
2020-08-28 04:03:12 -07:00
break ;
}
2023-03-22 17:45:52 +09:00
case VMCALL_INSTRUCTION_EXECUTION :
{
2020-08-28 04:03:12 -07:00
//
// Call vmcall instruction execution event terminator
//
2023-10-14 23:29:16 +09:00
TerminateVmcallExecutionEvent ( Event , InputFromVmxRoot ) ;
2024-03-01 23:20:18 +09:00
Result = TRUE ;
2020-08-28 04:03:12 -07:00
break ;
}
2023-11-03 14:51:21 +09:00
case TRAP_EXECUTION_MODE_CHANGED :
2023-09-13 19:59:55 +09:00
{
//
2023-09-18 19:47:13 +09:00
// Call mode execution trap event terminator
2023-09-13 19:59:55 +09:00
//
2023-11-02 15:27:51 +09:00
TerminateExecTrapModeChangedEvent ( Event , InputFromVmxRoot ) ;
2024-03-01 23:20:18 +09:00
Result = TRUE ;
2023-09-13 19:59:55 +09:00
break ;
}
2023-03-22 17:45:52 +09:00
case TSC_INSTRUCTION_EXECUTION :
{
2020-08-28 04:03:12 -07:00
//
// Call rdtsc/rdtscp instruction execution event terminator
//
2023-10-14 23:29:16 +09:00
TerminateTscEvent ( Event , InputFromVmxRoot ) ;
2024-03-01 23:20:18 +09:00
Result = TRUE ;
2020-08-28 04:03:12 -07:00
break ;
}
2023-03-22 17:45:52 +09:00
case PMC_INSTRUCTION_EXECUTION :
{
2020-08-28 04:03:12 -07:00
//
// Call rdtsc/rdtscp instructions execution event terminator
//
2023-10-14 23:29:16 +09:00
TerminatePmcEvent ( Event , InputFromVmxRoot ) ;
2024-03-01 23:20:18 +09:00
Result = TRUE ;
2020-08-28 04:03:12 -07:00
break ;
}
2023-03-22 17:45:52 +09:00
case DEBUG_REGISTERS_ACCESSED :
{
2020-08-28 04:03:12 -07:00
//
// Call mov to debugger register event terminator
//
2023-10-14 23:29:16 +09:00
TerminateDebugRegistersEvent ( Event , InputFromVmxRoot ) ;
2024-03-01 23:20:18 +09:00
Result = TRUE ;
2020-08-28 04:03:12 -07:00
break ;
}
2023-03-22 17:45:52 +09:00
case CPUID_INSTRUCTION_EXECUTION :
{
2020-08-28 04:03:12 -07:00
//
// Call cpuid instruction execution event terminator
//
2023-10-14 23:29:16 +09:00
TerminateCpuidExecutionEvent ( Event , InputFromVmxRoot ) ;
2024-03-01 23:20:18 +09:00
Result = TRUE ;
2020-08-28 04:03:12 -07:00
break ;
}
2023-03-22 17:45:52 +09:00
case CONTROL_REGISTER_MODIFIED :
{
2022-07-08 01:19:41 +02:00
//
// Call mov to control register event terminator
//
2023-10-14 23:29:16 +09:00
TerminateControlRegistersEvent ( Event , InputFromVmxRoot ) ;
2024-03-01 23:20:18 +09:00
Result = TRUE ;
2022-07-08 01:19:41 +02:00
break ;
}
2025-08-21 00:17:26 +02:00
case XSETBV_INSTRUCTION_EXECUTION :
{
//
// Call XSETBV instruction execution event terminator
//
TerminateXsetbvExecutionEvent ( Event , InputFromVmxRoot ) ;
Result = TRUE ;
break ;
}
2020-08-28 04:03:12 -07:00
default :
2021-08-30 17:23:17 +04:30
LogError ( " Err, unknown event for termination " ) ;
2024-03-01 23:20:18 +09:00
Result = FALSE ;
2020-08-28 04:03:12 -07:00
break ;
}
2024-03-01 23:20:18 +09:00
//
// Return status
//
return Result ;
2020-08-28 04:03:12 -07:00
}
/**
* @ brief Parse and validate requests to enable / disable / clear
* from the user - mode
2022-06-28 09:52:24 -07:00
*
2020-08-28 04:03:12 -07:00
* @ param DebuggerEventModificationRequest event modification request details
2023-10-14 21:28:08 +09:00
* @ param InputFromVmxRoot Whether the input comes from VMX root - mode or IOCTL
2023-10-22 03:10:48 +09:00
* @ param PoolManagerAllocatedMemory Whether the pools are allocated from the
* pool manager or original OS pools
2023-10-14 21:28:08 +09:00
*
2020-08-28 04:03:12 -07:00
* @ return BOOLEAN returns TRUE if there was no error , and FALSE if there was
* an error
*/
BOOLEAN
2023-10-14 21:28:08 +09:00
DebuggerParseEventsModification ( PDEBUGGER_MODIFY_EVENTS DebuggerEventModificationRequest ,
2023-10-22 03:10:48 +09:00
BOOLEAN InputFromVmxRoot ,
BOOLEAN PoolManagerAllocatedMemory )
2020-08-28 04:03:12 -07:00
{
BOOLEAN IsForAllEvents = FALSE ;
//
// Check if the tag is valid or not
//
2023-03-22 17:45:52 +09:00
if ( DebuggerEventModificationRequest - > Tag = = DEBUGGER_MODIFY_EVENTS_APPLY_TO_ALL_TAG )
{
2020-08-28 04:03:12 -07:00
IsForAllEvents = TRUE ;
2023-03-22 17:45:52 +09:00
}
else if ( ! DebuggerIsTagValid ( DebuggerEventModificationRequest - > Tag ) )
{
2020-08-28 04:03:12 -07:00
//
// Tag is invalid
//
2020-09-08 13:53:27 -07:00
DebuggerEventModificationRequest - > KernelStatus = DEBUGGER_ERROR_MODIFY_EVENTS_INVALID_TAG ;
2020-08-28 04:03:12 -07:00
return FALSE ;
}
//
// ***************************************************************************
//
//
// Check if it's a ENABLE, DISABLE or CLEAR
//
2023-03-22 17:45:52 +09:00
if ( DebuggerEventModificationRequest - > TypeOfAction = = DEBUGGER_MODIFY_EVENTS_ENABLE )
{
if ( IsForAllEvents )
{
2020-08-28 04:03:12 -07:00
//
// Enable all events
//
DebuggerEnableOrDisableAllEvents ( TRUE ) ;
2023-03-22 17:45:52 +09:00
}
else
{
2020-08-28 04:03:12 -07:00
//
// Enable just one event
//
DebuggerEnableEvent ( DebuggerEventModificationRequest - > Tag ) ;
}
2023-03-22 17:45:52 +09:00
}
else if ( DebuggerEventModificationRequest - > TypeOfAction = = DEBUGGER_MODIFY_EVENTS_DISABLE )
{
if ( IsForAllEvents )
{
2020-08-28 04:03:12 -07:00
//
// Disable all events
//
DebuggerEnableOrDisableAllEvents ( FALSE ) ;
2023-03-22 17:45:52 +09:00
}
else
{
2020-08-28 04:03:12 -07:00
//
// Disable just one event
//
DebuggerDisableEvent ( DebuggerEventModificationRequest - > Tag ) ;
}
2023-03-22 17:45:52 +09:00
}
else if ( DebuggerEventModificationRequest - > TypeOfAction = = DEBUGGER_MODIFY_EVENTS_CLEAR )
{
if ( IsForAllEvents )
{
2020-08-28 04:03:12 -07:00
//
// Clear all events
//
2023-10-22 03:10:48 +09:00
DebuggerClearAllEvents ( InputFromVmxRoot , PoolManagerAllocatedMemory ) ;
2023-03-22 17:45:52 +09:00
}
else
{
2020-08-28 04:03:12 -07:00
//
// Clear just one event
//
2023-10-22 03:10:48 +09:00
DebuggerClearEvent ( DebuggerEventModificationRequest - > Tag , InputFromVmxRoot , PoolManagerAllocatedMemory ) ;
2020-08-28 04:03:12 -07:00
}
2023-03-22 17:45:52 +09:00
}
else if ( DebuggerEventModificationRequest - > TypeOfAction = = DEBUGGER_MODIFY_EVENTS_QUERY_STATE )
{
2021-02-22 12:57:09 -08:00
//
// check if tag is valid or not
//
2023-03-22 17:45:52 +09:00
if ( ! DebuggerIsTagValid ( DebuggerEventModificationRequest - > Tag ) )
{
2021-11-18 18:27:33 +03:30
DebuggerEventModificationRequest - > KernelStatus = DEBUGGER_ERROR_TAG_NOT_EXISTS ;
2021-02-22 12:57:09 -08:00
return FALSE ;
}
//
// Set event state
//
2023-03-22 17:45:52 +09:00
if ( DebuggerQueryStateEvent ( DebuggerEventModificationRequest - > Tag ) )
{
2021-02-22 12:57:09 -08:00
DebuggerEventModificationRequest - > IsEnabled = TRUE ;
2023-03-22 17:45:52 +09:00
}
else
{
2021-02-22 12:57:09 -08:00
DebuggerEventModificationRequest - > IsEnabled = FALSE ;
}
2023-03-22 17:45:52 +09:00
}
else
{
2020-08-28 04:03:12 -07:00
//
2024-03-17 18:17:38 +09:00
// Invalid parameter specified in TypeOfAction
2020-08-28 04:03:12 -07:00
//
2020-09-08 13:53:27 -07:00
DebuggerEventModificationRequest - > KernelStatus = DEBUGGER_ERROR_MODIFY_EVENTS_INVALID_TYPE_OF_ACTION ;
2020-08-28 04:03:12 -07:00
return FALSE ;
}
//
// The function was successful
//
2022-10-06 17:45:07 +09:00
DebuggerEventModificationRequest - > KernelStatus = DEBUGGER_OPERATION_WAS_SUCCESSFUL ;
2020-08-28 04:03:12 -07:00
return TRUE ;
}