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

Header for routines related to kernel mode debugging. More...

Go to the source code of this file.

Classes

struct  _DEBUGGEE_REQUEST_TO_CHANGE_PROCESS
 request to change the process More...
 
struct  _DEBUGGEE_REQUEST_TO_CHANGE_THREAD
 request to change the thread More...
 
struct  _DEBUGGEE_REQUEST_TO_IGNORE_BREAKS_UNTIL_AN_EVENT
 request to pause and halt the system More...
 
struct  _HARDWARE_DEBUG_REGISTER_DETAILS
 store the details of a hardware debug register to ignore any trigger for other threads More...
 

Typedefs

typedef struct _DEBUGGEE_REQUEST_TO_CHANGE_PROCESS DEBUGGEE_REQUEST_TO_CHANGE_PROCESS
 request to change the process
 
typedef struct _DEBUGGEE_REQUEST_TO_CHANGE_PROCESSPDEBUGGEE_REQUEST_TO_CHANGE_PROCESS
 
typedef struct _DEBUGGEE_REQUEST_TO_CHANGE_THREAD DEBUGGEE_REQUEST_TO_CHANGE_THREAD
 request to change the thread
 
typedef struct _DEBUGGEE_REQUEST_TO_CHANGE_THREADPDEBUGGEE_REQUEST_TO_CHANGE_THREAD
 
typedef struct _DEBUGGEE_REQUEST_TO_IGNORE_BREAKS_UNTIL_AN_EVENT DEBUGGEE_REQUEST_TO_IGNORE_BREAKS_UNTIL_AN_EVENT
 request to pause and halt the system
 
typedef struct _DEBUGGEE_REQUEST_TO_IGNORE_BREAKS_UNTIL_AN_EVENTPDEBUGGEE_REQUEST_TO_IGNORE_BREAKS_UNTIL_AN_EVENT
 
typedef struct _HARDWARE_DEBUG_REGISTER_DETAILS HARDWARE_DEBUG_REGISTER_DETAILS
 store the details of a hardware debug register to ignore any trigger for other threads
 
typedef struct _HARDWARE_DEBUG_REGISTER_DETAILSPHARDWARE_DEBUG_REGISTER_DETAILS
 

Functions

VOID KdHaltSystem (PDEBUGGER_PAUSE_PACKET_RECEIVED PausePacket)
 Halt the system.
 
VOID KdHandleDebugEventsWhenKernelDebuggerIsAttached (PROCESSOR_DEBUGGING_STATE *DbgState, BOOLEAN TrapSetByDebugger)
 Handles debug events when kernel-debugger is attached.
 
VOID KdManageSystemHaltOnVmxRoot (PROCESSOR_DEBUGGING_STATE *DbgState, PDEBUGGER_TRIGGERED_EVENT_DETAILS EventDetails)
 manage system halt on vmx-root mode
 
BOOLEAN KdCheckAndHandleNmiCallback (_In_ UINT32 CoreId)
 
VOID KdHandleNmi (_Inout_ PROCESSOR_DEBUGGING_STATE *DbgState)
 
VOID KdInitializeKernelDebugger ()
 initialize kernel debugger
 
VOID KdUninitializeKernelDebugger ()
 uninitialize kernel debugger
 
VOID KdInitializeInstantEventPools ()
 Initialize the required pools for instant events.
 
VOID KdSendFormatsFunctionResult (UINT64 Value)
 Notify user-mode to unload the debuggee and close the connections.
 
VOID KdSendCommandFinishedSignal (UINT32 CoreId)
 Notify debugger that the execution of command finished.
 
VOID KdHandleBreakpointAndDebugBreakpointsCallback (_In_ UINT32 CoreId, _In_ DEBUGGEE_PAUSING_REASON Reason, PDEBUGGER_TRIGGERED_EVENT_DETAILS EventDetails)
 
VOID KdHandleBreakpointAndDebugBreakpoints (_Inout_ PROCESSOR_DEBUGGING_STATE *DbgState, _In_ DEBUGGEE_PAUSING_REASON Reason, PDEBUGGER_TRIGGERED_EVENT_DETAILS EventDetails)
 
VOID KdHandleRegisteredMtfCallback (_In_ UINT32 CoreId)
 
VOID KdHandleHaltsWhenNmiReceivedFromVmxRoot (_Inout_ PROCESSOR_DEBUGGING_STATE *DbgState)
 
BOOLEAN KdCheckImmediateMessagingMechanism (UINT32 OperationCode)
 Checks whether the immediate messaging mechism is needed or not.
 
BOOLEAN KdResponsePacketToDebugger (_In_ _Strict_type_match_ DEBUGGER_REMOTE_PACKET_TYPE PacketType, _In_ _Strict_type_match_ DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION Response, _In_reads_bytes_opt_(OptionalBufferLength) CHAR *OptionalBuffer, _In_ UINT32 OptionalBufferLength)
 
BOOLEAN KdLoggingResponsePacketToDebugger (_In_reads_bytes_(OptionalBufferLength) CHAR *OptionalBuffer, _In_ UINT32 OptionalBufferLength, _In_ UINT32 OperationCode)
 
BOOLEAN KdCheckGuestOperatingModeChanges (UINT16 PreviousCsSelector, UINT16 CurrentCsSelector)
 Check if the execution mode (kernel-mode to user-mode or user-mode to kernel-mode) changed.
 
BOOLEAN KdIsGuestOnUsermode32Bit ()
 determines if the guest was in 32-bit user-mode or 64-bit (long mode)
 
VOID KdHandleNmiBroadcastDebugBreaks (UINT32 CoreId, BOOLEAN IsOnVmxNmiHandler)
 Handle broadcast NMIs for halting cores in vmx-root mode.
 
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 KdQueryDebuggerQueryThreadOrProcessTracingDetailsByCoreId (UINT32 CoreId, DEBUGGER_THREAD_PROCESS_TRACING TracingType)
 Query for process/thread interception status.
 

Variables

volatile LONG DebuggerResponseLock
 Vmx-root lock for sending response of debugger.
 
volatile LONG DebuggerHandleBreakpointLock
 Vmx-root lock for handling breaks to debugger.
 

Detailed Description

Header for routines related to kernel mode debugging.

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

Typedef Documentation

◆ DEBUGGEE_REQUEST_TO_CHANGE_PROCESS

request to change the process

◆ DEBUGGEE_REQUEST_TO_CHANGE_THREAD

request to change the thread

◆ DEBUGGEE_REQUEST_TO_IGNORE_BREAKS_UNTIL_AN_EVENT

◆ HARDWARE_DEBUG_REGISTER_DETAILS

store the details of a hardware debug register to ignore any trigger for other threads

◆ PDEBUGGEE_REQUEST_TO_CHANGE_PROCESS

◆ PDEBUGGEE_REQUEST_TO_CHANGE_THREAD

◆ PDEBUGGEE_REQUEST_TO_IGNORE_BREAKS_UNTIL_AN_EVENT

◆ PHARDWARE_DEBUG_REGISTER_DETAILS

Function Documentation

◆ KdCheckAndHandleNmiCallback()

BOOLEAN KdCheckAndHandleNmiCallback ( _In_ UINT32 CoreId)

◆ 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
1454{
1455 PreviousCsSelector = PreviousCsSelector & ~3;
1456 CurrentCsSelector = CurrentCsSelector & ~3;
1457
1458 //
1459 // Check if the execution modes are the same or not
1460 //
1461 if (PreviousCsSelector == CurrentCsSelector)
1462 {
1463 //
1464 // Execution modes are not changed
1465 //
1466 return FALSE;
1467 }
1468
1469 if ((PreviousCsSelector == KGDT64_R3_CODE || PreviousCsSelector == KGDT64_R3_CMCODE) && CurrentCsSelector == KGDT64_R0_CODE)
1470 {
1471 //
1472 // User-mode -> Kernel-mode
1473 //
1474 LogInfo("User-mode -> Kernel-mode\n");
1475 }
1476 else if ((CurrentCsSelector == KGDT64_R3_CODE || CurrentCsSelector == KGDT64_R3_CMCODE) && PreviousCsSelector == KGDT64_R0_CODE)
1477 {
1478 //
1479 // Kernel-mode to user-mode
1480 //
1481 LogInfo("Kernel-mode -> User-mode\n");
1482 }
1483 else if (CurrentCsSelector == KGDT64_R3_CODE && PreviousCsSelector == KGDT64_R3_CMCODE)
1484 {
1485 //
1486 // A heaven's gate (User-mode 32-bit code -> User-mode 64-bit code)
1487 //
1488 LogInfo("32-bit User-mode -> 64-bit User-mode (Heaven's gate)\n");
1489 }
1490 else if (PreviousCsSelector == KGDT64_R3_CODE && CurrentCsSelector == KGDT64_R3_CMCODE)
1491 {
1492 //
1493 // A heaven's gate (User-mode 64-bit code -> User-mode 32-bit code)
1494 //
1495 LogInfo("64-bit User-mode -> 32-bit User-mode (Return from Heaven's gate)\n");
1496 }
1497 else
1498 {
1499 LogError("Err, unknown changes in cs selector during the instrumentation step-in\n");
1500 }
1501
1502 //
1503 // Execution modes are changed
1504 //
1505 return TRUE;
1506}
#define TRUE
Definition BasicTypes.h:55
#define FALSE
Definition BasicTypes.h:54
#define LogError(format,...)
Log in the case of error.
Definition HyperDbgHyperLogIntrinsics.h:113
#define LogInfo(format,...)
Define log variables.
Definition HyperDbgHyperLogIntrinsics.h:71
#define KGDT64_R3_CODE
Definition Common.h:127
#define KGDT64_R0_CODE
Definition Common.h:123
#define KGDT64_R3_CMCODE
Definition Common.h:125

◆ KdCheckImmediateMessagingMechanism()

BOOLEAN KdCheckImmediateMessagingMechanism ( UINT32 OperationCode)

Checks whether the immediate messaging mechism is needed or not.

Parameters
OperationCode
Returns
BOOLEAN
121{
122 return (g_KernelDebuggerState && !(OperationCode & OPERATION_MANDATORY_DEBUGGEE_BIT));
123}
#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:359
BOOLEAN g_KernelDebuggerState
shows whether the kernel debugger is enabled or disabled
Definition Global.h:103

◆ 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
1826{
1827 return SpinlockCheckLock(&DbgState->Lock);
1828}
BOOLEAN SpinlockCheckLock(volatile LONG *Lock)
Check the lock without changing the state.
Definition Spinlock.c:169
volatile LONG Lock
Definition State.h:166

◆ KdHaltSystem()

VOID KdHaltSystem ( PDEBUGGER_PAUSE_PACKET_RECEIVED PausePacket)

Halt the system.

Parameters
PausePacket
Returns
VOID
3377{
3378 //
3379 // Broadcast to halt everything
3380 // Instead of broadcasting we will just send one vmcall and
3381 // from that point, we halt all the other cores by NMIs, this
3382 // way we are sure that we get all the other cores at the middle
3383 // of their execution codes and not on HyperDbg routines
3384 //
3385 // KdBroadcastHaltOnAllCores();
3386 //
3387
3388 //
3389 // vm-exit and halt current core
3390 //
3392
3393 //
3394 // Set the status
3395 //
3397}
#define DEBUGGER_VMCALL_VM_EXIT_HALT_SYSTEM
VMCALL to cause vm-exit and halt the system.
Definition DebuggerVmcalls.h:22
#define DEBUGGER_OPERATION_WAS_SUCCESSFUL
General value to indicate that the operation or request was successful.
Definition ErrorCodes.h:23
NTSTATUS VmFuncVmxVmcall(unsigned long long VmcallNumber, unsigned long long OptionalParam1, unsigned long long OptionalParam2, unsigned long long OptionalParam3)
Export for running VMX VMCALLs.
Definition Export.c:683
UINT32 Result
Definition DataTypes.h:179

◆ KdHandleBreakpointAndDebugBreakpoints()

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

◆ KdHandleBreakpointAndDebugBreakpointsCallback()

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

◆ 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
427{
428 DEBUGGER_TRIGGERED_EVENT_DETAILS TargetContext = {0};
429 BOOLEAN IgnoreDebugEvent = FALSE;
430 UINT64 LastVmexitRip = VmFuncGetLastVmexitRip(DbgState->CoreId);
431
432 //
433 // It's a breakpoint and should be handled by the kernel debugger
434 //
435 TargetContext.Context = (PVOID)LastVmexitRip;
436
437 if (TrapSetByDebugger)
438 {
439 //
440 // *** Handle a regular trap flag (most of the times as a result of stepping) set by the debugger ***
441 //
442
443 //
444 // Check and handle if there is a software defined breakpoint
445 //
447 LastVmexitRip,
449 FALSE))
450 {
452 {
453 //
454 // Check if it's caused by a step-over hardware debug breakpoint or not
455 //
457 {
460 {
461 //
462 // It's a step caused by a debug register breakpoint step-over
463 //
465 }
466 else
467 {
468 //
469 // Should be ignored because it's a hardware debug register that is
470 // likely triggered by other thread
471 //
472 IgnoreDebugEvent = TRUE;
473
474 //
475 // Also, we should re-apply the hardware debug breakpoint on this thread
476 //
479 FALSE,
481 }
482 }
483 }
484
485 if (!IgnoreDebugEvent)
486 {
487 //
488 // Handle a regular step
489 //
492 &TargetContext);
493 }
494 }
495 }
496 else
497 {
498 //
499 // It's a regular debug break event
500 //
503 &TargetContext);
504 }
505}
UCHAR BOOLEAN
Definition BasicTypes.h:39
unsigned __int64 UINT64
Definition BasicTypes.h:21
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:497
@ DEBUGGEE_PAUSING_REASON_DEBUGGEE_STEPPED
Definition Connection.h:27
@ DEBUGGEE_PAUSING_REASON_DEBUGGEE_HARDWARE_DEBUG_REGISTER_HIT
Definition Connection.h:30
@ BREAK_ON_INSTRUCTION_FETCH
Definition DataTypes.h:70
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
UINT64 VmFuncGetLastVmexitRip(UINT32 CoreId)
get the last vm-exit RIP
Definition Export.c:318
_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:1214
#define HANDLE_TO_UINT32(_var)
Definition MetaMacros.h:39
#define DEBUGGER_DEBUG_REGISTER_FOR_STEP_OVER
debug register for step-over
Definition Debugger.h:21
HARDWARE_DEBUG_REGISTER_DETAILS g_HardwareDebugRegisterDetailsForStepOver
Holds the state of hardware debug register for step-over.
Definition Global.h:61
NULL()
Definition test-case-generator.py:530
The structure of detail of a triggered event in HyperDbg.
Definition DataTypes.h:192
PVOID Context
Definition DataTypes.h:194
store the details of a hardware debug register to ignore any trigger for other threads
Definition Kd.h:73
UINT32 ThreadId
Definition Kd.h:76
UINT64 Address
Definition Kd.h:74
UINT32 ProcessId
Definition Kd.h:75
UINT32 CoreId
Definition State.h:169

