mirror of
https://github.com/HyperDbg/HyperDbg.git
synced 2026-07-10 01:29:59 +00:00
add pre and post event concepts for cpuid, rdtsc and rdtscp, syscall, and sysret commnads
This commit is contained in:
parent
b8a2aa5ccc
commit
afb16b55a8
14 changed files with 497 additions and 221 deletions
|
|
@ -10,6 +10,7 @@ The second (2nd) of the HyperDbg Debugger.
|
|||
### Added
|
||||
- HyperDbg Software Development Kit (DK) is now available
|
||||
- **flush()** function in script engine ([link](https://docs.hyperdbg.org/commands/scripting-language/functions/events/flush))
|
||||
- **memcpy()** function in script engine ([link](https://docs.hyperdbg.org/commands/scripting-language/functions/memory/memcpy))
|
||||
- **!crwrite** - Control Register Modification Event ([link](https://docs.hyperdbg.org/commands/extension-commands/crwrite))
|
||||
|
||||
### Changed
|
||||
|
|
|
|||
|
|
@ -701,13 +701,20 @@ DebuggerRegisterEvent(PDEBUGGER_EVENT Event)
|
|||
* @brief Trigger events of a special type to be managed by debugger
|
||||
*
|
||||
* @param EventType Type of events
|
||||
* @param CallingStage Stage of calling (pre-event or post-event)
|
||||
* @param Regs Guest registers
|
||||
* @param Context An optional parameter (different in each event)
|
||||
* @param PostEventRequired Whether the caller is requested to
|
||||
* trigger a post-event event
|
||||
* @return DEBUGGER_TRIGGERING_EVENT_STATUS_TYPE returns the staus
|
||||
* of handling events
|
||||
*/
|
||||
DEBUGGER_TRIGGERING_EVENT_STATUS_TYPE
|
||||
DebuggerTriggerEvents(DEBUGGER_EVENT_TYPE_ENUM EventType, PGUEST_REGS Regs, PVOID Context)
|
||||
DebuggerTriggerEvents(DEBUGGER_EVENT_TYPE_ENUM EventType,
|
||||
DEBUGGER_EVENT_CALLING_STAGE_TYPE CallingStage,
|
||||
PGUEST_REGS Regs,
|
||||
PVOID Context,
|
||||
BOOLEAN * PostEventRequired)
|
||||
{
|
||||
DebuggerCheckForCondition * ConditionFunc;
|
||||
PLIST_ENTRY TempList = 0;
|
||||
|
|
@ -831,7 +838,7 @@ DebuggerTriggerEvents(DEBUGGER_EVENT_TYPE_ENUM EventType, PGUEST_REGS Regs, PVOI
|
|||
{
|
||||
TempList = &g_Events->ControlRegisterModifiedEventsHead;
|
||||
TempList2 = TempList;
|
||||
break;
|
||||
break;
|
||||
}
|
||||
case EXTERNAL_INTERRUPT_OCCURRED:
|
||||
{
|
||||
|
|
@ -895,6 +902,7 @@ DebuggerTriggerEvents(DEBUGGER_EVENT_TYPE_ENUM EventType, PGUEST_REGS Regs, PVOI
|
|||
switch (CurrentEvent->EventType)
|
||||
{
|
||||
case EXTERNAL_INTERRUPT_OCCURRED:
|
||||
|
||||
//
|
||||
// For external interrupt exiting events we check whether the
|
||||
// vector match the event's vector or not
|
||||
|
|
@ -908,11 +916,13 @@ DebuggerTriggerEvents(DEBUGGER_EVENT_TYPE_ENUM EventType, PGUEST_REGS Regs, PVOI
|
|||
//
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case HIDDEN_HOOK_READ_AND_WRITE:
|
||||
case HIDDEN_HOOK_READ:
|
||||
case HIDDEN_HOOK_WRITE:
|
||||
|
||||
//
|
||||
// For hidden hook read/writes we check whether the address
|
||||
// is in the range of what user specified or not, this is because
|
||||
|
|
@ -998,6 +1008,7 @@ DebuggerTriggerEvents(DEBUGGER_EVENT_TYPE_ENUM EventType, PGUEST_REGS Regs, PVOI
|
|||
|
||||
case RDMSR_INSTRUCTION_EXECUTION:
|
||||
case WRMSR_INSTRUCTION_EXECUTION:
|
||||
|
||||
//
|
||||
// check if MSR exit is what we want or not
|
||||
//
|
||||
|
|
@ -1008,9 +1019,11 @@ DebuggerTriggerEvents(DEBUGGER_EVENT_TYPE_ENUM EventType, PGUEST_REGS Regs, PVOI
|
|||
//
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case EXCEPTION_OCCURRED:
|
||||
|
||||
//
|
||||
// check if exception is what we need or not
|
||||
//
|
||||
|
|
@ -1021,10 +1034,12 @@ DebuggerTriggerEvents(DEBUGGER_EVENT_TYPE_ENUM EventType, PGUEST_REGS Regs, PVOI
|
|||
//
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case IN_INSTRUCTION_EXECUTION:
|
||||
case OUT_INSTRUCTION_EXECUTION:
|
||||
|
||||
//
|
||||
// check if I/O port is what we want or not
|
||||
//
|
||||
|
|
@ -1035,6 +1050,7 @@ DebuggerTriggerEvents(DEBUGGER_EVENT_TYPE_ENUM EventType, PGUEST_REGS Regs, PVOI
|
|||
//
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case SYSCALL_HOOK_EFER_SYSCALL:
|
||||
|
|
@ -1044,6 +1060,7 @@ DebuggerTriggerEvents(DEBUGGER_EVENT_TYPE_ENUM EventType, PGUEST_REGS Regs, PVOI
|
|||
//
|
||||
// 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
|
||||
//
|
||||
|
||||
//
|
||||
// check syscall number
|
||||
|
|
@ -1059,27 +1076,53 @@ DebuggerTriggerEvents(DEBUGGER_EVENT_TYPE_ENUM EventType, PGUEST_REGS Regs, PVOI
|
|||
break;
|
||||
|
||||
case CONTROL_REGISTER_MODIFIED:
|
||||
//
|
||||
|
||||
//
|
||||
// check if CR exit is what we want or not
|
||||
//
|
||||
if (CurrentEvent->OptionalParam1 != Context)
|
||||
{
|
||||
//
|
||||
//
|
||||
// The CR is not what we want
|
||||
//
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
// Check the stage of calling (pre and post event)
|
||||
//
|
||||
if (CallingStage == DEBUGGER_CALLING_STAGE_PRE_EVENT_EMULATION &&
|
||||
CurrentEvent->CallingStage == DEBUGGER_CALLING_STAGE_POST_EVENT_EMULATION)
|
||||
{
|
||||
//
|
||||
// Here it means that the current event is a post-event event and
|
||||
// the current stage of calling is for the pre-event events, thus
|
||||
// this event is not supposed to be runned at the current stage.
|
||||
// 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;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
//
|
||||
// Check if condtion is met or not , if the condition
|
||||
// is not met then we have to avoid performing the actions
|
||||
//
|
||||
|
||||
if (CurrentEvent->ConditionsBufferSize != 0)
|
||||
{
|
||||
//
|
||||
|
|
@ -2506,11 +2549,11 @@ DebuggerParseEventFromUsermode(PDEBUGGER_GENERAL_EVENT_DETAIL EventDetails, UINT
|
|||
//
|
||||
|
||||
//
|
||||
// Setting an indicator to CR
|
||||
//
|
||||
// Setting an indicator to CR
|
||||
//
|
||||
Event->OptionalParam1 = EventDetails->OptionalParam1;
|
||||
Event->OptionalParam2 = EventDetails->OptionalParam2;
|
||||
|
||||
|
||||
//
|
||||
// Let's see if it is for all cores or just one core
|
||||
//
|
||||
|
|
|
|||
236
hyperdbg/hprdbghv/code/debugger/core/Dispatch.c
Normal file
236
hyperdbg/hprdbghv/code/debugger/core/Dispatch.c
Normal file
|
|
@ -0,0 +1,236 @@
|
|||
/**
|
||||
* @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
|
||||
DispatchEventEferSysret(UINT32 CoreIndex, PGUEST_REGS Regs, PVOID Context)
|
||||
{
|
||||
BOOLEAN PostEventTriggerReq = FALSE;
|
||||
DEBUGGER_TRIGGERING_EVENT_STATUS_TYPE EventTriggerResult;
|
||||
VIRTUAL_MACHINE_STATE * CurrentVmState = &g_GuestState[CoreIndex];
|
||||
|
||||
//
|
||||
// We should trigger the event of SYSRET here
|
||||
//
|
||||
EventTriggerResult = DebuggerTriggerEvents(SYSCALL_HOOK_EFER_SYSRET,
|
||||
DEBUGGER_CALLING_STAGE_PRE_EVENT_EMULATION,
|
||||
Regs,
|
||||
Context,
|
||||
&PostEventTriggerReq);
|
||||
|
||||
//
|
||||
// Check whether we need to ignore event emulation or not
|
||||
//
|
||||
if (EventTriggerResult != DEBUGGER_TRIGGERING_EVENT_STATUS_SUCCESSFUL_IGNORE_EVENT)
|
||||
{
|
||||
SyscallHookEmulateSYSRET(Regs);
|
||||
CurrentVmState->IncrementRip = FALSE;
|
||||
}
|
||||
|
||||
//
|
||||
// Check for the post-event triggering needs
|
||||
//
|
||||
if (PostEventTriggerReq)
|
||||
{
|
||||
DebuggerTriggerEvents(SYSCALL_HOOK_EFER_SYSRET,
|
||||
DEBUGGER_CALLING_STAGE_POST_EVENT_EMULATION,
|
||||
Regs,
|
||||
Context,
|
||||
NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Handling debugger functions related to SYSCALL events
|
||||
*
|
||||
* @param CoreIndex Current core's index
|
||||
* @param Regs Guest's gp register
|
||||
* @param Context Context of triggering the event
|
||||
* @return VOID
|
||||
*/
|
||||
VOID
|
||||
DispatchEventEferSyscall(UINT32 CoreIndex, PGUEST_REGS Regs, PVOID Context)
|
||||
{
|
||||
BOOLEAN PostEventTriggerReq = FALSE;
|
||||
DEBUGGER_TRIGGERING_EVENT_STATUS_TYPE EventTriggerResult;
|
||||
VIRTUAL_MACHINE_STATE * CurrentVmState = &g_GuestState[CoreIndex];
|
||||
|
||||
//
|
||||
// We should trigger the event of SYSCALL here, we send the
|
||||
// syscall number in rax
|
||||
//
|
||||
EventTriggerResult = DebuggerTriggerEvents(SYSCALL_HOOK_EFER_SYSCALL,
|
||||
DEBUGGER_CALLING_STAGE_PRE_EVENT_EMULATION,
|
||||
Regs,
|
||||
Regs->rax,
|
||||
&PostEventTriggerReq);
|
||||
|
||||
//
|
||||
// Check whether we need to ignore event emulation or not
|
||||
//
|
||||
if (EventTriggerResult != DEBUGGER_TRIGGERING_EVENT_STATUS_SUCCESSFUL_IGNORE_EVENT)
|
||||
{
|
||||
SyscallHookEmulateSYSCALL(Regs);
|
||||
CurrentVmState->IncrementRip = FALSE;
|
||||
}
|
||||
|
||||
//
|
||||
// Check for the post-event triggering needs
|
||||
//
|
||||
if (PostEventTriggerReq)
|
||||
{
|
||||
DebuggerTriggerEvents(SYSCALL_HOOK_EFER_SYSCALL,
|
||||
DEBUGGER_CALLING_STAGE_POST_EVENT_EMULATION,
|
||||
Regs,
|
||||
Regs->rax,
|
||||
NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Handling debugger functions related to CPUID events
|
||||
*
|
||||
* @param Regs Guest's gp register
|
||||
* @return VOID
|
||||
*/
|
||||
VOID
|
||||
DispatchEventCpuid(PGUEST_REGS Regs)
|
||||
{
|
||||
UINT64 Context;
|
||||
DEBUGGER_TRIGGERING_EVENT_STATUS_TYPE EventTriggerResult;
|
||||
BOOLEAN PostEventTriggerReq = FALSE;
|
||||
|
||||
//
|
||||
// Check if attaching is for command dispatching in user debugger
|
||||
// or a regular CPUID
|
||||
//
|
||||
if (g_UserDebuggerState && UdCheckForCommand())
|
||||
{
|
||||
//
|
||||
// It's a thread command for user debugger, no need to run the
|
||||
// actual CPUID instruction and change the registers
|
||||
//
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// 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 = Regs->rax;
|
||||
|
||||
//
|
||||
// Triggering the pre-event
|
||||
//
|
||||
EventTriggerResult = DebuggerTriggerEvents(CPUID_INSTRUCTION_EXECUTION,
|
||||
DEBUGGER_CALLING_STAGE_PRE_EVENT_EMULATION,
|
||||
Regs,
|
||||
Context,
|
||||
&PostEventTriggerReq);
|
||||
|
||||
//
|
||||
// Check whether we need to ignore event emulation or not
|
||||
//
|
||||
if (EventTriggerResult != DEBUGGER_TRIGGERING_EVENT_STATUS_SUCCESSFUL_IGNORE_EVENT)
|
||||
{
|
||||
//
|
||||
// Handle the CPUID event in the case of triggering event
|
||||
//
|
||||
HvHandleCpuid(Regs);
|
||||
}
|
||||
|
||||
//
|
||||
// Check for the post-event triggering needs
|
||||
//
|
||||
if (PostEventTriggerReq)
|
||||
{
|
||||
DebuggerTriggerEvents(CPUID_INSTRUCTION_EXECUTION,
|
||||
DEBUGGER_CALLING_STAGE_POST_EVENT_EMULATION,
|
||||
Regs,
|
||||
Context,
|
||||
NULL);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
// Otherwise and if there is no event, we should handle the CPUID
|
||||
// normally
|
||||
//
|
||||
HvHandleCpuid(Regs);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Handling debugger functions related to RDTSC/RDTSCP events
|
||||
*
|
||||
* @param Regs Guest's gp register
|
||||
* @param ShouldEmulateTsc Whether or not the debugger is allowed to
|
||||
* emulate RDTSC/RDTSCP
|
||||
* @return VOID
|
||||
*/
|
||||
VOID
|
||||
DispatchEventTsc(PGUEST_REGS Regs, BOOLEAN IsRdtscp)
|
||||
{
|
||||
DEBUGGER_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)
|
||||
// Note : Using !tsc command in transparent-mode is not allowed
|
||||
//
|
||||
EventTriggerResult = DebuggerTriggerEvents(TSC_INSTRUCTION_EXECUTION,
|
||||
DEBUGGER_CALLING_STAGE_PRE_EVENT_EMULATION,
|
||||
Regs,
|
||||
IsRdtscp,
|
||||
&PostEventTriggerReq);
|
||||
|
||||
//
|
||||
// Check whether we need to ignore event emulation or not
|
||||
//
|
||||
if (EventTriggerResult != DEBUGGER_TRIGGERING_EVENT_STATUS_SUCCESSFUL_IGNORE_EVENT)
|
||||
{
|
||||
//
|
||||
// Handle rdtsc (emulate rdtsc/p)
|
||||
//
|
||||
CounterEmulateRdtsc(Regs);
|
||||
}
|
||||
|
||||
//
|
||||
// Check for the post-event triggering needs
|
||||
//
|
||||
if (PostEventTriggerReq)
|
||||
{
|
||||
DebuggerTriggerEvents(TSC_INSTRUCTION_EXECUTION,
|
||||
DEBUGGER_CALLING_STAGE_POST_EVENT_EMULATION,
|
||||
Regs,
|
||||
IsRdtscp,
|
||||
NULL);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,22 +1,22 @@
|
|||
/**
|
||||
* @file Termination.c
|
||||
* @author Sina Karvandi (sina@hyperdbg.org)
|
||||
* @brief Implementation of Debugger functions for terminating events
|
||||
* @brief Implementation of debugger functions for terminating events
|
||||
* @details
|
||||
*
|
||||
*
|
||||
* @version 0.1
|
||||
* @date 2020-08-16
|
||||
*
|
||||
*
|
||||
* @copyright This project is released under the GNU Public License v3.
|
||||
*
|
||||
*
|
||||
*/
|
||||
#include "pch.h"
|
||||
|
||||
/**
|
||||
* @brief Termination function for external-interrupts
|
||||
*
|
||||
*
|
||||
* @param Event Target Event Object
|
||||
* @return VOID
|
||||
* @return VOID
|
||||
*/
|
||||
VOID
|
||||
TerminateExternalInterruptEvent(PDEBUGGER_EVENT Event)
|
||||
|
|
@ -93,9 +93,9 @@ TerminateExternalInterruptEvent(PDEBUGGER_EVENT Event)
|
|||
|
||||
/**
|
||||
* @brief Termination function for hidden hook read/write
|
||||
*
|
||||
*
|
||||
* @param Event Target Event Object
|
||||
* @return VOID
|
||||
* @return VOID
|
||||
*/
|
||||
VOID
|
||||
TerminateHiddenHookReadAndWriteEvent(PDEBUGGER_EVENT Event)
|
||||
|
|
@ -126,9 +126,9 @@ TerminateHiddenHookReadAndWriteEvent(PDEBUGGER_EVENT Event)
|
|||
|
||||
/**
|
||||
* @brief Termination function for hidden hook (hidden breakpoints)
|
||||
*
|
||||
*
|
||||
* @param Event Target Event Object
|
||||
* @return VOID
|
||||
* @return VOID
|
||||
*/
|
||||
VOID
|
||||
TerminateHiddenHookExecCcEvent(PDEBUGGER_EVENT Event)
|
||||
|
|
@ -152,9 +152,9 @@ TerminateHiddenHookExecCcEvent(PDEBUGGER_EVENT Event)
|
|||
|
||||
/**
|
||||
* @brief Termination function for hidden hook (detours)
|
||||
*
|
||||
*
|
||||
* @param Event Target Event Object
|
||||
* @return VOID
|
||||
* @return VOID
|
||||
*/
|
||||
VOID
|
||||
TerminateHiddenHookExecDetoursEvent(PDEBUGGER_EVENT Event)
|
||||
|
|
@ -180,9 +180,9 @@ TerminateHiddenHookExecDetoursEvent(PDEBUGGER_EVENT Event)
|
|||
|
||||
/**
|
||||
* @brief Termination function for msr read events
|
||||
*
|
||||
*
|
||||
* @param Event Target Event Object
|
||||
* @return VOID
|
||||
* @return VOID
|
||||
*/
|
||||
VOID
|
||||
TerminateRdmsrExecutionEvent(PDEBUGGER_EVENT Event)
|
||||
|
|
@ -259,9 +259,9 @@ TerminateRdmsrExecutionEvent(PDEBUGGER_EVENT Event)
|
|||
|
||||
/**
|
||||
* @brief Termination function for msr write events
|
||||
*
|
||||
*
|
||||
* @param Event Target Event Object
|
||||
* @return VOID
|
||||
* @return VOID
|
||||
*/
|
||||
VOID
|
||||
TerminateWrmsrExecutionEvent(PDEBUGGER_EVENT Event)
|
||||
|
|
@ -338,9 +338,9 @@ TerminateWrmsrExecutionEvent(PDEBUGGER_EVENT Event)
|
|||
|
||||
/**
|
||||
* @brief Termination function for exception events
|
||||
*
|
||||
*
|
||||
* @param Event Target Event Object
|
||||
* @return VOID
|
||||
* @return VOID
|
||||
*/
|
||||
VOID
|
||||
TerminateExceptionEvent(PDEBUGGER_EVENT Event)
|
||||
|
|
@ -418,9 +418,9 @@ TerminateExceptionEvent(PDEBUGGER_EVENT Event)
|
|||
|
||||
/**
|
||||
* @brief Termination function for IN instruction events
|
||||
*
|
||||
*
|
||||
* @param Event Target Event Object
|
||||
* @return VOID
|
||||
* @return VOID
|
||||
*/
|
||||
VOID
|
||||
TerminateInInstructionExecutionEvent(PDEBUGGER_EVENT Event)
|
||||
|
|
@ -504,9 +504,9 @@ TerminateInInstructionExecutionEvent(PDEBUGGER_EVENT Event)
|
|||
|
||||
/**
|
||||
* @brief Termination function for OUT Instructions events
|
||||
*
|
||||
*
|
||||
* @param Event Target Event Object
|
||||
* @return VOID
|
||||
* @return VOID
|
||||
*/
|
||||
VOID
|
||||
TerminateOutInstructionExecutionEvent(PDEBUGGER_EVENT Event)
|
||||
|
|
@ -590,9 +590,9 @@ TerminateOutInstructionExecutionEvent(PDEBUGGER_EVENT Event)
|
|||
|
||||
/**
|
||||
* @brief Termination function for VMCALL Instruction events
|
||||
*
|
||||
*
|
||||
* @param Event Target Event Object
|
||||
* @return VOID
|
||||
* @return VOID
|
||||
*/
|
||||
VOID
|
||||
TerminateVmcallExecutionEvent(PDEBUGGER_EVENT Event)
|
||||
|
|
@ -628,9 +628,9 @@ TerminateVmcallExecutionEvent(PDEBUGGER_EVENT Event)
|
|||
|
||||
/**
|
||||
* @brief Termination function for CPUID Instruction events
|
||||
*
|
||||
*
|
||||
* @param Event Target Event Object
|
||||
* @return VOID
|
||||
* @return VOID
|
||||
*/
|
||||
VOID
|
||||
TerminateCpuidExecutionEvent(PDEBUGGER_EVENT Event)
|
||||
|
|
@ -666,9 +666,9 @@ TerminateCpuidExecutionEvent(PDEBUGGER_EVENT Event)
|
|||
|
||||
/**
|
||||
* @brief Termination function for RDTSC/RDTSCP Instruction events
|
||||
*
|
||||
*
|
||||
* @param Event Target Event Object
|
||||
* @return VOID
|
||||
* @return VOID
|
||||
*/
|
||||
VOID
|
||||
TerminateTscEvent(PDEBUGGER_EVENT Event)
|
||||
|
|
@ -745,9 +745,9 @@ TerminateTscEvent(PDEBUGGER_EVENT Event)
|
|||
|
||||
/**
|
||||
* @brief Termination function for RDPMC Instruction events
|
||||
*
|
||||
*
|
||||
* @param Event Target Event Object
|
||||
* @return VOID
|
||||
* @return VOID
|
||||
*/
|
||||
VOID
|
||||
TerminatePmcEvent(PDEBUGGER_EVENT Event)
|
||||
|
|
@ -903,9 +903,9 @@ TerminateControlRegistersEvent(PDEBUGGER_EVENT Event)
|
|||
|
||||
/**
|
||||
* @brief Termination function for MOV to debug registers events
|
||||
*
|
||||
*
|
||||
* @param Event Target Event Object
|
||||
* @return VOID
|
||||
* @return VOID
|
||||
*/
|
||||
VOID
|
||||
TerminateDebugRegistersEvent(PDEBUGGER_EVENT Event)
|
||||
|
|
@ -982,9 +982,9 @@ TerminateDebugRegistersEvent(PDEBUGGER_EVENT Event)
|
|||
|
||||
/**
|
||||
* @brief Termination function for SYSCALL Instruction events
|
||||
*
|
||||
*
|
||||
* @param Event Target Event Object
|
||||
* @return VOID
|
||||
* @return VOID
|
||||
*/
|
||||
VOID
|
||||
TerminateSyscallHookEferEvent(PDEBUGGER_EVENT Event)
|
||||
|
|
@ -1068,9 +1068,9 @@ TerminateSyscallHookEferEvent(PDEBUGGER_EVENT Event)
|
|||
|
||||
/**
|
||||
* @brief Termination function for SYSRET Instruction events
|
||||
*
|
||||
*
|
||||
* @param Event Target Event Object
|
||||
* @return VOID
|
||||
* @return VOID
|
||||
*/
|
||||
VOID
|
||||
TerminateSysretHookEferEvent(PDEBUGGER_EVENT Event)
|
||||
|
|
|
|||
|
|
@ -4,27 +4,27 @@
|
|||
* @brief Implenetation of the fucntions related to the EFER Syscall Hook
|
||||
* @details This is derived by the method demonstrated at
|
||||
* - https://revers.engineering/syscall-hooking-via-extended-feature-enable-register-efer/
|
||||
*
|
||||
*
|
||||
* also some of the functions derived from hvpp
|
||||
* - https://github.com/wbenny/hvpp
|
||||
*
|
||||
*
|
||||
* @version 0.1
|
||||
* @date 2020-04-10
|
||||
*
|
||||
*
|
||||
* @copyright This project is released under the GNU Public License v3.
|
||||
*
|
||||
*
|
||||
*/
|
||||
#include "pch.h"
|
||||
|
||||
/**
|
||||
* @brief This function enables or disables EFER syscall hoo
|
||||
* @details This function should be called for the first time
|
||||
* that we want to enable EFER hook because after calling this
|
||||
* that we want to enable EFER hook because after calling this
|
||||
* function EFER MSR is loaded from GUEST_EFER instead of loading
|
||||
* from the regular EFER MSR.
|
||||
*
|
||||
*
|
||||
* @param EnableEFERSyscallHook Determines whether we want to enable syscall hook or disable syscall hook
|
||||
* @return VOID
|
||||
* @return VOID
|
||||
*/
|
||||
VOID
|
||||
SyscallHookConfigureEFER(BOOLEAN EnableEFERSyscallHook)
|
||||
|
|
@ -104,8 +104,8 @@ SyscallHookConfigureEFER(BOOLEAN EnableEFERSyscallHook)
|
|||
}
|
||||
|
||||
/**
|
||||
* @brief This function emulates the SYSCALL execution
|
||||
*
|
||||
* @brief This function emulates the SYSCALL execution
|
||||
*
|
||||
* @param Regs Guest registers
|
||||
* @return BOOLEAN
|
||||
*/
|
||||
|
|
@ -171,8 +171,8 @@ SyscallHookEmulateSYSCALL(PGUEST_REGS Regs)
|
|||
}
|
||||
|
||||
/**
|
||||
* @brief This function emulates the SYSRET execution
|
||||
*
|
||||
* @brief This function emulates the SYSRET execution
|
||||
*
|
||||
* @param Regs Guest registers
|
||||
* @return BOOLEAN
|
||||
*/
|
||||
|
|
@ -218,7 +218,7 @@ SyscallHookEmulateSYSRET(PGUEST_REGS Regs)
|
|||
|
||||
/**
|
||||
* @brief Detect whether the #UD was because of Syscall or Sysret or not
|
||||
*
|
||||
*
|
||||
* @param Regs Guest register
|
||||
* @param CoreIndex Logical core index
|
||||
* @return BOOLEAN Shows whther the caller should inject #UD on the guest or not
|
||||
|
|
@ -230,7 +230,6 @@ SyscallHookHandleUD(PGUEST_REGS Regs, UINT32 CoreIndex)
|
|||
CR3_TYPE GuestCr3;
|
||||
UINT64 OriginalCr3;
|
||||
UINT64 Rip;
|
||||
BOOLEAN Result;
|
||||
VIRTUAL_MACHINE_STATE * CurrentVmState = &g_GuestState[CoreIndex];
|
||||
|
||||
//
|
||||
|
|
@ -339,6 +338,7 @@ SyscallHookHandleUD(PGUEST_REGS Regs, UINT32 CoreIndex)
|
|||
// Emulate SYSRET instruction
|
||||
//
|
||||
EmulateSYSRET:
|
||||
|
||||
//
|
||||
// Test
|
||||
//
|
||||
|
|
@ -346,13 +346,11 @@ EmulateSYSRET:
|
|||
//
|
||||
|
||||
//
|
||||
// We should trigger the event of SYSRET here
|
||||
// Perform the dispatching and the emulation of the SYSRET event
|
||||
//
|
||||
DebuggerTriggerEvents(SYSCALL_HOOK_EFER_SYSRET, Regs, Rip);
|
||||
DispatchEventEferSysret(CoreIndex, Regs, Rip);
|
||||
|
||||
Result = SyscallHookEmulateSYSRET(Regs);
|
||||
CurrentVmState->IncrementRip = FALSE;
|
||||
return Result;
|
||||
return TRUE;
|
||||
|
||||
//
|
||||
// Emulate SYSCALL instruction
|
||||
|
|
@ -367,13 +365,9 @@ EmulateSYSCALL:
|
|||
//
|
||||
|
||||
//
|
||||
// We should trigger the event of SYSCALL here, we send the
|
||||
// syscall number in rax
|
||||
// Perform the dispatching and the emulation of the SYSCAKK event
|
||||
//
|
||||
DebuggerTriggerEvents(SYSCALL_HOOK_EFER_SYSCALL, Regs, Regs->rax);
|
||||
DispatchEventEferSyscall(CoreIndex, Regs, Rip);
|
||||
|
||||
Result = SyscallHookEmulateSYSCALL(Regs);
|
||||
|
||||
CurrentVmState->IncrementRip = FALSE;
|
||||
return Result;
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,17 +5,17 @@
|
|||
* @details vmx related routines
|
||||
* @version 0.1
|
||||
* @date 2020-04-11
|
||||
*
|
||||
*
|
||||
* @copyright This project is released under the GNU Public License v3.
|
||||
*
|
||||
*
|
||||
*/
|
||||
#include "pch.h"
|
||||
|
||||
/**
|
||||
* @brief Adjust controls for VMCS based on processor capability
|
||||
*
|
||||
* @param Ctl
|
||||
* @param Msr
|
||||
*
|
||||
* @param Ctl
|
||||
* @param Msr
|
||||
* @return ULONG Returns the Cpu Based and Secondary Processor Based Controls
|
||||
* and other controls based on hardware support
|
||||
*/
|
||||
|
|
@ -32,11 +32,11 @@ HvAdjustControls(ULONG Ctl, ULONG Msr)
|
|||
|
||||
/**
|
||||
* @brief Set guest's selector registers
|
||||
*
|
||||
* @param GdtBase
|
||||
* @param SegmentRegister
|
||||
* @param Selector
|
||||
* @return BOOLEAN
|
||||
*
|
||||
* @param GdtBase
|
||||
* @param SegmentRegister
|
||||
* @param Selector
|
||||
* @return BOOLEAN
|
||||
*/
|
||||
BOOLEAN
|
||||
HvSetGuestSelector(PVOID GdtBase, ULONG SegmentRegister, UINT16 Selector)
|
||||
|
|
@ -59,34 +59,15 @@ HvSetGuestSelector(PVOID GdtBase, ULONG SegmentRegister, UINT16 Selector)
|
|||
|
||||
/**
|
||||
* @brief Handle Cpuid Vmexits
|
||||
*
|
||||
*
|
||||
* @param RegistersState Guest's gp registers
|
||||
* @return VOID
|
||||
* @return VOID
|
||||
*/
|
||||
VOID
|
||||
HvHandleCpuid(PGUEST_REGS RegistersState)
|
||||
{
|
||||
INT32 CpuInfo[4];
|
||||
ULONG Mode = 0;
|
||||
UINT64 Context = 0;
|
||||
|
||||
//
|
||||
// Check if attaching is for command dispatching in user debugger
|
||||
// or a regular CPUID
|
||||
//
|
||||
if (g_UserDebuggerState && UdCheckForCommand())
|
||||
{
|
||||
//
|
||||
// It's a thread command for user debugger, no need to run the
|
||||
// actual CPUID instruction and change the registers
|
||||
//
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Set the context (save eax for the debugger)
|
||||
//
|
||||
Context = RegistersState->rax;
|
||||
INT32 CpuInfo[4];
|
||||
ULONG Mode = 0;
|
||||
|
||||
//
|
||||
// Otherwise, issue the CPUID to the logical processor based on the indexes
|
||||
|
|
@ -112,7 +93,6 @@ HvHandleCpuid(PGUEST_REGS RegistersState)
|
|||
//
|
||||
CpuInfo[2] |= HYPERV_HYPERVISOR_PRESENT_BIT;
|
||||
}
|
||||
/*
|
||||
else if (RegistersState->rax == CPUID_HV_VENDOR_AND_MAX_FUNCTIONS)
|
||||
{
|
||||
//
|
||||
|
|
@ -135,7 +115,6 @@ HvHandleCpuid(PGUEST_REGS RegistersState)
|
|||
CpuInfo[0] = '0#vH'; // Hv#0
|
||||
CpuInfo[1] = CpuInfo[2] = CpuInfo[3] = 0;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
//
|
||||
|
|
@ -145,24 +124,14 @@ HvHandleCpuid(PGUEST_REGS RegistersState)
|
|||
RegistersState->rbx = CpuInfo[1];
|
||||
RegistersState->rcx = CpuInfo[2];
|
||||
RegistersState->rdx = CpuInfo[3];
|
||||
|
||||
//
|
||||
// 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)
|
||||
{
|
||||
DebuggerTriggerEvents(CPUID_INSTRUCTION_EXECUTION, RegistersState, Context);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Handles Guest Access to control registers
|
||||
*
|
||||
*
|
||||
* @param GuestState Guest's gp registers
|
||||
* @param ProcessorIndex Index of processor
|
||||
* @return VOID
|
||||
* @return VOID
|
||||
*/
|
||||
VOID
|
||||
HvHandleControlRegisterAccess(PGUEST_REGS GuestState, UINT32 ProcessorIndex)
|
||||
|
|
@ -189,7 +158,7 @@ HvHandleControlRegisterAccess(PGUEST_REGS GuestState, UINT32 ProcessorIndex)
|
|||
// We handled it in vm-exit handler, commented
|
||||
//
|
||||
|
||||
/*
|
||||
/*
|
||||
if (CrExitQualification->Fields.Register == 4)
|
||||
{
|
||||
__vmx_vmread(VMCS_GUEST_RSP, &GuestRsp);
|
||||
|
|
@ -204,9 +173,12 @@ HvHandleControlRegisterAccess(PGUEST_REGS GuestState, UINT32 ProcessorIndex)
|
|||
switch (CrExitQualification->ControlRegister)
|
||||
{
|
||||
case VMX_EXIT_QUALIFICATION_REGISTER_CR0:
|
||||
|
||||
__vmx_vmwrite(VMCS_GUEST_CR0, *RegPtr);
|
||||
__vmx_vmwrite(VMCS_CTRL_CR0_READ_SHADOW, *RegPtr);
|
||||
|
||||
DebuggerTriggerEvents(CONTROL_REGISTER_MODIFIED, GuestState, VMX_EXIT_QUALIFICATION_REGISTER_CR0);
|
||||
|
||||
break;
|
||||
case VMX_EXIT_QUALIFICATION_REGISTER_CR3:
|
||||
|
||||
|
|
@ -243,9 +215,12 @@ HvHandleControlRegisterAccess(PGUEST_REGS GuestState, UINT32 ProcessorIndex)
|
|||
|
||||
break;
|
||||
case VMX_EXIT_QUALIFICATION_REGISTER_CR4:
|
||||
|
||||
__vmx_vmwrite(VMCS_GUEST_CR4, *RegPtr);
|
||||
__vmx_vmwrite(VMCS_CTRL_CR4_READ_SHADOW, *RegPtr);
|
||||
|
||||
DebuggerTriggerEvents(CONTROL_REGISTER_MODIFIED, GuestState, VMX_EXIT_QUALIFICATION_REGISTER_CR4);
|
||||
|
||||
break;
|
||||
default:
|
||||
LogWarning("Unsupported register 0x%x in handling control registers access",
|
||||
|
|
@ -285,11 +260,11 @@ HvHandleControlRegisterAccess(PGUEST_REGS GuestState, UINT32 ProcessorIndex)
|
|||
|
||||
/**
|
||||
* @brief Fill the guest's selector data
|
||||
*
|
||||
* @param GdtBase
|
||||
* @param SegmentRegister
|
||||
* @param Selector
|
||||
* @return VOID
|
||||
*
|
||||
* @param GdtBase
|
||||
* @param SegmentRegister
|
||||
* @param Selector
|
||||
* @return VOID
|
||||
*/
|
||||
VOID
|
||||
HvFillGuestSelectorData(PVOID GdtBase, ULONG SegmentRegister, UINT16 Selector)
|
||||
|
|
@ -314,8 +289,8 @@ HvFillGuestSelectorData(PVOID GdtBase, ULONG SegmentRegister, UINT16 Selector)
|
|||
|
||||
/**
|
||||
* @brief Add the current instruction length to guest rip to resume to next instruction
|
||||
*
|
||||
* @return VOID
|
||||
*
|
||||
* @return VOID
|
||||
*/
|
||||
VOID
|
||||
HvResumeToNextInstruction()
|
||||
|
|
@ -334,9 +309,9 @@ HvResumeToNextInstruction()
|
|||
|
||||
/**
|
||||
* @brief Set the monitor trap flag
|
||||
*
|
||||
*
|
||||
* @param Set Set or unset the MTFs
|
||||
* @return VOID
|
||||
* @return VOID
|
||||
*/
|
||||
VOID
|
||||
HvSetMonitorTrapFlag(BOOLEAN Set)
|
||||
|
|
@ -365,9 +340,9 @@ HvSetMonitorTrapFlag(BOOLEAN Set)
|
|||
|
||||
/**
|
||||
* @brief Set LOAD DEBUG CONTROLS on Vm-entry controls
|
||||
*
|
||||
* @param Set Set or unset
|
||||
* @return VOID
|
||||
*
|
||||
* @param Set Set or unset
|
||||
* @return VOID
|
||||
*/
|
||||
VOID
|
||||
HvSetLoadDebugControls(BOOLEAN Set)
|
||||
|
|
@ -396,9 +371,9 @@ HvSetLoadDebugControls(BOOLEAN Set)
|
|||
|
||||
/**
|
||||
* @brief Set SAVE DEBUG CONTROLS on Vm-exit controls
|
||||
*
|
||||
* @param Set Set or unset
|
||||
* @return VOID
|
||||
*
|
||||
* @param Set Set or unset
|
||||
* @return VOID
|
||||
*/
|
||||
VOID
|
||||
HvSetSaveDebugControls(BOOLEAN Set)
|
||||
|
|
@ -427,8 +402,8 @@ HvSetSaveDebugControls(BOOLEAN Set)
|
|||
|
||||
/**
|
||||
* @brief Reset GDTR/IDTR and other old when you do vmxoff as the patchguard will detect them left modified
|
||||
*
|
||||
* @return VOID
|
||||
*
|
||||
* @return VOID
|
||||
*/
|
||||
VOID
|
||||
HvRestoreRegisters()
|
||||
|
|
@ -470,11 +445,11 @@ HvRestoreRegisters()
|
|||
}
|
||||
|
||||
/**
|
||||
* @brief Set vm-exit for rdpmc instructions
|
||||
* @brief Set vm-exit for rdpmc instructions
|
||||
* @details Should be called in vmx-root
|
||||
*
|
||||
*
|
||||
* @param Set Set or unset the vm-exits
|
||||
* @return VOID
|
||||
* @return VOID
|
||||
*/
|
||||
VOID
|
||||
HvSetPmcVmexit(BOOLEAN Set)
|
||||
|
|
@ -517,11 +492,11 @@ HvSetMovControlRegsExiting(BOOLEAN Set, UINT64 ControlRegister, UINT64 MaskRegis
|
|||
}
|
||||
|
||||
/**
|
||||
* @brief Set vm-exit for mov-to-cr3
|
||||
* @brief Set vm-exit for mov-to-cr3
|
||||
* @details Should be called in vmx-root
|
||||
*
|
||||
*
|
||||
* @param Set Set or unset the vm-exits
|
||||
* @return VOID
|
||||
* @return VOID
|
||||
*/
|
||||
VOID
|
||||
HvSetMovToCr3Vmexit(BOOLEAN Set)
|
||||
|
|
@ -530,12 +505,12 @@ HvSetMovToCr3Vmexit(BOOLEAN Set)
|
|||
}
|
||||
|
||||
/**
|
||||
* @brief Write on exception bitmap in VMCS
|
||||
* @brief Write on exception bitmap in VMCS
|
||||
* DO NOT CALL IT DIRECTLY, instead use HvSetExceptionBitmap
|
||||
* @details Should be called in vmx-root
|
||||
*
|
||||
* @param BitmapMask The content to write on exception bitmap
|
||||
* @return VOID
|
||||
*
|
||||
* @param BitmapMask The content to write on exception bitmap
|
||||
* @return VOID
|
||||
*/
|
||||
VOID
|
||||
HvWriteExceptionBitmap(UINT32 BitmapMask)
|
||||
|
|
@ -547,10 +522,10 @@ HvWriteExceptionBitmap(UINT32 BitmapMask)
|
|||
}
|
||||
|
||||
/**
|
||||
* @brief Read exception bitmap in VMCS
|
||||
* @brief Read exception bitmap in VMCS
|
||||
* @details Should be called in vmx-root
|
||||
*
|
||||
* @return UINT32
|
||||
*
|
||||
* @return UINT32
|
||||
*/
|
||||
UINT32
|
||||
HvReadExceptionBitmap()
|
||||
|
|
@ -567,9 +542,9 @@ HvReadExceptionBitmap()
|
|||
|
||||
/**
|
||||
* @brief Set Interrupt-window exiting
|
||||
*
|
||||
*
|
||||
* @param Set Set or unset the Interrupt-window exiting
|
||||
* @return VOID
|
||||
* @return VOID
|
||||
*/
|
||||
VOID
|
||||
HvSetInterruptWindowExiting(BOOLEAN Set)
|
||||
|
|
@ -601,9 +576,9 @@ HvSetInterruptWindowExiting(BOOLEAN Set)
|
|||
|
||||
/**
|
||||
* @brief Set NMI-window exiting
|
||||
*
|
||||
*
|
||||
* @param Set Set or unset the NMI-window exiting
|
||||
* @return VOID
|
||||
* @return VOID
|
||||
*/
|
||||
VOID
|
||||
HvSetNmiWindowExiting(BOOLEAN Set)
|
||||
|
|
@ -635,10 +610,10 @@ HvSetNmiWindowExiting(BOOLEAN Set)
|
|||
|
||||
/**
|
||||
* @brief Handle Mov to Debug Registers Exitings
|
||||
*
|
||||
*
|
||||
* @param ProcessorIndex Index of processor
|
||||
* @param Regs Registers of guest
|
||||
* @return VOID
|
||||
* @return VOID
|
||||
*/
|
||||
VOID
|
||||
HvHandleMovDebugRegister(UINT32 ProcessorIndex, PGUEST_REGS Regs)
|
||||
|
|
@ -843,9 +818,9 @@ HvHandleMovDebugRegister(UINT32 ProcessorIndex, PGUEST_REGS Regs)
|
|||
|
||||
/**
|
||||
* @brief Set the NMI Exiting
|
||||
*
|
||||
*
|
||||
* @param Set Set or unset the NMI Exiting
|
||||
* @return VOID
|
||||
* @return VOID
|
||||
*/
|
||||
VOID
|
||||
HvSetNmiExiting(BOOLEAN Set)
|
||||
|
|
@ -879,9 +854,9 @@ HvSetNmiExiting(BOOLEAN Set)
|
|||
|
||||
/**
|
||||
* @brief Set the VMX preemption timer
|
||||
*
|
||||
*
|
||||
* @param Set Set or unset the VMX preemption timer
|
||||
* @return VOID
|
||||
* @return VOID
|
||||
*/
|
||||
VOID
|
||||
HvSetVmxPreemptionTimerExiting(BOOLEAN Set)
|
||||
|
|
@ -909,11 +884,11 @@ HvSetVmxPreemptionTimerExiting(BOOLEAN Set)
|
|||
}
|
||||
|
||||
/**
|
||||
* @brief Set exception bitmap in VMCS
|
||||
* @brief Set exception bitmap in VMCS
|
||||
* @details Should be called in vmx-root
|
||||
*
|
||||
* @param IdtIndex Interrupt Descriptor Table index of exception
|
||||
* @return VOID
|
||||
*
|
||||
* @param IdtIndex Interrupt Descriptor Table index of exception
|
||||
* @return VOID
|
||||
*/
|
||||
VOID
|
||||
HvSetExceptionBitmap(UINT32 IdtIndex)
|
||||
|
|
@ -925,11 +900,11 @@ HvSetExceptionBitmap(UINT32 IdtIndex)
|
|||
}
|
||||
|
||||
/**
|
||||
* @brief Unset exception bitmap in VMCS
|
||||
* @brief Unset exception bitmap in VMCS
|
||||
* @details Should be called in vmx-root
|
||||
*
|
||||
* @param IdtIndex Interrupt Descriptor Table index of exception
|
||||
* @return VOID
|
||||
*
|
||||
* @param IdtIndex Interrupt Descriptor Table index of exception
|
||||
* @return VOID
|
||||
*/
|
||||
VOID
|
||||
HvUnsetExceptionBitmap(UINT32 IdtIndex)
|
||||
|
|
@ -942,9 +917,9 @@ HvUnsetExceptionBitmap(UINT32 IdtIndex)
|
|||
|
||||
/**
|
||||
* @brief Set the External Interrupt Exiting
|
||||
*
|
||||
*
|
||||
* @param Set Set or unset the External Interrupt Exiting
|
||||
* @return VOID
|
||||
* @return VOID
|
||||
*/
|
||||
VOID
|
||||
HvSetExternalInterruptExiting(BOOLEAN Set)
|
||||
|
|
@ -957,9 +932,9 @@ HvSetExternalInterruptExiting(BOOLEAN Set)
|
|||
|
||||
/**
|
||||
* @brief Set the RDTSC/P Exiting
|
||||
*
|
||||
*
|
||||
* @param Set Set or unset the RDTSC/P Exiting
|
||||
* @return VOID
|
||||
* @return VOID
|
||||
*/
|
||||
VOID
|
||||
HvSetRdtscExiting(BOOLEAN Set)
|
||||
|
|
@ -969,9 +944,9 @@ HvSetRdtscExiting(BOOLEAN Set)
|
|||
|
||||
/**
|
||||
* @brief Set or unset the Mov to Debug Registers Exiting
|
||||
*
|
||||
*
|
||||
* @param Set Set or unset the Mov to Debug Registers Exiting
|
||||
* @return VOID
|
||||
* @return VOID
|
||||
*/
|
||||
VOID
|
||||
HvSetMovDebugRegsExiting(BOOLEAN Set)
|
||||
|
|
|
|||
|
|
@ -1,19 +1,19 @@
|
|||
/**
|
||||
* @file Vmexit.c
|
||||
* @author Sina Karvandi (sina@hyperdbg.org)
|
||||
* @brief The functions for VM-Exit handler for different exit reasons
|
||||
* @brief The functions for VM-Exit handler for different exit reasons
|
||||
* @details
|
||||
* @version 0.1
|
||||
* @date 2020-04-11
|
||||
*
|
||||
*
|
||||
* @copyright This project is released under the GNU Public License v3.
|
||||
*
|
||||
*
|
||||
*/
|
||||
#include "pch.h"
|
||||
|
||||
/**
|
||||
* @brief VM-Exit handler for different exit reasons
|
||||
*
|
||||
*
|
||||
* @param GuestRegs Registers that are automatically saved by AsmVmexitHandler (HOST_RIP)
|
||||
* @return BOOLEAN Return True if VMXOFF executed (not in vmx anymore),
|
||||
* or return false if we are still in vmx (so we should use vm resume)
|
||||
|
|
@ -184,7 +184,7 @@ VmxVmexitHandler(_Inout_ PGUEST_REGS GuestRegs)
|
|||
}
|
||||
case VMX_EXIT_REASON_EXECUTE_CPUID:
|
||||
{
|
||||
HvHandleCpuid(GuestRegs);
|
||||
DispatchEventCpuid(CurrentProcessorIndex, GuestRegs);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -318,45 +318,17 @@ VmxVmexitHandler(_Inout_ PGUEST_REGS GuestRegs)
|
|||
break;
|
||||
}
|
||||
case VMX_EXIT_REASON_EXECUTE_RDTSC:
|
||||
{
|
||||
//
|
||||
// Check whether we are allowed to change
|
||||
// the registers and emulate rdtsc or not
|
||||
//
|
||||
if (ShouldEmulateRdtscp)
|
||||
{
|
||||
//
|
||||
// handle rdtsc (emulate rdtsc)
|
||||
//
|
||||
CounterEmulateRdtsc(GuestRegs);
|
||||
|
||||
//
|
||||
// As the context to event trigger, we send the false which means
|
||||
// it's an rdtsc (for rdtscp we set Context to true)
|
||||
// Note : Using !tsc command in transparent-mode is not allowed
|
||||
//
|
||||
DebuggerTriggerEvents(TSC_INSTRUCTION_EXECUTION, GuestRegs, FALSE);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case VMX_EXIT_REASON_EXECUTE_RDTSCP:
|
||||
|
||||
{
|
||||
//
|
||||
// Check whether we are allowed to change
|
||||
// the registers and emulate rdtscp or not
|
||||
// Check whether we are allowed to change the registers
|
||||
// and emulate rdtsc or not
|
||||
// Note : Using !tsc command in transparent-mode is not allowed
|
||||
//
|
||||
if (ShouldEmulateRdtscp)
|
||||
{
|
||||
//
|
||||
// handle rdtscp (emulate rdtscp)
|
||||
//
|
||||
CounterEmulateRdtscp(GuestRegs);
|
||||
//
|
||||
// As the context to event trigger, we send the false which means
|
||||
// it's an rdtsc (for rdtscp we set Context to true)
|
||||
// Note : Using !tsc command in transparent-mode is not allowed
|
||||
//
|
||||
DebuggerTriggerEvents(TSC_INSTRUCTION_EXECUTION, GuestRegs, TRUE);
|
||||
DispatchEventTsc(GuestRegs, ExitReason == VMX_EXIT_REASON_EXECUTE_RDTSCP ? TRUE : FALSE);
|
||||
}
|
||||
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -83,7 +83,7 @@ typedef struct _DEBUGGER_CORE_EVENTS
|
|||
LIST_ENTRY DebugRegistersAccessedEventsHead; // DEBUG_REGISTERS_ACCESSED [WARNING : MAKE SURE TO INITIALIZE LIST HEAD , Add it to DebuggerRegisterEvent, Add it to DebuggerTriggerEvents, Add termination to DebuggerTerminateEvent ]
|
||||
LIST_ENTRY ExternalInterruptOccurredEventsHead; // EXTERNAL_INTERRUPT_OCCURRED [WARNING : MAKE SURE TO INITIALIZE LIST HEAD , Add it to DebuggerRegisterEvent, Add it to DebuggerTriggerEvents, Add termination to DebuggerTerminateEvent ]
|
||||
LIST_ENTRY VmcallInstructionExecutionEventsHead; // VMCALL_INSTRUCTION_EXECUTION [WARNING : MAKE SURE TO INITIALIZE LIST HEAD , Add it to DebuggerRegisterEvent, Add it to DebuggerTriggerEvents, Add termination to DebuggerTerminateEvent ]
|
||||
LIST_ENTRY ControlRegisterModifiedEventsHead; // CONTROL_REGISTER_MODIFIED [WARNING : MAKE SURE TO INITIALIZE LIST HEAD , Add it to DebuggerRegisterEvent, Add it to DebuggerTriggerEvents, Add termination to DebuggerTerminateEvent ]
|
||||
LIST_ENTRY ControlRegisterModifiedEventsHead; // CONTROL_REGISTER_MODIFIED [WARNING : MAKE SURE TO INITIALIZE LIST HEAD , Add it to DebuggerRegisterEvent, Add it to DebuggerTriggerEvents, Add termination to DebuggerTerminateEvent ]
|
||||
|
||||
} DEBUGGER_CORE_EVENTS, *PDEBUGGER_CORE_EVENTS;
|
||||
|
||||
|
|
@ -218,6 +218,8 @@ typedef struct _DEBUGGER_EVENT
|
|||
LIST_ENTRY ActionsListHead; // Each entry is in DEBUGGER_EVENT_ACTION struct
|
||||
UINT32 CountOfActions; // The total count of actions
|
||||
|
||||
DEBUGGER_EVENT_CALLING_STAGE_TYPE CallingStage; // The stage that a event is supposed to be called
|
||||
|
||||
UINT64 OptionalParam1; // Optional parameter to be used differently by events
|
||||
UINT64 OptionalParam2; // Optional parameter to be used differently by events
|
||||
UINT64 OptionalParam3; // Optional parameter to be used differently by events
|
||||
|
|
@ -320,7 +322,11 @@ BOOLEAN
|
|||
DebuggerRegisterEvent(PDEBUGGER_EVENT Event);
|
||||
|
||||
DEBUGGER_TRIGGERING_EVENT_STATUS_TYPE
|
||||
DebuggerTriggerEvents(DEBUGGER_EVENT_TYPE_ENUM EventType, PGUEST_REGS Regs, PVOID Context);
|
||||
DebuggerTriggerEvents(DEBUGGER_EVENT_TYPE_ENUM EventType,
|
||||
DEBUGGER_EVENT_CALLING_STAGE_TYPE CallingStage,
|
||||
PGUEST_REGS Regs,
|
||||
PVOID Context,
|
||||
BOOLEAN * PostEventRequired);
|
||||
|
||||
PDEBUGGER_EVENT
|
||||
DebuggerGetEventByTag(UINT64 Tag);
|
||||
|
|
|
|||
29
hyperdbg/hprdbghv/header/debugger/core/Dispatch.h
Normal file
29
hyperdbg/hprdbghv/header/debugger/core/Dispatch.h
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
/**
|
||||
* @file Dispatch.h
|
||||
* @author Sina Karvandi (sina@hyperdbg.org)
|
||||
* @brief Headers of debugger functions for dispatching, triggering and
|
||||
* emulating events
|
||||
*
|
||||
* @version 0.1
|
||||
* @date 2022-09-21
|
||||
*
|
||||
* @copyright This project is released under the GNU Public License v3.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
// Functions //
|
||||
//////////////////////////////////////////////////
|
||||
|
||||
VOID
|
||||
DispatchEventEferSysret(UINT32 CoreIndex, PGUEST_REGS Regs, PVOID Context);
|
||||
|
||||
VOID
|
||||
DispatchEventEferSyscall(UINT32 CoreIndex, PGUEST_REGS Regs, PVOID Context);
|
||||
|
||||
VOID
|
||||
DispatchEventCpuid(PGUEST_REGS Regs);
|
||||
|
||||
VOID
|
||||
DispatchEventTsc(PGUEST_REGS Regs, BOOLEAN IsRdtscp);
|
||||
|
|
@ -1,14 +1,14 @@
|
|||
/**
|
||||
* @file Termination.h
|
||||
* @author Sina Karvandi (sina@hyperdbg.org)
|
||||
* @brief Headers of Debugger functions for terminating events
|
||||
* @brief Headers of debugger functions for terminating events
|
||||
* @details
|
||||
*
|
||||
*
|
||||
* @version 0.1
|
||||
* @date 2020-08-16
|
||||
*
|
||||
*
|
||||
* @copyright This project is released under the GNU Public License v3.
|
||||
*
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
|
|
@ -65,4 +65,4 @@ VOID
|
|||
TerminateCpuidExecutionEvent(PDEBUGGER_EVENT Event);
|
||||
|
||||
VOID
|
||||
TerminateControlRegistersEvent(PDEBUGGER_EVENT Event);
|
||||
TerminateControlRegistersEvent(PDEBUGGER_EVENT Event);
|
||||
|
|
|
|||
|
|
@ -127,6 +127,7 @@
|
|||
<ClCompile Include="code\debugger\communication\SerialConnection.c" />
|
||||
<ClCompile Include="code\debugger\core\Debugger.c" />
|
||||
<ClCompile Include="code\debugger\core\DebuggerEvents.c" />
|
||||
<ClCompile Include="code\debugger\core\Dispatch.c" />
|
||||
<ClCompile Include="code\debugger\core\Termination.c" />
|
||||
<ClCompile Include="code\debugger\features\hooks\ept-hook\EptHook.c" />
|
||||
<ClCompile Include="code\debugger\features\hooks\syscall-hook\EferHook.c" />
|
||||
|
|
@ -200,6 +201,7 @@
|
|||
<ClInclude Include="header\debugger\communication\SerialConnection.h" />
|
||||
<ClInclude Include="header\debugger\core\Debugger.h" />
|
||||
<ClInclude Include="header\debugger\core\DebuggerEvents.h" />
|
||||
<ClInclude Include="header\debugger\core\Dispatch.h" />
|
||||
<ClInclude Include="header\debugger\core\Termination.h" />
|
||||
<ClInclude Include="header\debugger\features\Hooks.h" />
|
||||
<ClInclude Include="header\debugger\kernel-level\Kd.h" />
|
||||
|
|
|
|||
|
|
@ -153,15 +153,15 @@
|
|||
<Filter Include="code\globals">
|
||||
<UniqueIdentifier>{a7f11b36-d144-4970-826a-a1e54e72e556}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="header\globals">
|
||||
<UniqueIdentifier>{740e29a4-86cf-41c1-b6d0-6e182ab55823}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="header\debugger\script-engine">
|
||||
<UniqueIdentifier>{5b6684f0-db1b-4920-987c-d5dfd8cdc0c1}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="code\script-eval">
|
||||
<UniqueIdentifier>{59005a75-5137-42a4-867a-ccf06fae2f9f}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="header\devices\globals">
|
||||
<UniqueIdentifier>{740e29a4-86cf-41c1-b6d0-6e182ab55823}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="code\common\Common.c">
|
||||
|
|
@ -344,6 +344,9 @@
|
|||
<ClCompile Include="..\script-eval\code\Regs.c">
|
||||
<Filter>code\script-eval</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="code\debugger\core\Dispatch.c">
|
||||
<Filter>code\debugger\core</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="pch.h">
|
||||
|
|
@ -497,10 +500,10 @@
|
|||
<Filter>header\debugger\commands</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="header\globals\GlobalVariableManagement.h">
|
||||
<Filter>header\globals</Filter>
|
||||
<Filter>header\devices\globals</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="header\globals\GlobalVariables.h">
|
||||
<Filter>header\globals</Filter>
|
||||
<Filter>header\devices\globals</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="header\platform\MetaMacros.h">
|
||||
<Filter>header\platform</Filter>
|
||||
|
|
@ -508,6 +511,9 @@
|
|||
<ClInclude Include="header\debugger\script-engine\ScriptEngine.h">
|
||||
<Filter>header\debugger\script-engine</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="header\debugger\core\Dispatch.h">
|
||||
<Filter>header\debugger\core</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<MASM Include="code\assembly\AsmCommon.asm">
|
||||
|
|
|
|||
|
|
@ -71,6 +71,7 @@
|
|||
#include "..\hprdbghv\header\debugger\user-level\Ud.h"
|
||||
#include "..\hprdbghv\header\vmm\vmx\Mtf.h"
|
||||
#include "..\hprdbghv\header\debugger\core\DebuggerEvents.h"
|
||||
#include "..\hprdbghv\header\debugger\core\Dispatch.h"
|
||||
#include "..\hprdbghv\header\debugger\features\Hooks.h"
|
||||
#include "..\hprdbghv\header\vmm\vmx\Counters.h"
|
||||
#include "..\hprdbghv\header\debugger\transparency\Transparency.h"
|
||||
|
|
|
|||
|
|
@ -66,6 +66,17 @@ typedef enum _DEBUGGER_EVENT_ACTION_TYPE_ENUM
|
|||
|
||||
} DEBUGGER_EVENT_ACTION_TYPE_ENUM;
|
||||
|
||||
/**
|
||||
* @brief Type of calling the event
|
||||
*
|
||||
*/
|
||||
typedef enum _DEBUGGER_EVENT_CALLING_STAGE_TYPE
|
||||
{
|
||||
DEBUGGER_CALLING_STAGE_PRE_EVENT_EMULATION,
|
||||
DEBUGGER_CALLING_STAGE_POST_EVENT_EMULATION,
|
||||
|
||||
} DEBUGGER_EVENT_CALLING_STAGE_TYPE;
|
||||
|
||||
/**
|
||||
* @brief Type of handling !syscall or !sysret
|
||||
*
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue