HyperDbg Debugger
Loading...
Searching...
No Matches
Kd.c File Reference

Routines related to kernel mode debugging. More...

#include "pch.h"

Functions

VOID KdInitializeKernelDebugger ()
 initialize kernel debugger
VOID KdUninitializeKernelDebugger ()
 uninitialize kernel debugger
BOOLEAN KdCheckImmediateMessagingMechanism (UINT32 OperationCode)
 Checks whether the immediate messaging mechism is needed or not.
VOID KdInitializeInstantEventPools ()
 Initialize the required pools for instant events.
VOID KdDummyDPC (PKDPC Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVOID SystemArgument2)
 A test function for DPC.
VOID KdFireDpc (PVOID Routine, PVOID Parameter)
 Add a DPC to dpc queue.
BOOLEAN KdQueryDebuggerQueryThreadOrProcessTracingDetailsByCoreId (UINT32 CoreId, DEBUGGER_THREAD_PROCESS_TRACING TracingType)
 Query for process/thread interception status.
BOOLEAN KdQueryIgnoreHandlingMov2DebugRegs (UINT32 CoreId)
 Query to ignore handling mov 2 debug regs exiting.
_Use_decl_annotations_ BYTE KdComputeDataChecksum (PVOID Buffer, UINT32 Length)
 calculate the checksum of received buffer from debugger
_Use_decl_annotations_ BOOLEAN KdResponsePacketToDebugger (DEBUGGER_REMOTE_PACKET_TYPE PacketType, DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION Response, CHAR *OptionalBuffer, UINT32 OptionalBufferLength)
 Sends a HyperDbg response packet to the debugger.
_Use_decl_annotations_ BOOLEAN KdLoggingResponsePacketToDebugger (CHAR *OptionalBuffer, UINT32 OptionalBufferLength, UINT32 OperationCode)
 Sends a HyperDbg logging response packet to the debugger.
VOID KdRegularStepOver (UINT64 LastRip, BOOLEAN IsNextInstructionACall, UINT32 CallLength)
 Regular step-over, step one instruction to the debuggee if there is a call then it jumps the call.
VOID KdHandleDebugEventsWhenKernelDebuggerIsAttached (PROCESSOR_DEBUGGING_STATE *DbgState, BOOLEAN TrapSetByDebugger)
 Handles debug events when kernel-debugger is attached.
VOID KdApplyTasksPreHaltCore (PROCESSOR_DEBUGGING_STATE *DbgState)
 before halting any core, all the tasks will be applied to all cores including the main core
VOID KdApplyTasksPostContinueCore (PROCESSOR_DEBUGGING_STATE *DbgState)
 before continue any core, all the tasks will be applied to all cores including the main core
_Use_decl_annotations_ VOID KdContinueDebuggee (PROCESSOR_DEBUGGING_STATE *DbgState, BOOLEAN PauseBreaksUntilSpecialMessageSent, DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION SpeialEventResponse)
 continue the debuggee, this function guarantees that all other cores are continued (except current core)
VOID KdContinueDebuggeeJustCurrentCore (PROCESSOR_DEBUGGING_STATE *DbgState)
 continue the debuggee, just the current operating core
BOOLEAN KdSwitchCore (PROCESSOR_DEBUGGING_STATE *DbgState, DEBUGGEE_CHANGE_CORE_PACKET *ChangeCorePacket)
 change the current operating core to new core
VOID KdCheckUserModePriorityBuffers ()
 Check the user-mode priority buffer.
VOID KdCloseConnectionAndUnloadDebuggee ()
 Notify user-mode to unload the debuggee and close the connections.
_Use_decl_annotations_ VOID KdReloadSymbolDetailsInDebuggee (PDEBUGGEE_SYMBOL_REQUEST_PACKET SymPacket)
 Notify user-mode to re-send (reload) the symbol packets.
VOID KdNotifyDebuggeeForUserInput (DEBUGGEE_USER_INPUT_PACKET *Descriptor, UINT32 Len)
 Notify user-mode to about new user-input buffer.
VOID KdSendFormatsFunctionResult (UINT64 Value)
 Send the result of formats command to the kernel debugger.
VOID KdSendCommandFinishedSignal (UINT32 CoreId)
 Notify debugger that the execution of command finished.
_Use_decl_annotations_ VOID KdHandleHaltsWhenNmiReceivedFromVmxRoot (PROCESSOR_DEBUGGING_STATE *DbgState)
 Tries to get the lock and won't return until successfully get the lock.
VOID KdCustomDebuggerBreakSpinlockLock (PROCESSOR_DEBUGGING_STATE *DbgState, volatile LONG *Lock)
 Tries to get the lock and won't return until successfully get the lock.
VOID KdHandleNmiBroadcastDebugBreaks (UINT32 CoreId, BOOLEAN IsOnVmxNmiHandler)
 Handle broadcast NMIs for halting cores in vmx-root mode.
_Use_decl_annotations_ VOID KdHandleBreakpointAndDebugBreakpointsCallback (UINT32 CoreId, DEBUGGEE_PAUSING_REASON Reason, PDEBUGGER_TRIGGERED_EVENT_DETAILS EventDetails)
 Handle #DBs and #BPs for kernel debugger.
BOOLEAN KdCheckAndHandleNmiStateForMtf (PROCESSOR_DEBUGGING_STATE *DbgState)
 Handle NMI state for MTF.
VOID KdHandleInstrumentationStepIn (PROCESSOR_DEBUGGING_STATE *DbgState)
 Handle instrumentation step-in for kernel debugger.
BOOLEAN KdHandleMtfCallback (UINT32 CoreId)
 Handle Monitor Trap Flag (MTF) callback for kernel debugger.
_Use_decl_annotations_ VOID KdHandleBreakpointAndDebugBreakpoints (PROCESSOR_DEBUGGING_STATE *DbgState, DEBUGGEE_PAUSING_REASON Reason, PDEBUGGER_TRIGGERED_EVENT_DETAILS EventDetails)
 Handle #DBs and #BPs for kernel debugger.
_Use_decl_annotations_ VOID KdHandleNmi (PROCESSOR_DEBUGGING_STATE *DbgState)
 Handle NMI Vm-exits.
VOID KdGuaranteedStepInstruction (PROCESSOR_DEBUGGING_STATE *DbgState)
 apply a guaranteed step one instruction to the debuggee
BOOLEAN KdCheckGuestOperatingModeChanges (UINT16 PreviousCsSelector, UINT16 CurrentCsSelector)
 Check if the execution mode (kernel-mode to user-mode or user-mode to kernel-mode) changed.
BOOLEAN KdPerformRegisterEvent (PDEBUGGEE_EVENT_AND_ACTION_HEADER_FOR_REMOTE_PACKET EventDetailHeader, DEBUGGER_EVENT_AND_ACTION_RESULT *DebuggerEventAndActionResult)
 Send event registration buffer to user-mode to register the event.
BOOLEAN KdPerformAddActionToEvent (PDEBUGGEE_EVENT_AND_ACTION_HEADER_FOR_REMOTE_PACKET ActionDetailHeader, DEBUGGER_EVENT_AND_ACTION_RESULT *DebuggerEventAndActionResult)
 Send action buffer to user-mode to be added to the event.
VOID KdQueryRflagTrapState ()
 Query state of the RFLAG's traps.
BOOLEAN KdCheckAllCoresAreLocked ()
 Check whether all cores are locked or not.
BOOLEAN KdCheckTargetCoreIsLocked (UINT32 CoreNumber)
 Check whether a specific target core is locked or not.
VOID KdQuerySystemState ()
 Query state of the system.
VOID KdUnlockTheHaltedCore (PROCESSOR_DEBUGGING_STATE *DbgState)
 unlock the target core
BOOLEAN KdCheckTheHaltedCore (PROCESSOR_DEBUGGING_STATE *DbgState)
 check the lock state of the target core
BOOLEAN KdBringPagein (PROCESSOR_DEBUGGING_STATE *DbgState, PDEBUGGER_PAGE_IN_REQUEST PageinRequest)
 routines to break page-in
VOID KdPerformTheTestPacketOperation (PROCESSOR_DEBUGGING_STATE *DbgState, DEBUGGER_DEBUGGER_TEST_QUERY_BUFFER *TestQueryPacket)
 Perform the test packet's operation.
VOID KdPerformSettingTheStateOfShortCircuiting (PROCESSOR_DEBUGGING_STATE *DbgState, PDEBUGGER_SHORT_CIRCUITING_EVENT ShortCircuitingEvent)
 Perform modify the state of short-circuiting.
BOOLEAN KdPerformEventQueryAndModification (PDEBUGGER_MODIFY_EVENTS ModifyAndQueryEvent)
 Perform modify and query events.
VOID KdDispatchAndPerformCommandsFromDebugger (PROCESSOR_DEBUGGING_STATE *DbgState)
 This function applies commands from the debugger to the debuggee.
BOOLEAN KdIsGuestOnUsermode32Bit ()
 determines if the guest was in 32-bit user-mode or 64-bit (long mode)
VOID KdManageSystemHaltOnVmxRoot (PROCESSOR_DEBUGGING_STATE *DbgState, PDEBUGGER_TRIGGERED_EVENT_DETAILS EventDetails)
 manage system halt on vmx-root mode
VOID KdBroadcastHaltOnAllCores ()
 routines for broadcast system halt
VOID KdHaltSystem (PDEBUGGER_PAUSE_PACKET_RECEIVED PausePacket)
 Halt the system.

Detailed Description

Routines related to kernel mode debugging.

Author
Sina Karvandi (sina@.nosp@m.hype.nosp@m.rdbg..nosp@m.org)
Alee Amini (alee@.nosp@m.hype.nosp@m.rdbg..nosp@m.org)
Version
0.1
Date
2020-12-20

Function Documentation

◆ KdApplyTasksPostContinueCore()

VOID KdApplyTasksPostContinueCore ( PROCESSOR_DEBUGGING_STATE * DbgState)

before continue any core, all the tasks will be applied to all cores including the main core

these tasks will be applied in vmx-root

Parameters
DbgStateThe state of the debugger on the current core
Returns
VOID
618{
619 //
620 // Check to apply hardware debug register breakpoints for step-over
621 //
622 if (DbgState->HardwareDebugRegisterForStepping != (UINT64)NULL)
623 {
626 FALSE,
628
629 DbgState->HardwareDebugRegisterForStepping = (UINT64)NULL;
630 }
631}
#define FALSE
Definition BasicTypes.h:113
@ BREAK_ON_INSTRUCTION_FETCH
Definition DataTypes.h:103
IMPORT_EXPORT_VMM BOOLEAN SetDebugRegisters(UINT32 DebugRegNum, DEBUG_REGISTER_TYPE ActionType, BOOLEAN ApplyToVmcs, UINT64 TargetAddress)
Configure hardware debug register for access, write and fetch breakpoints.
Definition DebugRegisters.c:37
#define DEBUGGER_DEBUG_REGISTER_FOR_STEP_OVER
debug register for step-over
Definition Debugger.h:21
UINT64 HardwareDebugRegisterForStepping
Definition State.h:183

◆ KdApplyTasksPreHaltCore()

VOID KdApplyTasksPreHaltCore ( PROCESSOR_DEBUGGING_STATE * DbgState)

before halting any core, all the tasks will be applied to all cores including the main core

these tasks will be applied in vmx-root

Parameters
DbgStateThe state of the debugger on the current core
Returns
VOID
579{
580 //
581 // Check to unset mov to cr3 vm-exits
582 //
584 {
585 //
586 // Disable process change detection
587 //
589 FALSE,
591 }
592
593 //
594 // Check to unset change thread alerts
595 //
597 {
598 //
599 // Disable thread change alerts
600 //
602 FALSE,
604 }
605}
VOID ProcessEnableOrDisableThreadChangeMonitor(PROCESSOR_DEBUGGING_STATE *DbgState, BOOLEAN Enable, BOOLEAN IsSwitchByClockIntrrupt)
Enable or disable the process change monitoring detection on the running core.
Definition Process.c:220
VOID ThreadEnableOrDisableThreadChangeMonitor(PROCESSOR_DEBUGGING_STATE *DbgState, BOOLEAN Enable, BOOLEAN IsSwitchByClockIntrrupt)
Enable or disable the thread change monitoring detection on the running core.
Definition Thread.c:614
#define TRUE
Definition BasicTypes.h:114
BOOLEAN InitialSetByClockInterrupt
Definition State.h:50
BOOLEAN InitialSetProcessChangeEvent
Definition State.h:47
BOOLEAN InitialSetThreadChangeEvent
Definition State.h:48
DEBUGGEE_PROCESS_OR_THREAD_TRACING_DETAILS ThreadOrProcessTracingDetails
Definition State.h:179

◆ KdBringPagein()

BOOLEAN KdBringPagein ( PROCESSOR_DEBUGGING_STATE * DbgState,
PDEBUGGER_PAGE_IN_REQUEST PageinRequest )

routines to break page-in

Parameters
DbgStateThe state of the debugger on the current core
PageinRequest
Returns
BOOLEAN
1807{
1808 //
1809 // Inject page-fault range
1810 //
1812 PageinRequest->VirtualAddressFrom,
1813 PageinRequest->VirtualAddressTo,
1814 PageinRequest->PageFaultErrorCode);
1815
1816 //
1817 // Also, set the RFLAGS.TF to intercept the process (thread) again after inject #PF
1818 //
1820
1821 //
1822 // Unset the trap flag next time that it's triggered (on current thread/process)
1823 //
1824 if (!BreakpointRestoreTheTrapFlagOnceTriggered(HANDLE_TO_UINT32(PsGetCurrentProcessId()), HANDLE_TO_UINT32(PsGetCurrentThreadId())))
1825 {
1826 //
1827 // Adjust the flags for showing there was error
1828 //
1830
1831 return FALSE;
1832 }
1833 else
1834 {
1835 //
1836 // Adjust the flags for showing the successful #PF injection
1837 //
1839
1840 return TRUE;
1841 }
1842}
BOOLEAN BreakpointRestoreTheTrapFlagOnceTriggered(UINT32 ProcessId, UINT32 ThreadId)
This function makes sure to unset the RFLAGS.TF on next trigger of DB on the target process/thread.
Definition BreakpointCommands.c:174
#define HANDLE_TO_UINT32(_var)
Definition MetaMacros.h:39
#define DEBUGGER_ERROR_THE_TRAP_FLAG_LIST_IS_FULL
error, the list of threads/process trap flag is full
Definition ErrorCodes.h:411
#define DEBUGGER_OPERATION_WAS_SUCCESSFUL
General value to indicate that the operation or request was successful.
Definition ErrorCodes.h:23
IMPORT_EXPORT_VMM VOID VmFuncSetRflagTrapFlag(BOOLEAN Set)
Set Rflag's trap flag.
Definition Export.c:123
IMPORT_EXPORT_VMM VOID VmFuncEventInjectPageFaultRangeAddress(UINT32 CoreId, UINT64 AddressFrom, UINT64 AddressTo, UINT32 PageFaultCode)
Inject a range of page-faults.
Definition Export.c:917
UINT64 VirtualAddressFrom
Definition RequestStructures.h:105
UINT32 KernelStatus
Definition RequestStructures.h:109
UINT32 PageFaultErrorCode
Definition RequestStructures.h:108
UINT64 VirtualAddressTo
Definition RequestStructures.h:106
UINT32 CoreId
Definition State.h:168

◆ KdBroadcastHaltOnAllCores()

VOID KdBroadcastHaltOnAllCores ( )

routines for broadcast system halt

Returns
VOID
3475{
3476 //
3477 // Broadcast to all cores
3478 //
3479 KeGenericCallDpc(DpcRoutineVmExitAndHaltSystemAllCores, NULL);
3480}
VOID DpcRoutineVmExitAndHaltSystemAllCores(KDPC *Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVOID SystemArgument2)
vm-exit and halt the system
Definition DpcRoutines.c:250

◆ KdCheckAllCoresAreLocked()

BOOLEAN KdCheckAllCoresAreLocked ( )

Check whether all cores are locked or not.

Returns
BOOLEAN
1668{
1669 ULONG ProcessorsCount;
1670
1671 ProcessorsCount = KeQueryActiveProcessorCount(0);
1672
1673 //
1674 // Query core debugging Lock info
1675 //
1676 for (SIZE_T i = 0; i < ProcessorsCount; i++)
1677 {
1678 if (!SpinlockCheckLock(&g_DbgState[i].Lock))
1679 {
1680 //
1681 // We found one core that is not locked
1682 //
1683 return FALSE;
1684 }
1685 }
1686
1687 //
1688 // Reaching here means all cores are locked
1689 //
1690 return TRUE;
1691}
BOOLEAN SpinlockCheckLock(volatile LONG *Lock)
Check the lock without changing the state.
Definition Spinlock.c:174
unsigned long ULONG
Definition BasicTypes.h:31
PROCESSOR_DEBUGGING_STATE * g_DbgState
Save the state and variables related to debugging on each to logical core.
Definition Global.h:17

◆ KdCheckAndHandleNmiStateForMtf()

BOOLEAN KdCheckAndHandleNmiStateForMtf ( PROCESSOR_DEBUGGING_STATE * DbgState)

Handle NMI state for MTF.

Parameters
DbgStateThe state of the debugger on the current core

This function should be called in vmx-root mode

Returns
BOOLEAN
1105{
1106 BOOLEAN Result = FALSE;
1107
1108 if (DbgState->NmiState.WaitingToBeLocked)
1109 {
1110 //
1111 // The NMI wait is handled here
1112 //
1113 Result = TRUE;
1114
1115 //
1116 // Handle break of the core
1117 //
1119 {
1120 //
1121 // Handle it like an NMI is received from VMX root
1122 //
1124 }
1125 else
1126 {
1127 //
1128 // Handle halt of the current core as an NMI
1129 //
1130 KdHandleNmi(DbgState);
1131 }
1132 }
1133
1134 return Result;
1135}
_Use_decl_annotations_ VOID KdHandleNmi(PROCESSOR_DEBUGGING_STATE *DbgState)
Handle NMI Vm-exits.
Definition Kd.c:1399
_Use_decl_annotations_ VOID KdHandleHaltsWhenNmiReceivedFromVmxRoot(PROCESSOR_DEBUGGING_STATE *DbgState)
Tries to get the lock and won't return until successfully get the lock.
Definition Kd.c:906
UCHAR BOOLEAN
Definition BasicTypes.h:35
volatile BOOLEAN WaitingToBeLocked
Definition State.h:96
volatile BOOLEAN NmiCalledInVmxRootRelatedToHaltDebuggee
Definition State.h:95
KD_NMI_STATE NmiState
Definition State.h:180

◆ KdCheckGuestOperatingModeChanges()

BOOLEAN KdCheckGuestOperatingModeChanges ( UINT16 PreviousCsSelector,
UINT16 CurrentCsSelector )

Check if the execution mode (kernel-mode to user-mode or user-mode to kernel-mode) changed.

Parameters
PreviousCsSelector
CurrentCsSelector
Returns
BOOLEAN
1488{
1489 PreviousCsSelector = PreviousCsSelector & ~3;
1490 CurrentCsSelector = CurrentCsSelector & ~3;
1491
1492 //
1493 // Check if the execution modes are the same or not
1494 //
1495 if (PreviousCsSelector == CurrentCsSelector)
1496 {
1497 //
1498 // Execution modes are not changed
1499 //
1500 return FALSE;
1501 }
1502
1503 if ((PreviousCsSelector == KGDT64_R3_CODE || PreviousCsSelector == KGDT64_R3_CMCODE) && CurrentCsSelector == KGDT64_R0_CODE)
1504 {
1505 //
1506 // User-mode -> Kernel-mode
1507 //
1508 LogInfo("User-mode -> Kernel-mode\n");
1509 }
1510 else if ((CurrentCsSelector == KGDT64_R3_CODE || CurrentCsSelector == KGDT64_R3_CMCODE) && PreviousCsSelector == KGDT64_R0_CODE)
1511 {
1512 //
1513 // Kernel-mode to user-mode
1514 //
1515 LogInfo("Kernel-mode -> User-mode\n");
1516 }
1517 else if (CurrentCsSelector == KGDT64_R3_CODE && PreviousCsSelector == KGDT64_R3_CMCODE)
1518 {
1519 //
1520 // A heaven's gate (User-mode 32-bit code -> User-mode 64-bit code)
1521 //
1522 LogInfo("32-bit User-mode -> 64-bit User-mode (Heaven's gate)\n");
1523 }
1524 else if (PreviousCsSelector == KGDT64_R3_CODE && CurrentCsSelector == KGDT64_R3_CMCODE)
1525 {
1526 //
1527 // A heaven's gate (User-mode 64-bit code -> User-mode 32-bit code)
1528 //
1529 LogInfo("64-bit User-mode -> 32-bit User-mode (Return from Heaven's gate)\n");
1530 }
1531 else
1532 {
1533 LogError("Err, unknown changes in cs selector during the instrumentation step-in\n");
1534 }
1535
1536 //
1537 // Execution modes are changed
1538 //
1539 return TRUE;
1540}
#define KGDT64_R3_CODE
Definition Constants.h:659
#define KGDT64_R0_CODE
Definition Constants.h:655
#define KGDT64_R3_CMCODE
Definition Constants.h:657
#define LogError(format,...)
Log in the case of error.
Definition HyperDbgHyperLogIntrinsics.h:113
#define LogInfo(format,...)
Define log variables.
Definition HyperDbgHyperLogIntrinsics.h:71

◆ KdCheckImmediateMessagingMechanism()

BOOLEAN KdCheckImmediateMessagingMechanism ( UINT32 OperationCode)

Checks whether the immediate messaging mechism is needed or not.

Parameters
OperationCode
Returns
BOOLEAN
108{
109 return (g_KernelDebuggerState && !(OperationCode & OPERATION_MANDATORY_DEBUGGEE_BIT));
110}
#define OPERATION_MANDATORY_DEBUGGEE_BIT
If a operation use this bit in its Operation code, then it means that the operation should be perform...
Definition Constants.h:367
BOOLEAN g_KernelDebuggerState
shows whether the kernel debugger is enabled or disabled
Definition Global.h:151

◆ KdCheckTargetCoreIsLocked()

BOOLEAN KdCheckTargetCoreIsLocked ( UINT32 CoreNumber)

Check whether a specific target core is locked or not.

Parameters
CoreNumber
Returns
BOOLEAN
1701{
1702 //
1703 // Query core debugging Lock info
1704 //
1705
1706 if (!SpinlockCheckLock(&g_DbgState[CoreNumber].Lock))
1707 {
1708 //
1709 // This core is not locked
1710 //
1711 return FALSE;
1712 }
1713 else
1714 {
1715 //
1716 // Target core is locked
1717 //
1718 return TRUE;
1719 }
1720}

◆ KdCheckTheHaltedCore()

BOOLEAN KdCheckTheHaltedCore ( PROCESSOR_DEBUGGING_STATE * DbgState)

check the lock state of the target core

Parameters
DbgStateThe state of the debugger on the target core
Returns
BOOLEAN
1792{
1793 return SpinlockCheckLock(&DbgState->Lock);
1794}
volatile LONG Lock
Definition State.h:165

◆ KdCheckUserModePriorityBuffers()

VOID KdCheckUserModePriorityBuffers ( )

Check the user-mode priority buffer.

Returns
VOID
772{
773 //
774 // Check if the priority buffer is full or not
775 //
777 {
778 LogWarning("Warning, the user-mode priority buffers are full, thus the new action replaces "
779 "previously unserviced actions. As the result, some functionalities might not work correctly!\n"
780 "For more information please visit: https://docs.hyperdbg.org/tips-and-tricks/misc/instant-events\n");
781 }
782}
IMPORT_EXPORT_HYPERLOG BOOLEAN LogCallbackCheckIfBufferIsFull(BOOLEAN Priority)
Checks whether the priority or regular buffer is full or not.
Definition Logging.c:262
#define LogWarning(format,...)
Log in the case of warning.
Definition HyperDbgHyperLogIntrinsics.h:99

◆ KdCloseConnectionAndUnloadDebuggee()

VOID KdCloseConnectionAndUnloadDebuggee ( )

Notify user-mode to unload the debuggee and close the connections.

Returns
VOID
791{
792 //
793 // Check if the priority buffer is full or not
794 //
796
797 //
798 // Send one byte buffer and operation codes
799 //
801 "$",
802 sizeof(CHAR),
803 TRUE);
804}
VOID KdCheckUserModePriorityBuffers()
Check the user-mode priority buffer.
Definition Kd.c:771
char CHAR
Definition BasicTypes.h:33
#define OPERATION_COMMAND_FROM_DEBUGGER_CLOSE_AND_UNLOAD_VMM
Definition Constants.h:381
IMPORT_EXPORT_HYPERLOG BOOLEAN LogCallbackSendBuffer(_In_ UINT32 OperationCode, _In_reads_bytes_(BufferLength) PVOID Buffer, _In_ UINT32 BufferLength, _In_ BOOLEAN Priority)
routines callback for sending buffer
Definition HyperLogCallback.c:123

◆ KdComputeDataChecksum()

_Use_decl_annotations_ BYTE KdComputeDataChecksum ( PVOID Buffer,
UINT32 Length )

calculate the checksum of received buffer from debugger

Parameters
Buffer
LengthReceived
Returns
BYTE
276{
277 BYTE CalculatedCheckSum = 0;
278 BYTE Temp = 0;
279 while (Length--)
280 {
281 Temp = *(BYTE *)Buffer;
282 CalculatedCheckSum = CalculatedCheckSum + Temp;
283 Buffer = (PVOID)((UINT64)Buffer + 1);
284 }
285 return CalculatedCheckSum;
286}
void * PVOID
Definition BasicTypes.h:56
unsigned char BYTE
Definition BasicTypes.h:40

◆ KdContinueDebuggee()

_Use_decl_annotations_ VOID KdContinueDebuggee ( PROCESSOR_DEBUGGING_STATE * DbgState,
BOOLEAN PauseBreaksUntilSpecialMessageSent,
DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION SpeialEventResponse )

continue the debuggee, this function guarantees that all other cores are continued (except current core)

Parameters
DbgStateThe state of the debugger on the current core
SpeialEventResponse
PauseBreaksUntilSpecialMessageSent
Returns
VOID
647{
648 if (PauseBreaksUntilSpecialMessageSent)
649 {
650 g_IgnoreBreaksToDebugger.PauseBreaksUntilSpecialMessageSent = TRUE;
651 g_IgnoreBreaksToDebugger.SpeialEventResponse = SpeialEventResponse;
652 }
653
654 //
655 // Check if we should enable interrupts in this core or not,
656 // we have another same check in SWITCHING CORES too
657 //
659
660 //
661 // Unlock all the cores
662 //
663 ULONG ProcessorsCount = KeQueryActiveProcessorCount(0);
664 for (SIZE_T i = 0; i < ProcessorsCount; i++)
665 {
666 SpinlockUnlock(&g_DbgState[i].Lock);
667 }
668}
VOID SpinlockUnlock(volatile LONG *Lock)
Release the lock.
Definition Spinlock.c:162
IMPORT_EXPORT_VMM VOID VmFuncCheckAndEnableExternalInterrupts(UINT32 CoreId)
Check and enable external interrupts.
Definition Export.c:755
DEBUGGEE_REQUEST_TO_IGNORE_BREAKS_UNTIL_AN_EVENT g_IgnoreBreaksToDebugger
Holds the requests to pause the break of debuggee until a special event happens.
Definition Global.h:97

◆ KdContinueDebuggeeJustCurrentCore()

VOID KdContinueDebuggeeJustCurrentCore ( PROCESSOR_DEBUGGING_STATE * DbgState)

continue the debuggee, just the current operating core

Parameters
DbgStateThe state of the debugger on the current core
Returns
VOID
678{
679 //
680 // In the case of any halting event, the processor won't send NMIs
681 // to other cores if this field is set
682 //
684
685 //
686 // Unlock the current core
687 //
688 SpinlockUnlock(&DbgState->Lock);
689}
BOOLEAN DoNotNmiNotifyOtherCoresByThisCore
Definition State.h:173

◆ KdCustomDebuggerBreakSpinlockLock()

VOID KdCustomDebuggerBreakSpinlockLock ( PROCESSOR_DEBUGGING_STATE * DbgState,
volatile LONG * Lock )

Tries to get the lock and won't return until successfully get the lock.

Parameters
DbgStateThe state of the debugger on the current core
LockThe lock variable
Returns
VOID
957{
958 UINT32 Wait = 1;
959
960 //
961 // *** Lock handling breaks ***
962 //
963
964 while (!SpinlockTryLock(Lock))
965 {
966 for (UINT32 i = 0; i < Wait; ++i)
967 {
968 CpuPause();
969 }
970
971 //
972 // check if the core needs to be locked
973 //
974 if (DbgState->NmiState.WaitingToBeLocked)
975 {
976 //
977 // We should ignore one MTF as we touched MTF and it's not usable anymore
978 //
980
981 //
982 // Handle break of the core
983 //
985 {
986 //
987 // Handle it like an NMI is received from VMX root
988 //
990 }
991 else
992 {
993 //
994 // Handle halt of the current core as an NMI
995 //
996 KdHandleNmi(DbgState);
997 }
998 }
999
1000 //
1001 // Don't call "pause" too many times. If the wait becomes too big,
1002 // clamp it to the MaxWait.
1003 //
1004
1005 if (Wait * 2 > 65536)
1006 {
1007 Wait = 65536;
1008 }
1009 else
1010 {
1011 Wait = Wait * 2;
1012 }
1013 }
1014}
VOID CpuPause(VOID)
Execute PAUSE (spin-wait hint).
Definition PlatformIntrinsics.c:523
BOOLEAN SpinlockTryLock(volatile LONG *Lock)
Tries to get the lock otherwise returns.
Definition Spinlock.c:41
unsigned int UINT32
Definition BasicTypes.h:54
IMPORT_EXPORT_VMM VOID VmFuncChangeIgnoreOneMtfState(UINT32 CoreId, BOOLEAN Set)
Change ignore one MTF state.
Definition Export.c:60

◆ KdDispatchAndPerformCommandsFromDebugger()

VOID KdDispatchAndPerformCommandsFromDebugger ( PROCESSOR_DEBUGGING_STATE * DbgState)

This function applies commands from the debugger to the debuggee.

when we reach here, we are on the first core

Parameters
DbgStateThe state of the debugger on the current core
Returns
VOID
2259{
2260 PDEBUGGEE_CHANGE_CORE_PACKET ChangeCorePacket;
2261 PDEBUGGEE_STEP_PACKET SteppingPacket;
2263 PDEBUGGER_CALLSTACK_REQUEST CallstackPacket;
2264 PDEBUGGER_SINGLE_CALLSTACK_FRAME CallstackFrameBuffer;
2266 PDEBUGGEE_REGISTER_READ_DESCRIPTION ReadRegisterPacket;
2267 PDEBUGGEE_REGISTER_WRITE_DESCRIPTION WriteRegisterPacket;
2268 PDEBUGGER_READ_MEMORY ReadMemoryPacket;
2269 PDEBUGGER_EDIT_MEMORY EditMemoryPacket;
2272 PDEBUGGEE_SCRIPT_PACKET ScriptPacket;
2273 PDEBUGGEE_USER_INPUT_PACKET UserInputPacket;
2274 PDEBUGGER_SEARCH_MEMORY SearchQueryPacket;
2275 PDEBUGGEE_BP_PACKET BpPacket;
2277 PSMI_OPERATION_PACKETS SmiOperationPacket;
2278 PHYPERTRACE_LBR_DUMP_PACKETS HyperTraceLbrdumpPacket;
2279 PHYPERTRACE_PT_OPERATION_PACKETS HyperTracePtOperationPacket;
2280 PDEBUGGER_APIC_REQUEST ApicPacket;
2282 PDEBUGGER_PAGE_IN_REQUEST PageinPacket;
2283 PDEBUGGER_VA2PA_AND_PA2VA_COMMANDS Va2paPa2vaPacket;
2284 PDEBUGGEE_BP_LIST_OR_MODIFY_PACKET BpListOrModifyPacket;
2285 PDEBUGGEE_SYMBOL_REQUEST_PACKET SymReloadPacket;
2288 PDEBUGGER_MODIFY_EVENTS QueryAndModifyEventPacket;
2289 PDEBUGGER_SHORT_CIRCUITING_EVENT ShortCircuitingEventPacket;
2290 UINT32 SizeToSend = 0;
2291 BOOLEAN UnlockTheNewCore = FALSE;
2292 UINT32 ReturnSize = 0;
2293 DEBUGGEE_RESULT_OF_SEARCH_PACKET SearchPacketResult = {0};
2294 DEBUGGER_EVENT_AND_ACTION_RESULT DebuggerEventAndActionResult = {0};
2296 PDEBUGGEE_PCIDEVINFO_REQUEST_RESPONSE_PACKET PcidevinfoPacket = {0};
2297
2298 while (TRUE)
2299 {
2300 BOOLEAN EscapeFromTheLoop = FALSE;
2301 CHAR * RecvBuffer = &DbgState->KdRecvBuffer[0];
2302 UINT32 RecvBufferLength = 0;
2303 PDEBUGGER_REMOTE_PACKET TheActualPacket = (PDEBUGGER_REMOTE_PACKET)RecvBuffer;
2304
2305 //
2306 // Zero the receiving buffer
2307 //
2308 RtlZeroMemory(RecvBuffer, MaxSerialPacketSize);
2309
2310 //
2311 // Receive the buffer in polling mode
2312 //
2313 if (!SerialConnectionRecvBuffer(RecvBuffer, &RecvBufferLength))
2314 {
2315 //
2316 // Invalid buffer
2317 //
2318 continue;
2319 }
2320
2321 if (TheActualPacket->Indicator == INDICATOR_OF_HYPERDBG_PACKET)
2322 {
2323 //
2324 // Check checksum
2325 //
2326 if (KdComputeDataChecksum((PVOID)&TheActualPacket->Indicator,
2327 RecvBufferLength - sizeof(BYTE)) != TheActualPacket->Checksum)
2328 {
2329 LogError("Err, checksum is invalid");
2330 continue;
2331 }
2332
2333 //
2334 // Check if the packet type is correct
2335 //
2337 {
2338 //
2339 // sth wrong happened, the packet is not belonging to use
2340 // nothing to do, just wait again
2341 //
2342 LogError("Err, unknown packet received from the debugger\n");
2343 continue;
2344 }
2345
2346 //
2347 // It's a HyperDbg packet
2348 //
2349 switch (TheActualPacket->RequestedActionOfThePacket)
2350 {
2352
2353 //
2354 // Unlock other cores
2355 //
2357
2358 //
2359 // No need to wait for new commands
2360 //
2361 EscapeFromTheLoop = TRUE;
2362
2363 break;
2364
2366
2367 SteppingPacket = (DEBUGGEE_STEP_PACKET *)(((CHAR *)TheActualPacket) + sizeof(DEBUGGER_REMOTE_PACKET));
2368
2369 switch (SteppingPacket->StepType)
2370 {
2373
2374 //
2375 // Guaranteed step in (i command) or used for tracking (creating call tree)
2376 //
2377
2378 //
2379 // Indicate a step
2380 //
2382
2383 //
2384 // Unlock just on core
2385 //
2387
2389 {
2390 DbgState->IgnoreDisasmInNextPacket = TRUE;
2391 }
2392
2393 //
2394 // No need to wait for new commands
2395 //
2396 EscapeFromTheLoop = TRUE;
2397
2398 break;
2399
2403
2404 //
2405 // Step-over (p command)
2406 //
2408 VmFuncGetLastVmexitRip(DbgState->CoreId),
2409 SteppingPacket->IsCurrentInstructionACall,
2410 SteppingPacket->CallLength);
2411
2412 //
2413 // Unlock other cores
2414 //
2416
2418 {
2419 DbgState->IgnoreDisasmInNextPacket = TRUE;
2420 }
2421
2422 //
2423 // Continue to the debuggee
2424 //
2425 EscapeFromTheLoop = TRUE;
2426
2427 break;
2428
2430
2431 //
2432 // Step in (t command)
2433 //
2434
2435 //
2436 // Indicate a step-in
2437 //
2439
2440 //
2441 // Unlock other cores
2442 //
2444
2445 //
2446 // Continue to the debuggee
2447 //
2448 EscapeFromTheLoop = TRUE;
2449
2450 break;
2451
2452 default:
2453 break;
2454 }
2455
2456 break;
2457
2459
2460 //
2461 // Send the close buffer
2462 //
2464
2465 //
2466 // Unlock other cores
2467 //
2469
2470 //
2471 // No need to wait for new commands
2472 //
2473 EscapeFromTheLoop = TRUE;
2474
2475 break;
2476
2478
2479 ChangeCorePacket = (DEBUGGEE_CHANGE_CORE_PACKET *)(((CHAR *)TheActualPacket) + sizeof(DEBUGGER_REMOTE_PACKET));
2480
2481 //
2482 // Switch to new core
2483 //
2484 if (KdSwitchCore(DbgState, ChangeCorePacket))
2485 {
2486 //
2487 // No need to wait for new commands
2488 //
2489 EscapeFromTheLoop = TRUE;
2490
2491 //
2492 // Unlock the new core
2493 //
2494 UnlockTheNewCore = TRUE;
2495 }
2496
2497 //
2498 // Send the result of switching core back to the debuggee
2499 //
2502 (CHAR *)ChangeCorePacket,
2504
2505 //
2506 // Because we don't want two cores to send the same packets simultaneously
2507 //
2508 if (UnlockTheNewCore)
2509 {
2510 UnlockTheNewCore = FALSE;
2511 SpinlockUnlock(&g_DbgState[ChangeCorePacket->NewCore].Lock);
2512 }
2513
2514 break;
2515
2517
2518 FlushPacket = (DEBUGGER_FLUSH_LOGGING_BUFFERS *)(((CHAR *)TheActualPacket) + sizeof(DEBUGGER_REMOTE_PACKET));
2519
2520 //
2521 // Flush the buffers
2522 //
2523 DebuggerCommandFlush(FlushPacket);
2524
2525 //
2526 // Send the result of flushing back to the debuggee
2527 //
2530 (CHAR *)FlushPacket,
2532
2533 break;
2534
2536
2537 CallstackPacket = (DEBUGGER_CALLSTACK_REQUEST *)(((CHAR *)TheActualPacket) + sizeof(DEBUGGER_REMOTE_PACKET));
2538
2539 CallstackFrameBuffer = (DEBUGGER_SINGLE_CALLSTACK_FRAME *)(((CHAR *)TheActualPacket) + sizeof(DEBUGGER_REMOTE_PACKET) + sizeof(DEBUGGER_CALLSTACK_REQUEST));
2540
2541 //
2542 // If the address is null, we use the current RSP register
2543 //
2544 if (CallstackPacket->BaseAddress == (UINT64)NULL)
2545 {
2546 CallstackPacket->BaseAddress = DbgState->Regs->rsp;
2547 }
2548
2549 //
2550 // Feel the callstack frames the buffers
2551 //
2552 if (CallstackWalkthroughStack(CallstackFrameBuffer,
2553 &CallstackPacket->FrameCount,
2554 CallstackPacket->BaseAddress,
2555 CallstackPacket->Size,
2556 CallstackPacket->Is32Bit))
2557 {
2559 }
2560 else
2561 {
2563 }
2564
2565 //
2566 // Send the result of flushing back to the debuggee
2567 //
2570 (CHAR *)CallstackPacket,
2571 (UINT32)CallstackPacket->BufferSize);
2572
2573 break;
2574
2576
2577 TestQueryPacket = (DEBUGGER_DEBUGGER_TEST_QUERY_BUFFER *)(((CHAR *)TheActualPacket) + sizeof(DEBUGGER_REMOTE_PACKET));
2578
2579 //
2580 // Perform the test packet operation
2581 //
2582 KdPerformTheTestPacketOperation(DbgState, TestQueryPacket);
2583
2584 //
2585 // Send the result of query system state to the debuggee
2586 //
2589 (CHAR *)TestQueryPacket,
2591
2592 break;
2593
2595
2596 ReadRegisterPacket = (DEBUGGEE_REGISTER_READ_DESCRIPTION *)(((CHAR *)TheActualPacket) + sizeof(DEBUGGER_REMOTE_PACKET));
2597
2598 //
2599 // Read registers
2600 //
2601 if (DebuggerCommandReadRegisters(DbgState->Regs, ReadRegisterPacket))
2602 {
2603 ReadRegisterPacket->KernelStatus = DEBUGGER_OPERATION_WAS_SUCCESSFUL;
2604 }
2605 else
2606 {
2608 }
2609
2610 if (ReadRegisterPacket->RegisterId == DEBUGGEE_SHOW_ALL_REGISTERS)
2611 {
2612 SizeToSend = sizeof(DEBUGGEE_REGISTER_READ_DESCRIPTION) + sizeof(GUEST_REGS) + sizeof(GUEST_EXTRA_REGISTERS);
2613 }
2614 else
2615 {
2616 SizeToSend = sizeof(DEBUGGEE_REGISTER_READ_DESCRIPTION);
2617 }
2618 //
2619 // Send the result of reading registers back to the debuggee
2620 //
2623 (CHAR *)ReadRegisterPacket,
2624 SizeToSend);
2625
2626 break;
2627
2629
2630 WriteRegisterPacket = (DEBUGGEE_REGISTER_WRITE_DESCRIPTION *)(((CHAR *)TheActualPacket) + sizeof(DEBUGGER_REMOTE_PACKET));
2631
2632 //
2633 // Write register
2634 //
2635 if (SetRegValue(DbgState->Regs, WriteRegisterPacket->RegisterId, WriteRegisterPacket->Value))
2636 {
2637 WriteRegisterPacket->KernelStatus = DEBUGGER_OPERATION_WAS_SUCCESSFUL;
2638 }
2639 else
2640 {
2642 }
2643
2644 //
2645 // Send the result of writing register back to the debuggee
2646 //
2649 (CHAR *)WriteRegisterPacket,
2651
2652 break;
2653
2655
2656 ReadMemoryPacket = (DEBUGGER_READ_MEMORY *)(((CHAR *)TheActualPacket) + sizeof(DEBUGGER_REMOTE_PACKET));
2657
2658 //
2659 // Read memory
2660 //
2661 if (DebuggerCommandReadMemoryVmxRoot(ReadMemoryPacket,
2662 (PVOID)((UINT64)ReadMemoryPacket + sizeof(DEBUGGER_READ_MEMORY)),
2663 &ReturnSize))
2664 {
2666 }
2667 else
2668 {
2669 ReadMemoryPacket->KernelStatus = DEBUGGER_ERROR_INVALID_ADDRESS;
2670 }
2671
2672 ReadMemoryPacket->ReturnLength = ReturnSize;
2673
2674 //
2675 // Send the result of reading memory back to the debuggee
2676 //
2679 (CHAR *)ReadMemoryPacket,
2680 sizeof(DEBUGGER_READ_MEMORY) + ReturnSize);
2681
2682 break;
2683
2685
2686 EditMemoryPacket = (PDEBUGGER_EDIT_MEMORY)(((CHAR *)TheActualPacket) + sizeof(DEBUGGER_REMOTE_PACKET));
2687
2688 //
2689 // Edit memory
2690 //
2691 DebuggerCommandEditMemoryVmxRoot(EditMemoryPacket);
2692
2693 //
2694 // Send the result of reading memory back to the debuggee
2695 //
2698 (CHAR *)EditMemoryPacket,
2699 sizeof(DEBUGGER_EDIT_MEMORY));
2700
2701 break;
2702
2704
2705 ChangeProcessPacket = (DEBUGGEE_DETAILS_AND_SWITCH_PROCESS_PACKET *)(((CHAR *)TheActualPacket) + sizeof(DEBUGGER_REMOTE_PACKET));
2706
2707 //
2708 // Interpret the process packet
2709 //
2710 ProcessInterpretProcess(DbgState, ChangeProcessPacket);
2711
2712 //
2713 // Send the result of switching process back to the debuggee
2714 //
2717 (CHAR *)ChangeProcessPacket,
2719
2720 break;
2721
2723
2724 ChangeThreadPacket = (DEBUGGEE_DETAILS_AND_SWITCH_THREAD_PACKET *)(((CHAR *)TheActualPacket) + sizeof(DEBUGGER_REMOTE_PACKET));
2725
2726 //
2727 // Interpret the thread packet
2728 //
2729 ThreadInterpretThread(DbgState, ChangeThreadPacket);
2730
2731 //
2732 // Send the result of switching thread back to the debuggee
2733 //
2736 (CHAR *)ChangeThreadPacket,
2738
2739 break;
2740
2742
2743 ScriptPacket = (DEBUGGEE_SCRIPT_PACKET *)(((CHAR *)TheActualPacket) + sizeof(DEBUGGER_REMOTE_PACKET));
2744
2745 //
2746 // Run the script in debuggee
2747 //
2748 if (DebuggerPerformRunScript(DbgState,
2749 NULL,
2750 ScriptPacket,
2752 {
2753 //
2754 // Set status
2755 //
2757 }
2758 else
2759 {
2760 //
2761 // Set status
2762 //
2764 }
2765
2766 //
2767 // Send the result of running script back to the debuggee
2768 //
2771 (CHAR *)ScriptPacket,
2772 sizeof(DEBUGGEE_SCRIPT_PACKET));
2773
2774 break;
2775
2777
2778 UserInputPacket = (DEBUGGEE_USER_INPUT_PACKET *)(((CHAR *)TheActualPacket) + sizeof(DEBUGGER_REMOTE_PACKET));
2779
2780 //
2781 // Send the user-input to user-mode debuggee
2782 //
2784 sizeof(DEBUGGEE_USER_INPUT_PACKET) + UserInputPacket->CommandLen);
2785
2786 //
2787 // Continue Debuggee
2788 //
2790 EscapeFromTheLoop = TRUE;
2791
2792 break;
2793
2795
2796 SearchQueryPacket = (DEBUGGER_SEARCH_MEMORY *)(((CHAR *)TheActualPacket) + sizeof(DEBUGGER_REMOTE_PACKET));
2797
2798 //
2799 // Perform the search in debuggee debuggee
2800 // Call the search wrapper
2801 //
2802
2803 if (SearchAddressWrapper(NULL,
2804 SearchQueryPacket,
2805 SearchQueryPacket->Address,
2806 SearchQueryPacket->Address + SearchQueryPacket->Length,
2807 TRUE,
2808 &SearchPacketResult.CountOfResults))
2809 {
2810 //
2811 // The search was successful
2812 //
2813 SearchPacketResult.Result = DEBUGGER_OPERATION_WAS_SUCCESSFUL;
2814 }
2815 else
2816 {
2817 //
2818 // There was an error, probably the address was not valid
2819 //
2820 SearchPacketResult.Result = DEBUGGER_ERROR_INVALID_ADDRESS;
2821 }
2822
2823 //
2824 // Send the result of the 's*' back to the debuggee
2825 //
2828 (CHAR *)&SearchPacketResult,
2830
2831 break;
2832
2834
2835 EventRegPacket = (DEBUGGEE_EVENT_AND_ACTION_HEADER_FOR_REMOTE_PACKET *)(((CHAR *)TheActualPacket) + sizeof(DEBUGGER_REMOTE_PACKET));
2836
2837 //
2838 // Parsing the event either in the VMX-root mode or pass it to the user-mode
2839 //
2840 if (KdPerformRegisterEvent(EventRegPacket, &DebuggerEventAndActionResult))
2841 {
2842 //
2843 // Continue Debuggee (Send the event buffer to user-mode debuggee)
2844 //
2846 EscapeFromTheLoop = TRUE;
2847 }
2848 else
2849 {
2850 //
2851 // Send the response of event registration to the debugger
2852 //
2855 (CHAR *)&DebuggerEventAndActionResult,
2857 }
2858
2859 break;
2860
2862
2863 AddActionPacket = (DEBUGGEE_EVENT_AND_ACTION_HEADER_FOR_REMOTE_PACKET *)(((CHAR *)TheActualPacket) + sizeof(DEBUGGER_REMOTE_PACKET));
2864
2865 //
2866 // Parsing the action either in the VMX-root mode or pass it to the user-mode
2867 //
2868 if (KdPerformAddActionToEvent(AddActionPacket, &DebuggerEventAndActionResult))
2869 {
2870 //
2871 // Continue Debuggee (Send the action buffer to user-mode debuggee)
2872 //
2874 EscapeFromTheLoop = TRUE;
2875 }
2876 else
2877 {
2878 //
2879 // Send the response of event registration to the debugger
2880 //
2883 (CHAR *)&DebuggerEventAndActionResult,
2885 }
2886
2887 break;
2888
2890
2891 QueryAndModifyEventPacket = (DEBUGGER_MODIFY_EVENTS *)(((CHAR *)TheActualPacket) + sizeof(DEBUGGER_REMOTE_PACKET));
2892
2893 //
2894 // Perform the action and check if we should continue the debuggee or not
2895 //
2896 if (KdPerformEventQueryAndModification(QueryAndModifyEventPacket))
2897 {
2898 //
2899 // Continue Debuggee
2900 //
2902 EscapeFromTheLoop = TRUE;
2903 }
2904 else
2905 {
2906 //
2907 // Send the response of event query and modification (anything other than clear)
2908 //
2911 (CHAR *)QueryAndModifyEventPacket,
2912 sizeof(DEBUGGER_MODIFY_EVENTS));
2913 }
2914
2915 break;
2916
2918
2919 ShortCircuitingEventPacket = (DEBUGGER_SHORT_CIRCUITING_EVENT *)(((CHAR *)TheActualPacket) + sizeof(DEBUGGER_REMOTE_PACKET));
2920
2921 //
2922 // Perform the action
2923 //
2924 KdPerformSettingTheStateOfShortCircuiting(DbgState, ShortCircuitingEventPacket);
2925
2926 //
2927 // Send the response of short-circuiting event
2928 //
2931 (CHAR *)ShortCircuitingEventPacket,
2933
2934 break;
2935
2937
2938 BpPacket = (DEBUGGEE_BP_PACKET *)(((CHAR *)TheActualPacket) + sizeof(DEBUGGER_REMOTE_PACKET));
2939
2940 //
2941 // Perform the action
2942 // This is on the vmx-root mode for the kernel debugger, thus, no need to switch
2943 // to the target process memory layout as we are already in it
2944 //
2945 BreakpointAddNew(BpPacket, FALSE);
2946
2947 //
2948 // Send the result of the 'bp' back to the debuggee
2949 //
2952 (CHAR *)BpPacket,
2953 sizeof(DEBUGGEE_BP_PACKET));
2954
2955 break;
2956
2958
2959 PtePacket = (DEBUGGER_READ_PAGE_TABLE_ENTRIES_DETAILS *)(((CHAR *)TheActualPacket) + sizeof(DEBUGGER_REMOTE_PACKET));
2960
2961 //
2962 // Get the page table details (it's in vmx-root)
2963 //
2964 ExtensionCommandPte(PtePacket, TRUE);
2965
2966 //
2967 // Send the result of the '!pte' back to the debuggee
2968 //
2971 (CHAR *)PtePacket,
2973
2974 break;
2975
2977
2978 SmiOperationPacket = (SMI_OPERATION_PACKETS *)(((CHAR *)TheActualPacket) + sizeof(DEBUGGER_REMOTE_PACKET));
2979
2980 //
2981 // Perform the SMI operations (it's in vmx-root)
2982 //
2983 VmFuncSmmPerformSmiOperation(SmiOperationPacket, TRUE);
2984
2985 //
2986 // Send the result of the '!smi' back to the debuggee
2987 //
2990 (CHAR *)SmiOperationPacket,
2992
2993 break;
2994
2996
2997 HyperTraceLbrdumpPacket = (HYPERTRACE_LBR_DUMP_PACKETS *)(((CHAR *)TheActualPacket) + sizeof(DEBUGGER_REMOTE_PACKET));
2998
2999 //
3000 // Perform the HyperTrace LBR dump (it's in vmx-root)
3001 //
3002 HyperTraceLbrPerformDump(HyperTraceLbrdumpPacket);
3003
3004 //
3005 // Send the result of the HyperTrace LBR dump back to the debuggee
3006 //
3009 (CHAR *)HyperTraceLbrdumpPacket,
3011
3012 break;
3013
3015
3016 HyperTracePtOperationPacket = (HYPERTRACE_PT_OPERATION_PACKETS *)(((CHAR *)TheActualPacket) + sizeof(DEBUGGER_REMOTE_PACKET));
3017
3018 //
3019 // Perform the HyperTrace PT operations (it's in vmx-root)
3020 //
3021 HyperTracePtPerformOperation(HyperTracePtOperationPacket);
3022
3023 //
3024 // Send the result of the HyperTrace PT back to the debuggee
3025 //
3028 (CHAR *)HyperTracePtOperationPacket,
3030
3031 break;
3032
3034
3035 ApicPacket = (DEBUGGER_APIC_REQUEST *)(((CHAR *)TheActualPacket) + sizeof(DEBUGGER_REMOTE_PACKET));
3036
3037 //
3038 // Call APIC handler (size to send is computed by this function)
3039 //
3040 SizeToSend = ExtensionCommandPerformActionsForApicRequests(ApicPacket);
3041
3042 //
3043 // Send the result of the APIC requests back to the debuggee
3044 //
3047 (CHAR *)ApicPacket,
3048 SizeToSend);
3049
3050 break;
3051
3053
3054 IdtEntryPacket = (INTERRUPT_DESCRIPTOR_TABLE_ENTRIES_PACKETS *)(((CHAR *)TheActualPacket) + sizeof(DEBUGGER_REMOTE_PACKET));
3055
3056 //
3057 // Call IDT query handler (read from VMX root-mode)
3058 //
3060
3061 //
3062 // Send the result of the IDT entries requests to the debuggee
3063 //
3066 (CHAR *)IdtEntryPacket,
3068
3069 break;
3070
3072
3073 PageinPacket = (DEBUGGER_PAGE_IN_REQUEST *)(((CHAR *)TheActualPacket) + sizeof(DEBUGGER_REMOTE_PACKET));
3074
3075 //
3076 // Perform bringing the pages in (it's in vmx-root)
3077 //
3078 KdBringPagein(DbgState, PageinPacket);
3079
3080 //
3081 // Send the result of the '.pagein' back to the debuggee
3082 //
3085 (CHAR *)PageinPacket,
3086 sizeof(DEBUGGER_PAGE_IN_REQUEST));
3087
3088 break;
3089
3091
3092 Va2paPa2vaPacket = (DEBUGGER_VA2PA_AND_PA2VA_COMMANDS *)(((CHAR *)TheActualPacket) + sizeof(DEBUGGER_REMOTE_PACKET));
3093
3094 //
3095 // Perform the virtual to physical or physical to virtual address
3096 // conversion (it's on vmx-root mode)
3097 //
3098 ExtensionCommandVa2paAndPa2va(Va2paPa2vaPacket, TRUE);
3099
3100 //
3101 // Send the result of the '!va2pa' or '!pa2va' back to the debuggee
3102 //
3105 (CHAR *)Va2paPa2vaPacket,
3107
3108 break;
3109
3111
3112 BpListOrModifyPacket = (DEBUGGEE_BP_LIST_OR_MODIFY_PACKET *)(((CHAR *)TheActualPacket) + sizeof(DEBUGGER_REMOTE_PACKET));
3113
3114 //
3115 // Perform the action
3116 // No need to switch to the target process memory layout as we are already in it
3117 //
3118 BreakpointListOrModify(BpListOrModifyPacket, FALSE);
3119
3120 //
3121 // Send the result of modify or list breakpoints to the debuggee
3122 //
3125 (CHAR *)BpListOrModifyPacket,
3127
3128 break;
3129
3131
3132 SymReloadPacket = (DEBUGGEE_SYMBOL_REQUEST_PACKET *)(((CHAR *)TheActualPacket) + sizeof(DEBUGGER_REMOTE_PACKET));
3133
3134 //
3135 // Send the reload symbol request buffer
3136 //
3137 KdReloadSymbolDetailsInDebuggee(SymReloadPacket);
3138
3139 //
3140 // Unlock other cores
3141 //
3143
3144 //
3145 // No need to wait for new commands
3146 //
3147 EscapeFromTheLoop = TRUE;
3148
3149 break;
3150
3152
3153 PcitreePacket = (DEBUGGEE_PCITREE_REQUEST_RESPONSE_PACKET *)(((CHAR *)TheActualPacket) + sizeof(DEBUGGER_REMOTE_PACKET));
3154
3155 //
3156 // Enumerate PCI tree
3157 //
3158 ExtensionCommandPcitree(PcitreePacket, TRUE);
3159
3160 //
3161 // Send the result of '!pcitree' back to the debugger
3162 //
3165 (CHAR *)PcitreePacket,
3167
3168 break;
3169
3171
3172 PcidevinfoPacket = (DEBUGGEE_PCIDEVINFO_REQUEST_RESPONSE_PACKET *)(((CHAR *)TheActualPacket) + sizeof(DEBUGGER_REMOTE_PACKET));
3173
3174 //
3175 // Retrieve PCI device info (CAM)
3176 //
3177 ExtensionCommandPcidevinfo(PcidevinfoPacket, TRUE);
3178
3179 //
3180 // Send the result back to the debugger
3181 //
3184 (CHAR *)PcidevinfoPacket,
3186
3187 break;
3188
3189 default:
3190 LogError("Err, unknown packet action received from the debugger\n");
3191 break;
3192 }
3193 }
3194 else
3195 {
3196 //
3197 // It's not a HyperDbg packet, the packet is probably deformed
3198 //
3199 LogError("Err, it's not a HyperDbg packet, the packet is probably deformed\n");
3200 continue;
3201 }
3202
3203 //
3204 // If we have to leave the loop, we apply it here
3205 //
3206 if (EscapeFromTheLoop)
3207 {
3208 break;
3209 }
3210 }
3211}
BOOLEAN BreakpointAddNew(PDEBUGGEE_BP_PACKET BpDescriptorArg, BOOLEAN SwitchToTargetMemoryLayout)
Add new breakpoints.
Definition BreakpointCommands.c:950
BOOLEAN BreakpointListOrModify(PDEBUGGEE_BP_LIST_OR_MODIFY_PACKET ListOrModifyBreakpoints, BOOLEAN SwitchToTargetMemoryLayout)
List of modify breakpoints.
Definition BreakpointCommands.c:1196
BOOLEAN CallstackWalkthroughStack(PDEBUGGER_SINGLE_CALLSTACK_FRAME AddressToSaveFrames, UINT32 *FrameCount, UINT64 StackBaseAddress, UINT32 Size, BOOLEAN Is32Bit)
Walkthrough the stack.
Definition Callstack.c:26
BOOLEAN DebuggerPerformRunScript(PROCESSOR_DEBUGGING_STATE *DbgState, DEBUGGER_EVENT_ACTION *Action, DEBUGGEE_SCRIPT_PACKET *ScriptDetails, DEBUGGER_TRIGGERED_EVENT_DETAILS *EventTriggerDetail)
Managing run script action.
Definition Debugger.c:1662
BOOLEAN DebuggerCommandEditMemoryVmxRoot(PDEBUGGER_EDIT_MEMORY EditMemRequest)
Edit physical and virtual memory on vmxroot mode.
Definition DebuggerCommands.c:612
BOOLEAN DebuggerCommandReadRegisters(GUEST_REGS *Regs, PDEBUGGEE_REGISTER_READ_DESCRIPTION ReadRegisterRequest)
read registers
Definition DebuggerCommands.c:23
BOOLEAN DebuggerCommandReadMemoryVmxRoot(PDEBUGGER_READ_MEMORY ReadMemRequest, UCHAR *UserBuffer, UINT32 *ReturnSize)
Read memory for different commands from vmxroot mode.
Definition DebuggerCommands.c:186
BOOLEAN SearchAddressWrapper(PUINT64 AddressToSaveResults, PDEBUGGER_SEARCH_MEMORY SearchMemRequest, UINT64 StartAddress, UINT64 EndAddress, BOOLEAN IsDebuggeePaused, PUINT32 CountOfMatchedCases)
The wrapper to check for validity of addresses and call the search routines for both physical and vir...
Definition DebuggerCommands.c:1019
NTSTATUS DebuggerCommandFlush(PDEBUGGER_FLUSH_LOGGING_BUFFERS DebuggerFlushBuffersRequest)
Perform the flush requests to vmx-root and vmx non-root buffers.
Definition DebuggerCommands.c:1292
VOID ExtensionCommandPerformQueryIdtEntriesRequest(PINTERRUPT_DESCRIPTOR_TABLE_ENTRIES_PACKETS IdtQueryRequest, BOOLEAN ReadFromVmxRoot)
Perform query for IDT entries.
Definition ExtensionCommands.c:92
VOID ExtensionCommandVa2paAndPa2va(PDEBUGGER_VA2PA_AND_PA2VA_COMMANDS AddressDetails, BOOLEAN OperateOnVmxRoot)
routines for !va2pa and !pa2va commands
Definition ExtensionCommands.c:114
VOID ExtensionCommandPcidevinfo(PDEBUGGEE_PCIDEVINFO_REQUEST_RESPONSE_PACKET PcidevinfoPacket, BOOLEAN OperateOnVmxRoot)
Request PCI device info.
Definition ExtensionCommands.c:760
UINT32 ExtensionCommandPerformActionsForApicRequests(PDEBUGGER_APIC_REQUEST ApicRequest)
Perform actions regarding APIC.
Definition ExtensionCommands.c:23
BOOLEAN ExtensionCommandPte(PDEBUGGER_READ_PAGE_TABLE_ENTRIES_DETAILS PteDetails, BOOLEAN IsOperatingInVmxRoot)
routines for !pte command
Definition ExtensionCommands.c:261
VOID ExtensionCommandPcitree(PDEBUGGEE_PCITREE_REQUEST_RESPONSE_PACKET PcitreePacket, BOOLEAN OperateOnVmxRoot)
routines for PCIe tree
Definition ExtensionCommands.c:697
VOID KdRegularStepOver(UINT64 LastRip, BOOLEAN IsNextInstructionACall, UINT32 CallLength)
Regular step-over, step one instruction to the debuggee if there is a call then it jumps the call.
Definition Kd.c:433
VOID KdContinueDebuggeeJustCurrentCore(PROCESSOR_DEBUGGING_STATE *DbgState)
continue the debuggee, just the current operating core
Definition Kd.c:677
VOID KdPerformTheTestPacketOperation(PROCESSOR_DEBUGGING_STATE *DbgState, DEBUGGER_DEBUGGER_TEST_QUERY_BUFFER *TestQueryPacket)
Perform the test packet's operation.
Definition Kd.c:1853
_Use_decl_annotations_ VOID KdReloadSymbolDetailsInDebuggee(PDEBUGGEE_SYMBOL_REQUEST_PACKET SymPacket)
Notify user-mode to re-send (reload) the symbol packets.
Definition Kd.c:814
VOID KdNotifyDebuggeeForUserInput(DEBUGGEE_USER_INPUT_PACKET *Descriptor, UINT32 Len)
Notify user-mode to about new user-input buffer.
Definition Kd.c:839
BOOLEAN KdBringPagein(PROCESSOR_DEBUGGING_STATE *DbgState, PDEBUGGER_PAGE_IN_REQUEST PageinRequest)
routines to break page-in
Definition Kd.c:1805
VOID KdGuaranteedStepInstruction(PROCESSOR_DEBUGGING_STATE *DbgState)
apply a guaranteed step one instruction to the debuggee
Definition Kd.c:1440
BOOLEAN KdPerformEventQueryAndModification(PDEBUGGER_MODIFY_EVENTS ModifyAndQueryEvent)
Perform modify and query events.
Definition Kd.c:2050
_Use_decl_annotations_ VOID KdContinueDebuggee(PROCESSOR_DEBUGGING_STATE *DbgState, BOOLEAN PauseBreaksUntilSpecialMessageSent, DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION SpeialEventResponse)
continue the debuggee, this function guarantees that all other cores are continued (except current co...
Definition Kd.c:644
_Use_decl_annotations_ BYTE KdComputeDataChecksum(PVOID Buffer, UINT32 Length)
calculate the checksum of received buffer from debugger
Definition Kd.c:275
BOOLEAN KdPerformRegisterEvent(PDEBUGGEE_EVENT_AND_ACTION_HEADER_FOR_REMOTE_PACKET EventDetailHeader, DEBUGGER_EVENT_AND_ACTION_RESULT *DebuggerEventAndActionResult)
Send event registration buffer to user-mode to register the event.
Definition Kd.c:1550
VOID KdCloseConnectionAndUnloadDebuggee()
Notify user-mode to unload the debuggee and close the connections.
Definition Kd.c:790
BOOLEAN KdPerformAddActionToEvent(PDEBUGGEE_EVENT_AND_ACTION_HEADER_FOR_REMOTE_PACKET ActionDetailHeader, DEBUGGER_EVENT_AND_ACTION_RESULT *DebuggerEventAndActionResult)
Send action buffer to user-mode to be added to the event.
Definition Kd.c:1602
VOID KdPerformSettingTheStateOfShortCircuiting(PROCESSOR_DEBUGGING_STATE *DbgState, PDEBUGGER_SHORT_CIRCUITING_EVENT ShortCircuitingEvent)
Perform modify the state of short-circuiting.
Definition Kd.c:2023
BOOLEAN KdSwitchCore(PROCESSOR_DEBUGGING_STATE *DbgState, DEBUGGEE_CHANGE_CORE_PACKET *ChangeCorePacket)
change the current operating core to new core
Definition Kd.c:699
_Use_decl_annotations_ BOOLEAN KdResponsePacketToDebugger(DEBUGGER_REMOTE_PACKET_TYPE PacketType, DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION Response, CHAR *OptionalBuffer, UINT32 OptionalBufferLength)
Sends a HyperDbg response packet to the debugger.
Definition Kd.c:299
BOOLEAN ProcessInterpretProcess(PROCESSOR_DEBUGGING_STATE *DbgState, PDEBUGGEE_DETAILS_AND_SWITCH_PROCESS_PACKET PidRequest)
change the current process @detail ONLY TO BE USED IN KD STUFFS
Definition Process.c:525
BOOLEAN SetRegValue(PGUEST_REGS GuestRegs, UINT32 RegisterId, UINT64 Value)
Set the register value.
Definition Regs.c:1003
BOOLEAN SerialConnectionRecvBuffer(CHAR *BufferToSave, UINT32 *LengthReceived)
Receive packet from the debugger.
Definition SerialConnection.c:99
BOOLEAN ThreadInterpretThread(PROCESSOR_DEBUGGING_STATE *DbgState, PDEBUGGEE_DETAILS_AND_SWITCH_THREAD_PACKET TidRequest)
change the current thread
Definition Thread.c:325
VOID TracingRegularStepInInstruction()
Regular step-in, step one instruction to the debuggee.
Definition Tracing.c:112
struct _DEBUGGER_REMOTE_PACKET * PDEBUGGER_REMOTE_PACKET
@ DEBUGGER_REMOTE_PACKET_TYPE_DEBUGGEE_TO_DEBUGGER
Definition Connection.h:178
@ DEBUGGER_REMOTE_PACKET_TYPE_DEBUGGER_TO_DEBUGGEE_EXECUTE_ON_VMX_ROOT
Definition Connection.h:168
@ DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_DEBUGGEE_RESULT_OF_BP
Definition Connection.h:129
@ DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_ON_VMX_ROOT_REGISTER_EVENT
Definition Connection.h:85
@ DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_DEBUGGEE_RESULT_OF_PTE
Definition Connection.h:135
@ DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_DEBUGGEE_RESULT_TEST_QUERY
Definition Connection.h:121
@ DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_ON_VMX_ROOT_SEARCH_QUERY
Definition Connection.h:84
@ DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_DEBUGGEE_RELOAD_SEARCH_QUERY
Definition Connection.h:134
@ DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_DEBUGGEE_RESULT_OF_PCITREE
Definition Connection.h:139
@ DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_DEBUGGEE_RESULT_OF_SHORT_CIRCUITING_STATE
Definition Connection.h:130
@ DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_NO_ACTION
Definition Connection.h:110
@ DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_ON_VMX_ROOT_READ_IDT_ENTRIES
Definition Connection.h:102
@ DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_ON_VMX_ROOT_QUERY_PCITREE
Definition Connection.h:99
@ DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_ON_VMX_ROOT_LIST_OR_MODIFY_BREAKPOINTS
Definition Connection.h:92
@ DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_ON_VMX_ROOT_INJECT_PAGE_FAULT
Definition Connection.h:97
@ DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_DEBUGGEE_RESULT_OF_FLUSH
Definition Connection.h:119
@ DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_ON_VMX_ROOT_EDIT_MEMORY
Definition Connection.h:90
@ DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_DEBUGGEE_RESULT_OF_APIC_REQUESTS
Definition Connection.h:140
@ DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_ON_VMX_ROOT_MODE_CONTINUE
Definition Connection.h:74
@ DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_ON_VMX_ROOT_ADD_ACTION_TO_EVENT
Definition Connection.h:86
@ DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_DEBUGGEE_RESULT_OF_ADDING_ACTION_TO_EVENT
Definition Connection.h:123
@ DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_ON_VMX_ROOT_MODE_CHANGE_CORE
Definition Connection.h:76
@ DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_DEBUGGEE_RESULT_OF_READING_REGISTERS
Definition Connection.h:126
@ DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_ON_VMX_ROOT_MODE_CHANGE_THREAD
Definition Connection.h:81
@ DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_ON_VMX_ROOT_MODE_CHANGE_PROCESS
Definition Connection.h:80
@ DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_ON_VMX_ROOT_READ_REGISTERS
Definition Connection.h:88
@ DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_DEBUGGEE_RESULT_OF_READING_MEMORY
Definition Connection.h:127
@ DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_DEBUGGEE_RESULT_OF_REGISTERING_EVENT
Definition Connection.h:122
@ DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_DEBUGGEE_RESULT_OF_WRITE_REGISTER
Definition Connection.h:138
@ DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_ON_VMX_ROOT_MODE_STEP
Definition Connection.h:73
@ DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_ON_VMX_ROOT_WRITE_REGISTER
Definition Connection.h:98
@ DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_DEBUGGEE_RESULT_OF_VA2PA_AND_PA2VA
Definition Connection.h:136
@ DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_DEBUGGEE_RESULT_OF_QUERY_IDT_ENTRIES_REQUESTS
Definition Connection.h:142
@ DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_ON_VMX_ROOT_SET_SHORT_CIRCUITING_STATE
Definition Connection.h:96
@ DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_ON_VMX_ROOT_MODE_CLOSE_AND_UNLOAD_DEBUGGEE
Definition Connection.h:75
@ DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_DEBUGGEE_RESULT_OF_EDITING_MEMORY
Definition Connection.h:128
@ DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_DEBUGGEE_RESULT_OF_CHANGING_THREAD
Definition Connection.h:116
@ DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_ON_VMX_ROOT_PERFORM_HYPERTRACE_LBR_DUMP
Definition Connection.h:104
@ DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_ON_VMX_ROOT_MODE_CALLSTACK
Definition Connection.h:78
@ DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_DEBUGGEE_RESULT_SMI_OPERATION_REQUESTS
Definition Connection.h:143
@ DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_DEBUGGEE_RESULT_HYPERTRACE_PT_OPERATION_REQUESTS
Definition Connection.h:145
@ DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_DEBUGGEE_RESULT_HYPERTRACE_LBR_DUMP_REQUESTS
Definition Connection.h:144
@ DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_ON_VMX_ROOT_MODE_TEST_QUERY
Definition Connection.h:79
@ DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_ON_VMX_ROOT_PERFORM_SMI_OPERATION
Definition Connection.h:103
@ DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_DEBUGGEE_RESULT_OF_PCIDEVINFO
Definition Connection.h:141
@ DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_ON_VMX_ROOT_QUERY_PA2VA_AND_VA2PA
Definition Connection.h:94
@ DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_ON_VMX_ROOT_PERFORM_HYPERTRACE_PT_OPERATION
Definition Connection.h:105
@ DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_DEBUGGEE_RESULT_OF_RUNNING_SCRIPT
Definition Connection.h:117
@ DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_DEBUGGEE_RESULT_OF_BRINGING_PAGES_IN
Definition Connection.h:137
@ DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_ON_VMX_ROOT_QUERY_PCIDEVINFO
Definition Connection.h:101
@ DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_ON_VMX_ROOT_BP
Definition Connection.h:91
@ DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_ON_VMX_ROOT_PERFORM_ACTIONS_ON_APIC
Definition Connection.h:100
@ DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_ON_VMX_ROOT_READ_MEMORY
Definition Connection.h:89
@ DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_DEBUGGEE_RESULT_OF_QUERY_AND_MODIFY_EVENT
Definition Connection.h:124
@ DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_ON_VMX_ROOT_SYMBOL_QUERY_PTE
Definition Connection.h:95
@ DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_DEBUGGEE_RESULT_OF_CALLSTACK
Definition Connection.h:120
@ DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_ON_VMX_ROOT_QUERY_AND_MODIFY_EVENT
Definition Connection.h:87
@ DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_ON_VMX_ROOT_MODE_FLUSH_BUFFERS
Definition Connection.h:77
@ DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_DEBUGGEE_RESULT_OF_CHANGING_CORE
Definition Connection.h:114
@ DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_DEBUGGEE_RESULT_OF_LIST_OR_MODIFY_BREAKPOINTS
Definition Connection.h:131
@ DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_ON_VMX_ROOT_RUN_SCRIPT
Definition Connection.h:82
@ DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_ON_VMX_ROOT_SYMBOL_RELOAD
Definition Connection.h:93
@ DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_DEBUGGEE_RESULT_OF_CHANGING_PROCESS
Definition Connection.h:115
@ DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_ON_VMX_ROOT_USER_INPUT_BUFFER
Definition Connection.h:83
struct _DEBUGGER_REMOTE_PACKET DEBUGGER_REMOTE_PACKET
The structure of remote packets in HyperDbg.
#define INDICATOR_OF_HYPERDBG_PACKET
constant indicator of a HyperDbg packet
Definition Constants.h:504
#define DEBUGGEE_SHOW_ALL_REGISTERS
for reading all registers in r command.
Definition Constants.h:793
#define MaxSerialPacketSize
size of buffer for serial
Definition Constants.h:202
struct _DEBUGGEE_EVENT_AND_ACTION_HEADER_FOR_REMOTE_PACKET DEBUGGEE_EVENT_AND_ACTION_HEADER_FOR_REMOTE_PACKET
The structure of user-input packet in HyperDbg.
struct _DEBUGGEE_USER_INPUT_PACKET * PDEBUGGEE_USER_INPUT_PACKET
struct _DEBUGGEE_EVENT_AND_ACTION_HEADER_FOR_REMOTE_PACKET * PDEBUGGEE_EVENT_AND_ACTION_HEADER_FOR_REMOTE_PACKET
struct _DEBUGGEE_USER_INPUT_PACKET DEBUGGEE_USER_INPUT_PACKET
The structure of user-input packet in HyperDbg.
#define DEBUGGER_ERROR_INVALID_REGISTER_NUMBER
error, invalid register number
Definition ErrorCodes.h:178
#define DEBUGGER_ERROR_UNABLE_TO_GET_CALLSTACK
error, unable to get the callstack
Definition ErrorCodes.h:380
#define DEBUGGER_ERROR_INVALID_ADDRESS
error, invalid address specified for debugger
Definition ErrorCodes.h:63
#define DEBUGGER_ERROR_PREPARING_DEBUGGEE_TO_RUN_SCRIPT
error, unable to run script in remote debuggee
Definition ErrorCodes.h:172
struct _DEBUGGER_SHORT_CIRCUITING_EVENT * PDEBUGGER_SHORT_CIRCUITING_EVENT
struct _DEBUGGER_MODIFY_EVENTS * PDEBUGGER_MODIFY_EVENTS
struct _DEBUGGER_SHORT_CIRCUITING_EVENT DEBUGGER_SHORT_CIRCUITING_EVENT
request for performing a short-circuiting event
struct _DEBUGGER_MODIFY_EVENTS DEBUGGER_MODIFY_EVENTS
request for modifying events (enable/disable/clear)
struct _DEBUGGER_EVENT_AND_ACTION_RESULT DEBUGGER_EVENT_AND_ACTION_RESULT
Status of register buffers.
struct _DEBUGGEE_STEP_PACKET DEBUGGEE_STEP_PACKET
The structure of stepping packet in HyperDbg.
struct _HYPERTRACE_PT_OPERATION_PACKETS HYPERTRACE_PT_OPERATION_PACKETS
The structure of HyperTrace PT result packet in HyperDbg.
struct _DEBUGGER_READ_PAGE_TABLE_ENTRIES_DETAILS * PDEBUGGER_READ_PAGE_TABLE_ENTRIES_DETAILS
struct _DEBUGGEE_SCRIPT_PACKET * PDEBUGGEE_SCRIPT_PACKET
struct _DEBUGGEE_REGISTER_WRITE_DESCRIPTION * PDEBUGGEE_REGISTER_WRITE_DESCRIPTION
struct _DEBUGGEE_SCRIPT_PACKET DEBUGGEE_SCRIPT_PACKET
The structure of script packet in HyperDbg.
struct _DEBUGGEE_PCIDEVINFO_REQUEST_RESPONSE_PACKET DEBUGGEE_PCIDEVINFO_REQUEST_RESPONSE_PACKET
PCI device info Request-Response Packet, used by !pcicam and future PCI-related commands....
struct _DEBUGGER_APIC_REQUEST * PDEBUGGER_APIC_REQUEST
struct _DEBUGGEE_CHANGE_CORE_PACKET * PDEBUGGEE_CHANGE_CORE_PACKET
struct _HYPERTRACE_PT_OPERATION_PACKETS * PHYPERTRACE_PT_OPERATION_PACKETS
struct _DEBUGGER_SEARCH_MEMORY * PDEBUGGER_SEARCH_MEMORY
struct _DEBUGGEE_RESULT_OF_SEARCH_PACKET DEBUGGEE_RESULT_OF_SEARCH_PACKET
The structure of result of search packet in HyperDbg.
struct _DEBUGGER_CALLSTACK_REQUEST * PDEBUGGER_CALLSTACK_REQUEST
struct _DEBUGGEE_PCITREE_REQUEST_RESPONSE_PACKET * PDEBUGGEE_PCITREE_REQUEST_RESPONSE_PACKET
struct _INTERRUPT_DESCRIPTOR_TABLE_ENTRIES_PACKETS INTERRUPT_DESCRIPTOR_TABLE_ENTRIES_PACKETS
The structure of IDT entries result packet in HyperDbg.
struct _DEBUGGER_PAGE_IN_REQUEST DEBUGGER_PAGE_IN_REQUEST
requests for the '.pagein' command
struct _DEBUGGER_SINGLE_CALLSTACK_FRAME * PDEBUGGER_SINGLE_CALLSTACK_FRAME
struct _DEBUGGEE_REGISTER_READ_DESCRIPTION * PDEBUGGEE_REGISTER_READ_DESCRIPTION
struct _DEBUGGEE_DETAILS_AND_SWITCH_THREAD_PACKET * PDEBUGGEE_DETAILS_AND_SWITCH_THREAD_PACKET
struct _DEBUGGER_FLUSH_LOGGING_BUFFERS DEBUGGER_FLUSH_LOGGING_BUFFERS
request for flushing buffers
struct _DEBUGGEE_BP_LIST_OR_MODIFY_PACKET DEBUGGEE_BP_LIST_OR_MODIFY_PACKET
The structure of breakpoint modification requests packet in HyperDbg.
struct _DEBUGGER_READ_MEMORY DEBUGGER_READ_MEMORY
request for reading virtual and physical memory
struct _DEBUGGEE_BP_PACKET * PDEBUGGEE_BP_PACKET
struct _SMI_OPERATION_PACKETS * PSMI_OPERATION_PACKETS
struct _DEBUGGEE_REGISTER_WRITE_DESCRIPTION DEBUGGEE_REGISTER_WRITE_DESCRIPTION
Register Descriptor Structure to write on registers.
struct _DEBUGGER_CALLSTACK_REQUEST DEBUGGER_CALLSTACK_REQUEST
request for callstack frames
struct _DEBUGGEE_PCIDEVINFO_REQUEST_RESPONSE_PACKET * PDEBUGGEE_PCIDEVINFO_REQUEST_RESPONSE_PACKET
struct _DEBUGGEE_DETAILS_AND_SWITCH_PROCESS_PACKET DEBUGGEE_DETAILS_AND_SWITCH_PROCESS_PACKET
The structure of changing process and show process packet in HyperDbg.
struct _DEBUGGER_PAGE_IN_REQUEST * PDEBUGGER_PAGE_IN_REQUEST
@ DEBUGGER_REMOTE_STEPPING_REQUEST_INSTRUMENTATION_STEP_IN
Definition RequestStructures.h:1047
@ DEBUGGER_REMOTE_STEPPING_REQUEST_INSTRUMENTATION_STEP_IN_FOR_TRACKING
Definition RequestStructures.h:1048
@ DEBUGGER_REMOTE_STEPPING_REQUEST_STEP_IN
Definition RequestStructures.h:1046
@ DEBUGGER_REMOTE_STEPPING_REQUEST_STEP_OVER_FOR_GU
Definition RequestStructures.h:1051
@ DEBUGGER_REMOTE_STEPPING_REQUEST_STEP_OVER
Definition RequestStructures.h:1050
@ DEBUGGER_REMOTE_STEPPING_REQUEST_STEP_OVER_FOR_GU_LAST_INSTRUCTION
Definition RequestStructures.h:1052
struct _DEBUGGEE_SYMBOL_REQUEST_PACKET * PDEBUGGEE_SYMBOL_REQUEST_PACKET
struct _HYPERTRACE_LBR_DUMP_PACKETS HYPERTRACE_LBR_DUMP_PACKETS
The structure of HyperTrace LBR dump result packet in HyperDbg.
#define SIZEOF_HYPERTRACE_PT_OPERATION_PACKETS
Debugger size of HYPERTRACE_PT_OPERATION_PACKETS.
Definition RequestStructures.h:1412
struct _DEBUGGEE_REGISTER_READ_DESCRIPTION DEBUGGEE_REGISTER_READ_DESCRIPTION
Register Descriptor Structure to use in r command.
struct _HYPERTRACE_LBR_DUMP_PACKETS * PHYPERTRACE_LBR_DUMP_PACKETS
struct _DEBUGGEE_BP_PACKET DEBUGGEE_BP_PACKET
The structure of bp command packet in HyperDbg.
struct _SMI_OPERATION_PACKETS SMI_OPERATION_PACKETS
The structure of I/O APIC result packet in HyperDbg.
struct _DEBUGGER_EDIT_MEMORY * PDEBUGGER_EDIT_MEMORY
struct _DEBUGGER_READ_MEMORY * PDEBUGGER_READ_MEMORY
struct _DEBUGGER_EDIT_MEMORY DEBUGGER_EDIT_MEMORY
request for edit virtual and physical memory
struct _DEBUGGEE_PCITREE_REQUEST_RESPONSE_PACKET DEBUGGEE_PCITREE_REQUEST_RESPONSE_PACKET
Pcitree Request-Response Packet. Represents PCI device tree.
struct _DEBUGGEE_DETAILS_AND_SWITCH_THREAD_PACKET DEBUGGEE_DETAILS_AND_SWITCH_THREAD_PACKET
The structure of changing thead and show thread packet in HyperDbg.
struct _DEBUGGEE_SYMBOL_REQUEST_PACKET DEBUGGEE_SYMBOL_REQUEST_PACKET
The structure of .sym reload packet in HyperDbg.
#define SIZEOF_SMI_OPERATION_PACKETS
Debugger size of SMI_OPERATION_PACKETS.
Definition RequestStructures.h:1275
struct _DEBUGGER_SEARCH_MEMORY DEBUGGER_SEARCH_MEMORY
request for searching memory
struct _DEBUGGER_APIC_REQUEST DEBUGGER_APIC_REQUEST
The structure of actions for APIC.
struct _DEBUGGEE_DETAILS_AND_SWITCH_PROCESS_PACKET * PDEBUGGEE_DETAILS_AND_SWITCH_PROCESS_PACKET
#define SIZEOF_HYPERTRACE_LBR_DUMP_PACKETS
Debugger size of HYPERTRACE_LBR_DUMP_PACKETS.
Definition RequestStructures.h:1343
struct _DEBUGGER_DEBUGGER_TEST_QUERY_BUFFER DEBUGGER_DEBUGGER_TEST_QUERY_BUFFER
request for test query buffers
struct _DEBUGGER_FLUSH_LOGGING_BUFFERS * PDEBUGGER_FLUSH_LOGGING_BUFFERS
struct _DEBUGGEE_STEP_PACKET * PDEBUGGEE_STEP_PACKET
struct _DEBUGGEE_BP_LIST_OR_MODIFY_PACKET * PDEBUGGEE_BP_LIST_OR_MODIFY_PACKET
struct _DEBUGGER_SINGLE_CALLSTACK_FRAME DEBUGGER_SINGLE_CALLSTACK_FRAME
The structure for saving the callstack frame of one parameter.
struct _DEBUGGER_VA2PA_AND_PA2VA_COMMANDS DEBUGGER_VA2PA_AND_PA2VA_COMMANDS
requests for !va2pa and !pa2va commands
struct _DEBUGGER_VA2PA_AND_PA2VA_COMMANDS * PDEBUGGER_VA2PA_AND_PA2VA_COMMANDS
struct _INTERRUPT_DESCRIPTOR_TABLE_ENTRIES_PACKETS * PINTERRUPT_DESCRIPTOR_TABLE_ENTRIES_PACKETS
struct _DEBUGGER_READ_PAGE_TABLE_ENTRIES_DETAILS DEBUGGER_READ_PAGE_TABLE_ENTRIES_DETAILS
request for !pte command
struct _DEBUGGEE_CHANGE_CORE_PACKET DEBUGGEE_CHANGE_CORE_PACKET
The structure of changing core packet in HyperDbg.
#define SIZEOF_INTERRUPT_DESCRIPTOR_TABLE_ENTRIES_PACKETS
Debugger size of INTERRUPT_DESCRIPTOR_TABLE_ENTRIES_PACKETS.
Definition RequestStructures.h:1474
struct _DEBUGGER_DEBUGGER_TEST_QUERY_BUFFER * PDEBUGGER_DEBUGGER_TEST_QUERY_BUFFER
IMPORT_EXPORT_HYPERTRACE BOOLEAN HyperTracePtPerformOperation(HYPERTRACE_PT_OPERATION_PACKETS *PtOperationRequest)
Perform actions related to HyperTrace PT.
Definition PtApi.c:553
IMPORT_EXPORT_HYPERTRACE BOOLEAN HyperTraceLbrPerformDump(HYPERTRACE_LBR_DUMP_PACKETS *LbrDumpRequest)
Perform actions related to HyperTrace LBR dumping.
Definition LbrApi.c:457
IMPORT_EXPORT_VMM BOOLEAN VmFuncSmmPerformSmiOperation(SMI_OPERATION_PACKETS *SmiOperationRequest, BOOLEAN ApplyFromVmxRootMode)
Perform actions related to System Management Interrupts (SMIs).
Definition Export.c:1140
IMPORT_EXPORT_VMM UINT64 VmFuncGetLastVmexitRip(UINT32 CoreId)
get the last vm-exit RIP
Definition Export.c:363
DEBUGGER_TRIGGERED_EVENT_DETAILS g_EventTriggerDetail
Trigger event details.
Definition Global.h:181
UINT32 RegisterId
Definition RequestStructures.h:1617
UINT32 KernelStatus
Definition RequestStructures.h:1619
UINT64 Value
Definition RequestStructures.h:1632
UINT32 RegisterId
Definition RequestStructures.h:1631
UINT32 KernelStatus
Definition RequestStructures.h:1633
UINT32 CountOfResults
Definition RequestStructures.h:1604
UINT32 Result
Definition RequestStructures.h:1605
UINT32 Result
Definition RequestStructures.h:1588
BOOLEAN IsCurrentInstructionACall
Definition RequestStructures.h:1068
UINT32 CallLength
Definition RequestStructures.h:1069
DEBUGGER_REMOTE_STEPPING_REQUEST StepType
Definition RequestStructures.h:1062
UINT32 CommandLen
Definition DataTypes.h:174
UINT32 Size
Definition RequestStructures.h:847
UINT32 KernelStatus
Definition RequestStructures.h:845
UINT32 FrameCount
Definition RequestStructures.h:848
BOOLEAN Is32Bit
Definition RequestStructures.h:844
UINT64 BaseAddress
Definition RequestStructures.h:849
UINT32 KernelStatus
Definition RequestStructures.h:301
UINT32 ReturnLength
Definition RequestStructures.h:300
DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION RequestedActionOfThePacket
Definition Connection.h:201
DEBUGGER_REMOTE_PACKET_TYPE TypeOfThePacket
Definition Connection.h:200
BYTE Checksum
Definition Connection.h:198
UINT64 Indicator
Definition Connection.h:199
UINT64 Length
Definition RequestStructures.h:548
UINT64 Address
Definition RequestStructures.h:547
GUEST_REGS * Regs
Definition State.h:167
CHAR KdRecvBuffer[MaxSerialPacketSize]
Definition State.h:186
BOOLEAN IgnoreDisasmInNextPacket
Definition State.h:170
struct for extra registers
Definition BasicTypes.h:208
Definition BasicTypes.h:136
UINT64 rsp
Definition BasicTypes.h:145

◆ KdDummyDPC()

VOID KdDummyDPC ( PKDPC Dpc,
PVOID DeferredContext,
PVOID SystemArgument1,
PVOID SystemArgument2 )

A test function for DPC.

Parameters
Dpc
DeferredContext
SystemArgument1
SystemArgument2
Returns
VOID
172{
173 UNREFERENCED_PARAMETER(Dpc);
174 UNREFERENCED_PARAMETER(SystemArgument1);
175 UNREFERENCED_PARAMETER(SystemArgument2);
176
177 LogInfo("I'm here %llx\n", DeferredContext);
178}

◆ KdFireDpc()

VOID KdFireDpc ( PVOID Routine,
PVOID Parameter )

Add a DPC to dpc queue.

Parameters
Routine
Parameter
ProcessorNumber
Returns
VOID
190{
191 ULONG CurrentCore = KeGetCurrentProcessorNumberEx(NULL);
192
193 KeInitializeDpc(g_DbgState[CurrentCore].KdDpcObject, (PKDEFERRED_ROUTINE)Routine, Parameter);
194
195 KeInsertQueueDpc(g_DbgState[CurrentCore].KdDpcObject, NULL, NULL);
196}

◆ KdGuaranteedStepInstruction()

VOID KdGuaranteedStepInstruction ( PROCESSOR_DEBUGGING_STATE * DbgState)

apply a guaranteed step one instruction to the debuggee

Parameters
DbgStateThe state of the debugger on the current core
Returns
VOID
1441{
1442 //
1443 // Only 16 bit is needed however, vmwrite might write on other bits
1444 // and corrupt other variables, that's why we get 64bit
1445 //
1446 UINT64 CsSel = (UINT64)NULL;
1447
1448 //
1449 // Read cs to have a trace of the execution mode of running application
1450 // in the debuggee
1451 //
1452 CsSel = VmFuncGetCsSelector();
1453
1454 DbgState->InstrumentationStepInTrace.CsSel = (UINT16)CsSel;
1455
1456 //
1457 // Set an indicator of instrumentation step-in MTF
1458 //
1460
1461 //
1462 // Not unset MTF again
1463 //
1465
1466 //
1467 // Disable external interrupts and interrupt Window
1468 //
1470
1471 //
1472 // Set the MTF flag
1473 //
1475}
unsigned short UINT16
Definition BasicTypes.h:53
IMPORT_EXPORT_VMM UINT16 VmFuncGetCsSelector()
Read CS selector.
Definition Export.c:386
IMPORT_EXPORT_VMM VOID VmFuncSetMonitorTrapFlag(BOOLEAN Set)
Set the monitor trap flag.
Definition Export.c:111
IMPORT_EXPORT_VMM VOID VmFuncChangeMtfUnsettingState(UINT32 CoreId, BOOLEAN Set)
Suppress unsetting MTF.
Definition Export.c:47
IMPORT_EXPORT_VMM VOID VmFuncSetInstrumentationStepInState(UINT32 CoreId)
Set instrumentation step in MTF (used for single stepping with MTF).
Definition Export.c:73
IMPORT_EXPORT_VMM VOID VmFuncDisableExternalInterruptsAndInterruptWindow(UINT32 CoreId)
Disable external-interrupts and interrupt window.
Definition Export.c:768
UINT16 CsSel
Definition State.h:36
DEBUGGEE_INSTRUMENTATION_STEP_IN_TRACE InstrumentationStepInTrace
Definition State.h:178

◆ KdHaltSystem()

VOID KdHaltSystem ( PDEBUGGER_PAUSE_PACKET_RECEIVED PausePacket)

Halt the system.

Parameters
PausePacket
Returns
VOID
3490{
3491 //
3492 // Broadcast to halt everything
3493 // Instead of broadcasting we will just send one vmcall and
3494 // from that point, we halt all the other cores by NMIs, this
3495 // way we are sure that we get all the other cores at the middle
3496 // of their execution codes and not on HyperDbg routines
3497 //
3498 // KdBroadcastHaltOnAllCores();
3499 //
3500
3501 //
3502 // vm-exit and halt current core
3503 //
3505
3506 //
3507 // Set the status
3508 //
3510}
#define DEBUGGER_VMCALL_VM_EXIT_HALT_SYSTEM
VMCALL to cause vm-exit and halt the system.
Definition DebuggerVmcalls.h:22
IMPORT_EXPORT_VMM NTSTATUS VmFuncVmxVmcall(UINT64 VmcallNumber, UINT64 OptionalParam1, UINT64 OptionalParam2, UINT64 OptionalParam3)
Export for running VMX VMCALLs.
Definition Export.c:957
UINT32 Result
Definition DataTypes.h:212

◆ KdHandleBreakpointAndDebugBreakpoints()

_Use_decl_annotations_ VOID KdHandleBreakpointAndDebugBreakpoints ( PROCESSOR_DEBUGGING_STATE * DbgState,
DEBUGGEE_PAUSING_REASON Reason,
PDEBUGGER_TRIGGERED_EVENT_DETAILS EventDetails )

Handle #DBs and #BPs for kernel debugger.

This function can be used in vmx-root

Parameters
DbgStateThe state of the debugger on the current core
Reason
EventDetails
Returns
VOID
1294{
1295 //
1296 // Lock handling breaks
1297 //
1299
1300 //
1301 // Check if we should ignore this break request or not
1302 //
1303 if (g_IgnoreBreaksToDebugger.PauseBreaksUntilSpecialMessageSent)
1304 {
1305 //
1306 // Unlock the above core
1307 //
1309
1310 //
1311 // Not continue anymore as the break should be ignored
1312 //
1313 return;
1314 }
1315
1316 //
1317 // Set it as the main core
1318 //
1319 DbgState->MainDebuggingCore = TRUE;
1320
1321 //
1322 // Lock current core
1323 //
1324 DbgState->NmiState.WaitingToBeLocked = FALSE;
1325 SpinlockLock(&DbgState->Lock);
1326
1327 //
1328 // Set the halting reason
1329 //
1330 g_DebuggeeHaltReason = Reason;
1331
1332 //
1333 // Set the context and tag, and stage
1334 //
1335 if (EventDetails != NULL)
1336 {
1337 RtlCopyMemory(&g_EventTriggerDetail, EventDetails, sizeof(DEBUGGER_TRIGGERED_EVENT_DETAILS));
1338 }
1339
1341 {
1342 //
1343 // Unset to avoid future not notifying events
1344 //
1346 }
1347 else
1348 {
1349 //
1350 // Make sure, nobody is in the middle of sending anything
1351 //
1353
1354 //
1355 // Broadcast NMI with the intention of halting cores
1356 //
1358
1359 //
1360 // Unlock the sending response lock to perform regular debugging
1361 //
1363 }
1364
1365 //
1366 // All the cores should go and manage through the following function
1367 //
1368 KdManageSystemHaltOnVmxRoot(DbgState, EventDetails);
1369
1370 //
1371 // Clear the halting reason
1372 //
1374
1375 //
1376 // Clear the context, tag, and stage
1377 //
1379
1380 //
1381 // Unlock handling breaks
1382 //
1383 if (DbgState->MainDebuggingCore)
1384 {
1385 DbgState->MainDebuggingCore = FALSE;
1387 }
1388}
VOID KdCustomDebuggerBreakSpinlockLock(PROCESSOR_DEBUGGING_STATE *DbgState, volatile LONG *Lock)
Tries to get the lock and won't return until successfully get the lock.
Definition Kd.c:956
VOID KdManageSystemHaltOnVmxRoot(PROCESSOR_DEBUGGING_STATE *DbgState, PDEBUGGER_TRIGGERED_EVENT_DETAILS EventDetails)
manage system halt on vmx-root mode
Definition Kd.c:3275
VOID SpinlockLock(volatile LONG *Lock)
Tries to get the lock and won't return until successfully get the lock.
Definition Spinlock.c:53
@ DEBUGGEE_PAUSING_REASON_NOT_PAUSED
Definition Connection.h:24
struct _DEBUGGER_TRIGGERED_EVENT_DETAILS DEBUGGER_TRIGGERED_EVENT_DETAILS
The structure of detail of a triggered event in HyperDbg.
IMPORT_EXPORT_VMM BOOLEAN VmFuncNmiBroadcastRequest(UINT32 CoreId)
Broadcast NMI requests.
Definition Export.c:683
DEBUGGEE_PAUSING_REASON g_DebuggeeHaltReason
Reason that the debuggee is halted.
Definition Global.h:175
volatile LONG DebuggerHandleBreakpointLock
Vmx-root lock for handling breaks to debugger.
Definition Kd.h:28
volatile LONG DebuggerResponseLock
Vmx-root lock for sending response of debugger.
Definition Kd.h:22
volatile BOOLEAN MainDebuggingCore
Definition State.h:166

◆ KdHandleBreakpointAndDebugBreakpointsCallback()

_Use_decl_annotations_ VOID KdHandleBreakpointAndDebugBreakpointsCallback ( UINT32 CoreId,
DEBUGGEE_PAUSING_REASON Reason,
PDEBUGGER_TRIGGERED_EVENT_DETAILS EventDetails )

Handle #DBs and #BPs for kernel debugger.

This function can be used in vmx-root

Parameters
CoreId
Reason
EventDetails
Returns
VOID
1090{
1091 PROCESSOR_DEBUGGING_STATE * DbgState = &g_DbgState[CoreId];
1092
1093 KdHandleBreakpointAndDebugBreakpoints(DbgState, Reason, EventDetails);
1094}
_Use_decl_annotations_ VOID KdHandleBreakpointAndDebugBreakpoints(PROCESSOR_DEBUGGING_STATE *DbgState, DEBUGGEE_PAUSING_REASON Reason, PDEBUGGER_TRIGGERED_EVENT_DETAILS EventDetails)
Handle DBs and BPs for kernel debugger.
Definition Kd.c:1291
struct _PROCESSOR_DEBUGGING_STATE PROCESSOR_DEBUGGING_STATE
Saves the debugger state.

◆ KdHandleDebugEventsWhenKernelDebuggerIsAttached()

VOID KdHandleDebugEventsWhenKernelDebuggerIsAttached ( PROCESSOR_DEBUGGING_STATE * DbgState,
BOOLEAN TrapSetByDebugger )

Handles debug events when kernel-debugger is attached.

Parameters
DbgStateThe state of the debugger on the current core
TrapSetByDebuggerShows whether a trap set by debugger or not
Returns
VOID
488{
489 DEBUGGER_TRIGGERED_EVENT_DETAILS TargetContext = {0};
490 BOOLEAN IgnoreDebugEvent = FALSE;
491 UINT64 LastVmexitRip = VmFuncGetLastVmexitRip(DbgState->CoreId);
492
493 //
494 // It's a breakpoint and should be handled by the kernel debugger
495 //
496 TargetContext.Context = (PVOID)LastVmexitRip;
497
498 if (TrapSetByDebugger)
499 {
500 //
501 // *** Handle a regular trap flag (most of the times as a result of stepping) set by the debugger ***
502 //
503
504 //
505 // Check and handle if there is a software defined breakpoint
506 //
508 LastVmexitRip,
510 FALSE))
511 {
512 if (g_HardwareDebugRegisterDetailsForStepOver.Address != (UINT64)NULL)
513 {
514 //
515 // Check if it's caused by a step-over hardware debug breakpoint or not
516 //
517 if (LastVmexitRip == g_HardwareDebugRegisterDetailsForStepOver.Address)
518 {
519 if (g_HardwareDebugRegisterDetailsForStepOver.ProcessId == HANDLE_TO_UINT32(PsGetCurrentProcessId()) &&
520 g_HardwareDebugRegisterDetailsForStepOver.ThreadId == HANDLE_TO_UINT32(PsGetCurrentThreadId()))
521 {
522 //
523 // It's a step caused by a debug register breakpoint step-over
524 //
526 }
527 else
528 {
529 //
530 // Should be ignored because it's a hardware debug register that is
531 // likely triggered by other thread
532 //
533 IgnoreDebugEvent = TRUE;
534
535 //
536 // Also, we should re-apply the hardware debug breakpoint on this thread
537 //
540 FALSE,
542 }
543 }
544 }
545
546 if (!IgnoreDebugEvent)
547 {
548 //
549 // Handle a regular step
550 //
553 &TargetContext);
554 }
555 }
556 }
557 else
558 {
559 //
560 // It's a regular debug break event
561 //
564 &TargetContext);
565 }
566}
BOOLEAN BreakpointCheckAndHandleDebuggerDefinedBreakpoints(PROCESSOR_DEBUGGING_STATE *DbgState, UINT64 GuestRip, DEBUGGEE_PAUSING_REASON Reason, BOOLEAN ChangeMtfState)
Check if the breakpoint vm-exit relates to 'bp' command or not.
Definition BreakpointCommands.c:478
@ DEBUGGEE_PAUSING_REASON_DEBUGGEE_STEPPED
Definition Connection.h:27
@ DEBUGGEE_PAUSING_REASON_DEBUGGEE_HARDWARE_DEBUG_REGISTER_HIT
Definition Connection.h:30
HARDWARE_DEBUG_REGISTER_DETAILS g_HardwareDebugRegisterDetailsForStepOver
Holds the state of hardware debug register for step-over.
Definition Global.h:103
struct _HARDWARE_DEBUG_REGISTER_DETAILS HARDWARE_DEBUG_REGISTER_DETAILS
store the details of a hardware debug register to ignore any trigger for other threads
PVOID Context
Definition DataTypes.h:227

