HyperDbg/hyperdbg/hyperkd/code/debugger/core/DebuggerVmcalls.c

140 lines
4.1 KiB
C
Raw Permalink Normal View History

2023-01-22 02:38:37 +09:00
/**
* @file DebuggerVmcalls.c
* @author Sina Karvandi (sina@hyperdbg.org)
* @brief Implementation of debugger VMCALLs
* @details
*
* @version 0.2
* @date 2023-01-22
*
* @copyright This project is released under the GNU Public License v3.
*
*/
#include "pch.h"
/**
* @brief Termination function for external-interrupts
*
* @param CoreId
* @param VmcallNumber
* @param OptionalParam1
* @param OptionalParam2
* @param OptionalParam3
*
* @return BOOLEAN
*/
BOOLEAN
DebuggerVmcallHandler(UINT32 CoreId,
2023-03-22 17:45:52 +09:00
UINT64 VmcallNumber,
UINT64 OptionalParam1,
UINT64 OptionalParam2,
UINT64 OptionalParam3)
2023-01-22 02:38:37 +09:00
{
2024-03-01 21:02:52 +09:00
UNREFERENCED_PARAMETER(OptionalParam3);
BOOLEAN Result = FALSE;
PROCESSOR_DEBUGGING_STATE * DbgState = &g_DbgState[CoreId];
2023-01-22 02:38:37 +09:00
2023-03-22 17:45:52 +09:00
switch (VmcallNumber)
{
case DEBUGGER_VMCALL_VM_EXIT_HALT_SYSTEM:
{
KdHandleBreakpointAndDebugBreakpoints(DbgState,
DEBUGGEE_PAUSING_REASON_REQUEST_FROM_DEBUGGER,
NULL);
2023-01-22 02:38:37 +09:00
Result = TRUE;
break;
}
2023-03-22 17:45:52 +09:00
case DEBUGGER_VMCALL_VM_EXIT_HALT_SYSTEM_AS_A_RESULT_OF_TRIGGERING_EVENT:
{
DEBUGGER_TRIGGERED_EVENT_DETAILS * TriggeredEventDetail = (DEBUGGER_TRIGGERED_EVENT_DETAILS *)OptionalParam1;
GUEST_REGS * TempReg = NULL;
2023-01-22 02:38:37 +09:00
//
// Get the original guest registers
//
TempReg = VmFuncGetGuestRegs(DbgState->CoreId);
2023-01-22 02:38:37 +09:00
//
// We won't send current vmcall registers instead we send the registers provided from the third parameter
2023-01-22 02:38:37 +09:00
//
VmFuncSetGuestRegs(DbgState->CoreId, (GUEST_REGS *)OptionalParam2);
2023-01-22 02:38:37 +09:00
//
// Handle the break (pause)
//
KdHandleBreakpointAndDebugBreakpoints(DbgState,
DEBUGGEE_PAUSING_REASON_DEBUGGEE_EVENT_TRIGGERED,
TriggeredEventDetail);
2023-01-22 02:38:37 +09:00
//
// Restore the register
//
VmFuncSetGuestRegs(DbgState->CoreId, TempReg);
2023-01-22 02:38:37 +09:00
Result = TRUE;
break;
}
2023-03-22 17:45:52 +09:00
case DEBUGGER_VMCALL_SIGNAL_DEBUGGER_EXECUTION_FINISHED:
{
2023-01-22 02:38:37 +09:00
KdSendCommandFinishedSignal(CoreId);
Result = TRUE;
break;
}
2023-03-22 17:45:52 +09:00
case DEBUGGER_VMCALL_SEND_MESSAGES_TO_DEBUGGER:
{
2023-01-22 02:38:37 +09:00
//
// Kernel debugger is active, we should send the bytes over serial
//
2024-03-01 23:51:41 +09:00
2024-03-03 15:15:38 +09:00
if (OptionalParam1 != NULL64_ZERO && OptionalParam2 != NULL64_ZERO)
2024-03-01 23:51:41 +09:00
{
KdLoggingResponsePacketToDebugger(
(CHAR *)OptionalParam1,
(UINT32)OptionalParam2,
OPERATION_LOG_INFO_MESSAGE);
}
2023-01-22 02:38:37 +09:00
Result = TRUE;
break;
}
2023-03-22 17:45:52 +09:00
case DEBUGGER_VMCALL_SEND_GENERAL_BUFFER_TO_DEBUGGER:
{
2023-01-22 02:38:37 +09:00
//
// Cast the buffer received to perform sending buffer and possibly
2023-07-13 16:05:42 +09:00
// halt the debuggee
2023-01-22 02:38:37 +09:00
//
2024-03-01 22:27:09 +09:00
PDEBUGGEE_SEND_GENERAL_PACKET_FROM_DEBUGGEE_TO_DEBUGGER DebuggeeBufferRequest = (DEBUGGEE_SEND_GENERAL_PACKET_FROM_DEBUGGEE_TO_DEBUGGER *)OptionalParam1;
2023-01-22 02:38:37 +09:00
KdResponsePacketToDebugger(DEBUGGER_REMOTE_PACKET_TYPE_DEBUGGEE_TO_DEBUGGER,
2023-03-22 17:45:52 +09:00
DebuggeeBufferRequest->RequestedAction,
2024-03-01 18:11:24 +09:00
(CHAR *)((UINT64)DebuggeeBufferRequest + (SIZEOF_DEBUGGEE_SEND_GENERAL_PACKET_FROM_DEBUGGEE_TO_DEBUGGER)),
2023-03-22 17:45:52 +09:00
DebuggeeBufferRequest->LengthOfBuffer);
2023-01-22 02:38:37 +09:00
//
// Check if we expect a buffer and command from the debugger or the
// request is just finished
//
2023-03-22 17:45:52 +09:00
if (DebuggeeBufferRequest->PauseDebuggeeWhenSent)
{
DbgState->IgnoreDisasmInNextPacket = TRUE;
KdHandleBreakpointAndDebugBreakpoints(DbgState,
DEBUGGEE_PAUSING_REASON_PAUSE,
NULL);
2023-01-22 02:38:37 +09:00
}
Result = TRUE;
break;
}
default:
Result = FALSE;
LogError("Err, invalid VMCALL in top-level debugger");
break;
}
return Result;
}