◆ KdHandleHaltsWhenNmiReceivedFromVmxRoot()

VOID KdHandleHaltsWhenNmiReceivedFromVmxRoot ( _Inout_ PROCESSOR_DEBUGGING_STATE * DbgState)

◆ KdHandleNmi()

VOID KdHandleNmi ( _Inout_ PROCESSOR_DEBUGGING_STATE * DbgState)

◆ KdHandleNmiBroadcastDebugBreaks()

VOID KdHandleNmiBroadcastDebugBreaks ( UINT32 CoreId,
BOOLEAN IsOnVmxNmiHandler )

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

Parameters
CoreId
IsOnVmxNmiHandler
Returns
VOID
1063{
1064 //
1065 // Get the current debugging state
1066 //
1067 PROCESSOR_DEBUGGING_STATE * DbgState = &g_DbgState[CoreId];
1068
1069 //
1070 // We use it as a global flag (for both vmx-root and vmx non-root), because
1071 // generally it doesn't have any use case in vmx-root (IsOnVmxNmiHandler == FALSE)
1072 // but in some cases, we might set the MTF but another vm-exit receives before
1073 // MTF and in that place if it tries to trigger and event, then the MTF is not
1074 // handled and the core is not locked properly, just waits to get the handle
1075 // of the "DebuggerHandleBreakpointLock", so we check this flag there
1076 //
1077 DbgState->NmiState.WaitingToBeLocked = TRUE;
1078
1079 if (IsOnVmxNmiHandler)
1080 {
1081 //
1082 // Indicate that it's called from NMI handle, and it relates to
1083 // halting the debuggee
1084 //
1086
1087 //
1088 // If the core was in the middle of spinning on the spinlock
1089 // of getting the debug lock, this mechanism is not needed,
1090 // but if the core is not spinning there or the core is processing
1091 // a random vm-exit, then we inject an immediate vm-exit after vm-entry
1092 // or inject a DPC
1093 // this is used for two reasons.
1094 //
1095 // 1. first, we will get the registers (context) to halt the core
1096 // 2. second, it guarantees that if the NMI arrives within any
1097 // instruction in vmx-root mode, then we injected an immediate
1098 // vm-exit and we won't miss any cpu cycle in the guest
1099 //
1100 // KdFireDpc(KdHaltCoreInTheCaseOfHaltedFromNmiInVmxRoot, NULL);
1102 }
1103 else
1104 {
1105 //
1106 // Handle core break
1107 //
1108 KdHandleNmi(DbgState);
1109 }
1110}
VOID VmFuncSetMonitorTrapFlag(BOOLEAN Set)
Set the monitor trap flag.
Definition Export.c:98
_Use_decl_annotations_ VOID KdHandleNmi(PROCESSOR_DEBUGGING_STATE *DbgState)
Handle NMI Vm-exits.
Definition Kd.c:1365
PROCESSOR_DEBUGGING_STATE * g_DbgState
Save the state and variables related to debugging on each to logical core.
Definition Global.h:17
volatile BOOLEAN WaitingToBeLocked
Definition State.h:97
volatile BOOLEAN NmiCalledInVmxRootRelatedToHaltDebuggee
Definition State.h:96
Saves the debugger state.
Definition State.h:165
KD_NMI_STATE NmiState
Definition State.h:179

◆ KdHandleRegisteredMtfCallback()

VOID KdHandleRegisteredMtfCallback ( _In_ UINT32 CoreId)

◆ KdInitializeInstantEventPools()

VOID KdInitializeInstantEventPools ( )

Initialize the required pools for instant events.

Returns
VOID
132{
133 //
134 // Request pages to be allocated for regular instant events
135 //
137
138 //
139 // Request pages to be allocated for regular instant events's actions
140 //
142
143#if MAXIMUM_BIG_INSTANT_EVENTS >= 1
144
145 //
146 // Request pages to be allocated for big instant events
147 //
149
150 //
151 // Request pages to be allocated for big instant events's actions
152 //
154
155#endif // MAXIMUM_BIG_INSTANT_EVENTS
156
157 //
158 // Pre-allocate pools for possible EPT hooks
159 // Because there are possible init EPT hook structures, we only allocate the
160 // maximum number of regular instant event subtracted from the initial pages
161 //
163
165 {
166 LogWarning("Warning, cannot allocate the pre-allocated pools for EPT hooks");
167
168 //
169 // BTW, won't fail the starting phase because of this
170 //
171 }
172}
VOID ConfigureEptHookReservePreallocatedPoolsForEptHooks(UINT32 Count)
Allocate (reserve) pages for storing EPT hooks page hooks.
Definition Configuration.c:239
#define MAXIMUM_NUMBER_OF_INITIAL_PREALLOCATED_EPT_HOOKS
Maximum number of initial pre-allocated EPT hooks.
Definition Constants.h:260
#define BIG_INSTANT_EVENT_ACTION_BUFFER
Pre-allocated size for a big action + custom code or script buffer.
Definition Constants.h:300
#define REGULAR_INSTANT_EVENT_ACTION_BUFFER
Pre-allocated size for a regular action + custom code or script buffer.
Definition Constants.h:294
#define MAXIMUM_BIG_INSTANT_EVENTS
Maximum number of (big) instant events that are pre-allocated.
Definition Constants.h:276
#define MAXIMUM_REGULAR_INSTANT_EVENTS
Maximum number of (regular) instant events that are pre-allocated.
Definition Constants.h:270
#define REGULAR_INSTANT_EVENT_CONDITIONAL_BUFFER
Pre-allocated size for a regular event + conditions buffer.
Definition Constants.h:282
#define BIG_INSTANT_EVENT_CONDITIONAL_BUFFER
Pre-allocated size for a big event + conditions buffer.
Definition Constants.h:288
@ INSTANT_BIG_EVENT_BUFFER
Definition DataTypes.h:52
@ INSTANT_BIG_EVENT_ACTION_BUFFER
Definition DataTypes.h:54
@ INSTANT_REGULAR_EVENT_ACTION_BUFFER
Definition DataTypes.h:53
@ INSTANT_REGULAR_EVENT_BUFFER
Definition DataTypes.h:51
#define LogWarning(format,...)
Log in the case of warning.
Definition HyperDbgHyperLogIntrinsics.h:99
BOOLEAN PoolManagerCheckAndPerformAllocationAndDeallocation()
This function performs allocations from VMX non-root based on g_RequestNewAllocation.
Definition PoolManager.c:302
BOOLEAN PoolManagerRequestAllocation(SIZE_T Size, UINT32 Count, POOL_ALLOCATION_INTENTION Intention)
Request to allocate new buffers.
Definition PoolManager.c:415

◆ 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 // Request pages for breakpoint detail
40 //
44
45 //
46 // Enable vm-exit on Hardware debug exceptions and breakpoints
47 // so, intercept #DBs and #BP by changing exception bitmap (one core)
48 //
50
51 //
52 // Reset pause break requests
53 //
55
56 //
57 // Initialize list of breakpoints and breakpoint id
58 //
61
62 //
63 // Initial the needed pools for instant events
64 //
66
67 //
68 // Indicate that the kernel debugger is active
69 //
71}
VOID BroadcastEnableDbAndBpExitingAllCores()
routines to set vm-exit on all #DBs and #BP on all cores
Definition Broadcast.c:35
#define MAXIMUM_BREAKPOINTS_WITHOUT_CONTINUE
maximum number of buffers to be allocated for a single breakpoint
Definition Constants.h:398
@ BREAKPOINT_DEFINITION_STRUCTURE
Definition DataTypes.h:45
VOID KdInitializeInstantEventPools()
Initialize the required pools for instant events.
Definition Kd.c:131
FORCEINLINE VOID InitializeListHead(_Out_ PLIST_ENTRY ListHead)
Definition Windows.h:41
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:55
LIST_ENTRY g_BreakpointsListHead
List header of breakpoints for debugger-mode.
Definition Global.h:91
UINT64 g_MaximumBreakpointId
Seed for setting id of breakpoints.
Definition Global.h:97
The structure of storing breakpoints.
Definition State.h:72
request to pause and halt the system
Definition Kd.h:61