◆ KdHandleHaltsWhenNmiReceivedFromVmxRoot()

_Use_decl_annotations_ VOID KdHandleHaltsWhenNmiReceivedFromVmxRoot ( PROCESSOR_DEBUGGING_STATE * DbgState)

Tries to get the lock and won't return until successfully get the lock.

Parameters
DbgStateThe state of the debugger on the current core
Returns
VOID
907{
908 //
909 // During the debugging of HyperDbg, we realized that whenever an
910 // event is set, one core might (and will) get the lock of the
911 // debugging and other cores that are triggering the same event
912 // go to the wait for the debugging lock
913 // As we send NMIs to all cores to notify them and halt them,
914 // a core might be in VMX-root and receive the NMI
915 // Handling the NMI and halting from the NMI handlers is not
916 // possible as the stack of the Windows' NMI handler routine
917 // is not big enough to handle HyperDbg's command dispatching
918 // routines, so if the user switches to the cores that are halted
919 // from an NMI handler then we ran out of stack and debugger crashes
920 // It is also not possible to change the stack to a bigger stack because
921 // we're not really interested in allocating other memories for the stack
922 // and also the target stack will not be a valid Windows stack as it's
923 // supposed to run with NMI handling routines.
924 //
925 // By the way, I conclude to let the NMI handler finish its normal
926 // execution and then we check for the possible pausing reasons.
927 //
928 // The pausing scenario should be checked two cases,
929 // 1. If the current core is stuck in spinlock of getting
930 // the debug lock
931 // 2. If the current core is making it self ready for the vm-entry
932 //
933 // In these two cases we should check for the possible halting of the core
934 //
935
936 //
937 // Handle halt of the current core as an NMI
938 //
939 KdHandleNmi(DbgState);
940
941 //
942 // Set the indication to false as we handled it
943 //
945}

