HyperDbg/hyperdbg/hyperhv/code/interface/Dispatch.c

1498 lines
50 KiB
C
Raw Permalink Normal View History

/**
* @file Dispatch.c
* @author Sina Karvandi (sina@hyperdbg.org)
* @brief Implementation of debugger functions for dispatching, triggering and
* emulating events
* @details
*
* @version 0.1
* @date 2022-09-21
*
* @copyright This project is released under the GNU Public License v3.
*
*/
#include "pch.h"
/**
* @brief Handling debugger functions related to SYSRET events
*
* @param CoreIndex Current core's index
* @param Regs Guest's gp register
* @param Context Context of triggering the event
* @return VOID
*/
VOID
2022-12-05 15:31:56 +09:00
DispatchEventEferSysret(VIRTUAL_MACHINE_STATE * VCpu, PVOID Context)
{
2023-01-29 04:06:01 +09:00
BOOLEAN PostEventTriggerReq = FALSE;
VMM_CALLBACK_TRIGGERING_EVENT_STATUS_TYPE EventTriggerResult;
//
// We should trigger the event of SYSRET here
//
2023-01-29 04:06:01 +09:00
EventTriggerResult = VmmCallbackTriggerEvents(SYSCALL_HOOK_EFER_SYSRET,
VMM_CALLBACK_CALLING_STAGE_PRE_EVENT_EMULATION,
Context,
&PostEventTriggerReq,
VCpu->Regs);
//
2022-10-04 10:20:15 +09:00
// Check whether we need to short-circuiting event emulation or not
//
2023-01-29 04:06:01 +09:00
if (EventTriggerResult != VMM_CALLBACK_TRIGGERING_EVENT_STATUS_SUCCESSFUL_IGNORE_EVENT)
{
2022-12-05 15:31:56 +09:00
SyscallHookEmulateSYSRET(VCpu);
HvSuppressRipIncrement(VCpu);
}
//
// Check for the post-event triggering needs
//
if (PostEventTriggerReq)
{
2023-01-29 04:06:01 +09:00
VmmCallbackTriggerEvents(SYSCALL_HOOK_EFER_SYSRET,
VMM_CALLBACK_CALLING_STAGE_POST_EVENT_EMULATION,
Context,
NULL,
VCpu->Regs);
}
}
/**
* @brief Handling debugger functions related to SYSCALL events
*
* @param CoreIndex Current core's index
* @param Regs Guest's gp register
* @return VOID
*/
VOID
2024-03-03 00:51:25 +09:00
DispatchEventEferSyscall(VIRTUAL_MACHINE_STATE * VCpu)
{
2023-01-29 04:06:01 +09:00
BOOLEAN PostEventTriggerReq = FALSE;
VMM_CALLBACK_TRIGGERING_EVENT_STATUS_TYPE EventTriggerResult;
//
// We should trigger the event of SYSCALL here, we send the
// syscall number in rax
//
2023-01-29 04:06:01 +09:00
EventTriggerResult = VmmCallbackTriggerEvents(SYSCALL_HOOK_EFER_SYSCALL,
VMM_CALLBACK_CALLING_STAGE_PRE_EVENT_EMULATION,
2024-03-02 23:58:00 +09:00
(PVOID)VCpu->Regs->rax,
2023-01-29 04:06:01 +09:00
&PostEventTriggerReq,
VCpu->Regs);
//
2022-10-04 10:20:15 +09:00
// Check whether we need to short-circuiting event emulation or not
//
2023-01-29 04:06:01 +09:00
if (EventTriggerResult != VMM_CALLBACK_TRIGGERING_EVENT_STATUS_SUCCESSFUL_IGNORE_EVENT)
{
2022-12-05 15:31:56 +09:00
SyscallHookEmulateSYSCALL(VCpu);
HvSuppressRipIncrement(VCpu);
}
//
// Check for the post-event triggering needs
//
if (PostEventTriggerReq)
{
2023-01-29 04:06:01 +09:00
VmmCallbackTriggerEvents(SYSCALL_HOOK_EFER_SYSCALL,
VMM_CALLBACK_CALLING_STAGE_POST_EVENT_EMULATION,
2024-03-02 23:58:00 +09:00
(PVOID)VCpu->Regs->rax,
2023-01-29 04:06:01 +09:00
NULL,
VCpu->Regs);
}
}
/**
* @brief Handling debugger functions related to CPUID events
*
2022-10-17 16:04:19 +09:00
* @param VCpu The virtual processor's state
* @return VOID
*/
VOID
2022-10-17 16:04:19 +09:00
DispatchEventCpuid(VIRTUAL_MACHINE_STATE * VCpu)
{
2023-01-29 04:06:01 +09:00
UINT64 Context;
VMM_CALLBACK_TRIGGERING_EVENT_STATUS_TYPE EventTriggerResult;
BOOLEAN PostEventTriggerReq = FALSE;
//
// As the context to event trigger, we send the eax before the cpuid
// so that the debugger can both read the eax as it's now changed by
// the cpuid instruction and also can modify the results
//
if (g_TriggerEventForCpuids)
{
//
// Adjusting the core context (save EAX for the debugger)
//
Context = VCpu->Regs->rax & 0xffffffff;
//
// Triggering the pre-event
//
2023-01-29 04:06:01 +09:00
EventTriggerResult = VmmCallbackTriggerEvents(CPUID_INSTRUCTION_EXECUTION,
VMM_CALLBACK_CALLING_STAGE_PRE_EVENT_EMULATION,
2024-03-02 23:58:00 +09:00
(PVOID)Context,
2023-01-29 04:06:01 +09:00
&PostEventTriggerReq,
VCpu->Regs);
//
2022-10-04 10:20:15 +09:00
// Check whether we need to short-circuiting event emulation or not
//
2023-01-29 04:06:01 +09:00
if (EventTriggerResult != VMM_CALLBACK_TRIGGERING_EVENT_STATUS_SUCCESSFUL_IGNORE_EVENT)
{
//
// Handle the CPUID event in the case of triggering event
//
2022-10-17 16:04:19 +09:00
HvHandleCpuid(VCpu);
}
//
// Check for the post-event triggering needs
//
if (PostEventTriggerReq)
{
2023-01-29 04:06:01 +09:00
VmmCallbackTriggerEvents(CPUID_INSTRUCTION_EXECUTION,
VMM_CALLBACK_CALLING_STAGE_POST_EVENT_EMULATION,
2024-03-02 23:58:00 +09:00
(PVOID)Context,
2023-01-29 04:06:01 +09:00
NULL,
VCpu->Regs);
}
}
else
{
//
// Otherwise and if there is no event, we should handle the CPUID
// normally
//
2022-10-17 16:04:19 +09:00
HvHandleCpuid(VCpu);
}
}
2025-08-21 00:17:26 +02:00
/**
* @brief Handling debugger functions related to XSETBV events
*
* @param VCpu The virtual processor's state
* @return VOID
*/
VOID
DispatchEventXsetbv(VIRTUAL_MACHINE_STATE * VCpu)
{
UINT64 Context;
VMM_CALLBACK_TRIGGERING_EVENT_STATUS_TYPE EventTriggerResult;
BOOLEAN PostEventTriggerReq = FALSE;
//
// As the context to event trigger, we send the ecx (XCR index) before the xsetbv
// so that the debugger can both read the ecx as it contains the XCR index
// and also can modify the results
//
if (g_TriggerEventForXsetbvs)
{
//
// Adjusting the core context (save ECX for the debugger)
//
Context = VCpu->Regs->rcx & 0xffffffff;
//
// Triggering the pre-event
//
EventTriggerResult = VmmCallbackTriggerEvents(XSETBV_INSTRUCTION_EXECUTION,
VMM_CALLBACK_CALLING_STAGE_PRE_EVENT_EMULATION,
(PVOID)Context,
&PostEventTriggerReq,
VCpu->Regs);
//
// Check whether we need to short-circuiting event emulation or not
//
if (EventTriggerResult != VMM_CALLBACK_TRIGGERING_EVENT_STATUS_SUCCESSFUL_IGNORE_EVENT)
{
//
// Handle the XSETBV event in the case of triggering event
//
VmxHandleXsetbv(VCpu);
}
//
// Check for the post-event triggering needs
//
if (PostEventTriggerReq)
{
VmmCallbackTriggerEvents(XSETBV_INSTRUCTION_EXECUTION,
VMM_CALLBACK_CALLING_STAGE_POST_EVENT_EMULATION,
(PVOID)Context,
NULL,
VCpu->Regs);
}
}
else
{
//
// Otherwise and if there is no event, we should handle the XSETBV
// normally
//
VmxHandleXsetbv(VCpu);
}
}
/**
* @brief Handling debugger functions related to RDTSC/RDTSCP events
*
2022-10-19 11:58:57 +09:00
* @param VCpu The virtual processor's state
* @param IsRdtscp Is a RDTSCP or RDTSC
* @return VOID
*/
VOID
2022-10-19 11:58:57 +09:00
DispatchEventTsc(VIRTUAL_MACHINE_STATE * VCpu, BOOLEAN IsRdtscp)
{
2023-01-29 04:06:01 +09:00
VMM_CALLBACK_TRIGGERING_EVENT_STATUS_TYPE EventTriggerResult;
BOOLEAN PostEventTriggerReq = FALSE;
//
// As the context to event trigger, we send the false which means
// it's an rdtsc (for rdtscp we set Context to true)
//
2023-01-29 04:06:01 +09:00
EventTriggerResult = VmmCallbackTriggerEvents(TSC_INSTRUCTION_EXECUTION,
VMM_CALLBACK_CALLING_STAGE_PRE_EVENT_EMULATION,
2024-03-02 23:58:00 +09:00
(PVOID)IsRdtscp,
2023-01-29 04:06:01 +09:00
&PostEventTriggerReq,
VCpu->Regs);
//
2022-10-04 10:20:15 +09:00
// Check whether we need to short-circuiting event emulation or not
//
2023-01-29 04:06:01 +09:00
if (EventTriggerResult != VMM_CALLBACK_TRIGGERING_EVENT_STATUS_SUCCESSFUL_IGNORE_EVENT)
{
//
// Handle rdtsc (emulate rdtsc/p)
//
2022-10-19 11:58:57 +09:00
if (IsRdtscp)
{
CounterEmulateRdtscp(VCpu);
}
else
{
CounterEmulateRdtsc(VCpu);
}
}
//
// Check for the post-event triggering needs
//
if (PostEventTriggerReq)
{
2023-01-29 04:06:01 +09:00
VmmCallbackTriggerEvents(TSC_INSTRUCTION_EXECUTION,
VMM_CALLBACK_CALLING_STAGE_POST_EVENT_EMULATION,
2024-03-02 23:58:00 +09:00
(PVOID)IsRdtscp,
2023-01-29 04:06:01 +09:00
NULL,
VCpu->Regs);
}
}
/**
* @brief Handling debugger functions related to VMCALL events
*
2022-10-19 11:58:57 +09:00
* @param VCpu The virtual processor's state
* @return VOID
*/
VOID
2022-10-19 11:58:57 +09:00
DispatchEventVmcall(VIRTUAL_MACHINE_STATE * VCpu)
{
2023-01-29 04:06:01 +09:00
VMM_CALLBACK_TRIGGERING_EVENT_STATUS_TYPE EventTriggerResult;
BOOLEAN PostEventTriggerReq = FALSE;
//
// As the context to event trigger, we send NULL
// Registers are the best source to know the purpose
//
if (g_TriggerEventForVmcalls)
{
//
// Triggering the pre-event
//
2023-01-29 04:06:01 +09:00
EventTriggerResult = VmmCallbackTriggerEvents(VMCALL_INSTRUCTION_EXECUTION,
VMM_CALLBACK_CALLING_STAGE_PRE_EVENT_EMULATION,
NULL,
&PostEventTriggerReq,
VCpu->Regs);
//
2022-10-04 10:20:15 +09:00
// Check whether we need to short-circuiting event emulation or not
//
2023-01-29 04:06:01 +09:00
if (EventTriggerResult != VMM_CALLBACK_TRIGGERING_EVENT_STATUS_SUCCESSFUL_IGNORE_EVENT)
{
//
// Handle the VMCALL event in the case of triggering event
//
2022-10-19 11:58:57 +09:00
VmxHandleVmcallVmExit(VCpu);
}
//
// Check for the post-event triggering needs
//
if (PostEventTriggerReq)
{
2023-01-29 04:06:01 +09:00
VmmCallbackTriggerEvents(CPUID_INSTRUCTION_EXECUTION,
VMM_CALLBACK_CALLING_STAGE_POST_EVENT_EMULATION,
NULL,
NULL,
VCpu->Regs);
}
}
else
{
//
// Otherwise and if there is no event, we should handle the VMCALL
// normally
//
2022-10-19 11:58:57 +09:00
VmxHandleVmcallVmExit(VCpu);
}
}
2023-09-13 19:59:55 +09:00
/**
2023-09-18 13:03:28 +09:00
* @brief Handling debugger functions related to user-mode/kernel-mode execution trap events
2023-09-13 19:59:55 +09:00
*
* @param VCpu The virtual processor's state
2023-09-18 13:03:28 +09:00
* @param IsUserMode Whether the execution event caused by a switch from kernel-to-user
* or otherwise user-to-kernel
*
* @return VOID
*/
VOID
DispatchEventMode(VIRTUAL_MACHINE_STATE * VCpu, DEBUGGER_EVENT_MODE_TYPE TargetMode)
{
VMM_CALLBACK_TRIGGERING_EVENT_STATUS_TYPE EventTriggerResult;
BOOLEAN PostEventTriggerReq = FALSE;
//
// As the context to event trigger, we send NULL
//
if (g_ExecTrapInitialized)
{
//
// check for user-mode thread interception
//
if (TargetMode == DEBUGGER_EVENT_MODE_TYPE_USER_MODE &&
DebuggingCallbackCheckThreadInterception(VCpu->CoreId))
{
//
// If the thread is intercepted, we should not trigger the event
// Being here means that the thread should be handled by the user-mode debugger
2026-06-09 15:04:20 +02:00
// ou
// LogInfo("Thread Id: %x, process Id: %x is intercepted by user-mode debugger - RIP: %llx",
// PsGetCurrentThreadId(),
// PsGetCurrentProcessId(),
// VCpu->LastVmexitRip);
2025-06-29 20:22:51 +02:00
//
// In this case, we need to short circuit the event, in user-mode debugger we
// prevent the execution by short-circuiting the event
//
EventTriggerResult = VMM_CALLBACK_TRIGGERING_EVENT_STATUS_SUCCESSFUL_IGNORE_EVENT;
}
else
{
//
// Triggering the pre-event
//
EventTriggerResult = VmmCallbackTriggerEvents(TRAP_EXECUTION_MODE_CHANGED,
VMM_CALLBACK_CALLING_STAGE_PRE_EVENT_EMULATION,
(PVOID)TargetMode,
&PostEventTriggerReq,
VCpu->Regs);
}
//
// Check whether we need to short-circuiting event emulation or not
//
if (EventTriggerResult != VMM_CALLBACK_TRIGGERING_EVENT_STATUS_SUCCESSFUL_IGNORE_EVENT)
{
//
2023-09-18 13:03:28 +09:00
// Handle the user-mode/kernel-mode execution trap event in the case of triggering event
//
ExecTrapHandleMoveToAdjustedTrapState(VCpu, TargetMode);
}
//
2023-11-03 21:26:02 +09:00
// *** Post-event doesn't make sense for this kind of event! ***
//
}
else
{
//
// Otherwise and if there is no event, we should handle the
2023-09-18 13:03:28 +09:00
// user-mode/kernel-mode execution trap normally
//
ExecTrapHandleMoveToAdjustedTrapState(VCpu, TargetMode);
}
}
/**
* @brief Handling debugger functions related to mov 2 cr3 events
*
* @param VCpu The virtual processor's state
* @return VOID
*/
VOID
DispatchEventMovToCr3(VIRTUAL_MACHINE_STATE * VCpu)
{
VMM_CALLBACK_TRIGGERING_EVENT_STATUS_TYPE EventTriggerResult;
BOOLEAN PostEventTriggerReq = FALSE;
//
// As the context to event trigger, we send NULL
//
if (g_ExecTrapInitialized)
{
//
// Triggering the pre-event
//
EventTriggerResult = VmmCallbackTriggerEvents(CONTROL_REGISTER_3_MODIFIED,
VMM_CALLBACK_CALLING_STAGE_PRE_EVENT_EMULATION,
NULL,
&PostEventTriggerReq,
VCpu->Regs);
//
// Check whether we need to short-circuiting event emulation or not
//
if (EventTriggerResult != VMM_CALLBACK_TRIGGERING_EVENT_STATUS_SUCCESSFUL_IGNORE_EVENT)
{
//
// Handle the mov 2 cr3 event in the case of triggering event
//
// ExecTrapHandleRestoringToNormalState(VCpu);
}
//
// Check for the post-event triggering needs
//
if (PostEventTriggerReq)
{
VmmCallbackTriggerEvents(CONTROL_REGISTER_3_MODIFIED,
VMM_CALLBACK_CALLING_STAGE_POST_EVENT_EMULATION,
NULL,
NULL,
VCpu->Regs);
}
}
else
{
//
// Otherwise and if there is no event, we should handle the
// mov 2 cr3 normally
//
// ExecTrapHandleRestoringToNormalState(VCpu);
}
}
/**
* @brief Handling debugger functions related to IO events
*
2022-10-17 16:04:19 +09:00
* @param VCpu The virtual processor's state
* @return VOID
*/
VOID
2022-10-17 16:04:19 +09:00
DispatchEventIO(VIRTUAL_MACHINE_STATE * VCpu)
{
2024-03-03 21:04:43 +09:00
VMM_CALLBACK_TRIGGERING_EVENT_STATUS_TYPE EventTriggerResult = VMM_CALLBACK_TRIGGERING_EVENT_STATUS_SUCCESSFUL_NO_INITIALIZED;
2023-01-29 04:06:01 +09:00
VMX_EXIT_QUALIFICATION_IO_INSTRUCTION IoQualification = {.AsUInt = VCpu->ExitQualification};
RFLAGS Flags = {0};
BOOLEAN PostEventTriggerReq = FALSE;
//
// Read Guest's RFLAGS
//
2024-03-03 19:06:22 +09:00
VmxVmread64P(VMCS_GUEST_RFLAGS, (UINT64 *)&Flags);
//
// As the context to event trigger, port address
//
if (IoQualification.DirectionOfAccess == AccessIn)
{
2023-01-29 04:06:01 +09:00
EventTriggerResult = VmmCallbackTriggerEvents(IN_INSTRUCTION_EXECUTION,
VMM_CALLBACK_CALLING_STAGE_PRE_EVENT_EMULATION,
2024-03-02 23:58:00 +09:00
(PVOID)IoQualification.PortNumber,
2023-01-29 04:06:01 +09:00
&PostEventTriggerReq,
VCpu->Regs);
}
else if (IoQualification.DirectionOfAccess == AccessOut)
{
2023-01-29 04:06:01 +09:00
EventTriggerResult = VmmCallbackTriggerEvents(OUT_INSTRUCTION_EXECUTION,
VMM_CALLBACK_CALLING_STAGE_PRE_EVENT_EMULATION,
2024-03-02 23:58:00 +09:00
(PVOID)IoQualification.PortNumber,
2023-01-29 04:06:01 +09:00
&PostEventTriggerReq,
VCpu->Regs);
}
//
2022-10-04 10:20:15 +09:00
// Check whether we need to short-circuiting event emulation or not
//
2023-01-29 04:06:01 +09:00
if (EventTriggerResult != VMM_CALLBACK_TRIGGERING_EVENT_STATUS_SUCCESSFUL_IGNORE_EVENT)
{
//
// Call the I/O Handler
//
2022-10-17 16:04:19 +09:00
IoHandleIoVmExits(VCpu, IoQualification, Flags);
}
//
// Check for the post-event triggering needs
//
if (PostEventTriggerReq)
{
if (IoQualification.DirectionOfAccess == AccessIn)
{
2023-01-29 04:06:01 +09:00
VmmCallbackTriggerEvents(IN_INSTRUCTION_EXECUTION,
VMM_CALLBACK_CALLING_STAGE_POST_EVENT_EMULATION,
2024-03-02 23:58:00 +09:00
(PVOID)IoQualification.PortNumber,
2023-01-29 04:06:01 +09:00
NULL,
VCpu->Regs);
}
else if (IoQualification.DirectionOfAccess == AccessOut)
{
2023-01-29 04:06:01 +09:00
VmmCallbackTriggerEvents(OUT_INSTRUCTION_EXECUTION,
VMM_CALLBACK_CALLING_STAGE_POST_EVENT_EMULATION,
2024-03-02 23:58:00 +09:00
(PVOID)IoQualification.PortNumber,
2023-01-29 04:06:01 +09:00
NULL,
VCpu->Regs);
}
}
}
2022-09-22 16:33:14 +09:00
/**
* @brief Handling debugger functions related to RDMSR events
*
2022-10-17 16:04:19 +09:00
* @param VCpu The virtual processor's state
2022-09-22 16:33:14 +09:00
* @return VOID
*/
VOID
2022-10-17 16:04:19 +09:00
DispatchEventRdmsr(VIRTUAL_MACHINE_STATE * VCpu)
2022-09-22 16:33:14 +09:00
{
2023-01-29 04:06:01 +09:00
VMM_CALLBACK_TRIGGERING_EVENT_STATUS_TYPE EventTriggerResult;
BOOLEAN PostEventTriggerReq = FALSE;
2022-09-22 16:33:14 +09:00
//
// Triggering the pre-event
//
2023-01-29 04:06:01 +09:00
EventTriggerResult = VmmCallbackTriggerEvents(RDMSR_INSTRUCTION_EXECUTION,
VMM_CALLBACK_CALLING_STAGE_PRE_EVENT_EMULATION,
2024-03-02 23:58:00 +09:00
(PVOID)(VCpu->Regs->rcx & 0xffffffff),
2023-01-29 04:06:01 +09:00
&PostEventTriggerReq,
VCpu->Regs);
2022-09-22 16:33:14 +09:00
//
2022-10-04 10:20:15 +09:00
// Check whether we need to short-circuiting event emulation or not
2022-09-22 16:33:14 +09:00
//
2023-01-29 04:06:01 +09:00
if (EventTriggerResult != VMM_CALLBACK_TRIGGERING_EVENT_STATUS_SUCCESSFUL_IGNORE_EVENT)
2022-09-22 16:33:14 +09:00
{
//
// Handle vm-exit and perform changes
//
MsrHandleRdmsrVmexit(VCpu);
2022-09-22 16:33:14 +09:00
}
//
// Check for the post-event triggering needs
//
if (PostEventTriggerReq)
{
2023-01-29 04:06:01 +09:00
VmmCallbackTriggerEvents(RDMSR_INSTRUCTION_EXECUTION,
VMM_CALLBACK_CALLING_STAGE_POST_EVENT_EMULATION,
2024-03-02 23:58:00 +09:00
(PVOID)(VCpu->Regs->rcx & 0xffffffff),
2023-01-29 04:06:01 +09:00
NULL,
VCpu->Regs);
2022-09-22 16:33:14 +09:00
}
}
/**
* @brief Handling debugger functions related to WRMSR events
*
2022-10-17 16:04:19 +09:00
* @param VCpu The virtual processor's state
2022-09-22 16:33:14 +09:00
* @return VOID
*/
VOID
2022-10-17 16:04:19 +09:00
DispatchEventWrmsr(VIRTUAL_MACHINE_STATE * VCpu)
2022-09-22 16:33:14 +09:00
{
2023-01-29 04:06:01 +09:00
VMM_CALLBACK_TRIGGERING_EVENT_STATUS_TYPE EventTriggerResult;
BOOLEAN PostEventTriggerReq = FALSE;
2022-09-22 16:33:14 +09:00
//
// Triggering the pre-event
//
2023-01-29 04:06:01 +09:00
EventTriggerResult = VmmCallbackTriggerEvents(WRMSR_INSTRUCTION_EXECUTION,
VMM_CALLBACK_CALLING_STAGE_PRE_EVENT_EMULATION,
2024-03-02 23:58:00 +09:00
(PVOID)(VCpu->Regs->rcx & 0xffffffff),
2023-01-29 04:06:01 +09:00
&PostEventTriggerReq,
VCpu->Regs);
2022-09-22 16:33:14 +09:00
//
2022-10-04 10:20:15 +09:00
// Check whether we need to short-circuiting event emulation or not
2022-09-22 16:33:14 +09:00
//
2023-01-29 04:06:01 +09:00
if (EventTriggerResult != VMM_CALLBACK_TRIGGERING_EVENT_STATUS_SUCCESSFUL_IGNORE_EVENT)
2022-09-22 16:33:14 +09:00
{
//
// Handle vm-exit and perform changes
//
MsrHandleWrmsrVmexit(VCpu);
2022-09-22 16:33:14 +09:00
}
//
// Check for the post-event triggering needs
//
if (PostEventTriggerReq)
{
2023-01-29 04:06:01 +09:00
VmmCallbackTriggerEvents(WRMSR_INSTRUCTION_EXECUTION,
VMM_CALLBACK_CALLING_STAGE_POST_EVENT_EMULATION,
2024-03-02 23:58:00 +09:00
(PVOID)(VCpu->Regs->rcx & 0xffffffff),
2023-01-29 04:06:01 +09:00
NULL,
VCpu->Regs);
2022-09-22 16:33:14 +09:00
}
}
/**
* @brief Handling debugger functions related to RDPMC events
*
2022-10-19 11:58:57 +09:00
* @param VCpu The virtual processor's state
* @return VOID
*/
VOID
2022-10-19 11:58:57 +09:00
DispatchEventRdpmc(VIRTUAL_MACHINE_STATE * VCpu)
{
2023-01-29 04:06:01 +09:00
VMM_CALLBACK_TRIGGERING_EVENT_STATUS_TYPE EventTriggerResult;
BOOLEAN PostEventTriggerReq = FALSE;
//
// Triggering the pre-event
//
2023-01-29 04:06:01 +09:00
EventTriggerResult = VmmCallbackTriggerEvents(PMC_INSTRUCTION_EXECUTION,
VMM_CALLBACK_CALLING_STAGE_PRE_EVENT_EMULATION,
NULL,
&PostEventTriggerReq,
VCpu->Regs);
//
2022-10-04 10:20:15 +09:00
// Check whether we need to short-circuiting event emulation or not
//
2023-01-29 04:06:01 +09:00
if (EventTriggerResult != VMM_CALLBACK_TRIGGERING_EVENT_STATUS_SUCCESSFUL_IGNORE_EVENT)
{
//
// Handle RDPMC (emulate RDPMC)
//
2022-10-19 11:58:57 +09:00
CounterEmulateRdpmc(VCpu);
}
//
// Check for the post-event triggering needs
//
if (PostEventTriggerReq)
{
2023-01-29 04:06:01 +09:00
VmmCallbackTriggerEvents(PMC_INSTRUCTION_EXECUTION,
VMM_CALLBACK_CALLING_STAGE_POST_EVENT_EMULATION,
NULL,
NULL,
VCpu->Regs);
}
}
/**
* @brief Handling debugger functions related to MOV 2 DR events
*
2022-10-19 11:58:57 +09:00
* @param VCpu The virtual processor's state
* @return VOID
*/
VOID
2022-10-19 11:58:57 +09:00
DispatchEventMov2DebugRegs(VIRTUAL_MACHINE_STATE * VCpu)
{
2023-01-29 04:06:01 +09:00
VMM_CALLBACK_TRIGGERING_EVENT_STATUS_TYPE EventTriggerResult;
BOOLEAN PostEventTriggerReq = FALSE;
//
2026-06-09 15:04:20 +02:00
// Check to see if we should ignore handling the mov 2 debug registers or not
//
2026-06-09 15:04:20 +02:00
if (DebuggingCallbackIgnoreHandlingMov2DebugRegs(VCpu->CoreId))
{
return;
}
//
// Triggering the pre-event
//
2023-01-29 04:06:01 +09:00
EventTriggerResult = VmmCallbackTriggerEvents(DEBUG_REGISTERS_ACCESSED,
VMM_CALLBACK_CALLING_STAGE_PRE_EVENT_EMULATION,
NULL,
&PostEventTriggerReq,
VCpu->Regs);
//
2022-10-04 10:20:15 +09:00
// Check whether we need to short-circuiting event emulation or not
//
2023-01-29 04:06:01 +09:00
if (EventTriggerResult != VMM_CALLBACK_TRIGGERING_EVENT_STATUS_SUCCESSFUL_IGNORE_EVENT)
{
//
// Handle RDPMC (emulate MOV 2 Debug Registers)
//
2022-10-19 11:58:57 +09:00
HvHandleMovDebugRegister(VCpu);
}
//
// Check for the post-event triggering needs
//
if (PostEventTriggerReq)
{
2023-01-29 04:06:01 +09:00
VmmCallbackTriggerEvents(DEBUG_REGISTERS_ACCESSED,
VMM_CALLBACK_CALLING_STAGE_POST_EVENT_EMULATION,
NULL,
NULL,
VCpu->Regs);
}
}
/**
* @brief Handling debugger functions related to mov to/from CR events
*
2022-10-17 16:04:19 +09:00
* @param VCpu The virtual processor's state
* @return VOID
*/
VOID
2022-10-17 16:04:19 +09:00
DispatchEventMovToFromControlRegisters(VIRTUAL_MACHINE_STATE * VCpu)
{
2023-01-29 04:06:01 +09:00
BOOLEAN ModifyReg;
VMX_EXIT_QUALIFICATION_MOV_CR * CrExitQualification;
VMM_CALLBACK_TRIGGERING_EVENT_STATUS_TYPE EventTriggerResult;
BOOLEAN PostEventTriggerReq = FALSE;
2024-03-03 16:27:16 +09:00
UINT32 ExitQualification = 0;
//
// Read the exit qualification
//
2024-03-03 16:27:16 +09:00
VmxVmread32P(VMCS_EXIT_QUALIFICATION, &ExitQualification);
CrExitQualification = (VMX_EXIT_QUALIFICATION_MOV_CR *)&ExitQualification;
if (CrExitQualification->AccessType == VMX_EXIT_QUALIFICATION_ACCESS_MOV_TO_CR)
{
ModifyReg = TRUE;
}
else
{
ModifyReg = FALSE;
}
//
// Triggering the pre-event
//
2023-01-29 04:06:01 +09:00
EventTriggerResult = VmmCallbackTriggerEvents(ModifyReg ? CONTROL_REGISTER_MODIFIED : CONTROL_REGISTER_READ,
VMM_CALLBACK_CALLING_STAGE_PRE_EVENT_EMULATION,
2024-03-02 23:58:00 +09:00
(PVOID)CrExitQualification->ControlRegister,
2023-01-29 04:06:01 +09:00
&PostEventTriggerReq,
VCpu->Regs);
//
2022-10-04 10:20:15 +09:00
// Check whether we need to short-circuiting event emulation or not
//
2023-01-29 04:06:01 +09:00
if (EventTriggerResult != VMM_CALLBACK_TRIGGERING_EVENT_STATUS_SUCCESSFUL_IGNORE_EVENT)
{
//
// Handle mov to/from control registers (emulate CR access)
//
2022-10-17 16:04:19 +09:00
HvHandleControlRegisterAccess(VCpu, CrExitQualification);
}
//
// Check for the post-event triggering needs
//
if (PostEventTriggerReq)
{
2023-01-29 04:06:01 +09:00
VmmCallbackTriggerEvents(ModifyReg ? CONTROL_REGISTER_MODIFIED : CONTROL_REGISTER_READ,
VMM_CALLBACK_CALLING_STAGE_POST_EVENT_EMULATION,
2024-03-02 23:58:00 +09:00
(PVOID)CrExitQualification->ControlRegister,
2023-01-29 04:06:01 +09:00
NULL,
VCpu->Regs);
}
}
/**
* @brief Handling debugger functions related to EXCEPTION events
*
2022-12-05 15:31:56 +09:00
* @param VCpu The virtual processor's state
* @return VOID
*/
VOID
2022-12-05 15:31:56 +09:00
DispatchEventException(VIRTUAL_MACHINE_STATE * VCpu)
{
2023-01-29 04:06:01 +09:00
VMM_CALLBACK_TRIGGERING_EVENT_STATUS_TYPE EventTriggerResult;
BOOLEAN PostEventTriggerReq = FALSE;
VMEXIT_INTERRUPT_INFORMATION InterruptExit = {0};
//
// read the exit interruption information
//
2024-03-03 20:25:27 +09:00
VmxVmread32P(VMCS_VMEXIT_INTERRUPTION_INFORMATION, &InterruptExit.AsUInt);
//
// This type of vm-exit, can be either because of an !exception event,
// or it might be because we triggered APIC or X2APIC to generate an
// NMI, we want to halt the debuggee. We perform the checks here to
// avoid triggering an event for NMIs when the debuggee requested it
//
if (InterruptExit.InterruptionType == INTERRUPT_TYPE_NMI &&
InterruptExit.Vector == EXCEPTION_VECTOR_NMI)
{
//
// Check if we're waiting for an NMI on this core and if the guest is NOT in
// a instrument step-in ('i' command) routine
//
2026-06-09 01:37:48 +02:00
if (!VCpu->InstrumentationStepInMtf &&
2022-12-05 15:31:56 +09:00
VmxBroadcastNmiHandler(VCpu, FALSE))
{
return;
}
}
//
// *** When we reached here it means that this is not a NMI cause by guest,
// probably an event ***
//
//
// Triggering the pre-event
// As the context to event trigger, we send the vector or IDT Index
//
2023-01-29 04:06:01 +09:00
EventTriggerResult = VmmCallbackTriggerEvents(EXCEPTION_OCCURRED,
VMM_CALLBACK_CALLING_STAGE_PRE_EVENT_EMULATION,
2024-03-02 23:58:00 +09:00
(PVOID)InterruptExit.Vector,
2023-01-29 04:06:01 +09:00
&PostEventTriggerReq,
VCpu->Regs);
//
// Now, we check if the guest enabled MTF for debugging (instrumentation stepping)
// This is because based on Intel SDM :
// If the "monitor trap flag" VM-execution control is 1 and VM entry is
// injecting a vectored event, an MTF VM exit is pending on the instruction
// boundary before the first instruction following the VM entry
// and,
// If VM entry is injecting a pending MTF VM exit, an MTF VM exit is pending on the
// instruction boundary before the first instruction following the VM entry
// This is the case even if the "monitor trap flag" VM-execution control is 0
//
// So, we'll ignore the injection of Exception in this case
//
2026-06-09 01:37:48 +02:00
if (VCpu->InstrumentationStepInMtf)
{
return;
}
//
2022-10-04 10:20:15 +09:00
// Check whether we need to short-circuiting event emulation or not
//
2023-01-29 04:06:01 +09:00
if (EventTriggerResult != VMM_CALLBACK_TRIGGERING_EVENT_STATUS_SUCCESSFUL_IGNORE_EVENT)
{
//
// Handle exception (emulate or inject the event)
//
2022-12-05 15:31:56 +09:00
IdtEmulationHandleExceptionAndNmi(VCpu, InterruptExit);
}
//
// Check for the post-event triggering needs
//
if (PostEventTriggerReq)
{
2023-01-29 04:06:01 +09:00
VmmCallbackTriggerEvents(EXCEPTION_OCCURRED,
VMM_CALLBACK_CALLING_STAGE_POST_EVENT_EMULATION,
2024-03-02 23:58:00 +09:00
(PVOID)InterruptExit.Vector,
2023-01-29 04:06:01 +09:00
NULL,
VCpu->Regs);
}
}
/**
* @brief Handling debugger functions related to external-interrupt events
*
2022-12-05 15:31:56 +09:00
* @param VCpu The virtual processor's state
* @return VOID
*/
VOID
2022-12-05 15:31:56 +09:00
DispatchEventExternalInterrupts(VIRTUAL_MACHINE_STATE * VCpu)
{
2024-03-01 18:11:24 +09:00
VMEXIT_INTERRUPT_INFORMATION InterruptExit = {0};
2023-01-29 04:06:01 +09:00
VMM_CALLBACK_TRIGGERING_EVENT_STATUS_TYPE EventTriggerResult;
BOOLEAN PostEventTriggerReq = FALSE;
//
// read the exit interruption information
//
2024-03-03 20:25:27 +09:00
VmxVmread32P(VMCS_VMEXIT_INTERRUPTION_INFORMATION, &InterruptExit.AsUInt);
//
// Check for immediate vm-exit mechanism
//
2022-12-05 15:31:56 +09:00
if (VCpu->WaitForImmediateVmexit &&
InterruptExit.Vector == IMMEDIATE_VMEXIT_MECHANISM_VECTOR_FOR_SELF_IPI)
{
//
// Disable vm-exit on external interrupts
//
2022-12-06 16:02:49 +09:00
HvSetExternalInterruptExiting(VCpu, FALSE);
//
// Not increase the RIP
//
HvSuppressRipIncrement(VCpu);
//
2024-03-17 18:17:38 +09:00
// Handle immediate vm-exit mechanism
//
2022-12-05 15:31:56 +09:00
VmxMechanismHandleImmediateVmexit(VCpu);
//
// No need to continue, it's a HyperDbg mechanism
//
return;
}
//
// Check process or thread change detections
// we cannot ignore injecting the interrupt to the guest if the target interrupt
// and process or thread proved to cause a system halt. it halts the system as
// we Windows expects to switch the thread while we're forcing it to not do it
// Windows fires a clk interrupt on core 0 and fires IPI on other cores
// to change a thread
//
// It seems that clock interrupt is not applied to all cores,
// (https://twitter.com/Intel80x86/status/1655461171280105472?s=20)
// So, we no longer check for clock interrupts only in core 0
//
if ((/* VCpu->CoreId == 0 && */ InterruptExit.Vector == CLOCK_INTERRUPT) ||
(VCpu->CoreId != 0 && InterruptExit.Vector == IPI_INTERRUPT))
{
2026-06-09 15:04:20 +02:00
//
// Calling the callback to trigger on clock and IPI events
// This is usually used for detecting changes to processes and threads
//
DebuggingCallbackTriggerOnClockAndIpiEvents(VCpu->CoreId);
}
//
// Triggering the pre-event
//
2023-01-29 04:06:01 +09:00
EventTriggerResult = VmmCallbackTriggerEvents(EXTERNAL_INTERRUPT_OCCURRED,
VMM_CALLBACK_CALLING_STAGE_PRE_EVENT_EMULATION,
2024-03-02 23:58:00 +09:00
(PVOID)InterruptExit.Vector,
2023-01-29 04:06:01 +09:00
&PostEventTriggerReq,
VCpu->Regs);
//
2022-10-04 10:20:15 +09:00
// Check whether we need to short-circuiting event emulation or not
//
2023-01-29 04:06:01 +09:00
if (EventTriggerResult != VMM_CALLBACK_TRIGGERING_EVENT_STATUS_SUCCESSFUL_IGNORE_EVENT)
{
//
// Handle vm-exit and perform changes
//
2022-12-05 15:31:56 +09:00
IdtEmulationHandleExternalInterrupt(VCpu, InterruptExit);
}
//
// Check for the post-event triggering needs
//
if (PostEventTriggerReq)
{
//
// Trigger the event
//
// As the context to event trigger, we send the vector index
//
2024-03-17 18:17:38 +09:00
// Keep in mind that interrupt might be inserted in pending list
// because the guest is not in a interruptible state and will
// be re-injected when the guest is ready for interrupts
//
2023-01-29 04:06:01 +09:00
VmmCallbackTriggerEvents(EXTERNAL_INTERRUPT_OCCURRED,
VMM_CALLBACK_CALLING_STAGE_POST_EVENT_EMULATION,
2024-03-02 23:58:00 +09:00
(PVOID)InterruptExit.Vector,
2023-01-29 04:06:01 +09:00
NULL,
VCpu->Regs);
}
}
/**
* @brief Handling debugger functions related to hidden hook exec
* CC events
*
2022-12-05 15:31:56 +09:00
* @param VCpu The virtual processor's state
* @param Context The context of the caller
* @return VOID
*/
VOID
2022-12-05 15:31:56 +09:00
DispatchEventHiddenHookExecCc(VIRTUAL_MACHINE_STATE * VCpu, PVOID Context)
{
BOOLEAN PostEventTriggerReq = FALSE;
2025-05-04 20:50:34 +02:00
//
// In syscall back, a hidden hook for the system call handler gets inserted
2025-05-04 20:50:34 +02:00
//
if (g_SyscallCallbackStatus && Context == g_SystemCallHookAddress)
2025-05-04 20:50:34 +02:00
{
SyscallCallbackHandleSystemCallHook(VCpu);
2025-05-04 20:50:34 +02:00
}
//
// Triggering the pre-event (This command only support the
// pre-event, the post-event doesn't make sense in this command)
//
2023-01-29 04:06:01 +09:00
VmmCallbackTriggerEvents(HIDDEN_HOOK_EXEC_CC,
VMM_CALLBACK_CALLING_STAGE_PRE_EVENT_EMULATION,
Context,
&PostEventTriggerReq,
VCpu->Regs); // it will crash if we pass it NULL
}
/**
* @brief Handling debugger functions related to hidden hook exec
* detours events
*
2022-12-05 15:31:56 +09:00
* @param VCpu The virtual processor's state
* @param Context The context of the caller
* @return VOID
*/
VOID
2022-12-05 15:31:56 +09:00
DispatchEventHiddenHookExecDetours(VIRTUAL_MACHINE_STATE * VCpu, PVOID Context)
{
BOOLEAN PostEventTriggerReq = FALSE;
//
// Triggering the pre-event (This command only support the
// pre-event, the post-event doesn't make sense in this command)
//
2023-01-29 04:06:01 +09:00
VmmCallbackTriggerEvents(HIDDEN_HOOK_EXEC_DETOURS,
VMM_CALLBACK_CALLING_STAGE_PRE_EVENT_EMULATION,
Context,
&PostEventTriggerReq,
VCpu->Regs); // it will crash if we pass it NULL
}
/**
2023-07-07 01:21:07 +09:00
* @brief Handling debugger functions related to read & write & execute, read events (pre)
*
* @param VCpu The virtual processor's state
* @param Context The context of the caller
* @param IsTriggeringPostEventAllowed
* @return BOOLEAN
*/
BOOLEAN
DispatchEventHiddenHookPageReadWriteExecuteReadPreEvent(VIRTUAL_MACHINE_STATE * VCpu, PVOID Context, BOOLEAN * IsTriggeringPostEventAllowed)
{
VMM_CALLBACK_TRIGGERING_EVENT_STATUS_TYPE EventTriggerResult;
BOOLEAN PostEventTriggerReq = FALSE;
BOOLEAN ShortCircuitingEvent = FALSE;
//
// Triggering the pre-event (for the read hooks)
//
EventTriggerResult = VmmCallbackTriggerEvents(HIDDEN_HOOK_READ,
VMM_CALLBACK_CALLING_STAGE_PRE_EVENT_EMULATION,
Context,
&PostEventTriggerReq,
VCpu->Regs);
if (EventTriggerResult == VMM_CALLBACK_TRIGGERING_EVENT_STATUS_SUCCESSFUL_IGNORE_EVENT)
{
ShortCircuitingEvent = TRUE;
}
if (PostEventTriggerReq)
{
*IsTriggeringPostEventAllowed = TRUE;
}
//
// Triggering the pre-event (for the read & write hooks)
//
EventTriggerResult = VmmCallbackTriggerEvents(HIDDEN_HOOK_READ_AND_WRITE,
VMM_CALLBACK_CALLING_STAGE_PRE_EVENT_EMULATION,
Context,
&PostEventTriggerReq,
VCpu->Regs);
if (EventTriggerResult == VMM_CALLBACK_TRIGGERING_EVENT_STATUS_SUCCESSFUL_IGNORE_EVENT)
{
ShortCircuitingEvent = TRUE;
}
if (PostEventTriggerReq)
{
*IsTriggeringPostEventAllowed = TRUE;
}
//
// Triggering the pre-event (for the read & execute hooks)
//
EventTriggerResult = VmmCallbackTriggerEvents(HIDDEN_HOOK_READ_AND_EXECUTE,
VMM_CALLBACK_CALLING_STAGE_PRE_EVENT_EMULATION,
Context,
&PostEventTriggerReq,
VCpu->Regs);
if (EventTriggerResult == VMM_CALLBACK_TRIGGERING_EVENT_STATUS_SUCCESSFUL_IGNORE_EVENT)
{
ShortCircuitingEvent = TRUE;
}
if (PostEventTriggerReq)
{
*IsTriggeringPostEventAllowed = TRUE;
}
//
// Triggering the pre-event (for the read & write & execute hooks)
//
EventTriggerResult = VmmCallbackTriggerEvents(HIDDEN_HOOK_READ_AND_WRITE_AND_EXECUTE,
VMM_CALLBACK_CALLING_STAGE_PRE_EVENT_EMULATION,
Context,
&PostEventTriggerReq,
VCpu->Regs);
if (EventTriggerResult == VMM_CALLBACK_TRIGGERING_EVENT_STATUS_SUCCESSFUL_IGNORE_EVENT)
{
ShortCircuitingEvent = TRUE;
}
if (PostEventTriggerReq)
{
*IsTriggeringPostEventAllowed = TRUE;
}
return ShortCircuitingEvent;
}
/**
* @brief Handling debugger functions related to read & write & execute, write events (pre)
*
* @param VCpu The virtual processor's state
* @param Context The context of the caller
* @param IsTriggeringPostEventAllowed Is the caller required to trigger post event
* @return BOOLEAN
*/
BOOLEAN
2023-07-07 01:21:07 +09:00
DispatchEventHiddenHookPageReadWriteExecuteWritePreEvent(VIRTUAL_MACHINE_STATE * VCpu, PVOID Context, BOOLEAN * IsTriggeringPostEventAllowed)
{
2023-01-29 04:06:01 +09:00
VMM_CALLBACK_TRIGGERING_EVENT_STATUS_TYPE EventTriggerResult;
BOOLEAN PostEventTriggerReq = FALSE;
BOOLEAN ShortCircuitingEvent = FALSE;
//
// Triggering the pre-event (for the write hooks)
//
2023-01-29 04:06:01 +09:00
EventTriggerResult = VmmCallbackTriggerEvents(HIDDEN_HOOK_WRITE,
VMM_CALLBACK_CALLING_STAGE_PRE_EVENT_EMULATION,
Context,
&PostEventTriggerReq,
VCpu->Regs);
2023-01-29 04:06:01 +09:00
if (EventTriggerResult == VMM_CALLBACK_TRIGGERING_EVENT_STATUS_SUCCESSFUL_IGNORE_EVENT)
{
2022-10-04 10:20:15 +09:00
ShortCircuitingEvent = TRUE;
}
if (PostEventTriggerReq)
{
*IsTriggeringPostEventAllowed = TRUE;
}
//
// Triggering the pre-event (for the read & write hooks)
//
2023-01-29 04:06:01 +09:00
EventTriggerResult = VmmCallbackTriggerEvents(HIDDEN_HOOK_READ_AND_WRITE,
VMM_CALLBACK_CALLING_STAGE_PRE_EVENT_EMULATION,
Context,
&PostEventTriggerReq,
VCpu->Regs);
2023-01-29 04:06:01 +09:00
if (EventTriggerResult == VMM_CALLBACK_TRIGGERING_EVENT_STATUS_SUCCESSFUL_IGNORE_EVENT)
{
2022-10-04 10:20:15 +09:00
ShortCircuitingEvent = TRUE;
}
if (PostEventTriggerReq)
{
*IsTriggeringPostEventAllowed = TRUE;
}
2023-07-07 01:21:07 +09:00
//
// Triggering the pre-event (for the write & execute hooks)
//
EventTriggerResult = VmmCallbackTriggerEvents(HIDDEN_HOOK_WRITE_AND_EXECUTE,
VMM_CALLBACK_CALLING_STAGE_PRE_EVENT_EMULATION,
Context,
&PostEventTriggerReq,
VCpu->Regs);
if (EventTriggerResult == VMM_CALLBACK_TRIGGERING_EVENT_STATUS_SUCCESSFUL_IGNORE_EVENT)
{
ShortCircuitingEvent = TRUE;
}
if (PostEventTriggerReq)
{
*IsTriggeringPostEventAllowed = TRUE;
}
//
// Triggering the pre-event (for the read & write & execute hooks)
//
EventTriggerResult = VmmCallbackTriggerEvents(HIDDEN_HOOK_READ_AND_WRITE_AND_EXECUTE,
VMM_CALLBACK_CALLING_STAGE_PRE_EVENT_EMULATION,
Context,
&PostEventTriggerReq,
VCpu->Regs);
if (EventTriggerResult == VMM_CALLBACK_TRIGGERING_EVENT_STATUS_SUCCESSFUL_IGNORE_EVENT)
{
ShortCircuitingEvent = TRUE;
}
if (PostEventTriggerReq)
{
*IsTriggeringPostEventAllowed = TRUE;
}
2022-10-04 10:20:15 +09:00
return ShortCircuitingEvent;
}
/**
2023-07-07 01:21:07 +09:00
* @brief Handling debugger functions related to read & write & execute, execute events (pre)
*
* @param VCpu The virtual processor's state
* @param Context The context of the caller
* @param IsTriggeringPostEventAllowed
* @return BOOLEAN
*/
BOOLEAN
2023-07-07 01:21:07 +09:00
DispatchEventHiddenHookPageReadWriteExecuteExecutePreEvent(VIRTUAL_MACHINE_STATE * VCpu, PVOID Context, BOOLEAN * IsTriggeringPostEventAllowed)
{
2023-01-29 04:06:01 +09:00
VMM_CALLBACK_TRIGGERING_EVENT_STATUS_TYPE EventTriggerResult;
BOOLEAN PostEventTriggerReq = FALSE;
BOOLEAN ShortCircuitingEvent = FALSE;
//
2023-07-07 01:21:07 +09:00
// Triggering the pre-event (for the execute hooks)
//
2023-07-07 01:21:07 +09:00
EventTriggerResult = VmmCallbackTriggerEvents(HIDDEN_HOOK_EXECUTE,
2023-01-29 04:06:01 +09:00
VMM_CALLBACK_CALLING_STAGE_PRE_EVENT_EMULATION,
Context,
&PostEventTriggerReq,
VCpu->Regs);
2023-01-29 04:06:01 +09:00
if (EventTriggerResult == VMM_CALLBACK_TRIGGERING_EVENT_STATUS_SUCCESSFUL_IGNORE_EVENT)
{
2022-10-04 10:20:15 +09:00
ShortCircuitingEvent = TRUE;
}
if (PostEventTriggerReq)
{
*IsTriggeringPostEventAllowed = TRUE;
}
//
2023-07-07 01:21:07 +09:00
// Triggering the pre-event (for the read & execute hooks)
//
2023-07-07 01:21:07 +09:00
EventTriggerResult = VmmCallbackTriggerEvents(HIDDEN_HOOK_READ_AND_EXECUTE,
VMM_CALLBACK_CALLING_STAGE_PRE_EVENT_EMULATION,
Context,
&PostEventTriggerReq,
VCpu->Regs);
if (EventTriggerResult == VMM_CALLBACK_TRIGGERING_EVENT_STATUS_SUCCESSFUL_IGNORE_EVENT)
{
ShortCircuitingEvent = TRUE;
}
if (PostEventTriggerReq)
{
*IsTriggeringPostEventAllowed = TRUE;
}
//
// Triggering the pre-event (for the write & execute hooks)
//
EventTriggerResult = VmmCallbackTriggerEvents(HIDDEN_HOOK_WRITE_AND_EXECUTE,
VMM_CALLBACK_CALLING_STAGE_PRE_EVENT_EMULATION,
Context,
&PostEventTriggerReq,
VCpu->Regs);
if (EventTriggerResult == VMM_CALLBACK_TRIGGERING_EVENT_STATUS_SUCCESSFUL_IGNORE_EVENT)
{
ShortCircuitingEvent = TRUE;
}
if (PostEventTriggerReq)
{
*IsTriggeringPostEventAllowed = TRUE;
}
//
// Triggering the pre-event (for the read & write & execute hooks)
//
EventTriggerResult = VmmCallbackTriggerEvents(HIDDEN_HOOK_READ_AND_WRITE_AND_EXECUTE,
2023-01-29 04:06:01 +09:00
VMM_CALLBACK_CALLING_STAGE_PRE_EVENT_EMULATION,
Context,
&PostEventTriggerReq,
VCpu->Regs);
2023-01-29 04:06:01 +09:00
if (EventTriggerResult == VMM_CALLBACK_TRIGGERING_EVENT_STATUS_SUCCESSFUL_IGNORE_EVENT)
{
2022-10-04 10:20:15 +09:00
ShortCircuitingEvent = TRUE;
}
if (PostEventTriggerReq)
{
*IsTriggeringPostEventAllowed = TRUE;
}
2022-10-04 10:20:15 +09:00
return ShortCircuitingEvent;
}
/**
2023-07-07 01:21:07 +09:00
* @brief Handling debugger functions related to read & write & execute, read events (post)
*
2022-12-05 15:31:56 +09:00
* @param VCpu The virtual processor's state
* @param Context The context of the caller
* @return VOID
*/
VOID
2023-07-07 01:21:07 +09:00
DispatchEventHiddenHookPageReadWriteExecReadPostEvent(VIRTUAL_MACHINE_STATE * VCpu, PVOID Context)
{
//
// Triggering the post-event (for the read hooks)
//
VmmCallbackTriggerEvents(HIDDEN_HOOK_READ,
2023-07-30 04:56:07 +09:00
VMM_CALLBACK_CALLING_STAGE_POST_EVENT_EMULATION,
2023-07-07 01:21:07 +09:00
Context,
NULL,
VCpu->Regs);
//
// Triggering the post-event (for the read & write hooks)
//
VmmCallbackTriggerEvents(HIDDEN_HOOK_READ_AND_WRITE,
2023-07-30 04:56:07 +09:00
VMM_CALLBACK_CALLING_STAGE_POST_EVENT_EMULATION,
2023-07-07 01:21:07 +09:00
Context,
NULL,
VCpu->Regs);
//
// Triggering the post-event (for the read & execute hooks)
//
VmmCallbackTriggerEvents(HIDDEN_HOOK_READ_AND_EXECUTE,
2023-07-30 04:56:07 +09:00
VMM_CALLBACK_CALLING_STAGE_POST_EVENT_EMULATION,
2023-07-07 01:21:07 +09:00
Context,
NULL,
VCpu->Regs);
//
// Triggering the post-event (for the read & write & execute hooks)
//
VmmCallbackTriggerEvents(HIDDEN_HOOK_READ_AND_WRITE_AND_EXECUTE,
VMM_CALLBACK_CALLING_STAGE_POST_EVENT_EMULATION,
Context,
NULL,
VCpu->Regs);
}
/**
* @brief Handling debugger functions related to read & write & execute, write events (post)
*
* @param VCpu The virtual processor's state
* @param Context The context of the caller
* @return VOID
*/
VOID
DispatchEventHiddenHookPageReadWriteExecWritePostEvent(VIRTUAL_MACHINE_STATE * VCpu, PVOID Context)
{
//
// Triggering the post-event (for the write hooks)
//
2023-01-29 04:06:01 +09:00
VmmCallbackTriggerEvents(HIDDEN_HOOK_WRITE,
VMM_CALLBACK_CALLING_STAGE_POST_EVENT_EMULATION,
Context,
NULL,
VCpu->Regs);
//
// Triggering the post-event (for the read & write hooks)
//
2023-01-29 04:06:01 +09:00
VmmCallbackTriggerEvents(HIDDEN_HOOK_READ_AND_WRITE,
VMM_CALLBACK_CALLING_STAGE_POST_EVENT_EMULATION,
Context,
NULL,
VCpu->Regs);
2023-07-07 01:21:07 +09:00
//
// Triggering the post-event (for the write & execute hooks)
//
VmmCallbackTriggerEvents(HIDDEN_HOOK_WRITE_AND_EXECUTE,
VMM_CALLBACK_CALLING_STAGE_POST_EVENT_EMULATION,
Context,
NULL,
VCpu->Regs);
//
// Triggering the post-event (for the read & write & execute hooks)
//
VmmCallbackTriggerEvents(HIDDEN_HOOK_READ_AND_WRITE_AND_EXECUTE,
VMM_CALLBACK_CALLING_STAGE_POST_EVENT_EMULATION,
Context,
NULL,
VCpu->Regs);
}
/**
2023-07-07 01:21:07 +09:00
* @brief Handling debugger functions related to read & write & execute, execute events (post)
*
2022-12-05 15:31:56 +09:00
* @param VCpu The virtual processor's state
* @param Context The context of the caller
* @return VOID
*/
VOID
2023-07-07 01:21:07 +09:00
DispatchEventHiddenHookPageReadWriteExecExecutePostEvent(VIRTUAL_MACHINE_STATE * VCpu, PVOID Context)
{
//
2023-07-07 01:21:07 +09:00
// Triggering the post-event (for the execute hooks)
//
2023-07-07 01:21:07 +09:00
VmmCallbackTriggerEvents(HIDDEN_HOOK_EXECUTE,
2023-07-30 04:56:07 +09:00
VMM_CALLBACK_CALLING_STAGE_POST_EVENT_EMULATION,
2023-01-29 04:06:01 +09:00
Context,
NULL,
VCpu->Regs);
//
2023-07-07 01:21:07 +09:00
// Triggering the post-event (for the read & execute hooks)
//
2023-07-07 01:21:07 +09:00
VmmCallbackTriggerEvents(HIDDEN_HOOK_READ_AND_EXECUTE,
2023-07-30 04:56:07 +09:00
VMM_CALLBACK_CALLING_STAGE_POST_EVENT_EMULATION,
2023-01-29 04:06:01 +09:00
Context,
NULL,
VCpu->Regs);
2023-07-07 01:21:07 +09:00
//
// Triggering the post-event (for the write & execute hooks)
//
VmmCallbackTriggerEvents(HIDDEN_HOOK_WRITE_AND_EXECUTE,
2023-07-30 04:56:07 +09:00
VMM_CALLBACK_CALLING_STAGE_POST_EVENT_EMULATION,
2023-07-07 01:21:07 +09:00
Context,
NULL,
VCpu->Regs);
//
// Triggering the post-event (for the read & write & execute hooks)
//
VmmCallbackTriggerEvents(HIDDEN_HOOK_READ_AND_WRITE_AND_EXECUTE,
VMM_CALLBACK_CALLING_STAGE_POST_EVENT_EMULATION,
Context,
NULL,
VCpu->Regs);
}