◆ 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
3108{
3109 //
3110 // Only 16 bit is needed however, vmwrite might write on other bits
3111 // and corrupt other variables, that's why we get 64bit
3112 //
3113 UINT64 CsSel = (UINT64)NULL;
3114
3115 //
3116 // Read guest's cs selector
3117 //
3118 CsSel = VmFuncGetCsSelector();
3119
3120 if (CsSel == KGDT64_R0_CODE)
3121 {
3122 //
3123 // 64-bit kernel-mode
3124 //
3125 return FALSE;
3126 }
3127 else if ((CsSel & ~3) == KGDT64_R3_CODE)
3128 {
3129 //
3130 // 64-bit user-mode
3131 //
3132 return FALSE;
3133 }
3134 else if ((CsSel & ~3) == KGDT64_R3_CMCODE)
3135 {
3136 //
3137 // 32-bit user-mode
3138 //
3139 return TRUE;
3140 }
3141 else
3142 {
3143 LogError("Err, unknown value for cs, cannot determine wow64 mode");
3144 }
3145
3146 //
3147 // By default, 64-bit
3148 //
3149 return FALSE;
3150}
UINT16 VmFuncGetCsSelector()
Read CS selector.
Definition Export.c:341

◆ KdLoggingResponsePacketToDebugger()

BOOLEAN KdLoggingResponsePacketToDebugger ( _In_reads_bytes_(OptionalBufferLength) CHAR * OptionalBuffer,
_In_ UINT32 OptionalBufferLength,
_In_ UINT32 OperationCode )