◆ KdHandleInstrumentationStepIn()

VOID KdHandleInstrumentationStepIn ( PROCESSOR_DEBUGGING_STATE * DbgState)

Handle instrumentation step-in for kernel debugger.

This function will be called from vmx-root mode

Parameters
DbgStateThe state of the debugger on the current core
Returns
VOID
1147{
1148 //
1149 // Check for tracing instructions
1150 //
1151 if (DbgState->TracingMode)
1152 {
1153 //
1154 // Handle callback for tracing instructions
1155 //
1156 TracingHandleMtf(DbgState);
1157 }
1158 else
1159 {
1160 //
1161 // Only 16 bit is needed however, vmwrite might write on other bits
1162 // and corrupt other variables, that's why we get 64bit
1163 //
1164 UINT64 CsSel = NULL64_ZERO;
1165 DEBUGGER_TRIGGERED_EVENT_DETAILS TargetContext = {0};
1166 UINT64 LastVmexitRip = VmFuncGetLastVmexitRip(DbgState->CoreId);
1167
1168 //
1169 // Check if the cs selector changed or not, which indicates that the
1170 // execution changed from user-mode to kernel-mode or kernel-mode to
1171 // user-mode
1172 //
1173 CsSel = VmFuncGetCsSelector();
1174
1176 (UINT16)CsSel);
1177
1178 //
1179 // Unset the MTF flag and previous cs selector
1180 //
1181 DbgState->InstrumentationStepInTrace.CsSel = 0;
1182
1183 //
1184 // Check and handle if there is a software defined breakpoint
1185 //
1187 LastVmexitRip,
1189 TRUE))
1190 {
1191 //
1192 // Handle the step (if the disassembly ignored here, it means the debugger wants to use it
1193 // as a tracking mechanism, so we'll change the reason for that)
1194 //
1195 TargetContext.Context = (PVOID)LastVmexitRip;
1198 &TargetContext);
1199 }
1200 }
1201}
BOOLEAN KdCheckGuestOperatingModeChanges(UINT16 PreviousCsSelector, UINT16 CurrentCsSelector)
Check if the execution mode (kernel-mode to user-mode or user-mode to kernel-mode) changed.
Definition Kd.c:1487
VOID TracingHandleMtf(PROCESSOR_DEBUGGING_STATE *DbgState)
Callback for handling VM-exits for MTF in the case of tracing instructions.
Definition Tracing.c:43
#define NULL64_ZERO
Definition BasicTypes.h:111
@ DEBUGGEE_PAUSING_REASON_DEBUGGEE_TRACKING_STEPPED
Definition Connection.h:28
BOOLEAN TracingMode
Definition State.h:174

◆ KdHandleMtfCallback()

BOOLEAN KdHandleMtfCallback ( UINT32 CoreId)

Handle Monitor Trap Flag (MTF) callback for kernel debugger.

This function will be called from vmx-root mode

Parameters
CoreId
Returns
BOOLEAN
1213{
1214 PROCESSOR_DEBUGGING_STATE * DbgState = &g_DbgState[CoreId];
1215 BOOLEAN IsMtfHandled = FALSE;
1216
1217 //
1218 // *** Check if we need to re-apply a breakpoint or not
1219 // We check it separately because the guest might step
1220 // instructions on an MTF so we want to check for the step too ***
1221 //
1223 {
1224 //
1225 // Check for re-enabling external interrupts
1226 //
1228
1229 //
1230 // MTF is handled
1231 //
1232 IsMtfHandled = TRUE;
1233 }
1234
1235 //
1236 // *** Check for instrumentation step-in ***
1237 //
1239 {
1240 //
1241 // Unset the MTF instrumentation state (might be changed in the caller)
1242 //
1244
1245 //
1246 // Handle MTF in the debugger
1247 //
1249
1250 //
1251 // MTF is handled
1252 //
1253 IsMtfHandled = TRUE;
1254 }
1255
1256 //
1257 // check the condition of passing the execution to NMIs
1258 //
1259 // This one wastes one week of my life!
1260 // During the testing we realized the !epthook command in Debugger Mode
1261 // is not working. After some tests, it's because if in the middle of a
1262 // command in vmx-root and NMI is sent and the debugger waits for another
1263 // MTF, we'll ignore that MTF and a new MTF is not set again.
1264 // That's why we moved this check here so every command that needs a task
1265 // from MTF is doing its tasks and when we reached here, the check for halting
1266 // the debuggee in MTF is performed
1267 //
1268 else if (KdCheckAndHandleNmiStateForMtf(DbgState))
1269 {
1270 //
1271 // MTF is handled
1272 //
1273 IsMtfHandled = TRUE;
1274 }
1275
1276 return IsMtfHandled;
1277}
BOOLEAN BreakpointCheckAndHandleReApplyingBreakpoint(PROCESSOR_DEBUGGING_STATE *DbgState)
Check and reapply breakpoint.
Definition BreakpointCommands.c:440
BOOLEAN KdCheckAndHandleNmiStateForMtf(PROCESSOR_DEBUGGING_STATE *DbgState)
Handle NMI state for MTF.
Definition Kd.c:1104
VOID KdHandleInstrumentationStepIn(PROCESSOR_DEBUGGING_STATE *DbgState)
Handle instrumentation step-in for kernel debugger.
Definition Kd.c:1146
IMPORT_EXPORT_VMM VOID VmFuncEnableAndCheckForPreviousExternalInterrupts(UINT32 CoreId)
Checks to enable and reinject previous interrupts.
Definition Export.c:1086
IMPORT_EXPORT_VMM VOID VmFuncUnsetInstrumentationStepInState(UINT32 CoreId)
Unset instrumentation step in MTF (used for single stepping with MTF).
Definition Export.c:86
IMPORT_EXPORT_VMM BOOLEAN VmFuncQueryInstrumentationStepInState(UINT32 CoreId)
Query instrumentation step in MTF state.
Definition Export.c:99

◆ KdHandleNmi()

_Use_decl_annotations_ VOID KdHandleNmi ( PROCESSOR_DEBUGGING_STATE * DbgState)

Handle NMI Vm-exits.

Parameters
DbgStateThe state of the debugger on the current core

This function should be called in vmx-root mode

Returns
VOID
1400{
1401 //
1402 // Test
1403 //
1404 // LogInfo("NMI Arrived on : %d \n",CurrentProcessorIndex);
1405
1406 //
1407 // Not the main debugging core
1408 //
1409 DbgState->MainDebuggingCore = FALSE;
1410
1411 //
1412 // Lock current core
1413 //
1414 DbgState->NmiState.WaitingToBeLocked = FALSE;
1415 SpinlockLock(&DbgState->Lock);
1416
1417 //
1418 // All the cores should go and manage through the following function
1419 //
1420 KdManageSystemHaltOnVmxRoot(DbgState, NULL);
1421
1422 //
1423 // Unlock handling breaks
1424 //
1425 if (DbgState->MainDebuggingCore)
1426 {
1427 DbgState->MainDebuggingCore = FALSE;
1429 }
1430}

◆ KdHandleNmiBroadcastDebugBreaks()

VOID KdHandleNmiBroadcastDebugBreaks ( UINT32 CoreId,
BOOLEAN IsOnVmxNmiHandler )

Handle broadcast NMIs for halting cores in vmx-root mode.

Parameters
CoreId
IsOnVmxNmiHandler
Returns
VOID
1026{
1027 //
1028 // Get the current debugging state
1029 //
1030 PROCESSOR_DEBUGGING_STATE * DbgState = &g_DbgState[CoreId];
1031
1032 //
1033 // We use it as a global flag (for both vmx-root and vmx non-root), because
1034 // generally it doesn't have any use case in vmx-root (IsOnVmxNmiHandler == FALSE)
1035 // but in some cases, we might set the MTF but another vm-exit receives before
1036 // MTF and in that place if it tries to trigger and event, then the MTF is not
1037 // handled and the core is not locked properly, just waits to get the handle
1038 // of the "DebuggerHandleBreakpointLock", so we check this flag there
1039 //
1040 DbgState->NmiState.WaitingToBeLocked = TRUE;
1041
1042 if (IsOnVmxNmiHandler)
1043 {
1044 //
1045 // Indicate that it's called from NMI handle, and it relates to
1046 // halting the debuggee
1047 //
1049
1050 //
1051 // If the core was in the middle of spinning on the spinlock
1052 // of getting the debug lock, this mechanism is not needed,
1053 // but if the core is not spinning there or the core is processing
1054 // a random vm-exit, then we inject an immediate vm-exit after vm-entry
1055 // or inject a DPC
1056 // this is used for two reasons.
1057 //
1058 // 1. first, we will get the registers (context) to halt the core
1059 // 2. second, it guarantees that if the NMI arrives within any
1060 // instruction in vmx-root mode, then we injected an immediate
1061 // vm-exit and we won't miss any cpu cycle in the guest
1062 //
1063 // KdFireDpc(KdHaltCoreInTheCaseOfHaltedFromNmiInVmxRoot, NULL);
1065 }
1066 else
1067 {
1068 //
1069 // Handle core break
1070 //
1071 KdHandleNmi(DbgState);
1072 }
1073}

◆ KdInitializeInstantEventPools()

VOID KdInitializeInstantEventPools ( )

Initialize the required pools for instant events.

Returns
VOID
119{
120 //
121 // Request pages to be allocated for regular instant events
122 //
124
125 //
126 // Request pages to be allocated for regular instant events's actions
127 //
129
130#if MAXIMUM_BIG_INSTANT_EVENTS >= 1
131
132 //
133 // Request pages to be allocated for big instant events
134 //
136
137 //
138 // Request pages to be allocated for big instant events's actions
139 //
141
142#endif // MAXIMUM_BIG_INSTANT_EVENTS
143
144 //
145 // Pre-allocate pools for possible EPT hooks
146 // Because there are possible init EPT hook structures, we only allocate the
147 // maximum number of regular instant event subtracted from the initial pages
148 //
150
152 {
153 LogWarning("Warning, cannot allocate the pre-allocated pools for EPT hooks");
154
155 //
156 // BTW, won't fail the starting phase because of this
157 //
158 }
159}
BOOLEAN PoolManagerCheckAndPerformAllocationAndDeallocation()
This function performs allocations from VMX non-root based on g_RequestNewAllocation.
Definition PoolManager.c:320
BOOLEAN PoolManagerRequestAllocation(SIZE_T Size, UINT32 Count, POOL_ALLOCATION_INTENTION Intention)
Request to allocate new buffers.
Definition PoolManager.c:436
#define MAXIMUM_NUMBER_OF_INITIAL_PREALLOCATED_EPT_HOOKS
Maximum number of initial pre-allocated EPT hooks.
Definition Constants.h:268
#define BIG_INSTANT_EVENT_ACTION_BUFFER
Pre-allocated size for a big action + custom code or script buffer.
Definition Constants.h:308
#define REGULAR_INSTANT_EVENT_ACTION_BUFFER
Pre-allocated size for a regular action + custom code or script buffer.
Definition Constants.h:302
#define MAXIMUM_BIG_INSTANT_EVENTS
Maximum number of (big) instant events that are pre-allocated.
Definition Constants.h:284
#define MAXIMUM_REGULAR_INSTANT_EVENTS
Maximum number of (regular) instant events that are pre-allocated.
Definition Constants.h:278
#define REGULAR_INSTANT_EVENT_CONDITIONAL_BUFFER
Pre-allocated size for a regular event + conditions buffer.
Definition Constants.h:290
#define BIG_INSTANT_EVENT_CONDITIONAL_BUFFER
Pre-allocated size for a big event + conditions buffer.
Definition Constants.h:296
@ INSTANT_BIG_EVENT_BUFFER
Definition DataTypes.h:85
@ INSTANT_BIG_EVENT_ACTION_BUFFER
Definition DataTypes.h:87
@ INSTANT_REGULAR_EVENT_ACTION_BUFFER
Definition DataTypes.h:86
@ INSTANT_REGULAR_EVENT_BUFFER
Definition DataTypes.h:84
IMPORT_EXPORT_VMM VOID ConfigureEptHookReservePreallocatedPoolsForEptHooks(UINT32 Count)
Allocate (reserve) pages for storing EPT hooks page hooks.
Definition Configuration.c:241

◆ KdInitializeKernelDebugger()

VOID KdInitializeKernelDebugger ( )

initialize kernel debugger

this function should be called on vmx non-root

Returns
VOID
23{
24 //
25 // Allocate DPC routine
26 //
27 // for (SIZE_T i = 0; i < CoreCount; i++)
28 // {
29 // g_DbgState[i].KdDpcObject = PlatformMemAllocateNonPagedPool(sizeof(KDPC));
30 //
31 // if (g_DbgState[i].KdDpcObject == NULL)
32 // {
33 // LogError("Err, allocating dpc holder for debuggee");
34 // return;
35 // }
36 // }
37
38 //
39 // Enable vm-exit on Hardware debug exceptions and breakpoints
40 // so, intercept #DBs and #BP by changing exception bitmap (one core)
41 //
43
44 //
45 // Reset pause break requests
46 //
48
49 //
50 // Initial the needed pools for instant events
51 //
53
54 //
55 // Indicate that the kernel debugger is active
56 //
58}
VOID KdInitializeInstantEventPools()
Initialize the required pools for instant events.
Definition Kd.c:118
IMPORT_EXPORT_VMM VOID BroadcastEnableDbAndBpExitingAllCores()
routines to set vm-exit on all DBs and BP on all cores
Definition Broadcast.c:35
struct _DEBUGGEE_REQUEST_TO_IGNORE_BREAKS_UNTIL_AN_EVENT DEBUGGEE_REQUEST_TO_IGNORE_BREAKS_UNTIL_AN_EVENT
request to pause and halt the system

◆ KdIsGuestOnUsermode32Bit()

BOOLEAN KdIsGuestOnUsermode32Bit ( )

determines if the guest was in 32-bit user-mode or 64-bit (long mode)

this function should be called from vmx-root

Returns
BOOLEAN
3221{
3222 //
3223 // Only 16 bit is needed however, vmwrite might write on other bits
3224 // and corrupt other variables, that's why we get 64bit
3225 //
3226 UINT64 CsSel = (UINT64)NULL;
3227
3228 //
3229 // Read guest's cs selector
3230 //
3231 CsSel = VmFuncGetCsSelector();
3232
3233 if (CsSel == KGDT64_R0_CODE)
3234 {
3235 //
3236 // 64-bit kernel-mode
3237 //
3238 return FALSE;
3239 }
3240 else if ((CsSel & ~3) == KGDT64_R3_CODE)
3241 {
3242 //
3243 // 64-bit user-mode
3244 //
3245 return FALSE;
3246 }
3247 else if ((CsSel & ~3) == KGDT64_R3_CMCODE)
3248 {
3249 //
3250 // 32-bit user-mode
3251 //
3252 return TRUE;
3253 }
3254 else
3255 {
3256 LogError("Err, unknown value for cs, cannot determine wow64 mode");
3257 }
3258
3259 //
3260 // By default, 64-bit
3261 //
3262 return FALSE;
3263}

◆ KdLoggingResponsePacketToDebugger()

_Use_decl_annotations_ BOOLEAN KdLoggingResponsePacketToDebugger ( CHAR * OptionalBuffer,
UINT32 OptionalBufferLength,
UINT32 OperationCode )

Sends a HyperDbg logging response packet to the debugger.

Parameters
OptionalBuffer
OptionalBufferLength
OperationCode
Returns
BOOLEAN
381{
382 DEBUGGER_REMOTE_PACKET Packet = {0};
383 BOOLEAN Result = FALSE;
384
385 //
386 // Make the packet's structure
387 //
390
391 //
392 // Set the requested action
393 //
395
396 //
397 // Calculate checksum
398 //
399 Packet.Checksum = KdComputeDataChecksum((PVOID)((UINT64)&Packet + 1),
400 sizeof(DEBUGGER_REMOTE_PACKET) - sizeof(BYTE));
401
402 Packet.Checksum += KdComputeDataChecksum((PVOID)&OperationCode, sizeof(UINT32));
403 Packet.Checksum += KdComputeDataChecksum((PVOID)OptionalBuffer, OptionalBufferLength);
404
405 //
406 // Check if we're in Vmx-root, if it is then we use our customized HIGH_IRQL Spinlock,
407 // if not we use the windows spinlock
408 //
409
412 Result = SerialConnectionSendThreeBuffers((CHAR *)&Packet,
414 (CHAR *)&OperationCode,
415 sizeof(UINT32),
416 OptionalBuffer,
417 OptionalBufferLength));
418
419 return Result;
420}
BOOLEAN SerialConnectionSendThreeBuffers(CHAR *Buffer1, UINT32 Length1, CHAR *Buffer2, UINT32 Length2, CHAR *Buffer3, UINT32 Length3)
Perform sending 3 not appended buffers over serial.
Definition SerialConnection.c:242
#define ScopedSpinlock(LockObject, CodeToRun)
Definition Spinlock.h:39
@ DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_DEBUGGEE_LOGGING_MECHANISM
Definition Connection.h:112

◆ KdManageSystemHaltOnVmxRoot()

VOID KdManageSystemHaltOnVmxRoot ( PROCESSOR_DEBUGGING_STATE * DbgState,
PDEBUGGER_TRIGGERED_EVENT_DETAILS EventDetails )

manage system halt on vmx-root mode

This function should only be called from KdHandleBreakpointAndDebugBreakpoints