◆ 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
3164{
3165 DEBUGGEE_KD_PAUSED_PACKET PausePacket;
3166 ULONG ExitInstructionLength = 0;
3167 RFLAGS Rflags = {0};
3168 UINT64 LastVmexitRip = 0;
3169
3170 //
3171 // Perform Pre-halt tasks
3172 //
3173 KdApplyTasksPreHaltCore(DbgState);
3174
3175StartAgain:
3176
3177 //
3178 // We check for receiving buffer (unhalting) only on the
3179 // first core and not on every cores
3180 //
3181 if (DbgState->MainDebuggingCore)
3182 {
3183 //
3184 // *** Current Operating Core ***
3185 //
3186 RtlZeroMemory(&PausePacket, sizeof(DEBUGGEE_KD_PAUSED_PACKET));
3187
3188 //
3189 // Get the last RIP for vm-exit handler
3190 //
3191 LastVmexitRip = VmFuncGetRip();
3192
3193 //
3194 // Set the halt reason
3195 //
3196 PausePacket.PausingReason = g_DebuggeeHaltReason;
3197
3198 //
3199 // Set the current core
3200 //
3201 PausePacket.CurrentCore = DbgState->CoreId;
3202
3203 //
3204 // Set the RIP and mode of execution
3205 //
3206 PausePacket.Rip = LastVmexitRip;
3208
3209 //
3210 // Set disassembly state
3211 //
3212 PausePacket.IgnoreDisassembling = DbgState->IgnoreDisasmInNextPacket;
3213 DbgState->IgnoreDisasmInNextPacket = FALSE;
3214
3215 //
3216 // Set rflags for finding the results of conditional jumps
3217 //
3218 Rflags.AsUInt = VmFuncGetRflags();
3219 PausePacket.Rflags = Rflags.AsUInt;
3220
3221 //
3222 // Set the event tag (if it's an event)
3223 //
3224 if (EventDetails != NULL)
3225 {
3226 PausePacket.EventTag = EventDetails->Tag;
3227 PausePacket.EventCallingStage = EventDetails->Stage;
3228 }
3229
3230 //
3231 // Read the instruction len hint
3232 //
3233 if (DbgState->InstructionLengthHint != 0)
3234 {
3235 ExitInstructionLength = DbgState->InstructionLengthHint;
3236 }
3237 else
3238 {
3239 //
3240 // Reading instruction length (VMCS_VMEXIT_INSTRUCTION_LENGTH) won't work for anything that is not instruction exiting,
3241 // so we won't use it anymore
3242 //
3243
3244 //
3245 // Set the length to notify debuggee
3246 //
3247 ExitInstructionLength = CheckAddressMaximumInstructionLength((PVOID)LastVmexitRip);
3248 }
3249
3250 //
3251 // Set the reading length of bytes (for instruction disassembling)
3252 //
3253 PausePacket.ReadInstructionLen = (UINT16)ExitInstructionLength;
3254
3255 //
3256 // Find the current instruction
3257 //
3259 &PausePacket.InstructionBytesOnRip,
3260 ExitInstructionLength);
3261
3262 //
3263 // Send the pause packet, along with RIP and an indication
3264 // to pause to the debugger
3265 //
3268 (CHAR *)&PausePacket,
3270
3271 //
3272 // Perform Commands from the debugger
3273 //
3275
3276 //
3277 // Check if it's a change core event or not, otherwise finish the execution
3278 // and continue debuggee
3279 //
3280 if (!DbgState->MainDebuggingCore)
3281 {
3282 //
3283 // It's a core switch, start again
3284 //
3285 goto StartAgain;
3286 }
3287 }
3288 else
3289 {
3290 //
3291 // All cores except operating core
3292 //
3293
3294 //
3295 // Lock and unlock the lock so all core can get the lock
3296 // and continue their normal execution
3297 //
3298 DbgState->NmiState.WaitingToBeLocked = FALSE;
3299
3301 DbgState->Lock,
3302
3303 //
3304 // Check if it's a change core event or not
3305 //
3306 if (DbgState->MainDebuggingCore) {
3307 //
3308 // It's a core change event
3309 //
3310 g_DebuggeeHaltReason = DEBUGGEE_PAUSING_REASON_DEBUGGEE_CORE_SWITCHED;
3311
3312 goto StartAgain;
3313 }
3314
3315 );
3316
3317 //
3318 // Check if any task needs to be executed on this core or not
3319 //
3320 if (DbgState->HaltedCoreTask.PerformHaltedTask)
3321 {
3322 //
3323 // Indicate that the halted core is no longer needed to execute a task
3324 // as the current task is executed once
3325 //
3327
3328 //
3329 // Perform the target task
3330 //
3332 DbgState->HaltedCoreTask.TargetTask,
3333 DbgState->HaltedCoreTask.Context);
3334
3335 //
3336 // Check if the core needs to be locked again
3337 //
3338 if (DbgState->HaltedCoreTask.LockAgainAfterTask)
3339 {
3340 //
3341 // Lock again
3342 //
3343 SpinlockLock(&DbgState->Lock);
3344
3345 goto StartAgain;
3346 }
3347 }
3348 }
3349
3350 //
3351 // Apply the basic task for the core before continue
3352 //
3354}
UINT32 CheckAddressMaximumInstructionLength(PVOID Address)
This function returns the maximum instruction length that can be read from this address.
Definition AddressCheck.c:306
unsigned short UINT16
Definition BasicTypes.h:47
char CHAR
Definition BasicTypes.h:31
unsigned long ULONG
Definition BasicTypes.h:37
@ DEBUGGER_REMOTE_PACKET_TYPE_DEBUGGEE_TO_DEBUGGER
Definition Connection.h:164
@ DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_DEBUGGEE_PAUSED_AND_CURRENT_INSTRUCTION
Definition Connection.h:106
UINT64 VmFuncGetRflags()
Read guest's RFLAGS.
Definition Export.c:352
UINT64 VmFuncGetRip()
Read guest's RIP.
Definition Export.c:375
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:517
BOOLEAN KdIsGuestOnUsermode32Bit()
determines if the guest was in 32-bit user-mode or 64-bit (long mode)
Definition Kd.c:3107
VOID KdDispatchAndPerformCommandsFromDebugger(PROCESSOR_DEBUGGING_STATE *DbgState)
This function applies commands from the debugger to the debuggee.
Definition Kd.c:2292
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:556
_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:294
_Use_decl_annotations_ BOOLEAN MemoryMapperReadMemorySafeOnTargetProcess(UINT64 VaAddressToRead, PVOID BufferToSaveMemory, SIZE_T SizeToRead)
Read memory safely by mapping the buffer on the target process memory (It's a wrapper)
Definition MemoryMapper.c:1120
void SpinlockLock(volatile LONG *Lock)
Tries to get the lock and won't return until successfully get the lock.
Definition Spinlock.c:52
#define ScopedSpinlock(LockObject, CodeToRun)
Definition Spinlock.h:39
DEBUGGEE_PAUSING_REASON g_DebuggeeHaltReason
Reason that the debuggee is halted.
Definition Global.h:127
if(.test_var==4)
Definition script_conditional_statement_global_var.txt:5
BOOLEAN LockAgainAfterTask
Definition State.h:139
PVOID Context
Definition State.h:141
BOOLEAN PerformHaltedTask
Definition State.h:138
UINT64 TargetTask
Definition State.h:140
The structure of pausing packet in kHyperDbg.
Definition DataTypes.h:207
UINT16 ReadInstructionLen
Definition DataTypes.h:217
UINT64 Rip
Definition DataTypes.h:208
UINT64 Rflags
Definition DataTypes.h:215
BYTE InstructionBytesOnRip[MAXIMUM_INSTR_SIZE]
Definition DataTypes.h:216
BOOLEAN IsProcessorOn32BitMode
Definition DataTypes.h:209
DEBUGGEE_PAUSING_REASON PausingReason
Definition DataTypes.h:211
UINT64 EventTag
Definition DataTypes.h:213
ULONG CurrentCore
Definition DataTypes.h:212
BOOLEAN IgnoreDisassembling
Definition DataTypes.h:210
VMM_CALLBACK_EVENT_CALLING_STAGE_TYPE EventCallingStage
Definition DataTypes.h:214
UINT64 Tag
Definition DataTypes.h:193
VMM_CALLBACK_EVENT_CALLING_STAGE_TYPE Stage
Definition DataTypes.h:195
BOOLEAN IgnoreDisasmInNextPacket
Definition State.h:171
volatile BOOLEAN MainDebuggingCore
Definition State.h:167
UINT16 InstructionLengthHint
Definition State.h:182
DEBUGGEE_HALTED_CORE_TASK HaltedCoreTask
Definition State.h:180

◆ 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
221{
222 BOOLEAN Result = FALSE;
223 PROCESSOR_DEBUGGING_STATE * DbgState = &g_DbgState[CoreId];
224
225 switch (TracingType)
226 {
228
230
231 break;
232
234
236
237 break;
238
240
242
243 break;
244
246
248
249 break;
250
251 default:
252
253 LogError("Err, debugger encountered an unknown query type for querying process or thread interception details");
254
255 break;
256 }
257
258 return Result;
259}
@ DEBUGGER_THREAD_PROCESS_TRACING_INTERCEPT_CLOCK_INTERRUPTS_FOR_THREAD_CHANGE
Definition DataTypes.h:106
@ DEBUGGER_THREAD_PROCESS_TRACING_INTERCEPT_CLOCK_INTERRUPTS_FOR_PROCESS_CHANGE
Definition DataTypes.h:107
@ DEBUGGER_THREAD_PROCESS_TRACING_INTERCEPT_CLOCK_DEBUG_REGISTER_INTERCEPTION
Definition DataTypes.h:108
@ DEBUGGER_THREAD_PROCESS_TRACING_INTERCEPT_CLOCK_WAITING_FOR_MOV_CR3_VM_EXITS
Definition DataTypes.h:109
BOOLEAN InterceptClockInterruptsForProcessChange
Definition State.h:63
BOOLEAN DebugRegisterInterceptionState
Definition State.h:56
BOOLEAN IsWatingForMovCr3VmExits
Definition State.h:62
BOOLEAN InterceptClockInterruptsForThreadChange
Definition State.h:57
DEBUGGEE_PROCESS_OR_THREAD_TRACING_DETAILS ThreadOrProcessTracingDetails
Definition State.h:178

◆ KdResponsePacketToDebugger()

BOOLEAN KdResponsePacketToDebugger ( _In_ _Strict_type_match_ DEBUGGER_REMOTE_PACKET_TYPE PacketType,
_In_ _Strict_type_match_ DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION Response,
_In_reads_bytes_opt_(OptionalBufferLength) CHAR * OptionalBuffer,
_In_ UINT32 OptionalBufferLength )

◆ KdSendCommandFinishedSignal()

VOID KdSendCommandFinishedSignal ( UINT32 CoreId)

Notify debugger that the execution of command finished.

Parameters
CoreId
Returns
VOID
925{
926 //
927 // Halt other cores again
928 //
931 NULL);
932}
@ DEBUGGEE_PAUSING_REASON_DEBUGGEE_COMMAND_EXECUTION_FINISHED
Definition Connection.h:34
_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:1124