Parameters
DbgStateThe state of the debugger on the current core
EventDetails
MainCorethe core that triggered the event
Returns
VOID
3277{
3278 DEBUGGEE_KD_PAUSED_PACKET PausePacket;
3279 ULONG ExitInstructionLength = 0;
3280 RFLAGS Rflags = {0};
3281 UINT64 LastVmexitRip = 0;
3282
3283 //
3284 // Perform Pre-halt tasks
3285 //
3286 KdApplyTasksPreHaltCore(DbgState);
3287
3288StartAgain:
3289
3290 //
3291 // We check for receiving buffer (unhalting) only on the
3292 // first core and not on every cores
3293 //
3294 if (DbgState->MainDebuggingCore)
3295 {
3296 //
3297 // *** Current Operating Core ***
3298 //
3299 RtlZeroMemory(&PausePacket, sizeof(DEBUGGEE_KD_PAUSED_PACKET));
3300
3301 //
3302 // Get the last RIP for vm-exit handler
3303 //
3304 LastVmexitRip = VmFuncGetRip();
3305
3306 //
3307 // Set the halt reason
3308 //
3309 PausePacket.PausingReason = g_DebuggeeHaltReason;
3310
3311 //
3312 // Set the current core
3313 //
3314 PausePacket.CurrentCore = DbgState->CoreId;
3315
3316 //
3317 // Set the RIP and mode of execution
3318 //
3319 PausePacket.Rip = LastVmexitRip;
3321
3322 //
3323 // Set disassembly state
3324 //
3325 PausePacket.IgnoreDisassembling = DbgState->IgnoreDisasmInNextPacket;
3326 DbgState->IgnoreDisasmInNextPacket = FALSE;
3327
3328 //
3329 // Set rflags for finding the results of conditional jumps
3330 //
3331 Rflags.AsUInt = VmFuncGetRflags();
3332 PausePacket.Rflags = Rflags.AsUInt;
3333
3334 //
3335 // Set the event tag (if it's an event)
3336 //
3337 if (EventDetails != NULL)
3338 {
3339 PausePacket.EventTag = EventDetails->Tag;
3340 PausePacket.EventCallingStage = EventDetails->Stage;
3341 }
3342
3343 //
3344 // Read the instruction len hint
3345 //
3346 if (DbgState->InstructionLengthHint != 0)
3347 {
3348 ExitInstructionLength = DbgState->InstructionLengthHint;
3349 }
3350 else
3351 {
3352 //
3353 // Reading instruction length (VMCS_VMEXIT_INSTRUCTION_LENGTH) won't work for anything that is not instruction exiting,
3354 // so we won't use it anymore
3355 //
3356
3357 //
3358 // Set the length to notify debuggee
3359 //
3360 ExitInstructionLength = CheckAddressMaximumInstructionLength((PVOID)LastVmexitRip);
3361 }
3362
3363 //
3364 // Set the reading length of bytes (for instruction disassembling)
3365 //
3366 PausePacket.ReadInstructionLen = (UINT16)ExitInstructionLength;
3367
3368 //
3369 // Find the current instruction
3370 //
3372 &PausePacket.InstructionBytesOnRip,
3373 ExitInstructionLength);
3374
3375 //
3376 // Send the pause packet, along with RIP and an indication
3377 // to pause to the debugger
3378 //
3381 (CHAR *)&PausePacket,
3383
3384 //
3385 // Perform Commands from the debugger
3386 //
3388
3389 //
3390 // Check if it's a change core event or not, otherwise finish the execution
3391 // and continue debuggee
3392 //
3393 if (!DbgState->MainDebuggingCore)
3394 {
3395 //
3396 // It's a core switch, start again
3397 //
3398 goto StartAgain;
3399 }
3400 }
3401 else
3402 {
3403 //
3404 // All cores except operating core
3405 //
3406
3407 //
3408 // Lock and unlock the lock so all core can get the lock
3409 // and continue their normal execution
3410 //
3411 DbgState->NmiState.WaitingToBeLocked = FALSE;
3412
3414 DbgState->Lock,
3415
3416 //
3417 // Check if it's a change core event or not
3418 //
3419 if (DbgState->MainDebuggingCore) {
3420 //
3421 // It's a core change event
3422 //
3423 g_DebuggeeHaltReason = DEBUGGEE_PAUSING_REASON_DEBUGGEE_CORE_SWITCHED;
3424
3425 goto StartAgain;
3426 }
3427
3428 );
3429
3430 //
3431 // Check if any task needs to be executed on this core or not
3432 //
3433 if (DbgState->HaltedCoreTask.PerformHaltedTask)
3434 {
3435 //
3436 // Indicate that the halted core is no longer needed to execute a task
3437 // as the current task is executed once
3438 //
3440
3441 //
3442 // Perform the target task
3443 //
3445 DbgState->HaltedCoreTask.TargetTask,
3446 DbgState->HaltedCoreTask.Context);
3447
3448 //
3449 // Check if the core needs to be locked again
3450 //
3451 if (DbgState->HaltedCoreTask.LockAgainAfterTask)
3452 {
3453 //
3454 // Lock again
3455 //
3456 SpinlockLock(&DbgState->Lock);
3457
3458 goto StartAgain;
3459 }
3460 }
3461 }
3462
3463 //
3464 // Apply the basic task for the core before continue
3465 //
3467}
VOID HaltedCorePerformTargetTask(PROCESSOR_DEBUGGING_STATE *DbgState, UINT64 TargetTask, PVOID Context)
Perform the task on halted core.
Definition HaltedCore.c:45
VOID KdApplyTasksPreHaltCore(PROCESSOR_DEBUGGING_STATE *DbgState)
before halting any core, all the tasks will be applied to all cores including the main core
Definition Kd.c:578
BOOLEAN KdIsGuestOnUsermode32Bit()
determines if the guest was in 32-bit user-mode or 64-bit (long mode)
Definition Kd.c:3220
VOID KdDispatchAndPerformCommandsFromDebugger(PROCESSOR_DEBUGGING_STATE *DbgState)
This function applies commands from the debugger to the debuggee.
Definition Kd.c:2258
VOID KdApplyTasksPostContinueCore(PROCESSOR_DEBUGGING_STATE *DbgState)
before continue any core, all the tasks will be applied to all cores including the main core
Definition Kd.c:617
@ DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_DEBUGGEE_PAUSED_AND_CURRENT_INSTRUCTION
Definition Connection.h:113
struct _DEBUGGEE_KD_PAUSED_PACKET DEBUGGEE_KD_PAUSED_PACKET
The structure of pausing packet in kHyperDbg.
IMPORT_EXPORT_VMM UINT32 CheckAddressMaximumInstructionLength(PVOID Address)
This function returns the maximum instruction length that can be read from this address.
Definition AddressCheck.c:345
IMPORT_EXPORT_VMM UINT64 VmFuncGetRflags()
Read guest's RFLAGS.
Definition Export.c:397
IMPORT_EXPORT_VMM BOOLEAN MemoryMapperReadMemorySafeOnTargetProcess(_In_ UINT64 VaAddressToRead, _Inout_ PVOID BufferToSaveMemory, _In_ SIZE_T SizeToRead)
IMPORT_EXPORT_VMM UINT64 VmFuncGetRip()
Read guest's RIP.
Definition Export.c:420
if(.test_var==4)
Definition script_conditional_statement_global_var.hds.hex.txt:6
BOOLEAN LockAgainAfterTask
Definition State.h:138
PVOID Context
Definition State.h:140
BOOLEAN PerformHaltedTask
Definition State.h:137
UINT64 TargetTask
Definition State.h:139
UINT16 ReadInstructionLen
Definition DataTypes.h:250
UINT64 Rip
Definition DataTypes.h:241
UINT64 Rflags
Definition DataTypes.h:248
BOOLEAN IsProcessorOn32BitMode
Definition DataTypes.h:242
DEBUGGEE_PAUSING_REASON PausingReason
Definition DataTypes.h:244
UINT64 EventTag
Definition DataTypes.h:246
ULONG CurrentCore
Definition DataTypes.h:245
BYTE InstructionBytesOnRip[MAXIMUM_INSTR_SIZE]
Definition DataTypes.h:249
BOOLEAN IgnoreDisassembling
Definition DataTypes.h:243
VMM_CALLBACK_EVENT_CALLING_STAGE_TYPE EventCallingStage
Definition DataTypes.h:247
UINT64 Tag
Definition DataTypes.h:226
VMM_CALLBACK_EVENT_CALLING_STAGE_TYPE Stage
Definition DataTypes.h:228
UINT16 InstructionLengthHint
Definition State.h:182
DEBUGGEE_HALTED_CORE_TASK HaltedCoreTask
Definition State.h:181

◆ KdNotifyDebuggeeForUserInput()

VOID KdNotifyDebuggeeForUserInput ( DEBUGGEE_USER_INPUT_PACKET * Descriptor,
UINT32 Len )

Notify user-mode to about new user-input buffer.

Parameters
Descriptor
Len
Returns
VOID
840{
841 //
842 // Check if the priority buffer is full or not
843 //
845
846 //
847 // Send user-input buffer along with operation code to
848 // the user-mode
849 //
851 Descriptor,
852 Len,
853 TRUE);
854}
#define OPERATION_DEBUGGEE_USER_INPUT
Definition Constants.h:382

◆ KdPerformAddActionToEvent()

BOOLEAN KdPerformAddActionToEvent ( PDEBUGGEE_EVENT_AND_ACTION_HEADER_FOR_REMOTE_PACKET ActionDetailHeader,
DEBUGGER_EVENT_AND_ACTION_RESULT * DebuggerEventAndActionResult )

Send action buffer to user-mode to be added to the event.

Parameters
ActionDetailHeader
DebuggerEventAndActionResult
Returns
BOOLEAN Shows whether the debuggee should be continued or not
1604{
1605#if EnableInstantEventMechanism
1606
1607 DEBUGGER_GENERAL_ACTION * GeneralActionDetail = NULL;
1608
1609 GeneralActionDetail = (PDEBUGGER_GENERAL_ACTION)(((CHAR *)ActionDetailHeader) +
1611
1612 //
1613 // Parse action from the VMX-root mode
1614 //
1615 DebuggerParseAction(GeneralActionDetail, DebuggerEventAndActionResult, TRUE);
1616
1617 return FALSE;
1618
1619#else
1620
1621 //
1622 // Check if the priority buffer is full or not
1623 //
1625
1627 ((CHAR *)ActionDetailHeader + sizeof(DEBUGGEE_EVENT_AND_ACTION_HEADER_FOR_REMOTE_PACKET)),
1628 ActionDetailHeader->Length,
1629 TRUE);
1630 return TRUE;
1631
1632#endif // EnableInstantEventMechanism
1633}
BOOLEAN DebuggerParseAction(PDEBUGGER_GENERAL_ACTION ActionDetails, PDEBUGGER_EVENT_AND_ACTION_RESULT ResultsToReturn, BOOLEAN InputFromVmxRoot)
Routine for validating and parsing actions that are coming from the user-mode.
Definition Debugger.c:3307
#define OPERATION_DEBUGGEE_ADD_ACTION_TO_EVENT
Definition Constants.h:384
struct _DEBUGGER_GENERAL_ACTION DEBUGGER_GENERAL_ACTION
Each event can have multiple actions.
struct _DEBUGGER_GENERAL_ACTION * PDEBUGGER_GENERAL_ACTION
NULL()
Definition test-case-generator.py:530

◆ KdPerformEventQueryAndModification()

BOOLEAN KdPerformEventQueryAndModification ( PDEBUGGER_MODIFY_EVENTS ModifyAndQueryEvent)

Perform modify and query events.

Parameters
ModifyAndQueryEvent
Returns
BOOLEAN Shows whether the debuggee should be continued or not
2051{
2052 BOOLEAN IsForAllEvents = FALSE;
2053 BOOLEAN ContinueDebugger = FALSE;
2054
2055 //
2056 // Check if the tag is valid or not
2057 //
2058 if (ModifyAndQueryEvent->Tag == DEBUGGER_MODIFY_EVENTS_APPLY_TO_ALL_TAG)
2059 {
2060 IsForAllEvents = TRUE;
2061 }
2062 else if (!DebuggerIsTagValid(ModifyAndQueryEvent->Tag))
2063 {
2064 //
2065 // Tag is invalid
2066 //
2068 return FALSE;
2069 }
2070
2071 //
2072 // ***************************************************************************
2073 //
2074
2075 //
2076 // Check if it's a query state command
2077 //
2078 if (ModifyAndQueryEvent->TypeOfAction == DEBUGGER_MODIFY_EVENTS_QUERY_STATE)
2079 {
2080 //
2081 // check if tag is valid or not
2082 //
2083 if (!DebuggerIsTagValid(ModifyAndQueryEvent->Tag))
2084 {
2085 ModifyAndQueryEvent->KernelStatus = DEBUGGER_ERROR_TAG_NOT_EXISTS;
2086 }
2087 else
2088 {
2089 //
2090 // Set event state
2091 //
2092 if (DebuggerQueryStateEvent(ModifyAndQueryEvent->Tag))
2093 {
2094 ModifyAndQueryEvent->IsEnabled = TRUE;
2095 }
2096 else
2097 {
2098 ModifyAndQueryEvent->IsEnabled = FALSE;
2099 }
2100
2101 //
2102 // The function was successful
2103 //
2104 ModifyAndQueryEvent->KernelStatus = DEBUGGER_OPERATION_WAS_SUCCESSFUL;
2105 }
2106 }
2107 else if (ModifyAndQueryEvent->TypeOfAction == DEBUGGER_MODIFY_EVENTS_ENABLE)
2108 {
2109 if (IsForAllEvents)
2110 {
2111 //
2112 // Enable all events
2113 //
2115 }
2116 else
2117 {
2118 //
2119 // Enable just one event
2120 //
2121 DebuggerEnableEvent(ModifyAndQueryEvent->Tag);
2122 }
2123
2124 //
2125 // The function was successful
2126 //
2127 ModifyAndQueryEvent->KernelStatus = DEBUGGER_OPERATION_WAS_SUCCESSFUL;
2128 }
2129 else if (ModifyAndQueryEvent->TypeOfAction == DEBUGGER_MODIFY_EVENTS_DISABLE)
2130 {
2131 if (IsForAllEvents)
2132 {
2133 //
2134 // Disable all events
2135 //
2137 }
2138 else
2139 {
2140 //
2141 // Disable just one event
2142 //
2143 DebuggerDisableEvent(ModifyAndQueryEvent->Tag);
2144 }
2145
2146 //
2147 // The function was successful
2148 //
2149 ModifyAndQueryEvent->KernelStatus = DEBUGGER_OPERATION_WAS_SUCCESSFUL;
2150 }
2151 else if (ModifyAndQueryEvent->TypeOfAction == DEBUGGER_MODIFY_EVENTS_CLEAR)
2152 {
2153#if EnableInstantEventMechanism
2154
2155 //
2156 // For clearing events, we just disable them here and after that
2157 // we'll send a DPC to the user-mode to clear the event
2158 //
2159 // This is because we want to make sure that no other core is in middle
2160 // of handling anything (so the structures and the track of the debugger
2161 // might be lost)
2162 //
2163 // For example, the debugger might be (and will be) paused while other cores
2164 // are halted but in the middle of handling an EPT, and if we remove the EPT
2165 // hook directly, it might break the operation of the other cores, but when
2166 // we disable it then we're sure no other cores get a chance to trigger the
2167 // event
2168 //
2169 if (IsForAllEvents)
2170 {
2171 //
2172 // Disable all events
2173 //
2175 }
2176 else
2177 {
2178 //
2179 // Disable just one event
2180 //
2181 DebuggerDisableEvent(ModifyAndQueryEvent->Tag);
2182 }
2183
2184 //
2185 // Send the DPC to remove the event at next run
2186 //
2187
2188 //
2189 // Send one byte buffer and operation codes to the user-mode
2190 // This buffer won't notify the debugger and silently removes
2191 // the event(s)
2192 //
2194 {
2196 ModifyAndQueryEvent,
2197 sizeof(DEBUGGER_MODIFY_EVENTS),
2198 TRUE);
2199
2200 //
2201 // The function was successful
2202 //
2203 ModifyAndQueryEvent->KernelStatus = DEBUGGER_OPERATION_WAS_SUCCESSFUL;
2204 }
2205 else
2206 {
2207 //
2208 // The event is already disabled, but we cannot deliver the user-mode
2209 // to clear the buffer because the buffers are either not served or
2210 // too much buffers are added to queue
2211 //
2213 }
2214
2215#else
2216
2217 //
2218 // Check if the priority buffer is full or not
2219 //
2221
2222 //
2223 // Send one byte buffer and operation codes to the user-mode
2224 //
2226 ModifyAndQueryEvent,
2227 sizeof(DEBUGGER_MODIFY_EVENTS),
2228 TRUE);
2229
2230 ContinueDebugger = TRUE;
2231
2232#endif // EnableInstantEventMechanism
2233 }
2234 else
2235 {
2236 //
2237 // Invalid parameter specified in Action
2238 //
2240 }
2241
2242 //
2243 // In all of the cases except clearing event while instant event
2244 // mechanism is disabled, we shouldn't continue the debugger and
2245 // keep the debugger in the halt state
2246 //
2247 return ContinueDebugger;
2248}
BOOLEAN DebuggerEnableOrDisableAllEvents(BOOLEAN IsEnable)
Enable or disable all events from all the types.
Definition Debugger.c:1932
BOOLEAN DebuggerDisableEvent(UINT64 Tag)
Disable an event by tag.
Definition Debugger.c:2397
BOOLEAN DebuggerIsTagValid(UINT64 Tag)
Detect whether the tag exists or not.
Definition Debugger.c:2505
BOOLEAN DebuggerEnableEvent(UINT64 Tag)
Enable an event by tag.
Definition Debugger.c:2336
BOOLEAN DebuggerQueryStateEvent(UINT64 Tag)
returns whether an event is enabled/disabled by tag
Definition Debugger.c:2370
#define DEBUGGER_MODIFY_EVENTS_APPLY_TO_ALL_TAG
Apply event modifications to all tags.
Definition Constants.h:714
#define OPERATION_DEBUGGEE_CLEAR_EVENTS_WITHOUT_NOTIFYING_DEBUGGER
Definition Constants.h:386
#define OPERATION_DEBUGGEE_CLEAR_EVENTS
Definition Constants.h:385
#define DEBUGGER_ERROR_TAG_NOT_EXISTS
error, the tag not exist
Definition ErrorCodes.h:33
#define DEBUGGER_ERROR_MODIFY_EVENTS_INVALID_TYPE_OF_ACTION
error, type of action (enable/disable/clear) is wrong
Definition ErrorCodes.h:127
#define DEBUGGER_ERROR_MODIFY_EVENTS_INVALID_TAG
error, invalid tag for 'events' command (tag id is unknown for kernel)
Definition ErrorCodes.h:121
#define DEBUGGER_ERROR_THE_TARGET_EVENT_IS_DISABLED_BUT_CANNOT_BE_CLEARED_PRIRITY_BUFFER_IS_FULL
error, the target event(s) is/are disabled but cannot clear them because the buffer of the user-mode ...
Definition ErrorCodes.h:520
@ DEBUGGER_MODIFY_EVENTS_ENABLE
Definition Events.h:235
@ DEBUGGER_MODIFY_EVENTS_DISABLE
Definition Events.h:236
@ DEBUGGER_MODIFY_EVENTS_QUERY_STATE
Definition Events.h:234
@ DEBUGGER_MODIFY_EVENTS_CLEAR
Definition Events.h:237
DEBUGGER_MODIFY_EVENTS_TYPE TypeOfAction
Definition Events.h:249
BOOLEAN IsEnabled
Definition Events.h:250
UINT64 KernelStatus
Definition Events.h:247
UINT64 Tag
Definition Events.h:246

◆ KdPerformRegisterEvent()

BOOLEAN KdPerformRegisterEvent ( PDEBUGGEE_EVENT_AND_ACTION_HEADER_FOR_REMOTE_PACKET EventDetailHeader,
DEBUGGER_EVENT_AND_ACTION_RESULT * DebuggerEventAndActionResult )

Send event registration buffer to user-mode to register the event.

Parameters
EventDetailHeader
DebuggerEventAndActionResult
Returns
BOOLEAN Shows whether the debuggee should be continued or not
1552{
1553#if EnableInstantEventMechanism
1554
1555 DEBUGGER_GENERAL_EVENT_DETAIL * GeneralEventDetail = NULL;
1556
1557 GeneralEventDetail = (PDEBUGGER_GENERAL_EVENT_DETAIL)(((CHAR *)EventDetailHeader) +
1559
1560 //
1561 // Check to see whether all cores are halted (in instant event)
1562 //
1564 {
1565 DebuggerEventAndActionResult->IsSuccessful = FALSE;
1567 }
1568 else
1569 {
1570 //
1571 // Parse event from the VMX-root mode
1572 //
1573 DebuggerParseEvent(GeneralEventDetail, DebuggerEventAndActionResult, TRUE);
1574 }
1575
1576 return FALSE;
1577
1578#else
1579
1580 //
1581 // Check if the priority buffer is full or not
1582 //
1584
1586 ((CHAR *)EventDetailHeader + sizeof(DEBUGGEE_EVENT_AND_ACTION_HEADER_FOR_REMOTE_PACKET)),
1587 EventDetailHeader->Length,
1588 TRUE);
1589 return TRUE;
1590
1591#endif // EnableInstantEventMechanism
1592}
BOOLEAN DebuggerParseEvent(PDEBUGGER_GENERAL_EVENT_DETAIL EventDetails, PDEBUGGER_EVENT_AND_ACTION_RESULT ResultsToReturn, BOOLEAN InputFromVmxRoot)
Routine for parsing events.
Definition Debugger.c:3163
BOOLEAN KdCheckAllCoresAreLocked()
Check whether all cores are locked or not.
Definition Kd.c:1667
#define OPERATION_DEBUGGEE_REGISTER_EVENT
Definition Constants.h:383
#define DEBUGGER_ERROR_NOT_ALL_CORES_ARE_LOCKED_FOR_APPLYING_INSTANT_EVENT
error, not all cores are locked (probably due to a race condition in HyperDbg) in instant-event mecha...
Definition ErrorCodes.h:527
struct _DEBUGGER_GENERAL_EVENT_DETAIL DEBUGGER_GENERAL_EVENT_DETAIL
Each command is like the following struct, it also used for tracing works in user mode and sending it...
struct _DEBUGGER_GENERAL_EVENT_DETAIL * PDEBUGGER_GENERAL_EVENT_DETAIL
UINT32 Error
Definition Events.h:434
BOOLEAN IsSuccessful
Definition Events.h:433

◆ KdPerformSettingTheStateOfShortCircuiting()

VOID KdPerformSettingTheStateOfShortCircuiting ( PROCESSOR_DEBUGGING_STATE * DbgState,
PDEBUGGER_SHORT_CIRCUITING_EVENT ShortCircuitingEvent )

Perform modify the state of short-circuiting.

Parameters
DbgStateThe state of the debugger on the current core
ShortCircuitingEvent
Returns
VOID
2024{
2025 //
2026 // Perform the short-circuiting changes
2027 //
2028 if (ShortCircuitingEvent->IsShortCircuiting)
2029 {
2030 DbgState->ShortCircuitingEvent = TRUE;
2031 }
2032 else
2033 {
2034 DbgState->ShortCircuitingEvent = FALSE;
2035 }
2036
2037 //
2038 // The status was okay
2039 //
2040 ShortCircuitingEvent->KernelStatus = DEBUGGER_OPERATION_WAS_SUCCESSFUL;
2041}
BOOLEAN IsShortCircuiting
Definition Events.h:263
UINT64 KernelStatus
Definition Events.h:262
BOOLEAN ShortCircuitingEvent
Definition State.h:169

◆ KdPerformTheTestPacketOperation()

VOID KdPerformTheTestPacketOperation ( PROCESSOR_DEBUGGING_STATE * DbgState,
DEBUGGER_DEBUGGER_TEST_QUERY_BUFFER * TestQueryPacket )

Perform the test packet's operation.