◆ KdSendFormatsFunctionResult()

VOID KdSendFormatsFunctionResult ( UINT64 Value)

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

Parameters
Value
Returns
VOID
901{
902 DEBUGGEE_FORMATS_PACKET FormatsPacket = {0};
903
905 FormatsPacket.Value = Value;
906
907 //
908 // Kernel debugger is active, we should send the bytes over serial
909 //
913 (CHAR *)&FormatsPacket,
915}
@ DEBUGGER_REMOTE_PACKET_REQUESTED_ACTION_DEBUGGEE_RESULT_OF_FORMATS
Definition Connection.h:111
RequestedActionOfThePacket Value(0x1) 00000000
The structure of .formats result packet in HyperDbg.
Definition RequestStructures.h:1033
UINT32 Result
Definition RequestStructures.h:1035
UINT64 Value
Definition RequestStructures.h:1034

◆ KdUninitializeKernelDebugger()

VOID KdUninitializeKernelDebugger ( )

uninitialize kernel debugger

this function should be called on vmx non-root

Returns
VOID
82{
83 ULONG ProcessorsCount;
84
86 {
87 ProcessorsCount = KeQueryActiveProcessorCount(0);
88
89 //
90 // Indicate that the kernel debugger is not active
91 //
93
94 //
95 // Reset pause break requests
96 //
98
99 //
100 // Remove all active breakpoints
101 //
103
104 //
105 // Disable vm-exit on Hardware debug exceptions and breakpoints
106 // so, not intercept #DBs and #BP by changing exception bitmap (one core)
107 //
109 }
110}
VOID BreakpointRemoveAllBreakpoints()
Remove all the breakpoints if possible.
Definition BreakpointCommands.c:803
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
1813{
1814 SpinlockUnlock(&DbgState->Lock);
1815}
void SpinlockUnlock(volatile LONG *Lock)
Release the lock.
Definition Spinlock.c:158

Variable Documentation

◆ DebuggerHandleBreakpointLock

volatile LONG DebuggerHandleBreakpointLock

Vmx-root lock for handling breaks to debugger.

◆ DebuggerResponseLock

volatile LONG DebuggerResponseLock

Vmx-root lock for sending response of debugger.