Parameters
DbgStateThe state of the debugger on the current core
TestQueryPackettest packet request
Returns
VOID
1855{
1856 //
1857 // Dispatch the request
1858 //
1859 switch (TestQueryPacket->RequestType)
1860 {
1862
1863 //
1864 // Query state of the system
1865 //
1867
1869
1870 break;
1871
1873
1874 //
1875 // Query state of the trap
1876 //
1878
1880
1881 break;
1882
1884
1885 //
1886 // Query state of pre-allocated pools
1887 //
1889
1891
1892 break;
1893
1896
1897 //
1898 // Send request for the target task to the halted cores (synchronized and unsynchronized)
1899 //
1902 TRUE,
1904 (PVOID)0x55);
1905
1907
1908 break;
1909
1911
1912 //
1913 // Validate core number
1914 //
1915 if (!CommonValidateCoreNumber((UINT32)TestQueryPacket->Context))
1916 {
1917 //
1918 // Core number is invalid
1919 //
1921 }
1922 else
1923 {
1924 //
1925 // Send request for the target task to the target halted core
1926 //
1929 TRUE,
1930 (PVOID)0x85);
1931
1933 }
1934
1935 break;
1936
1938
1939 //
1940 // Turn off the breakpoint interception
1941 //
1943
1945
1946 break;
1947
1949
1950 //
1951 // Turn on the breakpoint interception
1952 //
1954
1956
1957 break;
1958
1960
1961 //
1962 // Turn off the breakpoints and events interception before executing the commands in the remote computer
1963 //
1965
1967
1968 break;
1969
1971
1972 //
1973 // Turn on the breakpoints and events interception after finishing the commands in the remote computer
1974 //
1976
1978
1979 break;
1980
1982
1983 //
1984 // Turn off the debug break interception
1985 //
1987
1989
1990 break;
1991
1993
1994 //
1995 // Turn on the debug break interception
1996 //
1998
2000
2001 break;
2002
2003 default:
2004
2005 //
2006 // Query index not found
2007 //
2009
2010 break;
2011 }
2012}
VOID HaltedCoreRunTaskOnSingleCore(UINT32 TargetCoreId, UINT64 TargetTask, BOOLEAN LockAgainAfterTask, PVOID Context)
Run the task on a single halted core.
Definition HaltedCore.c:356
BOOLEAN HaltedCoreBroadcastTaskAllCores(PROCESSOR_DEBUGGING_STATE *DbgState, UINT64 TargetTask, BOOLEAN LockAgainAfterTask, BOOLEAN Synchronize, PVOID Context)
Broadcast tasks to halted cores.
Definition HaltedCore.c:399
#define DEBUGGER_HALTED_CORE_TASK_TEST
Halted core task for testing purpose.
Definition HaltedCore.h:22
VOID KdQueryRflagTrapState()
Query state of the RFLAG's traps.
Definition Kd.c:1641
VOID KdQuerySystemState()
Query state of the system.
Definition Kd.c:1728
VOID PoolManagerShowPreAllocatedPools()
Shows list of pre-allocated pools available (used for debugging purposes).
Definition PoolManager.c:195
#define DEBUGGER_ERROR_INVALID_CORE_ID
error, the core id is invalid
Definition ErrorCodes.h:69
#define DEBUGGER_ERROR_UNKNOWN_TEST_QUERY_RECEIVED
error, unknown test query is received
Definition ErrorCodes.h:399
@ TEST_BREAKPOINT_TURN_OFF_DBS
Definition RequestStructures.h:347
@ TEST_BREAKPOINT_TURN_ON_BPS_AND_EVENTS_FOR_COMMANDS_IN_REMOTE_COMPUTER
Definition RequestStructures.h:343
@ TEST_BREAKPOINT_TURN_OFF_BPS
Definition RequestStructures.h:340
@ TEST_BREAKPOINT_TURN_ON_DBS
Definition RequestStructures.h:348
@ TEST_SETTING_TARGET_TASKS_ON_HALTED_CORES_ASYNCHRONOUS
Definition RequestStructures.h:345
@ TEST_BREAKPOINT_TURN_ON_BPS
Definition RequestStructures.h:341
@ TEST_SETTING_TARGET_TASKS_ON_HALTED_CORES_SYNCHRONOUS
Definition RequestStructures.h:344
@ TEST_QUERY_PREALLOCATED_POOL_STATE
Definition RequestStructures.h:338
@ TEST_QUERY_HALTING_CORE_STATUS
Definition RequestStructures.h:337
@ TEST_QUERY_TRAP_STATE
Definition RequestStructures.h:339
@ TEST_SETTING_TARGET_TASKS_ON_TARGET_HALTED_CORES
Definition RequestStructures.h:346
@ TEST_BREAKPOINT_TURN_OFF_BPS_AND_EVENTS_FOR_COMMANDS_IN_REMOTE_COMPUTER
Definition RequestStructures.h:342
BOOLEAN g_InterceptDebugBreaks
shows whether the debugger should intercept breakpoints (DB) or not
Definition Global.h:169
BOOLEAN g_InterceptBreakpoints
shows whether the debugger should intercept breakpoints (BP) or not
Definition Global.h:163
BOOLEAN g_InterceptBreakpointsAndEventsForCommandsInRemoteComputer
To avoid getting stuck from getting hit from the breakpoints while executing the commands in the remo...
Definition Global.h:214
_Use_decl_annotations_ BOOLEAN CommonValidateCoreNumber(UINT32 CoreNumber)
Validate core number.
Definition Common.c:256
UINT64 Context
Definition RequestStructures.h:359
UINT32 KernelStatus
Definition RequestStructures.h:360
DEBUGGER_TEST_QUERY_STATE RequestType
Definition RequestStructures.h:358

◆ KdQueryDebuggerQueryThreadOrProcessTracingDetailsByCoreId()

BOOLEAN KdQueryDebuggerQueryThreadOrProcessTracingDetailsByCoreId ( UINT32 CoreId,
DEBUGGER_THREAD_PROCESS_TRACING TracingType )

Query for process/thread interception status.

Parameters
CoreId
TracingType
Returns
BOOLEAN whether it's activated or not
208{
209 BOOLEAN Result = FALSE;
210 PROCESSOR_DEBUGGING_STATE * DbgState = &g_DbgState[CoreId];
211
212 switch (TracingType)
213 {
215
217
218 break;
219
221
223
224 break;
225
227
229
230 break;
231
233
235
236 break;
237
238 default:
239
240 LogError("Err, debugger encountered an unknown query type for querying process or thread interception details");
241
242 break;
243 }
244
245 return Result;
246}
@ DEBUGGER_THREAD_PROCESS_TRACING_INTERCEPT_CLOCK_INTERRUPTS_FOR_THREAD_CHANGE
Definition DataTypes.h:139
@ DEBUGGER_THREAD_PROCESS_TRACING_INTERCEPT_CLOCK_INTERRUPTS_FOR_PROCESS_CHANGE
Definition DataTypes.h:140
@ DEBUGGER_THREAD_PROCESS_TRACING_INTERCEPT_CLOCK_DEBUG_REGISTER_INTERCEPTION
Definition DataTypes.h:141
@ DEBUGGER_THREAD_PROCESS_TRACING_INTERCEPT_CLOCK_WAITING_FOR_MOV_CR3_VM_EXITS
Definition DataTypes.h:142
BOOLEAN InterceptClockInterruptsForProcessChange
Definition State.h:63
BOOLEAN DebugRegisterInterceptionState
Definition State.h:56
BOOLEAN IsWatingForMovCr3VmExits
Definition State.h:62
BOOLEAN InterceptClockInterruptsForThreadChange
Definition State.h:57

◆ KdQueryIgnoreHandlingMov2DebugRegs()

BOOLEAN KdQueryIgnoreHandlingMov2DebugRegs ( UINT32 CoreId)

Query to ignore handling mov 2 debug regs exiting.

Parameters
CoreId
Returns
BOOLEAN whether it's activated or not
256{
257 //
258 // Handle access to debug registers, if we should not ignore it, it is
259 // because on detecting thread scheduling we ignore the hardware debug
260 // registers modifications
261 //
264}
BOOLEAN KdQueryDebuggerQueryThreadOrProcessTracingDetailsByCoreId(UINT32 CoreId, DEBUGGER_THREAD_PROCESS_TRACING TracingType)
Query for process/thread interception status.
Definition Kd.c:206

◆ KdQueryRflagTrapState()

VOID KdQueryRflagTrapState ( )

Query state of the RFLAG's traps.

Returns
VOID
1642{
1643 //
1644 // show the number of items
1645 //
1646 LogInfo("Number of valid entries: 0x%x\n"
1647 "(Please be aware that only top 0x%x items are considered valid. "
1648 "There could be other items present in the array, but they are not valid.)",
1649 g_TrapFlagState.NumberOfItems,
1650 g_TrapFlagState.NumberOfItems);
1651
1652 for (SIZE_T i = 0; i < MAXIMUM_NUMBER_OF_THREAD_INFORMATION_FOR_TRAPS; i++)
1653 {
1654 LogInfo("g_TrapFlagState.ThreadInformation[%d].ProcessId = %x | ThreadId = %x",
1655 i,
1656 g_TrapFlagState.ThreadInformation[i].Fields.ProcessId,
1657 g_TrapFlagState.ThreadInformation[i].Fields.ThreadId);
1658 }
1659}
#define MAXIMUM_NUMBER_OF_THREAD_INFORMATION_FOR_TRAPS
maximum number of thread/process ids to be allocated for a simultaneous debugging
Definition Constants.h:409
DEBUGGER_TRAP_FLAG_STATE g_TrapFlagState
State of the trap-flag.
Definition Global.h:77

◆ KdQuerySystemState()

VOID KdQuerySystemState ( )

Query state of the system.

Returns
VOID
1729{
1730 ULONG ProcessorsCount;
1731
1732 ProcessorsCount = KeQueryActiveProcessorCount(0);
1733
1734 //
1735 // Query core debugging Lock info
1736 //
1737 Log("================================================ Debugging Lock Info ================================================\n");
1738
1739 for (SIZE_T i = 0; i < ProcessorsCount; i++)
1740 {
1741 if (SpinlockCheckLock(&g_DbgState[i].Lock))
1742 {
1743 LogInfo("Core : %d is locked", i);
1744 }
1745 else
1746 {
1747 LogInfo("Core : %d isn't locked", i);
1748 }
1749 }
1750
1751 //
1752 // Query if the core is halted (or NMI is received) when the debuggee
1753 // was in the vmx-root mode
1754 //
1755 Log("\n================================================ NMI Receiver State =======+=========================================\n");
1756
1757 for (SIZE_T i = 0; i < ProcessorsCount; i++)
1758 {
1759 if (g_DbgState[i].NmiState.NmiCalledInVmxRootRelatedToHaltDebuggee)
1760 {
1761 LogInfo("Core : %d - called from an NMI that is called in VMX-root mode", i);
1762 }
1763 else
1764 {
1765 LogInfo("Core : %d - not called from an NMI handler (through the immediate VM-exit mechanism)", i);
1766 }
1767 }
1768}
#define Log(format,...)
Log without any prefix.
Definition HyperDbgHyperLogIntrinsics.h:129

◆ KdRegularStepOver()

VOID KdRegularStepOver ( UINT64 LastRip,
BOOLEAN IsNextInstructionACall,
UINT32 CallLength )

Regular step-over, step one instruction to the debuggee if there is a call then it jumps the call.

Parameters
LastRipLast RIP register
IsNextInstructionACall
CallLength
Returns
VOID
434{
435 UINT64 NextAddressForHardwareDebugBp = 0;
436 ULONG ProcessorsCount;
437
438 // LogInfo("Last Rip: %llx, IsNextInstructionACall: %s, Call length: %x",
439 // LastRip,
440 // IsNextInstructionACall ? "true" : "false",
441 // CallLength);
442
443 if (IsNextInstructionACall)
444 {
445 //
446 // It's a call, we should put a hardware debug register breakpoint
447 // on the next instruction
448 //
449 NextAddressForHardwareDebugBp = LastRip + CallLength;
450
451 ProcessorsCount = KeQueryActiveProcessorCount(0);
452
453 //
454 // Store the detail of the hardware debug register to avoid trigger
455 // in other processes
456 //
457 g_HardwareDebugRegisterDetailsForStepOver.Address = NextAddressForHardwareDebugBp;
458 g_HardwareDebugRegisterDetailsForStepOver.ProcessId = HANDLE_TO_UINT32(PsGetCurrentProcessId());
459 g_HardwareDebugRegisterDetailsForStepOver.ThreadId = HANDLE_TO_UINT32(PsGetCurrentThreadId());
460
461 //
462 // Add hardware debug breakpoints on all core on vm-entry
463 //
464 for (SIZE_T i = 0; i < ProcessorsCount; i++)
465 {
466 g_DbgState[i].HardwareDebugRegisterForStepping = NextAddressForHardwareDebugBp;
467 }
468 }
469 else
470 {
471 //
472 // Any instruction other than call (regular step)
473 //
475 }
476}

◆ KdReloadSymbolDetailsInDebuggee()

_Use_decl_annotations_ VOID KdReloadSymbolDetailsInDebuggee ( PDEBUGGEE_SYMBOL_REQUEST_PACKET SymPacket)

Notify user-mode to re-send (reload) the symbol packets.

Parameters
SymPacket
Returns
VOID
815{
816 //
817 // Check if the priority buffer is full or not
818 //
820
821 //
822 // Send one byte buffer and operation codes
823 //
825 SymPacket,
827 TRUE);
828}
#define OPERATION_COMMAND_FROM_DEBUGGER_RELOAD_SYMBOL
Definition Constants.h:389

◆ KdResponsePacketToDebugger()

_Use_decl_annotations_ BOOLEAN KdResponsePacketToDebugger ( DEBUGGER_REMOTE_PACKET_TYPE PacketType,
DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION Response,
CHAR * OptionalBuffer,
UINT32 OptionalBufferLength )

Sends a HyperDbg response packet to the debugger.

Parameters
PacketType
Response
OptionalBuffer
OptionalBufferLength
Returns
BOOLEAN
304{
305 DEBUGGER_REMOTE_PACKET Packet = {0};
306 BOOLEAN Result = FALSE;
307
308 //
309 // Make the packet's structure
310 //
312 Packet.TypeOfThePacket = PacketType;
313
314 //
315 // Set the requested action
316 //
317 Packet.RequestedActionOfThePacket = Response;
318
319 //
320 // Send the serial packets to the debugger
321 //
322 if (OptionalBuffer == NULL || OptionalBufferLength == 0)
323 {
324 Packet.Checksum = KdComputeDataChecksum((PVOID)((UINT64)&Packet + 1),
325 sizeof(DEBUGGER_REMOTE_PACKET) - sizeof(BYTE));
326
327 //
328 // Check if we're in Vmx-root, if it is then we use our customized HIGH_IRQL Spinlock,
329 // if not we use the windows spinlock
330 //
333 Result = SerialConnectionSend((CHAR *)&Packet,
334 sizeof(DEBUGGER_REMOTE_PACKET)));
335 }
336 else
337 {
338 Packet.Checksum = KdComputeDataChecksum((PVOID)((UINT64)&Packet + 1),
339 sizeof(DEBUGGER_REMOTE_PACKET) - sizeof(BYTE));
340
341 Packet.Checksum += KdComputeDataChecksum((PVOID)OptionalBuffer, OptionalBufferLength);
342
343 //
344 // Check if we're in Vmx-root, if it is then we use our customized HIGH_IRQL Spinlock,
345 // if not we use the windows spinlock
346 //
347
350 Result = SerialConnectionSendTwoBuffers((CHAR *)&Packet,
352 OptionalBuffer,
353 OptionalBufferLength));
354 }
355
356 if (g_IgnoreBreaksToDebugger.PauseBreaksUntilSpecialMessageSent && g_IgnoreBreaksToDebugger.SpeialEventResponse == Response)
357 {
358 //
359 // Set it to false by zeroing it
360 //
362 }
363
364 return Result;
365}
BOOLEAN SerialConnectionSendTwoBuffers(CHAR *Buffer1, UINT32 Length1, CHAR *Buffer2, UINT32 Length2)
Perform sending 2 not appended buffers over serial.
Definition SerialConnection.c:192
BOOLEAN SerialConnectionSend(CHAR *Buffer, UINT32 Length)
Perform sending buffer over serial.
Definition SerialConnection.c:155

◆ KdSendCommandFinishedSignal()

VOID KdSendCommandFinishedSignal ( UINT32 CoreId)

Notify debugger that the execution of command finished.

Parameters
CoreId
Returns
VOID
888{
889 //
890 // Halt other cores again
891 //
894 NULL);
895}
_Use_decl_annotations_ VOID KdHandleBreakpointAndDebugBreakpointsCallback(UINT32 CoreId, DEBUGGEE_PAUSING_REASON Reason, PDEBUGGER_TRIGGERED_EVENT_DETAILS EventDetails)
Handle DBs and BPs for kernel debugger.
Definition Kd.c:1087
@ DEBUGGEE_PAUSING_REASON_DEBUGGEE_COMMAND_EXECUTION_FINISHED
Definition Connection.h:34

◆ KdSendFormatsFunctionResult()

VOID KdSendFormatsFunctionResult ( UINT64 Value)

Send the result of formats command to the kernel debugger.

Parameters
Value
Returns
VOID
864{
865 DEBUGGEE_FORMATS_PACKET FormatsPacket = {0};
866
868 FormatsPacket.Value = Value;
869
870 //
871 // Kernel debugger is active, we should send the bytes over serial
872 //
876 (CHAR *)&FormatsPacket,
878}
@ DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_DEBUGGEE_RESULT_OF_FORMATS
Definition Connection.h:118
struct _DEBUGGEE_FORMATS_PACKET DEBUGGEE_FORMATS_PACKET
check so the INTERRUPT_DESCRIPTOR_TABLE_ENTRIES_PACKETS should be smaller than packet size
RequestedActionOfThePacket Value(0x1) 00000000
UINT32 Result
Definition RequestStructures.h:1493
UINT64 Value
Definition RequestStructures.h:1492

◆ KdSwitchCore()

BOOLEAN KdSwitchCore ( PROCESSOR_DEBUGGING_STATE * DbgState,
DEBUGGEE_CHANGE_CORE_PACKET * ChangeCorePacket )

change the current operating core to new core

Parameters
DbgStateThe state of the debugger on the current core
ChangeCorePacket
Returns
BOOLEAN
701{
702 ULONG ProcessorsCount = KeQueryActiveProcessorCount(0);
703
704 if (DbgState->CoreId == ChangeCorePacket->NewCore)
705 {
706 //
707 // The operating core and the target core is the same, no need for further action
708 //
709 ChangeCorePacket->Result = DEBUGGER_OPERATION_WAS_SUCCESSFUL;
710 return FALSE; // Return FALSE to not unlock anything
711 }
712
713 //
714 // Check if core is valid or not
715 //
716 if (ChangeCorePacket->NewCore >= ProcessorsCount)
717 {
718 //
719 // Invalid core count
720 //
722 return FALSE;
723 }
724
725 //
726 // *** Core is valid ***
727 //
728
729 //
730 // Check to see whether this core is locked or not
731 //
732 if (!KdCheckTargetCoreIsLocked(ChangeCorePacket->NewCore))
733 {
735 return FALSE;
736 }
737
738 //
739 // Check if we should enable interrupts in this core or not
740 //
742
743 //
744 // Unset the current operating core (this is not important as if we
745 // return from the operating function then the it will be unset
746 // automatically but as we want to not have two operating cores
747 // at the same time so we unset it here too)
748 //
749 DbgState->MainDebuggingCore = FALSE;
750
751 //
752 // Set new operating core
753 //
754 g_DbgState[ChangeCorePacket->NewCore].MainDebuggingCore = TRUE;
755
756 //
757 // Unlock the new core
758 // *** We should not unlock the spinlock here as the other core might
759 // simultaneously start sending packets and corrupt our packets ***
760 //
761 ChangeCorePacket->Result = DEBUGGER_OPERATION_WAS_SUCCESSFUL;
762 return TRUE;
763}
BOOLEAN KdCheckTargetCoreIsLocked(UINT32 CoreNumber)
Check whether a specific target core is locked or not.
Definition Kd.c:1700
#define DEBUGGER_ERROR_PREPARING_DEBUGGEE_INVALID_CORE_IN_REMOTE_DEBUGGE
error, invalid core selected in changing core in remote debuggee
Definition ErrorCodes.h:158
#define DEBUGGER_ERROR_TARGET_SWITCHING_CORE_IS_NOT_LOCKED
error, switching to the target core is not possible because core is not locked (probably due to a rac...
Definition ErrorCodes.h:534
UINT32 Result
Definition RequestStructures.h:649
UINT32 NewCore
Definition RequestStructures.h:648

◆ KdUninitializeKernelDebugger()

VOID KdUninitializeKernelDebugger ( )

uninitialize kernel debugger

this function should be called on vmx non-root

Returns
VOID
69{
70 ULONG ProcessorsCount;
71
73 {
74 ProcessorsCount = KeQueryActiveProcessorCount(0);
75
76 //
77 // Indicate that the kernel debugger is not active
78 //
80
81 //
82 // Reset pause break requests
83 //
85
86 //
87 // Remove all active breakpoints
88 //
90
91 //
92 // Disable vm-exit on Hardware debug exceptions and breakpoints
93 // so, not intercept #DBs and #BP by changing exception bitmap (one core)
94 //
96 }
97}
VOID BreakpointRemoveAllBreakpoints()
Remove all the breakpoints if possible.
Definition BreakpointCommands.c:859
IMPORT_EXPORT_VMM VOID BroadcastDisableDbAndBpExitingAllCores()
routines to unset vm-exit on all DBs and BP on all cores
Definition Broadcast.c:49

◆ KdUnlockTheHaltedCore()

VOID KdUnlockTheHaltedCore ( PROCESSOR_DEBUGGING_STATE * DbgState)

unlock the target core

Parameters
DbgStateThe state of the debugger on the target core
Returns
VOID
1779{
1780 SpinlockUnlock(&DbgState->Lock);
1781}