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

General debugger headers. More...

Go to the source code of this file.

Classes

struct  _DEBUGGER_CORE_EVENTS
 List of all the different events. More...
struct  _DEBUGGER_EVENT_ACTION
 The structure of actions in HyperDbg. More...
struct  _DEBUGGER_EVENT
 The structure of events in HyperDbg. More...

Macros

#define DEBUGGER_DEBUG_REGISTER_FOR_STEP_OVER   0
 debug register for step-over
#define DEBUGGER_DEBUG_REGISTER_FOR_THREAD_MANAGEMENT   1
 debug register to monitor thread changes

Typedefs

typedef struct _DEBUGGER_CORE_EVENTS DEBUGGER_CORE_EVENTS
 List of all the different events.
typedef struct _DEBUGGER_CORE_EVENTSPDEBUGGER_CORE_EVENTS
typedef struct _DEBUGGER_EVENT_ACTION DEBUGGER_EVENT_ACTION
 The structure of actions in HyperDbg.
typedef struct _DEBUGGER_EVENT_ACTIONPDEBUGGER_EVENT_ACTION
typedef struct _DEBUGGER_EVENT DEBUGGER_EVENT
 The structure of events in HyperDbg.
typedef struct _DEBUGGER_EVENTPDEBUGGER_EVENT
typedef UINT64 DebuggerCheckForCondition(PGUEST_REGS Regs, PVOID Context)
 The prototype that Condition codes are called.
typedef PVOID DebuggerRunCustomCodeFunc(PVOID PreAllocatedBufferAddress, PGUEST_REGS Regs, PVOID Context)
 The prototype that Custom code buffers are called.

Functions

UINT64 DebuggerGetRegValueWrapper (PGUEST_REGS GuestRegs, UINT32 RegId)
 A wrapper for GetRegValue() in script-engine.
UINT32 DebuggerGetLastError ()
 Debugger get the last error.
VOID DebuggerSetLastError (UINT32 LastError)
 Debugger set the last error.
BOOLEAN DebuggerInitializeScriptEngine ()
 Initialize script engine global variables and per-core stack buffers.
BOOLEAN DebuggerInitializeTrapsAndBreakpoints ()
 Initialize trap flag state and breakpoint related structures.
BOOLEAN DebuggerInitializeVmmOperations ()
 Initialize VMM operations (events and related operations).
BOOLEAN DebuggerInitialize ()
 Initialize Debugger Structures and Routines.
VOID DebuggerUninitializeVmmOperations ()
 Uninitialize Debugger VMM Operations (Events and other related operations).
VOID DebuggerUninitialize ()
 Uninitialize Debugger Structures and Routines.
PDEBUGGER_EVENT DebuggerCreateEvent (BOOLEAN Enabled, UINT32 CoreId, UINT32 ProcessId, VMM_EVENT_TYPE_ENUM EventType, UINT64 Tag, DEBUGGER_EVENT_OPTIONS *Options, UINT32 ConditionsBufferSize, PVOID ConditionBuffer, PDEBUGGER_EVENT_AND_ACTION_RESULT ResultsToReturn, BOOLEAN InputFromVmxRoot)
 Create an Event Object.
PDEBUGGER_EVENT_ACTION DebuggerAddActionToEvent (PDEBUGGER_EVENT Event, DEBUGGER_EVENT_ACTION_TYPE_ENUM ActionType, BOOLEAN SendTheResultsImmediately, PDEBUGGER_EVENT_REQUEST_CUSTOM_CODE InTheCaseOfCustomCode, PDEBUGGER_EVENT_ACTION_RUN_SCRIPT_CONFIGURATION InTheCaseOfRunScript, PDEBUGGER_EVENT_AND_ACTION_RESULT ResultsToReturn, BOOLEAN InputFromVmxRoot)
 Create an action and add the action to an event.
BOOLEAN DebuggerRegisterEvent (PDEBUGGER_EVENT Event)
 Register an event to a list of active events.
VMM_CALLBACK_TRIGGERING_EVENT_STATUS_TYPE DebuggerTriggerEvents (VMM_EVENT_TYPE_ENUM EventType, VMM_CALLBACK_EVENT_CALLING_STAGE_TYPE CallingStage, PVOID Context, BOOLEAN *PostEventRequired, GUEST_REGS *Regs)
 Trigger events of a special type to be managed by debugger.
PDEBUGGER_EVENT DebuggerGetEventByTag (UINT64 Tag)
 Find event object by tag.
BOOLEAN DebuggerRemoveEvent (UINT64 Tag, BOOLEAN PoolManagerAllocatedMemory)
 Remove the event by its tags and also remove its actions and de-allocate their buffers.
BOOLEAN DebuggerQueryDebuggerStatus ()
 Detect whether the user or kernel debugger is active or not.
BOOLEAN DebuggerParseEvent (PDEBUGGER_GENERAL_EVENT_DETAIL EventDetails, PDEBUGGER_EVENT_AND_ACTION_RESULT ResultsToReturn, BOOLEAN InputFromVmxRoot)
 Routine for parsing events.
BOOLEAN DebuggerApplyEvent (PDEBUGGER_EVENT Event, PDEBUGGER_EVENT_AND_ACTION_RESULT ResultsToReturn, BOOLEAN InputFromVmxRoot)
 Applying events.
BOOLEAN DebuggerParseAction (PDEBUGGER_GENERAL_ACTION Action, PDEBUGGER_EVENT_AND_ACTION_RESULT ResultsToReturn, BOOLEAN InputFromVmxRoot)
 Routine for validating and parsing actions that are coming from the user-mode.
BOOLEAN DebuggerParseEventsModification (PDEBUGGER_MODIFY_EVENTS DebuggerEventModificationRequest, BOOLEAN InputFromVmxRoot, BOOLEAN PoolManagerAllocatedMemory)
 Parse and validate requests to enable/disable/clear from the user-mode.
BOOLEAN DebuggerTerminateEvent (UINT64 Tag, BOOLEAN InputFromVmxRoot)
 Terminate one event's effect by its tag.
UINT32 DebuggerEventListCount (PLIST_ENTRY TargetEventList)
 Count the list of events in a special list.
VOID DebuggerClearAllEvents (BOOLEAN InputFromVmxRoot, BOOLEAN PoolManagerAllocatedMemory)
 Clear all events.
BOOLEAN DebuggerEnableOrDisableAllEvents (BOOLEAN IsEnable)
 Enable or disable all events from all the types.
UINT32 DebuggerEventListCountByCore (PLIST_ENTRY TargetEventList, UINT32 TargetCore)
 Count the list of events in a special list that are activate on a target core.
UINT32 DebuggerEventListCountByEventType (VMM_EVENT_TYPE_ENUM EventType, UINT32 TargetCore)
 Count the list of events by a special event type that are activate on a target core.
UINT32 DebuggerExceptionEventBitmapMask (UINT32 CoreIndex)
 Get the mask related to the !exception command for the target core.
BOOLEAN DebuggerIsTagValid (UINT64 Tag)
 Detect whether the tag exists or not.
BOOLEAN DebuggerEnableEvent (UINT64 Tag)
 Enable an event by tag.
BOOLEAN DebuggerQueryStateEvent (UINT64 Tag)
 returns whether an event is enabled/disabled by tag
BOOLEAN DebuggerDisableEvent (UINT64 Tag)
 Disable an event by tag.
BOOLEAN DebuggerClearEvent (UINT64 Tag, BOOLEAN InputFromVmxRoot, BOOLEAN PoolManagerAllocatedMemory)
 Clear an event by tag.
VOID DebuggerPerformActions (PROCESSOR_DEBUGGING_STATE *DbgState, DEBUGGER_EVENT *Event, DEBUGGER_TRIGGERED_EVENT_DETAILS *EventTriggerDetail)
 Run a special event's action(s).
VOID DebuggerPerformBreakToDebugger (PROCESSOR_DEBUGGING_STATE *DbgState, DEBUGGER_EVENT_ACTION *Action, DEBUGGER_TRIGGERED_EVENT_DETAILS *EventTriggerDetail)
 Manage breaking to the debugger action.
BOOLEAN DebuggerPerformRunScript (PROCESSOR_DEBUGGING_STATE *DbgState, DEBUGGER_EVENT_ACTION *Action, DEBUGGEE_SCRIPT_PACKET *ScriptDetails, DEBUGGER_TRIGGERED_EVENT_DETAILS *EventTriggerDetail)
 Managing run script action.
VOID DebuggerPerformRunTheCustomCode (PROCESSOR_DEBUGGING_STATE *DbgState, DEBUGGER_EVENT_ACTION *Action, DEBUGGER_TRIGGERED_EVENT_DETAILS *EventTriggerDetail)
 Manage running the custom code action.
PLIST_ENTRY DebuggerGetEventListByEventType (VMM_EVENT_TYPE_ENUM EventType)
 Get List of event based on event type.

Detailed Description

General debugger headers.

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

Macro Definition Documentation

◆ DEBUGGER_DEBUG_REGISTER_FOR_STEP_OVER

#define DEBUGGER_DEBUG_REGISTER_FOR_STEP_OVER   0

debug register for step-over

◆ DEBUGGER_DEBUG_REGISTER_FOR_THREAD_MANAGEMENT

#define DEBUGGER_DEBUG_REGISTER_FOR_THREAD_MANAGEMENT   1

debug register to monitor thread changes

Typedef Documentation

◆ DEBUGGER_CORE_EVENTS

List of all the different events.

◆ DEBUGGER_EVENT

The structure of events in HyperDbg.

◆ DEBUGGER_EVENT_ACTION

The structure of actions in HyperDbg.

◆ DebuggerCheckForCondition

typedef UINT64 DebuggerCheckForCondition(PGUEST_REGS Regs, PVOID Context)

The prototype that Condition codes are called.

Parameters
RegsGuest registers
ContextOptional parameter which is different for each event and shows a unique description about the event
Returns
UINT64 if return 0 then the event is not allowed to trigger and if any other value then the event is allowed to be triggered return value should be on RAX

◆ DebuggerRunCustomCodeFunc

typedef PVOID DebuggerRunCustomCodeFunc(PVOID PreAllocatedBufferAddress, PGUEST_REGS Regs, PVOID Context)

The prototype that Custom code buffers are called.

Parameters
PreAllocatedBufferAddressThe address of a pre-allocated non-paged pool if the user-requested for it
RegsGuest registers
ContextOptional parameter which is different for each event and shows a unique description about the event
Returns
PVOID A pointer to a buffer that should be delivered to the user-mode if returns null or an invalid address then nothing will be delivered return address should be on RAX

◆ PDEBUGGER_CORE_EVENTS

◆ PDEBUGGER_EVENT

typedef struct _DEBUGGER_EVENT * PDEBUGGER_EVENT

◆ PDEBUGGER_EVENT_ACTION

Function Documentation

◆ DebuggerAddActionToEvent()

PDEBUGGER_EVENT_ACTION DebuggerAddActionToEvent ( PDEBUGGER_EVENT Event,
DEBUGGER_EVENT_ACTION_TYPE_ENUM ActionType,
BOOLEAN SendTheResultsImmediately,
PDEBUGGER_EVENT_REQUEST_CUSTOM_CODE InTheCaseOfCustomCode,
PDEBUGGER_EVENT_ACTION_RUN_SCRIPT_CONFIGURATION InTheCaseOfRunScript,
PDEBUGGER_EVENT_AND_ACTION_RESULT ResultsToReturn,
BOOLEAN InputFromVmxRoot )

Create an action and add the action to an event.

Parameters
EventTarget event object
ActionTypeType of action
SendTheResultsImmediatelywhether the results should be received by the user-mode immediately
InTheCaseOfCustomCodeCustom code structure (if any)
InTheCaseOfRunScriptRun script structure (if any)
ResultsToReturnThe buffer address that should be returned to the user-mode as the result
InputFromVmxRootWhether the input comes from VMX root-mode or IOCTL
Returns
PDEBUGGER_EVENT_ACTION
714{
716 SIZE_T ActionBufferSize;
717 PVOID RequestedBuffer = NULL;
718
719 //
720 // Allocate action + allocate code for custom code
721 //
722
723 if (InTheCaseOfCustomCode != NULL)
724 {
725 //
726 // We should allocate extra buffer for custom code
727 //
728 ActionBufferSize = sizeof(DEBUGGER_EVENT_ACTION) + InTheCaseOfCustomCode->CustomCodeBufferSize;
729 }
730 else if (InTheCaseOfRunScript != NULL)
731 {
732 //
733 // We should allocate extra buffer for script
734 //
735 ActionBufferSize = sizeof(DEBUGGER_EVENT_ACTION) + InTheCaseOfRunScript->ScriptLength;
736 }
737 else
738 {
739 //
740 // We shouldn't allocate extra buffer as there is no custom code
741 //
742 ActionBufferSize = sizeof(DEBUGGER_EVENT_ACTION);
743 }
744
745 //
746 // Allocate buffer for storing the action
747 //
748
749 if (InputFromVmxRoot)
750 {
751 //
752 // *** The buffer is coming from VMX-root mode ***
753 //
754
755 //
756 // If the buffer is smaller than regular instant events's action
757 //
758 if (REGULAR_INSTANT_EVENT_ACTION_BUFFER >= ActionBufferSize)
759 {
760 //
761 // The buffer fits into a regular instant event's action
762 //
764
765 if (!Action)
766 {
767 //
768 // Here we try again to see if we could store it into a big instant event's action buffer instead
769 //
771
772 if (!Action)
773 {
774 //
775 // Set the error
776 //
777 ResultsToReturn->IsSuccessful = FALSE;
779
780 //
781 // There is a problem with allocating event's action
782 //
783 return NULL;
784 }
785 }
786 }
787 else if (BIG_INSTANT_EVENT_ACTION_BUFFER >= ActionBufferSize)
788 {
789 //
790 // The buffer fits into a big instant event's action buffer
791 //
793
794 if (!Action)
795 {
796 //
797 // Set the error
798 //
799 ResultsToReturn->IsSuccessful = FALSE;
801
802 //
803 // There is a problem with allocating event's action buffer
804 //
805 return NULL;
806 }
807 }
808 else
809 {
810 //
811 // The buffer doesn't fit into any of the regular or big event's action preallocated buffers
812 //
813
814 //
815 // Set the error
816 //
817 ResultsToReturn->IsSuccessful = FALSE;
819
820 return NULL;
821 }
822 }
823 else
824 {
825 //
826 // If it's not coming from the VMX-root mode then we're allocating it from the OS buffers
827 //
828 Action = PlatformMemAllocateZeroedNonPagedPool(ActionBufferSize);
829
830 if (Action == NULL)
831 {
832 //
833 // Set the appropriate error
834 //
835 ResultsToReturn->IsSuccessful = FALSE;
837
838 //
839 // There was an error in allocation
840 //
841 return NULL;
842 }
843 }
844
845 //
846 // If the user needs a buffer to be passed to the debugger then
847 // we should allocate it here (Requested buffer is only available for custom code types)
848 //
849 if (ActionType == RUN_CUSTOM_CODE &&
850 InTheCaseOfCustomCode != NULL &&
851 InTheCaseOfCustomCode->OptionalRequestedBufferSize != 0)
852 {
853 //
854 // Check if the optional buffer is not more that the size
855 // we can send to usermode
856 //
857 if (InTheCaseOfCustomCode->OptionalRequestedBufferSize >= MaximumPacketsCapacity)
858 {
859 //
860 // There was an error
861 //
862 if (InputFromVmxRoot)
863 {
864 PoolManagerFreePool((UINT64)Action);
865 }
866 else
867 {
868 PlatformMemFreePool(Action);
869 }
870
871 //
872 // Set the appropriate error
873 //
874 ResultsToReturn->IsSuccessful = FALSE;
876
877 return NULL;
878 }
879
880 //
881 // User needs a buffer to play with
882 //
883 RequestedBuffer = DebuggerAllocateSafeRequestedBuffer(InTheCaseOfCustomCode->OptionalRequestedBufferSize, ResultsToReturn, InputFromVmxRoot);
884
885 if (!RequestedBuffer)
886 {
887 //
888 // There was an error in allocation
889 //
890 if (InputFromVmxRoot)
891 {
892 PoolManagerFreePool((UINT64)Action);
893 }
894 else
895 {
896 PlatformMemFreePool(Action);
897 }
898
899 //
900 // Not need to set error as the above function already adjust the error
901 //
902 return NULL;
903 }
904
905 //
906 // Add it to the action
907 //
909 Action->RequestedBuffer.RequestBufferSize = InTheCaseOfCustomCode->OptionalRequestedBufferSize;
910 Action->RequestedBuffer.RequstBufferAddress = (UINT64)RequestedBuffer;
911 }
912
913 //
914 // If the user needs a buffer to be passed to the debugger script then
915 // we should allocate it here (Requested buffer is only available for custom code types)
916 //
917 if (ActionType == RUN_SCRIPT &&
918 InTheCaseOfRunScript != NULL &&
919 InTheCaseOfRunScript->OptionalRequestedBufferSize != 0)
920 {
921 //
922 // Check if the optional buffer is not more that the size
923 // we can send to usermode
924 //
925 if (InTheCaseOfRunScript->OptionalRequestedBufferSize >= MaximumPacketsCapacity)
926 {
927 //
928 // There was an error
929 //
930 if (InputFromVmxRoot)
931 {
932 PoolManagerFreePool((UINT64)Action);
933 }
934 else
935 {
936 PlatformMemFreePool(Action);
937 }
938
939 //
940 // Set the appropriate error
941 //
942 ResultsToReturn->IsSuccessful = FALSE;
944
945 return NULL;
946 }
947
948 //
949 // User needs a buffer to play with
950 //
951 RequestedBuffer = DebuggerAllocateSafeRequestedBuffer(InTheCaseOfRunScript->OptionalRequestedBufferSize, ResultsToReturn, InputFromVmxRoot);
952
953 if (!RequestedBuffer)
954 {
955 //
956 // There was an error in allocation
957 //
958 if (InputFromVmxRoot)
959 {
960 PoolManagerFreePool((UINT64)Action);
961 }
962 else
963 {
964 PlatformMemFreePool(Action);
965 }
966
967 //
968 // Not need to set error as the above function already adjust the error
969 //
970 return NULL;
971 }
972
973 //
974 // Add it to the action
975 //
977 Action->RequestedBuffer.RequestBufferSize = InTheCaseOfRunScript->OptionalRequestedBufferSize;
978 Action->RequestedBuffer.RequstBufferAddress = (UINT64)RequestedBuffer;
979 }
980
981 if (ActionType == RUN_CUSTOM_CODE && InTheCaseOfCustomCode != NULL)
982 {
983 //
984 // Check if it's a Custom code without custom code buffer which is invalid
985 //
986 if (InTheCaseOfCustomCode != NULL && InTheCaseOfCustomCode->CustomCodeBufferSize == 0)
987 {
988 //
989 // There was an error
990 //
991 if (InputFromVmxRoot)
992 {
993 PoolManagerFreePool((UINT64)Action);
994
995 if (RequestedBuffer != NULL)
996 {
997 PoolManagerFreePool((UINT64)RequestedBuffer);
998 }
999 }
1000 else
1001 {
1002 PlatformMemFreePool(Action);
1003
1004 if (RequestedBuffer != NULL)
1005 {
1006 PlatformMemFreePool(RequestedBuffer);
1007 }
1008 }
1009
1010 ResultsToReturn->IsSuccessful = FALSE;
1012
1013 return NULL;
1014 }
1015
1016 //
1017 // Move the custom code buffer to the end of the action
1018 //
1019 Action->CustomCodeBufferSize = InTheCaseOfCustomCode->CustomCodeBufferSize;
1020 Action->CustomCodeBufferAddress = (PVOID)((UINT64)Action + sizeof(DEBUGGER_EVENT_ACTION));
1021
1022 //
1023 // copy the custom code buffer to the end of the buffer of the action
1024 //
1025 memcpy(Action->CustomCodeBufferAddress, InTheCaseOfCustomCode->CustomCodeBufferAddress, InTheCaseOfCustomCode->CustomCodeBufferSize);
1026 }
1027
1028 //
1029 // If it's run script action type
1030 //
1031 else if (ActionType == RUN_SCRIPT && InTheCaseOfRunScript != NULL)
1032 {
1033 //
1034 // Check the buffers of run script
1035 //
1036 if (InTheCaseOfRunScript->ScriptBuffer == NULL64_ZERO || InTheCaseOfRunScript->ScriptLength == NULL_ZERO)
1037 {
1038 //
1039 // There was an error
1040 //
1041 if (InputFromVmxRoot)
1042 {
1043 PoolManagerFreePool((UINT64)Action);
1044
1045 if (RequestedBuffer != 0)
1046 {
1047 PoolManagerFreePool((UINT64)RequestedBuffer);
1048 }
1049 }
1050 else
1051 {
1052 PlatformMemFreePool(Action);
1053
1054 if (RequestedBuffer != 0)
1055 {
1056 PlatformMemFreePool(RequestedBuffer);
1057 }
1058 }
1059
1060 ResultsToReturn->IsSuccessful = FALSE;
1062
1063 return NULL;
1064 }
1065
1066 //
1067 // Allocate the buffer from a non-page pool on the script
1068 //
1069 Action->ScriptConfiguration.ScriptBuffer = (UINT64)((BYTE *)Action + sizeof(DEBUGGER_EVENT_ACTION));
1070
1071 //
1072 // Copy the memory of script to our non-paged pool
1073 //
1074 RtlCopyMemory((PVOID)Action->ScriptConfiguration.ScriptBuffer, (const PVOID)InTheCaseOfRunScript->ScriptBuffer, InTheCaseOfRunScript->ScriptLength);
1075
1076 //
1077 // Set other fields
1078 //
1079 Action->ScriptConfiguration.ScriptLength = InTheCaseOfRunScript->ScriptLength;
1080 Action->ScriptConfiguration.ScriptPointer = InTheCaseOfRunScript->ScriptPointer;
1082 }
1083
1084 //
1085 // Create an order code for the current action
1086 // and also increase the Count of action in event
1087 //
1088 Event->CountOfActions++;
1089 Action->ActionOrderCode = Event->CountOfActions;
1090
1091 //
1092 // Fill other parts of the action
1093 //
1094 Action->ImmediatelySendTheResults = SendTheResultsImmediately;
1095 Action->ActionType = ActionType;
1096 Action->Tag = Event->Tag;
1097
1098 //
1099 // Now we should add the action to the event's LIST_ENTRY of actions
1100 //
1101 InsertHeadList(&Event->ActionsListHead, &(Action->ActionsList));
1102
1103 return Action;
1104}
PVOID DebuggerAllocateSafeRequestedBuffer(SIZE_T SizeOfRequestedSafeBuffer, PDEBUGGER_EVENT_AND_ACTION_RESULT ResultsToReturn, BOOLEAN InputFromVmxRoot)
Allocates buffer for requested safe buffer.
Definition Debugger.c:592
PVOID PlatformMemAllocateZeroedNonPagedPool(SIZE_T NumberOfBytes)
Allocates zeroed non-paged pool memory.
Definition PlatformMem.c:248
PVOID PlatformMemFreePool(PVOID BufferAddress)
Frees a memory pool.
Definition PlatformMem.c:269
UINT64 PoolManagerRequestPool(POOL_ALLOCATION_INTENTION Intention, BOOLEAN RequestNewPool, UINT32 Size)
This function should be called from vmx-root in order to get a pool from the list.
Definition PoolManager.c:230
BOOLEAN PoolManagerFreePool(UINT64 AddressToFree)
This function set a pool flag to be freed, and it will be freed on the next IOCTL when it's safe to r...
Definition PoolManager.c:154
void * PVOID
Definition BasicTypes.h:56
#define NULL_ZERO
Definition BasicTypes.h:110
unsigned char BYTE
Definition BasicTypes.h:40
#define NULL64_ZERO
Definition BasicTypes.h:111
#define TRUE
Definition BasicTypes.h:114
#define FALSE
Definition BasicTypes.h:113
#define BIG_INSTANT_EVENT_ACTION_BUFFER
Pre-allocated size for a big action + custom code or script buffer.
Definition Constants.h:308
#define MaximumPacketsCapacity
Default buffer count of packets for message tracing.
Definition Constants.h:171
#define REGULAR_INSTANT_EVENT_ACTION_BUFFER
Pre-allocated size for a regular action + custom code or script buffer.
Definition Constants.h:302
@ INSTANT_BIG_EVENT_ACTION_BUFFER
Definition DataTypes.h:87
@ INSTANT_REGULAR_EVENT_ACTION_BUFFER
Definition DataTypes.h:86
#define DEBUGGER_ERROR_ACTION_BUFFER_SIZE_IS_ZERO
error, the action buffer size is invalid
Definition ErrorCodes.h:45
#define DEBUGGER_ERROR_INSTANT_EVENT_REQUESTED_OPTIONAL_BUFFER_IS_BIGGER_THAN_DEBUGGERS_SEND_RECEIVE_STACK
error, the requested optional buffer is bigger than send/receive stack of the debugger
Definition ErrorCodes.h:477
#define DEBUGGER_ERROR_INSTANT_EVENT_PREALLOCATED_BUFFER_IS_NOT_ENOUGH_FOR_ACTION_BUFFER
error, the preallocated buffer is not enough for storing action buffer
Definition ErrorCodes.h:471
#define DEBUGGER_ERROR_UNABLE_TO_CREATE_ACTION_CANNOT_ALLOCATE_BUFFER
error, enable to create action (cannot allocate buffer)
Definition ErrorCodes.h:453
#define DEBUGGER_ERROR_INSTANT_EVENT_ACTION_BIG_PREALLOCATED_BUFFER_NOT_FOUND
error, the big preallocated buffer not found (for action)
Definition ErrorCodes.h:465
#define DEBUGGER_ERROR_INSTANT_EVENT_ACTION_REGULAR_PREALLOCATED_BUFFER_NOT_FOUND
error, the regular preallocated buffer not found (for action)
Definition ErrorCodes.h:459
@ RUN_CUSTOM_CODE
Definition Events.h:187
@ RUN_SCRIPT
Definition Events.h:186
struct _DEBUGGER_EVENT_ACTION DEBUGGER_EVENT_ACTION
The structure of actions in HyperDbg.
struct _DEBUGGER_EVENT_ACTION * PDEBUGGER_EVENT_ACTION
NULL()
Definition test-case-generator.py:530
UINT32 ScriptPointer
Definition RequestStructures.h:882
UINT32 ScriptLength
Definition RequestStructures.h:881
UINT64 ScriptBuffer
Definition RequestStructures.h:880
UINT32 OptionalRequestedBufferSize
Definition RequestStructures.h:883
DEBUGGER_EVENT_ACTION_RUN_SCRIPT_CONFIGURATION ScriptConfiguration
Definition Debugger.h:90
LIST_ENTRY ActionsList
Definition Debugger.h:83
PVOID CustomCodeBufferAddress
Definition Debugger.h:97
UINT32 CustomCodeBufferSize
Definition Debugger.h:96
DEBUGGER_EVENT_ACTION_TYPE_ENUM ActionType
Definition Debugger.h:84
UINT64 Tag
Definition Debugger.h:81
DEBUGGER_EVENT_REQUEST_BUFFER RequestedBuffer
Definition Debugger.h:93
BOOLEAN ImmediatelySendTheResults
Definition Debugger.h:85
UINT32 ActionOrderCode
Definition Debugger.h:82
UINT32 Error
Definition Events.h:434
BOOLEAN IsSuccessful
Definition Events.h:433
UINT32 RequestBufferSize
Definition RequestStructures.h:895
BOOLEAN EnabledRequestBuffer
Definition RequestStructures.h:894
UINT64 RequstBufferAddress
Definition RequestStructures.h:896
UINT32 CustomCodeBufferSize
Definition RequestStructures.h:906
UINT32 OptionalRequestedBufferSize
Definition RequestStructures.h:908
PVOID CustomCodeBufferAddress
Definition RequestStructures.h:907
LIST_ENTRY ActionsListHead
Definition Debugger.h:121
UINT32 CountOfActions
Definition Debugger.h:122
UINT64 Tag
Definition Debugger.h:110

◆ DebuggerApplyEvent()

BOOLEAN DebuggerApplyEvent ( PDEBUGGER_EVENT Event,
PDEBUGGER_EVENT_AND_ACTION_RESULT ResultsToReturn,
BOOLEAN InputFromVmxRoot )

Applying events.

Parameters
EventThe created event object
ResultsToReturnResult buffer that should be returned to the user-mode
InputFromVmxRootWhether the input comes from VMX root-mode or IOCTL
Returns
BOOLEAN TRUE if the event was applied otherwise returns FALSE
2925{
2926 //
2927 // Now we should configure the cpu to generate the events
2928 //
2929 switch (Event->EventType)
2930 {
2935 case HIDDEN_HOOK_READ:
2936 case HIDDEN_HOOK_WRITE:
2938 {
2939 //
2940 // Apply the monitor memory hook events
2941 //
2942 if (!ApplyEventMonitorEvent(Event, ResultsToReturn, InputFromVmxRoot))
2943 {
2944 goto ClearTheEventAfterCreatingEvent;
2945 }
2946
2947 break;
2948 }
2950 {
2951 //
2952 // Apply the EPT hidden hook (hidden breakpoint) events
2953 //
2954 if (!ApplyEventEptHookExecCcEvent(Event, ResultsToReturn, InputFromVmxRoot))
2955 {
2956 goto ClearTheEventAfterCreatingEvent;
2957 }
2958
2959 break;
2960 }
2962 {
2963 //
2964 // Apply the EPT hook trampoline (inline hook) events
2965 //
2966 if (!ApplyEventEpthookInlineEvent(Event, ResultsToReturn, InputFromVmxRoot))
2967 {
2968 goto ClearTheEventAfterCreatingEvent;
2969 }
2970
2971 break;
2972 }
2974 {
2975 //
2976 // Apply the RDMSR execution exiting events
2977 //
2978 ApplyEventRdmsrExecutionEvent(Event, ResultsToReturn, InputFromVmxRoot);
2979
2980 break;
2981 }
2983 {
2984 //
2985 // Apply the WRMSR execution exiting events
2986 //
2987 ApplyEventWrmsrExecutionEvent(Event, ResultsToReturn, InputFromVmxRoot);
2988
2989 break;
2990 }
2993 {
2994 //
2995 // Apply the IN/OUT instructions execution exiting events
2996 //
2997 ApplyEventInOutExecutionEvent(Event, ResultsToReturn, InputFromVmxRoot);
2998
2999 break;
3000 }
3002 {
3003 //
3004 // Apply the RDTSC/RDTSCP instructions execution exiting events
3005 //
3006 ApplyEventTscExecutionEvent(Event, ResultsToReturn, InputFromVmxRoot);
3007
3008 break;
3009 }
3011 {
3012 //
3013 // Apply the RDPMC instruction execution exiting events
3014 //
3015 ApplyEventRdpmcExecutionEvent(Event, ResultsToReturn, InputFromVmxRoot);
3016
3017 break;
3018 }
3020 {
3021 //
3022 // Apply the mov 2 debug register exiting events
3023 //
3024 ApplyEventMov2DebugRegExecutionEvent(Event, ResultsToReturn, InputFromVmxRoot);
3025
3026 break;
3027 }
3029 {
3030 //
3031 // Apply the control register access exiting events
3032 //
3033 ApplyEventControlRegisterAccessedEvent(Event, ResultsToReturn, InputFromVmxRoot);
3034
3035 break;
3036 }
3037 case EXCEPTION_OCCURRED:
3038 {
3039 //
3040 // Apply the exception events
3041 //
3042 ApplyEventExceptionEvent(Event, ResultsToReturn, InputFromVmxRoot);
3043
3044 break;
3045 }
3047 {
3048 //
3049 // Apply the interrupt events
3050 //
3051 ApplyEventInterruptEvent(Event, ResultsToReturn, InputFromVmxRoot);
3052
3053 break;
3054 }
3056 {
3057 //
3058 // Apply the EFER SYSCALL hook events
3059 //
3060 ApplyEventEferSyscallHookEvent(Event, ResultsToReturn, InputFromVmxRoot);
3061
3062 break;
3063 }
3065 {
3066 //
3067 // Apply the EFER SYSRET hook events
3068 //
3069 ApplyEventEferSysretHookEvent(Event, ResultsToReturn, InputFromVmxRoot);
3070
3071 break;
3072 }
3074 {
3075 //
3076 // Apply the VMCALL instruction interception events
3077 //
3078 ApplyEventVmcallExecutionEvent(Event, ResultsToReturn, InputFromVmxRoot);
3079
3080 break;
3081 }
3083 {
3084 //
3085 // Apply the trap mode change and single instruction trace events
3086 //
3087 if (!ApplyEventTrapModeChangeEvent(Event, ResultsToReturn, InputFromVmxRoot))
3088 {
3089 goto ClearTheEventAfterCreatingEvent;
3090 }
3091
3092 break;
3093 }
3095 {
3096 //
3097 // Apply the CPUID instruction execution events
3098 //
3099 ApplyEventCpuidExecutionEvent(Event, ResultsToReturn, InputFromVmxRoot);
3100
3101 break;
3102 }
3104 {
3105 //
3106 // Apply the tracing events
3107 //
3108 ApplyEventTracingEvent(Event, ResultsToReturn, InputFromVmxRoot);
3109
3110 break;
3111 }
3113 {
3114 //
3115 // Apply the XSETBV instruction execution events
3116 //
3117 ApplyEventXsetbvExecutionEvent(Event, ResultsToReturn, InputFromVmxRoot);
3118
3119 break;
3120 }
3121 default:
3122 {
3123 //
3124 // Set the error
3125 //
3126 ResultsToReturn->IsSuccessful = FALSE;
3128 goto ClearTheEventAfterCreatingEvent;
3129
3130 break;
3131 }
3132 }
3133
3134 //
3135 // Set the status
3136 //
3137 ResultsToReturn->IsSuccessful = TRUE;
3138 ResultsToReturn->Error = 0;
3139
3140 //
3141 // Event was applied successfully
3142 //
3143 return TRUE;
3144
3145ClearTheEventAfterCreatingEvent:
3146
3147 return FALSE;
3148}
BOOLEAN ApplyEventEpthookInlineEvent(PDEBUGGER_EVENT Event, PDEBUGGER_EVENT_AND_ACTION_RESULT ResultsToReturn, BOOLEAN InputFromVmxRoot)
Applying EPT hook trampoline (inline hook) events.
Definition ApplyEvents.c:425
VOID ApplyEventMov2DebugRegExecutionEvent(PDEBUGGER_EVENT Event, PDEBUGGER_EVENT_AND_ACTION_RESULT ResultsToReturn, BOOLEAN InputFromVmxRoot)
Applying mov 2 debug registers events.
Definition ApplyEvents.c:798
VOID ApplyEventRdmsrExecutionEvent(PDEBUGGER_EVENT Event, PDEBUGGER_EVENT_AND_ACTION_RESULT ResultsToReturn, BOOLEAN InputFromVmxRoot)
Applying RDMSR execution events.
Definition ApplyEvents.c:533
VOID ApplyEventCpuidExecutionEvent(PDEBUGGER_EVENT Event, PDEBUGGER_EVENT_AND_ACTION_RESULT ResultsToReturn, BOOLEAN InputFromVmxRoot)
Applying CPUID instruction execution events.
Definition ApplyEvents.c:1263
VOID ApplyEventWrmsrExecutionEvent(PDEBUGGER_EVENT Event, PDEBUGGER_EVENT_AND_ACTION_RESULT ResultsToReturn, BOOLEAN InputFromVmxRoot)
Applying WRMSR execution events.
Definition ApplyEvents.c:588
VOID ApplyEventInOutExecutionEvent(PDEBUGGER_EVENT Event, PDEBUGGER_EVENT_AND_ACTION_RESULT ResultsToReturn, BOOLEAN InputFromVmxRoot)
Applying IN/OUT instructions execution events.
Definition ApplyEvents.c:643
BOOLEAN ApplyEventMonitorEvent(PDEBUGGER_EVENT Event, PDEBUGGER_EVENT_AND_ACTION_RESULT ResultsToReturn, BOOLEAN InputFromVmxRoot)
Applying monitor memory hook events.
Definition ApplyEvents.c:26
VOID ApplyEventTscExecutionEvent(PDEBUGGER_EVENT Event, PDEBUGGER_EVENT_AND_ACTION_RESULT ResultsToReturn, BOOLEAN InputFromVmxRoot)
Applying RDTSC/RDTSCP instructions execution events.
Definition ApplyEvents.c:698
VOID ApplyEventEferSysretHookEvent(PDEBUGGER_EVENT Event, PDEBUGGER_EVENT_AND_ACTION_RESULT ResultsToReturn, BOOLEAN InputFromVmxRoot)
Applying EFER SYSRET hook events.
Definition ApplyEvents.c:1087
BOOLEAN ApplyEventEptHookExecCcEvent(PDEBUGGER_EVENT Event, PDEBUGGER_EVENT_AND_ACTION_RESULT ResultsToReturn, BOOLEAN InputFromVmxRoot)
Applying EPT hook execution (hidden breakpoints) events.
Definition ApplyEvents.c:324
VOID ApplyEventControlRegisterAccessedEvent(PDEBUGGER_EVENT Event, PDEBUGGER_EVENT_AND_ACTION_RESULT ResultsToReturn, BOOLEAN InputFromVmxRoot)
Applying control registers accessed events.
Definition ApplyEvents.c:848
BOOLEAN ApplyEventTrapModeChangeEvent(PDEBUGGER_EVENT Event, PDEBUGGER_EVENT_AND_ACTION_RESULT ResultsToReturn, BOOLEAN InputFromVmxRoot)
Applying trap mode change events.
Definition ApplyEvents.c:1190
VOID ApplyEventXsetbvExecutionEvent(PDEBUGGER_EVENT Event, PDEBUGGER_EVENT_AND_ACTION_RESULT ResultsToReturn, BOOLEAN InputFromVmxRoot)
Applying XSETBV instruction execution events.
Definition ApplyEvents.c:1325
VOID ApplyEventExceptionEvent(PDEBUGGER_EVENT Event, PDEBUGGER_EVENT_AND_ACTION_RESULT ResultsToReturn, BOOLEAN InputFromVmxRoot)
Applying exception events.
Definition ApplyEvents.c:904
VOID ApplyEventRdpmcExecutionEvent(PDEBUGGER_EVENT Event, PDEBUGGER_EVENT_AND_ACTION_RESULT ResultsToReturn, BOOLEAN InputFromVmxRoot)
Applying RDPMC instruction execution events.
Definition ApplyEvents.c:748
VOID ApplyEventInterruptEvent(PDEBUGGER_EVENT Event, PDEBUGGER_EVENT_AND_ACTION_RESULT ResultsToReturn, BOOLEAN InputFromVmxRoot)
Applying interrupt interception events.
Definition ApplyEvents.c:959
VOID ApplyEventTracingEvent(PDEBUGGER_EVENT Event, PDEBUGGER_EVENT_AND_ACTION_RESULT ResultsToReturn, BOOLEAN InputFromVmxRoot)
Applying trace events.
Definition ApplyEvents.c:1296
VOID ApplyEventVmcallExecutionEvent(PDEBUGGER_EVENT Event, PDEBUGGER_EVENT_AND_ACTION_RESULT ResultsToReturn, BOOLEAN InputFromVmxRoot)
Applying VMCALL instruction execution events.
Definition ApplyEvents.c:1163
VOID ApplyEventEferSyscallHookEvent(PDEBUGGER_EVENT Event, PDEBUGGER_EVENT_AND_ACTION_RESULT ResultsToReturn, BOOLEAN InputFromVmxRoot)
Applying EFER SYSCALL hook events.
Definition ApplyEvents.c:1014
#define DEBUGGER_ERROR_EVENT_TYPE_IS_INVALID
error, the event type is unknown
Definition ErrorCodes.h:51
@ SYSCALL_HOOK_EFER_SYSCALL
Definition Events.h:117
@ DEBUG_REGISTERS_ACCESSED
Definition Events.h:146
@ OUT_INSTRUCTION_EXECUTION
Definition Events.h:135
@ CPUID_INSTRUCTION_EXECUTION
Definition Events.h:123
@ EXTERNAL_INTERRUPT_OCCURRED
Definition Events.h:141
@ EXCEPTION_OCCURRED
Definition Events.h:140
@ HIDDEN_HOOK_WRITE_AND_EXECUTE
Definition Events.h:103
@ TRAP_EXECUTION_INSTRUCTION_TRACE
Definition Events.h:170
@ RDMSR_INSTRUCTION_EXECUTION
Definition Events.h:128
@ IN_INSTRUCTION_EXECUTION
Definition Events.h:134
@ HIDDEN_HOOK_EXEC_DETOURS
Definition Events.h:111
@ TSC_INSTRUCTION_EXECUTION
Definition Events.h:151
@ WRMSR_INSTRUCTION_EXECUTION
Definition Events.h:129
@ CONTROL_REGISTER_MODIFIED
Definition Events.h:162
@ PMC_INSTRUCTION_EXECUTION
Definition Events.h:152
@ XSETBV_INSTRUCTION_EXECUTION
Definition Events.h:175
@ HIDDEN_HOOK_READ_AND_WRITE
Definition Events.h:101
@ HIDDEN_HOOK_READ_AND_EXECUTE
Definition Events.h:102
@ HIDDEN_HOOK_EXEC_CC
Definition Events.h:112
@ HIDDEN_HOOK_READ
Definition Events.h:104
@ SYSCALL_HOOK_EFER_SYSRET
Definition Events.h:118
@ HIDDEN_HOOK_WRITE
Definition Events.h:105
@ HIDDEN_HOOK_READ_AND_WRITE_AND_EXECUTE
Definition Events.h:100
@ TRAP_EXECUTION_MODE_CHANGED
Definition Events.h:169
@ VMCALL_INSTRUCTION_EXECUTION
Definition Events.h:157
@ HIDDEN_HOOK_EXECUTE
Definition Events.h:106
VMM_EVENT_TYPE_ENUM EventType
Definition Debugger.h:112

◆ DebuggerClearAllEvents()

VOID DebuggerClearAllEvents ( BOOLEAN InputFromVmxRoot,
BOOLEAN PoolManagerAllocatedMemory )

Clear all events.

Parameters
InputFromVmxRootWhether the input comes from VMX root-mode or IOCTL
PoolManagerAllocatedMemoryWhether the pools are allocated from the pool manager or original OS pools
Returns
VOID
2472{
2473 //
2474 // Because we want to delete all the objects and buffers (pools)
2475 // after we finished termination, the debugger might still use
2476 // the buffers for events and action, for solving this problem
2477 // we first disable the tag(s) and this way the debugger no longer
2478 // use that event and this way we can safely remove and deallocate
2479 // the buffers later after termination
2480 //
2481
2482 //
2483 // First, disable all events
2484 //
2486
2487 //
2488 // Second, terminate all events
2489 //
2490 DebuggerTerminateAllEvents(InputFromVmxRoot);
2491
2492 //
2493 // Third, remove all events
2494 //
2495 DebuggerRemoveAllEvents(PoolManagerAllocatedMemory);
2496}
BOOLEAN DebuggerEnableOrDisableAllEvents(BOOLEAN IsEnable)
Enable or disable all events from all the types.
Definition Debugger.c:1932
BOOLEAN DebuggerRemoveAllEvents(BOOLEAN PoolManagerAllocatedMemory)
Remove all the events from all the lists and also de-allocate their structures and actions.
Definition Debugger.c:2041
BOOLEAN DebuggerTerminateAllEvents(BOOLEAN InputFromVmxRoot)
Terminate effect and configuration to vmx-root and non-root for all the events.
Definition Debugger.c:1989

◆ DebuggerClearEvent()

BOOLEAN DebuggerClearEvent ( UINT64 Tag,
BOOLEAN InputFromVmxRoot,
BOOLEAN PoolManagerAllocatedMemory )

Clear an event by tag.

Parameters
TagTag of target event
InputFromVmxRootWhether the input comes from VMX root-mode or IOCTL
PoolManagerAllocatedMemoryWhether the pools are allocated from the pool manager or original OS pools
Returns
BOOLEAN
2435{
2436 //
2437 // Because we want to delete all the objects and buffers (pools)
2438 // after we finished termination, the debugger might still use
2439 // the buffers for events and action, for solving this problem
2440 // we first disable the tag(s) and this way the debugger no longer
2441 // use that event and this way we can safely remove and deallocate
2442 // the buffers later after termination
2443 //
2444
2445 //
2446 // First, disable just one event
2447 //
2449
2450 //
2451 // Second, terminate it
2452 //
2453 DebuggerTerminateEvent(Tag, InputFromVmxRoot);
2454
2455 //
2456 // Third, remove it from the list
2457 //
2458 return DebuggerRemoveEvent(Tag, PoolManagerAllocatedMemory);
2459}
BOOLEAN DebuggerTerminateEvent(UINT64 Tag, BOOLEAN InputFromVmxRoot)
Terminate one event's effect by its tag.
Definition Debugger.c:3483
BOOLEAN DebuggerDisableEvent(UINT64 Tag)
Disable an event by tag.
Definition Debugger.c:2397
BOOLEAN DebuggerRemoveEvent(UINT64 Tag, BOOLEAN PoolManagerAllocatedMemory)
Remove the event by its tags and also remove its actions and de-allocate their buffers.
Definition Debugger.c:2681
POOL_TYPE SIZE_T ULONG Tag
Definition Hooks.h:89

◆ DebuggerCreateEvent()

PDEBUGGER_EVENT DebuggerCreateEvent ( BOOLEAN Enabled,
UINT32 CoreId,
UINT32 ProcessId,
VMM_EVENT_TYPE_ENUM EventType,
UINT64 Tag,
DEBUGGER_EVENT_OPTIONS * Options,
UINT32 ConditionsBufferSize,
PVOID ConditionBuffer,
PDEBUGGER_EVENT_AND_ACTION_RESULT ResultsToReturn,
BOOLEAN InputFromVmxRoot )

Create an Event Object.

should NOT be called in vmx-root

Parameters
EnabledIs the event enabled or disabled
CoreIdThe core id that this event is allowed to run
ProcessIdThe process id that this event is allowed to run
EventTypeThe type of event
TagUser-mode generated unique tag (id) of the event
OptionsOptional parameters for the event
ConditionsBufferSizeSize of condition code buffer (if any)
ConditionBufferAddress of condition code buffer (if any)
ResultsToReturnResult buffer that should be returned to the user-mode
InputFromVmxRootWhether the input comes from VMX root-mode or IOCTL
Returns
PDEBUGGER_EVENT Returns null in the case of error and event object address when it's successful
431{
432 PDEBUGGER_EVENT Event = NULL;
433 UINT32 EventBufferSize = sizeof(DEBUGGER_EVENT) + ConditionsBufferSize;
434
435 //
436 // Initialize the event structure
437 //
438 if (InputFromVmxRoot)
439 {
440 //
441 // *** The buffer is coming from VMX-root mode ***
442 //
443
444 //
445 // If the buffer is smaller than regular instant events
446 //
447 if (REGULAR_INSTANT_EVENT_CONDITIONAL_BUFFER >= EventBufferSize)
448 {
449 //
450 // The buffer fits into a regular instant event
451 //
453
454 if (!Event)
455 {
456 //
457 // Here we try again to see if we could store it into a big instant event instead
458 //
460
461 if (!Event)
462 {
463 //
464 // Set the error
465 //
466 ResultsToReturn->IsSuccessful = FALSE;
468
469 //
470 // There is a problem with allocating event
471 //
472 return NULL;
473 }
474 }
475 }
476 else if (BIG_INSTANT_EVENT_CONDITIONAL_BUFFER >= EventBufferSize)
477 {
478 //
479 // The buffer fits into a big instant event
480 //
482
483 if (!Event)
484 {
485 //
486 // Set the error
487 //
488 ResultsToReturn->IsSuccessful = FALSE;
490
491 //
492 // There is a problem with allocating event
493 //
494 return NULL;
495 }
496 }
497 else
498 {
499 //
500 // The buffer doesn't fit into any of the regular or big event's preallocated buffers
501 //
502
503 //
504 // Set the error
505 //
506 ResultsToReturn->IsSuccessful = FALSE;
508
509 return NULL;
510 }
511 }
512 else
513 {
514 //
515 // If it's not coming from the VMX-root mode then we're allocating it from the OS buffers
516 //
517 Event = PlatformMemAllocateZeroedNonPagedPool(EventBufferSize);
518
519 if (!Event)
520 {
521 //
522 // Set the error
523 //
524 ResultsToReturn->IsSuccessful = FALSE;
526
527 //
528 // There is a problem with allocating event
529 //
530 return NULL;
531 }
532 }
533
534 Event->CoreId = CoreId;
535 Event->ProcessId = ProcessId;
536 Event->Enabled = Enabled;
537 Event->EventType = EventType;
538 Event->Tag = Tag;
539 Event->CountOfActions = 0; // currently there is no action
540
541 //
542 // Copy Options
543 //
544 memcpy(&Event->InitOptions, Options, sizeof(DEBUGGER_EVENT_OPTIONS));
545
546 //
547 // check if this event is conditional or not
548 //
549 if (ConditionBuffer != 0)
550 {
551 //
552 // It's conditional
553 //
554 Event->ConditionsBufferSize = ConditionsBufferSize;
555 Event->ConditionBufferAddress = (PVOID)((UINT64)Event + sizeof(DEBUGGER_EVENT));
556
557 //
558 // copy the condition buffer to the end of the buffer of the event
559 //
560 memcpy(Event->ConditionBufferAddress, ConditionBuffer, ConditionsBufferSize);
561 }
562 else
563 {
564 //
565 // It's unconditioanl
566 //
567 Event->ConditionsBufferSize = 0;
568 }
569
570 //
571 // Make the action lists ready
572 //
573 InitializeListHead(&Event->ActionsListHead);
574
575 //
576 // Return our event
577 //
578 return Event;
579}
unsigned int UINT32
Definition BasicTypes.h:54
#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_REGULAR_EVENT_BUFFER
Definition DataTypes.h:84
#define DEBUGGER_ERROR_INSTANT_EVENT_REGULAR_PREALLOCATED_BUFFER_NOT_FOUND
error, the regular preallocated buffer not found
Definition ErrorCodes.h:441
#define DEBUGGER_ERROR_INSTANT_EVENT_PREALLOCATED_BUFFER_IS_NOT_ENOUGH_FOR_EVENT_AND_CONDITIONALS
error, the preallocated buffer is not enough for storing event+conditional buffer
Definition ErrorCodes.h:435
#define DEBUGGER_ERROR_INSTANT_EVENT_BIG_PREALLOCATED_BUFFER_NOT_FOUND
error, the big preallocated buffer not found
Definition ErrorCodes.h:447
#define DEBUGGER_ERROR_UNABLE_TO_CREATE_EVENT
error, enable to create event
Definition ErrorCodes.h:57
struct _DEBUGGER_EVENT_OPTIONS DEBUGGER_EVENT_OPTIONS
request for performing a short-circuiting event
struct _DEBUGGER_EVENT DEBUGGER_EVENT
The structure of events in HyperDbg.
struct _DEBUGGER_EVENT * PDEBUGGER_EVENT
UINT32 ConditionsBufferSize
Definition Debugger.h:134
PVOID ConditionBufferAddress
Definition Debugger.h:135
DEBUGGER_EVENT_OPTIONS InitOptions
Definition Debugger.h:130
UINT32 CoreId
Definition Debugger.h:114
BOOLEAN Enabled
Definition Debugger.h:113
UINT32 ProcessId
Definition Debugger.h:118

◆ DebuggerDisableEvent()

BOOLEAN DebuggerDisableEvent ( UINT64 Tag)

Disable an event by tag.

Parameters
TagTag of target event
Returns
BOOLEAN TRUE if event enabled and FALSE if event not found
2398{
2399 PDEBUGGER_EVENT Event;
2400
2401 //
2402 // Search all the cores for enable this event
2403 //
2404 Event = DebuggerGetEventByTag(Tag);
2405
2406 //
2407 // Check if tag is valid or not
2408 //
2409 if (Event == NULL)
2410 {
2411 return FALSE;
2412 }
2413
2414 //
2415 // Disable the event
2416 //
2417 Event->Enabled = FALSE;
2418
2419 return TRUE;
2420}
PDEBUGGER_EVENT DebuggerGetEventByTag(UINT64 Tag)
Find event object by tag.
Definition Debugger.c:1889

◆ DebuggerEnableEvent()

BOOLEAN DebuggerEnableEvent ( UINT64 Tag)

Enable an event by tag.

Parameters
TagTag of target event
Returns
BOOLEAN TRUE if event enabled and FALSE if event not found
2337{
2338 PDEBUGGER_EVENT Event;
2339 //
2340 // Search all the cores for enable this event
2341 //
2342 Event = DebuggerGetEventByTag(Tag);
2343
2344 //
2345 // Check if tag is valid or not
2346 //
2347 if (Event == NULL)
2348 {
2349 return FALSE;
2350 }
2351
2352 //
2353 // Enable the event
2354 //
2355 Event->Enabled = TRUE;
2356
2357 return TRUE;
2358}

◆ DebuggerEnableOrDisableAllEvents()

BOOLEAN DebuggerEnableOrDisableAllEvents ( BOOLEAN IsEnable)

Enable or disable all events from all the types.

Parameters
IsEnableIf you want to enable then true and if you want to disable then false
Returns
BOOLEAN if at least one event enabled/disabled then it returns true, and otherwise false
1933{
1934 BOOLEAN FindAtLeastOneEvent = FALSE;
1935 PLIST_ENTRY TempList = 0;
1936 PLIST_ENTRY TempList2 = 0;
1937
1938 //
1939 // We have to iterate through all events
1940 //
1941 for (SIZE_T i = 0; i < sizeof(DEBUGGER_CORE_EVENTS) / sizeof(LIST_ENTRY); i++)
1942 {
1943 TempList = (PLIST_ENTRY)((UINT64)(g_Events) + (i * sizeof(LIST_ENTRY)));
1944 TempList2 = TempList;
1945
1946 while (TempList2 != TempList->Flink)
1947 {
1948 TempList = TempList->Flink;
1949 PDEBUGGER_EVENT CurrentEvent = CONTAINING_RECORD(TempList, DEBUGGER_EVENT, EventsOfSameTypeList);
1950
1951 //
1952 // Check if we find at least one event or not
1953 //
1954 if (!FindAtLeastOneEvent)
1955 {
1956 FindAtLeastOneEvent = TRUE;
1957 }
1958
1959 //
1960 // Enable or disable event
1961 // (We could directly modify the "enabled" flag here, however
1962 // in the case of any possible callback for enabling/disabling let's
1963 // modify the state of being enable all of them in a single place)
1964 //
1965 if (IsEnable)
1966 {
1967 DebuggerEnableEvent(CurrentEvent->Tag);
1968 }
1969 else
1970 {
1971 DebuggerDisableEvent(CurrentEvent->Tag);
1972 }
1973 }
1974 }
1975
1976 return FindAtLeastOneEvent;
1977}
BOOLEAN DebuggerEnableEvent(UINT64 Tag)
Enable an event by tag.
Definition Debugger.c:2336
UCHAR BOOLEAN
Definition BasicTypes.h:35
DEBUGGER_CORE_EVENTS * g_Events
events list (for debugger)
Definition Global.h:90
struct _DEBUGGER_CORE_EVENTS DEBUGGER_CORE_EVENTS
List of all the different events.
#define CONTAINING_RECORD(address, type, field)
Definition nt-list.h:36

◆ DebuggerEventListCount()

UINT32 DebuggerEventListCount ( PLIST_ENTRY TargetEventList)

Count the list of events in a special list.

Parameters
TargetEventListtarget event list
Returns
UINT32 count of events on the list
2086{
2087 PLIST_ENTRY TempList = 0;
2088 UINT32 Counter = 0;
2089
2090 //
2091 // We have to iterate through all events of this list
2092 //
2093 TempList = TargetEventList;
2094
2095 while (TargetEventList != TempList->Flink)
2096 {
2097 TempList = TempList->Flink;
2098 /* PDEBUGGER_EVENT CurrentEvent = CONTAINING_RECORD(TempList, DEBUGGER_EVENT, EventsOfSameTypeList); */
2099
2100 //
2101 // Increase the counter
2102 //
2103 Counter++;
2104 }
2105
2106 return Counter;
2107}

◆ DebuggerEventListCountByCore()

UINT32 DebuggerEventListCountByCore ( PLIST_ENTRY TargetEventList,
UINT32 TargetCore )

Count the list of events in a special list that are activate on a target core.

Parameters
TargetEventListtarget event list
TargetCoretarget core
Returns
UINT32 count of events on the list which is activated on the target core
2229{
2230 PLIST_ENTRY TempList = 0;
2231 UINT32 Counter = 0;
2232
2233 //
2234 // We have to iterate through all events of this list
2235 //
2236 TempList = TargetEventList;
2237
2238 while (TargetEventList != TempList->Flink)
2239 {
2240 TempList = TempList->Flink;
2241 PDEBUGGER_EVENT CurrentEvent = CONTAINING_RECORD(TempList, DEBUGGER_EVENT, EventsOfSameTypeList);
2242
2243 if (CurrentEvent->CoreId == DEBUGGER_EVENT_APPLY_TO_ALL_CORES || CurrentEvent->CoreId == TargetCore)
2244 {
2245 //
2246 // Increase the counter
2247 //
2248 Counter++;
2249 }
2250 }
2251
2252 return Counter;
2253}
#define DEBUGGER_EVENT_APPLY_TO_ALL_CORES
Apply the event to all the cores.
Definition Constants.h:739

◆ DebuggerEventListCountByEventType()

UINT32 DebuggerEventListCountByEventType ( VMM_EVENT_TYPE_ENUM EventType,
UINT32 TargetCore )

Count the list of events by a special event type that are activate on a target core.

Parameters
EventTypetarget event type
TargetCoretarget core
Returns
UINT32 count of events on the list which is activated on the target core
2267{
2268 PLIST_ENTRY TempList = 0;
2269 UINT32 Counter = 0;
2270
2271 PLIST_ENTRY TargetEventList = DebuggerGetEventListByEventType(EventType);
2272
2273 //
2274 // We have to iterate through all events of this list
2275 //
2276 TempList = TargetEventList;
2277
2278 while (TargetEventList != TempList->Flink)
2279 {
2280 TempList = TempList->Flink;
2281 PDEBUGGER_EVENT CurrentEvent = CONTAINING_RECORD(TempList, DEBUGGER_EVENT, EventsOfSameTypeList);
2282
2283 if (CurrentEvent->CoreId == DEBUGGER_EVENT_APPLY_TO_ALL_CORES || CurrentEvent->CoreId == TargetCore)
2284 {
2285 //
2286 // Increase the counter
2287 //
2288 Counter++;
2289 }
2290 }
2291
2292 return Counter;
2293}
PLIST_ENTRY DebuggerGetEventListByEventType(VMM_EVENT_TYPE_ENUM EventType)
Get List of event based on event type.
Definition Debugger.c:2116

◆ DebuggerExceptionEventBitmapMask()

UINT32 DebuggerExceptionEventBitmapMask ( UINT32 CoreIndex)

Get the mask related to the !exception command for the target core.

Parameters
CoreIndexThe index of core
Returns
UINT32 Returns the current mask for the core
2305{
2306 PLIST_ENTRY TempList = 0;
2307 UINT32 ExceptionMask = 0;
2308
2309 //
2310 // We have to iterate through all events of this list
2311 //
2312 TempList = &g_Events->ExceptionOccurredEventsHead;
2313
2314 while (&g_Events->ExceptionOccurredEventsHead != TempList->Flink)
2315 {
2316 TempList = TempList->Flink;
2317 PDEBUGGER_EVENT CurrentEvent = CONTAINING_RECORD(TempList, DEBUGGER_EVENT, EventsOfSameTypeList);
2318
2319 if (CurrentEvent->CoreId == DEBUGGER_EVENT_APPLY_TO_ALL_CORES || CurrentEvent->CoreId == CoreIndex)
2320 {
2321 ExceptionMask |= CurrentEvent->Options.OptionalParam1;
2322 }
2323 }
2324
2325 return ExceptionMask;
2326}
UINT64 OptionalParam1
Definition Events.h:277
DEBUGGER_EVENT_OPTIONS Options
Definition Debugger.h:132

◆ DebuggerGetEventByTag()

PDEBUGGER_EVENT DebuggerGetEventByTag ( UINT64 Tag)

Find event object by tag.

Parameters
TagTag of event
Returns
PDEBUGGER_EVENT Returns null if not found and event object if found
1890{
1891 PLIST_ENTRY TempList = 0;
1892 PLIST_ENTRY TempList2 = 0;
1893
1894 //
1895 // We have to iterate through all events
1896 //
1897 for (SIZE_T i = 0; i < sizeof(DEBUGGER_CORE_EVENTS) / sizeof(LIST_ENTRY); i++)
1898 {
1899 TempList = (PLIST_ENTRY)((UINT64)(g_Events) + (i * sizeof(LIST_ENTRY)));
1900 TempList2 = TempList;
1901
1902 while (TempList2 != TempList->Flink)
1903 {
1904 TempList = TempList->Flink;
1905 PDEBUGGER_EVENT CurrentEvent = CONTAINING_RECORD(TempList, DEBUGGER_EVENT, EventsOfSameTypeList);
1906
1907 //
1908 // Check if we find the event or not
1909 //
1910 if (CurrentEvent->Tag == Tag)
1911 {
1912 return CurrentEvent;
1913 }
1914 }
1915 }
1916
1917 //
1918 // We didn't find anything, so return null
1919 //
1920 return NULL;
1921}

◆ DebuggerGetEventListByEventType()

PLIST_ENTRY DebuggerGetEventListByEventType ( VMM_EVENT_TYPE_ENUM EventType)

Get List of event based on event type.

Parameters
EventTypetype of event
Returns
PLIST_ENTRY
2117{
2118 PLIST_ENTRY ResultList = NULL;
2119 //
2120 // Register the event
2121 //
2122 switch (EventType)
2123 {
2125 ResultList = &g_Events->HiddenHookReadAndWriteAndExecuteEventsHead;
2126 break;
2128 ResultList = &g_Events->HiddenHookReadAndWriteEventsHead;
2129 break;
2131 ResultList = &g_Events->HiddenHookReadAndExecuteEventsHead;
2132 break;
2134 ResultList = &g_Events->HiddenHookWriteAndExecuteEventsHead;
2135 break;
2136 case HIDDEN_HOOK_READ:
2137 ResultList = &g_Events->HiddenHookReadEventsHead;
2138 break;
2139 case HIDDEN_HOOK_WRITE:
2140 ResultList = &g_Events->HiddenHookWriteEventsHead;
2141 break;
2143 ResultList = &g_Events->HiddenHookExecuteEventsHead;
2144 break;
2146 ResultList = &g_Events->EptHook2sExecDetourEventsHead;
2147 break;
2149 ResultList = &g_Events->EptHookExecCcEventsHead;
2150 break;
2152 ResultList = &g_Events->SyscallHooksEferSyscallEventsHead;
2153 break;
2155 ResultList = &g_Events->SyscallHooksEferSysretEventsHead;
2156 break;
2158 ResultList = &g_Events->CpuidInstructionExecutionEventsHead;
2159 break;
2161 ResultList = &g_Events->RdmsrInstructionExecutionEventsHead;
2162 break;
2164 ResultList = &g_Events->WrmsrInstructionExecutionEventsHead;
2165 break;
2166 case EXCEPTION_OCCURRED:
2167 ResultList = &g_Events->ExceptionOccurredEventsHead;
2168 break;
2170 ResultList = &g_Events->TscInstructionExecutionEventsHead;
2171 break;
2173 ResultList = &g_Events->PmcInstructionExecutionEventsHead;
2174 break;
2176 ResultList = &g_Events->InInstructionExecutionEventsHead;
2177 break;
2179 ResultList = &g_Events->OutInstructionExecutionEventsHead;
2180 break;
2182 ResultList = &g_Events->DebugRegistersAccessedEventsHead;
2183 break;
2185 ResultList = &g_Events->ExternalInterruptOccurredEventsHead;
2186 break;
2188 ResultList = &g_Events->VmcallInstructionExecutionEventsHead;
2189 break;
2191 ResultList = &g_Events->TrapExecutionModeChangedEventsHead;
2192 break;
2194 ResultList = &g_Events->TrapExecutionInstructionTraceEventsHead;
2195 break;
2197 ResultList = &g_Events->ControlRegister3ModifiedEventsHead;
2198 break;
2200 ResultList = &g_Events->ControlRegisterModifiedEventsHead;
2201 break;
2203 ResultList = &g_Events->XsetbvInstructionExecutionEventsHead;
2204 break;
2205 default:
2206
2207 //
2208 // Wrong event type
2209 //
2210 LogError("Err, wrong event type is specified");
2211 ResultList = NULL;
2212 break;
2213 }
2214
2215 return ResultList;
2216}
@ CONTROL_REGISTER_3_MODIFIED
Definition Events.h:164
#define LogError(format,...)
Log in the case of error.
Definition HyperDbgHyperLogIntrinsics.h:113

◆ DebuggerGetLastError()

UINT32 DebuggerGetLastError ( )

Debugger get the last error.

Returns
UINT32 Error value
33{
34 return g_LastError;
35}
UINT32 g_LastError
The value of last error.
Definition Global.h:127

◆ DebuggerGetRegValueWrapper()

UINT64 DebuggerGetRegValueWrapper ( PGUEST_REGS GuestRegs,
UINT32 RegId )

A wrapper for GetRegValue() in script-engine.

Returns
BOOLEAN Value of register
22{
23 return GetRegValue(GuestRegs, RegId);
24}
UINT64 GetRegValue(PGUEST_REGS GuestRegs, REGS_ENUM RegId)
Get the register value.
Definition Regs.c:40

◆ DebuggerInitialize()

BOOLEAN DebuggerInitialize ( )

Initialize Debugger Structures and Routines.

Returns
BOOLEAN Shows whether the initialization process was successful or not
228{
229 ULONG ProcessorsCount = KeQueryActiveProcessorCount(0);
230
231 //
232 // Also allocate the debugging state
233 //
235 {
236 return FALSE;
237 }
238
239 //
240 // Allocate buffer for saving events
241 //
243 {
244 return FALSE;
245 }
246
247 //
248 // Set the core's IDs
249 //
250 for (UINT32 i = 0; i < ProcessorsCount; i++)
251 {
252 g_DbgState[i].CoreId = i;
253 }
254
255 //
256 // Initialize Pool Manager
257 //
259 {
260 LogError("Err, could not initialize pool manager");
261 return FALSE;
262 }
263
264 //
265 // Initialize script engine global variables and per-core stack buffers
266 //
268 {
269 return FALSE;
270 }
271
272 //
273 // Initialize trap flag state and breakpoint related structures
274 //
276 {
277 return FALSE;
278 }
279
280 //
281 // Initialize attaching mechanism,
282 // we'll use the functionalities of the attaching in reading modules
283 // of user mode applications (other than attaching mechanism itself)
284 //
285 if (!AttachingInitialize())
286 {
287 return FALSE;
288 }
289
290 return TRUE;
291}
BOOLEAN GlobalEventsAllocateZeroedMemory(VOID)
Allocate event store memory.
Definition Allocations.c:61
BOOLEAN GlobalDebuggingStateAllocateZeroedMemory(VOID)
Allocate debugging state memory.
Definition Allocations.c:21
BOOLEAN AttachingInitialize()
Initialize the attaching mechanism.
Definition Attaching.c:22
BOOLEAN DebuggerInitializeScriptEngine()
Initialize script engine global variables and per-core stack buffers.
Definition Debugger.c:56
BOOLEAN DebuggerInitializeTrapsAndBreakpoints()
Initialize trap flag state and breakpoint related structures.
Definition Debugger.c:118
BOOLEAN PoolManagerInitialize()
Initializes the pool manager.
Definition PoolManager.c:53
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

◆ DebuggerInitializeScriptEngine()

BOOLEAN DebuggerInitializeScriptEngine ( )

Initialize script engine global variables and per-core stack buffers.

Returns
BOOLEAN Shows whether the initialization process was successful or not
57{
58 ULONG ProcessorsCount = KeQueryActiveProcessorCount(0);
59 PROCESSOR_DEBUGGING_STATE * CurrentDebuggerState = NULL;
60
61 //
62 // Initialize script engines global variables holder
63 //
65 {
67 }
68
70 {
71 //
72 // Out of resource, initialization of script engine's global variable holders failed
73 //
74 return FALSE;
75 }
76
77 //
78 // Zero the global variables memory
79 //
80 RtlZeroMemory(g_ScriptGlobalVariables, MAX_VAR_COUNT * sizeof(UINT64));
81
82 //
83 // Initialize the local and temp variables
84 //
85 for (SIZE_T i = 0; i < ProcessorsCount; i++)
86 {
87 CurrentDebuggerState = &g_DbgState[i];
88
89 if (!CurrentDebuggerState->ScriptEngineCoreSpecificStackBuffer)
90 {
92 }
93
94 if (!CurrentDebuggerState->ScriptEngineCoreSpecificStackBuffer)
95 {
96 //
97 // Out of resource, initialization of script engine's stack buffer holders failed
98 //
99 return FALSE;
100 }
101
102 //
103 // Zero stack buffer memory
104 //
105 RtlZeroMemory(CurrentDebuggerState->ScriptEngineCoreSpecificStackBuffer, MAX_STACK_BUFFER_COUNT * sizeof(UINT64));
106 }
107
108 return TRUE;
109}
PVOID PlatformMemAllocateNonPagedPool(SIZE_T NumberOfBytes)
Allocates non-paged pool memory.
Definition PlatformMem.c:208
#define MAX_VAR_COUNT
Definition Constants.h:580
#define MAX_STACK_BUFFER_COUNT
Maximum number of stack buffer count in the script engine.
Definition Constants.h:571
UINT64 * g_ScriptGlobalVariables
Holder of script engines global variables.
Definition Global.h:71
struct _PROCESSOR_DEBUGGING_STATE PROCESSOR_DEBUGGING_STATE
Saves the debugger state.
UINT64 * ScriptEngineCoreSpecificStackBuffer
Definition State.h:184

◆ DebuggerInitializeTrapsAndBreakpoints()

BOOLEAN DebuggerInitializeTrapsAndBreakpoints ( )

Initialize trap flag state and breakpoint related structures.

Returns
BOOLEAN Shows whether the initialization process was successful or not
119{
120 //
121 // Zero the TRAP FLAG state memory
122 //
123 RtlZeroMemory(&g_TrapFlagState, sizeof(DEBUGGER_TRAP_FLAG_STATE));
124
125 //
126 // Request pages for breakpoint detail
127 //
131
132 //
133 // Initialize list of breakpoints and breakpoint id
134 //
136 InitializeListHead(&g_BreakpointsListHead);
137
138 return TRUE;
139}
BOOLEAN PoolManagerRequestAllocation(SIZE_T Size, UINT32 Count, POOL_ALLOCATION_INTENTION Intention)
Request to allocate new buffers.
Definition PoolManager.c:436
#define MAXIMUM_BREAKPOINTS_WITHOUT_CONTINUE
maximum number of buffers to be allocated for a single breakpoint
Definition Constants.h:400
@ BREAKPOINT_DEFINITION_STRUCTURE
Definition DataTypes.h:78
DEBUGGER_TRAP_FLAG_STATE g_TrapFlagState
State of the trap-flag.
Definition Global.h:77
LIST_ENTRY g_BreakpointsListHead
List header of breakpoints for debugger-mode.
Definition Global.h:139
UINT64 g_MaximumBreakpointId
Seed for setting id of breakpoints.
Definition Global.h:145
struct _DEBUGGER_TRAP_FLAG_STATE DEBUGGER_TRAP_FLAG_STATE
The status of RFLAGS.TF masking.
struct _DEBUGGEE_BP_DESCRIPTOR DEBUGGEE_BP_DESCRIPTOR
The structure of storing breakpoints.

◆ DebuggerInitializeVmmOperations()

BOOLEAN DebuggerInitializeVmmOperations ( )

Initialize VMM operations (events and related operations).

Returns
BOOLEAN Shows whether the initialization process was successful or not
149{
150 //
151 // Initialize lists relating to the debugger events store
152 //
153 InitializeListHead(&g_Events->EptHookExecCcEventsHead);
154 InitializeListHead(&g_Events->HiddenHookReadAndWriteAndExecuteEventsHead);
155 InitializeListHead(&g_Events->HiddenHookReadAndWriteEventsHead);
156 InitializeListHead(&g_Events->HiddenHookReadAndExecuteEventsHead);
157 InitializeListHead(&g_Events->HiddenHookWriteAndExecuteEventsHead);
158 InitializeListHead(&g_Events->HiddenHookReadEventsHead);
159 InitializeListHead(&g_Events->HiddenHookWriteEventsHead);
160 InitializeListHead(&g_Events->HiddenHookExecuteEventsHead);
161 InitializeListHead(&g_Events->EptHook2sExecDetourEventsHead);
162 InitializeListHead(&g_Events->SyscallHooksEferSyscallEventsHead);
163 InitializeListHead(&g_Events->SyscallHooksEferSysretEventsHead);
164 InitializeListHead(&g_Events->CpuidInstructionExecutionEventsHead);
165 InitializeListHead(&g_Events->RdmsrInstructionExecutionEventsHead);
166 InitializeListHead(&g_Events->WrmsrInstructionExecutionEventsHead);
167 InitializeListHead(&g_Events->ExceptionOccurredEventsHead);
168 InitializeListHead(&g_Events->TscInstructionExecutionEventsHead);
169 InitializeListHead(&g_Events->PmcInstructionExecutionEventsHead);
170 InitializeListHead(&g_Events->InInstructionExecutionEventsHead);
171 InitializeListHead(&g_Events->OutInstructionExecutionEventsHead);
172 InitializeListHead(&g_Events->DebugRegistersAccessedEventsHead);
173 InitializeListHead(&g_Events->ExternalInterruptOccurredEventsHead);
174 InitializeListHead(&g_Events->VmcallInstructionExecutionEventsHead);
175 InitializeListHead(&g_Events->TrapExecutionModeChangedEventsHead);
176 InitializeListHead(&g_Events->TrapExecutionInstructionTraceEventsHead);
177 InitializeListHead(&g_Events->ControlRegister3ModifiedEventsHead);
178 InitializeListHead(&g_Events->ControlRegisterModifiedEventsHead);
179 InitializeListHead(&g_Events->XsetbvInstructionExecutionEventsHead);
180
181
182 //
183 // Initialize NMI broadcasting mechanism
184 //
186
187 //
188 // Set initial state of triggering events for VMCALLs
189 //
191
192 //
193 // Set initial state of triggering events for CPUIDs
194 //
196
197 //
198 // Pre-allocate pools for possible EPT hooks
199 //
201
203 {
204 LogWarning("Warning, cannot allocate the pre-allocated pools for EPT hooks");
205
206 //
207 // BTW, won't fail the starting phase because of this
208 //
209 }
210
211
212 //
213 // Enabled Debugger VMX Events
214 //
216
217 return TRUE;
218}
BOOLEAN PoolManagerCheckAndPerformAllocationAndDeallocation()
This function performs allocations from VMX non-root based on g_RequestNewAllocation.
Definition PoolManager.c:320
#define MAXIMUM_NUMBER_OF_INITIAL_PREALLOCATED_EPT_HOOKS
Maximum number of initial pre-allocated EPT hooks.
Definition Constants.h:268
#define LogWarning(format,...)
Log in the case of warning.
Definition HyperDbgHyperLogIntrinsics.h:99
IMPORT_EXPORT_VMM VOID VmFuncSetTriggerEventForVmcalls(BOOLEAN Set)
Set triggering events for VMCALLs.
Definition Export.c:825
IMPORT_EXPORT_VMM VOID VmFuncSetTriggerEventForCpuids(BOOLEAN Set)
Set triggering events for CPUIDs.
Definition Export.c:837
IMPORT_EXPORT_VMM VOID VmFuncVmxBroadcastInitialize()
Export for initialize the VMX Broadcast mechanism.
Definition Export.c:971
IMPORT_EXPORT_VMM VOID ConfigureEptHookReservePreallocatedPoolsForEptHooks(UINT32 Count)
Allocate (reserve) pages for storing EPT hooks page hooks.
Definition Configuration.c:241
BOOLEAN g_EnableDebuggerVmxEvents
Determines whether the debugger events should be active or not.
Definition Global.h:133

◆ DebuggerIsTagValid()

BOOLEAN DebuggerIsTagValid ( UINT64 Tag)

Detect whether the tag exists or not.

Parameters
TagTag of target event
Returns
BOOLEAN TRUE if event found and FALSE if event not found
2506{
2507 PDEBUGGER_EVENT Event;
2508
2509 //
2510 // Search this event
2511 //
2512 Event = DebuggerGetEventByTag(Tag);
2513
2514 //
2515 // Check if tag is valid or not
2516 //
2517 if (Event == NULL)
2518 {
2519 return FALSE;
2520 }
2521
2522 return TRUE;
2523}

◆ DebuggerParseAction()

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.

Parameters
ActionDetailsStructure that describes the action that comes from the user-mode
ResultsToReturnThe buffer address that should be returned to the user-mode as the result
InputFromVmxRootWhether the input comes from VMX root-mode or IOCTL
Returns
BOOLEAN if action was parsed and added successfully, return TRUE otherwise, returns FALSE
3310{
3311 DEBUGGER_EVENT_ACTION * Action = NULL;
3312
3313 //
3314 // Check if Tag is valid or not
3315 //
3316 PDEBUGGER_EVENT Event = DebuggerGetEventByTag(ActionDetails->EventTag);
3317
3318 if (Event == NULL)
3319 {
3320 //
3321 // Set the appropriate error
3322 //
3323 ResultsToReturn->IsSuccessful = FALSE;
3324 ResultsToReturn->Error = DEBUGGER_ERROR_TAG_NOT_EXISTS;
3325
3326 //
3327 // Show that the
3328 //
3329 return FALSE;
3330 }
3331
3332 if (ActionDetails->ActionType == RUN_CUSTOM_CODE)
3333 {
3334 //
3335 // Check if buffer is not invalid
3336 //
3337 if (ActionDetails->CustomCodeBufferSize == 0)
3338 {
3339 //
3340 // Set the appropriate error
3341 //
3342 ResultsToReturn->IsSuccessful = FALSE;
3344
3345 //
3346 // Show that the
3347 //
3348 return FALSE;
3349 }
3350
3351 //
3352 // Add action for RUN_CUSTOM_CODE
3353 //
3354 DEBUGGER_EVENT_REQUEST_CUSTOM_CODE CustomCode = {0};
3355
3356 CustomCode.CustomCodeBufferSize = ActionDetails->CustomCodeBufferSize;
3357 CustomCode.CustomCodeBufferAddress = (PVOID)((UINT64)ActionDetails + sizeof(DEBUGGER_GENERAL_ACTION));
3358 CustomCode.OptionalRequestedBufferSize = ActionDetails->PreAllocatedBuffer;
3359
3360 //
3361 // Add action to event
3362 //
3363 Action = DebuggerAddActionToEvent(Event,
3365 ActionDetails->ImmediateMessagePassing,
3366 &CustomCode,
3367 NULL,
3368 ResultsToReturn,
3369 InputFromVmxRoot);
3370
3371 if (!Action)
3372 {
3373 //
3374 // Show that there was an error (error is set by the above function)
3375 //
3376 return FALSE;
3377 }
3378 }
3379 else if (ActionDetails->ActionType == RUN_SCRIPT)
3380 {
3381 //
3382 // Check if buffer is not invalid
3383 //
3384 if (ActionDetails->ScriptBufferSize == 0)
3385 {
3386 //
3387 // Set the appropriate error
3388 //
3389 ResultsToReturn->IsSuccessful = FALSE;
3391
3392 //
3393 // Show that the
3394 //
3395 return FALSE;
3396 }
3397
3398 //
3399 // Add action for RUN_SCRIPT
3400 //
3402 UserScriptConfig.ScriptBuffer = (UINT64)ActionDetails + sizeof(DEBUGGER_GENERAL_ACTION);
3403 UserScriptConfig.ScriptLength = ActionDetails->ScriptBufferSize;
3404 UserScriptConfig.ScriptPointer = ActionDetails->ScriptBufferPointer;
3405 UserScriptConfig.OptionalRequestedBufferSize = ActionDetails->PreAllocatedBuffer;
3406
3407 Action = DebuggerAddActionToEvent(Event,
3408 RUN_SCRIPT,
3409 ActionDetails->ImmediateMessagePassing,
3410 NULL,
3411 &UserScriptConfig,
3412 ResultsToReturn,
3413 InputFromVmxRoot);
3414
3415 if (!Action)
3416 {
3417 //
3418 // Show that there was an error (error is set by the above function)
3419 //
3420 return FALSE;
3421 }
3422 }
3423 else if (ActionDetails->ActionType == BREAK_TO_DEBUGGER)
3424 {
3425 //
3426 // Add action BREAK_TO_DEBUGGER to event
3427 //
3428 Action = DebuggerAddActionToEvent(Event,
3430 ActionDetails->ImmediateMessagePassing,
3431 NULL,
3432 NULL,
3433 ResultsToReturn,
3434 InputFromVmxRoot);
3435
3436 if (!Action)
3437 {
3438 //
3439 // Show that there was an error (error is set by the above function)
3440 //
3441 return FALSE;
3442 }
3443 }
3444 else
3445 {
3446 //
3447 // Set the appropriate error
3448 //
3449 ResultsToReturn->IsSuccessful = FALSE;
3450 ResultsToReturn->Error = DEBUGGER_ERROR_INVALID_ACTION_TYPE;
3451
3452 //
3453 // Show that there was an error
3454 //
3455 return FALSE;
3456 }
3457
3458 //
3459 // Enable the event
3460 //
3461 DebuggerEnableEvent(Event->Tag);
3462
3463 ResultsToReturn->IsSuccessful = TRUE;
3464 ResultsToReturn->Error = 0;
3465
3466 return TRUE;
3467}
PDEBUGGER_EVENT_ACTION DebuggerAddActionToEvent(PDEBUGGER_EVENT Event, DEBUGGER_EVENT_ACTION_TYPE_ENUM ActionType, BOOLEAN SendTheResultsImmediately, PDEBUGGER_EVENT_REQUEST_CUSTOM_CODE InTheCaseOfCustomCode, PDEBUGGER_EVENT_ACTION_RUN_SCRIPT_CONFIGURATION InTheCaseOfRunScript, PDEBUGGER_EVENT_AND_ACTION_RESULT ResultsToReturn, BOOLEAN InputFromVmxRoot)
Create an action and add the action to an event.
Definition Debugger.c:707
#define DEBUGGER_ERROR_TAG_NOT_EXISTS
error, the tag not exist
Definition ErrorCodes.h:33
#define DEBUGGER_ERROR_INVALID_ACTION_TYPE
error, invalid type of action
Definition ErrorCodes.h:39
@ BREAK_TO_DEBUGGER
Definition Events.h:185
struct _DEBUGGER_GENERAL_ACTION DEBUGGER_GENERAL_ACTION
Each event can have multiple actions.
struct _DEBUGGER_EVENT_ACTION_RUN_SCRIPT_CONFIGURATION DEBUGGER_EVENT_ACTION_RUN_SCRIPT_CONFIGURATION
Used for run the script.
struct _DEBUGGER_EVENT_REQUEST_CUSTOM_CODE DEBUGGER_EVENT_REQUEST_CUSTOM_CODE
used in the case of custom code requests to the debugger
UINT32 CustomCodeBufferSize
Definition Events.h:419
UINT32 ScriptBufferSize
Definition Events.h:420
DEBUGGER_EVENT_ACTION_TYPE_ENUM ActionType
Definition Events.h:415
UINT32 ScriptBufferPointer
Definition Events.h:421
UINT32 PreAllocatedBuffer
Definition Events.h:417
BOOLEAN ImmediateMessagePassing
Definition Events.h:416
UINT64 EventTag
Definition Events.h:414

◆ DebuggerParseEvent()

BOOLEAN DebuggerParseEvent ( PDEBUGGER_GENERAL_EVENT_DETAIL EventDetails,
PDEBUGGER_EVENT_AND_ACTION_RESULT ResultsToReturn,
BOOLEAN InputFromVmxRoot )

Routine for parsing events.

Parameters
EventDetailsThe structure that describes event that came from the user-mode
ResultsToReturnResult buffer that should be returned to the user-mode
InputFromVmxRootWhether the input comes from VMX root-mode or IOCTL
Returns
BOOLEAN TRUE if the event was valid and registered without error, otherwise returns FALSE
3166{
3167 PDEBUGGER_EVENT Event;
3168
3169 //
3170 // ----------------------------------------------------------------------------------
3171 // *** Validating the Event's parameters ***
3172 // ----------------------------------------------------------------------------------
3173 //
3174
3175 //
3176 // Validate the event parameters
3177 //
3178 if (!DebuggerValidateEvent(EventDetails, ResultsToReturn, InputFromVmxRoot))
3179 {
3180 //
3181 // Input event is not valid
3182 //
3183 return FALSE;
3184 }
3185
3186 //
3187 // ----------------------------------------------------------------------------------
3188 // *** Create Event ***
3189 // ----------------------------------------------------------------------------------
3190 //
3191
3192 //
3193 // We initialize event with disabled mode as it doesn't have action yet
3194 //
3195 if (EventDetails->ConditionBufferSize != 0)
3196 {
3197 //
3198 // Conditional Event
3199 //
3200 Event = DebuggerCreateEvent(FALSE,
3201 EventDetails->CoreId,
3202 EventDetails->ProcessId,
3203 EventDetails->EventType,
3204 EventDetails->Tag,
3205 &EventDetails->Options,
3206 EventDetails->ConditionBufferSize,
3207 (PVOID)((UINT64)EventDetails + sizeof(DEBUGGER_GENERAL_EVENT_DETAIL)),
3208 ResultsToReturn,
3209 InputFromVmxRoot);
3210 }
3211 else
3212 {
3213 //
3214 // Unconditional Event
3215 //
3216 Event = DebuggerCreateEvent(FALSE,
3217 EventDetails->CoreId,
3218 EventDetails->ProcessId,
3219 EventDetails->EventType,
3220 EventDetails->Tag,
3221 &EventDetails->Options,
3222 0,
3223 NULL,
3224 ResultsToReturn,
3225 InputFromVmxRoot);
3226 }
3227
3228 if (Event == NULL)
3229 {
3230 //
3231 // Error is already set in the creation function
3232 //
3233 return FALSE;
3234 }
3235
3236 //
3237 // Register the event
3238 //
3239 DebuggerRegisterEvent(Event);
3240
3241 //
3242 // ----------------------------------------------------------------------------------
3243 // *** Apply & Enable Event ***
3244 // ----------------------------------------------------------------------------------
3245 //
3246 if (DebuggerApplyEvent(Event, ResultsToReturn, InputFromVmxRoot))
3247 {
3248 //
3249 // *** Set the short-circuiting state ***
3250 //
3251 Event->EnableShortCircuiting = EventDetails->EnableShortCircuiting;
3252
3253 //
3254 // Set the event stage (pre- post- event)
3255 //
3257 {
3259 }
3261 {
3263 }
3264 else
3265 {
3266 //
3267 // Any other value results to be pre-event
3268 //
3270 }
3271
3272 return TRUE;
3273 }
3274 else
3275 {
3276 //
3277 // Remove the event as it was not successful
3278 // The same input as of input from VMX-root is
3279 // selected here because we apply it directly in the
3280 // above function and based on this input we can
3281 // conclude whether the pool is allocated from the
3282 // pool manager or not
3283 //
3284 if (Event != NULL)
3285 {
3286 DebuggerRemoveEvent(Event->Tag, InputFromVmxRoot);
3287 }
3288
3289 return FALSE;
3290 }
3291}
BOOLEAN DebuggerApplyEvent(PDEBUGGER_EVENT Event, PDEBUGGER_EVENT_AND_ACTION_RESULT ResultsToReturn, BOOLEAN InputFromVmxRoot)
Applying events.
Definition Debugger.c:2922
BOOLEAN DebuggerRegisterEvent(PDEBUGGER_EVENT Event)
Register an event to a list of active events.
Definition Debugger.c:1113
BOOLEAN DebuggerValidateEvent(PDEBUGGER_GENERAL_EVENT_DETAIL EventDetails, PDEBUGGER_EVENT_AND_ACTION_RESULT ResultsToReturn, BOOLEAN InputFromVmxRoot)
validating events
Definition Debugger.c:2748
PDEBUGGER_EVENT DebuggerCreateEvent(BOOLEAN Enabled, UINT32 CoreId, UINT32 ProcessId, VMM_EVENT_TYPE_ENUM EventType, UINT64 Tag, DEBUGGER_EVENT_OPTIONS *Options, UINT32 ConditionsBufferSize, PVOID ConditionBuffer, PDEBUGGER_EVENT_AND_ACTION_RESULT ResultsToReturn, BOOLEAN InputFromVmxRoot)
Create an Event Object.
Definition Debugger.c:421
@ VMM_CALLBACK_CALLING_STAGE_ALL_EVENT_EMULATION
Definition DataTypes.h:128
@ VMM_CALLBACK_CALLING_STAGE_PRE_EVENT_EMULATION
Definition DataTypes.h:126
@ VMM_CALLBACK_CALLING_STAGE_POST_EVENT_EMULATION
Definition DataTypes.h:127
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...
VMM_CALLBACK_EVENT_CALLING_STAGE_TYPE EventMode
Definition Debugger.h:127
BOOLEAN EnableShortCircuiting
Definition Debugger.h:124
DEBUGGER_EVENT_OPTIONS Options
Definition Events.h:396
BOOLEAN EnableShortCircuiting
Definition Events.h:371
VMM_EVENT_TYPE_ENUM EventType
Definition Events.h:394
UINT64 Tag
Definition Events.h:393
VMM_CALLBACK_EVENT_CALLING_STAGE_TYPE EventStage
Definition Events.h:374
UINT32 ConditionBufferSize
Definition Events.h:400
UINT32 ProcessId
Definition Events.h:365
UINT32 CoreId
Definition Events.h:362

◆ DebuggerParseEventsModification()

BOOLEAN DebuggerParseEventsModification ( PDEBUGGER_MODIFY_EVENTS DebuggerEventModificationRequest,
BOOLEAN InputFromVmxRoot,
BOOLEAN PoolManagerAllocatedMemory )

Parse and validate requests to enable/disable/clear from the user-mode.

Parameters
DebuggerEventModificationRequestevent modification request details
InputFromVmxRootWhether the input comes from VMX root-mode or IOCTL
PoolManagerAllocatedMemoryWhether the pools are allocated from the pool manager or original OS pools
Returns
BOOLEAN returns TRUE if there was no error, and FALSE if there was an error
3731{
3732 BOOLEAN IsForAllEvents = FALSE;
3733
3734 //
3735 // Check if the tag is valid or not
3736 //
3737 if (DebuggerEventModificationRequest->Tag == DEBUGGER_MODIFY_EVENTS_APPLY_TO_ALL_TAG)
3738 {
3739 IsForAllEvents = TRUE;
3740 }
3741 else if (!DebuggerIsTagValid(DebuggerEventModificationRequest->Tag))
3742 {
3743 //
3744 // Tag is invalid
3745 //
3746 DebuggerEventModificationRequest->KernelStatus = DEBUGGER_ERROR_MODIFY_EVENTS_INVALID_TAG;
3747
3748 return FALSE;
3749 }
3750
3751 //
3752 // ***************************************************************************
3753 //
3754
3755 //
3756 // Check if it's a ENABLE, DISABLE or CLEAR
3757 //
3758 if (DebuggerEventModificationRequest->TypeOfAction == DEBUGGER_MODIFY_EVENTS_ENABLE)
3759 {
3760 if (IsForAllEvents)
3761 {
3762 //
3763 // Enable all events
3764 //
3766 }
3767 else
3768 {
3769 //
3770 // Enable just one event
3771 //
3772 DebuggerEnableEvent(DebuggerEventModificationRequest->Tag);
3773 }
3774 }
3775 else if (DebuggerEventModificationRequest->TypeOfAction == DEBUGGER_MODIFY_EVENTS_DISABLE)
3776 {
3777 if (IsForAllEvents)
3778 {
3779 //
3780 // Disable all events
3781 //
3783 }
3784 else
3785 {
3786 //
3787 // Disable just one event
3788 //
3789 DebuggerDisableEvent(DebuggerEventModificationRequest->Tag);
3790 }
3791 }
3792 else if (DebuggerEventModificationRequest->TypeOfAction == DEBUGGER_MODIFY_EVENTS_CLEAR)
3793 {
3794 if (IsForAllEvents)
3795 {
3796 //
3797 // Clear all events
3798 //
3799 DebuggerClearAllEvents(InputFromVmxRoot, PoolManagerAllocatedMemory);
3800 }
3801 else
3802 {
3803 //
3804 // Clear just one event
3805 //
3806 DebuggerClearEvent(DebuggerEventModificationRequest->Tag, InputFromVmxRoot, PoolManagerAllocatedMemory);
3807 }
3808 }
3809 else if (DebuggerEventModificationRequest->TypeOfAction == DEBUGGER_MODIFY_EVENTS_QUERY_STATE)
3810 {
3811 //
3812 // check if tag is valid or not
3813 //
3814 if (!DebuggerIsTagValid(DebuggerEventModificationRequest->Tag))
3815 {
3816 DebuggerEventModificationRequest->KernelStatus = DEBUGGER_ERROR_TAG_NOT_EXISTS;
3817 return FALSE;
3818 }
3819
3820 //
3821 // Set event state
3822 //
3823 if (DebuggerQueryStateEvent(DebuggerEventModificationRequest->Tag))
3824 {
3825 DebuggerEventModificationRequest->IsEnabled = TRUE;
3826 }
3827 else
3828 {
3829 DebuggerEventModificationRequest->IsEnabled = FALSE;
3830 }
3831 }
3832 else
3833 {
3834 //
3835 // Invalid parameter specified in TypeOfAction
3836 //
3837 DebuggerEventModificationRequest->KernelStatus = DEBUGGER_ERROR_MODIFY_EVENTS_INVALID_TYPE_OF_ACTION;
3838
3839 return FALSE;
3840 }
3841
3842 //
3843 // The function was successful
3844 //
3845 DebuggerEventModificationRequest->KernelStatus = DEBUGGER_OPERATION_WAS_SUCCESSFUL;
3846 return TRUE;
3847}
BOOLEAN DebuggerIsTagValid(UINT64 Tag)
Detect whether the tag exists or not.
Definition Debugger.c:2505
BOOLEAN DebuggerQueryStateEvent(UINT64 Tag)
returns whether an event is enabled/disabled by tag
Definition Debugger.c:2370
BOOLEAN DebuggerClearEvent(UINT64 Tag, BOOLEAN InputFromVmxRoot, BOOLEAN PoolManagerAllocatedMemory)
Clear an event by tag.
Definition Debugger.c:2434
VOID DebuggerClearAllEvents(BOOLEAN InputFromVmxRoot, BOOLEAN PoolManagerAllocatedMemory)
Clear all events.
Definition Debugger.c:2471
#define DEBUGGER_MODIFY_EVENTS_APPLY_TO_ALL_TAG
Apply event modifications to all tags.
Definition Constants.h:714
#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_OPERATION_WAS_SUCCESSFUL
General value to indicate that the operation or request was successful.
Definition ErrorCodes.h:23
@ 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

◆ DebuggerPerformActions()

VOID DebuggerPerformActions ( PROCESSOR_DEBUGGING_STATE * DbgState,
DEBUGGER_EVENT * Event,
DEBUGGER_TRIGGERED_EVENT_DETAILS * EventTriggerDetail )

Run a special event's action(s).

Parameters
DbgStateThe state of the debugger on the current core
EventEvent Object
EventTriggerDetailEvent trigger details
Returns
VOID
1607{
1608 PLIST_ENTRY TempList = 0;
1609
1610 //
1611 // Find and run all the actions in this Event
1612 //
1613 TempList = &Event->ActionsListHead;
1614 while (&Event->ActionsListHead != TempList->Flink)
1615 {
1616 TempList = TempList->Flink;
1617 PDEBUGGER_EVENT_ACTION CurrentAction = CONTAINING_RECORD(TempList, DEBUGGER_EVENT_ACTION, ActionsList);
1618
1619 //
1620 // Perform the action
1621 //
1622 switch (CurrentAction->ActionType)
1623 {
1624 case BREAK_TO_DEBUGGER:
1625
1626 DebuggerPerformBreakToDebugger(DbgState, CurrentAction, EventTriggerDetail);
1627
1628 break;
1629
1630 case RUN_SCRIPT:
1631
1632 DebuggerPerformRunScript(DbgState, CurrentAction, NULL, EventTriggerDetail);
1633
1634 break;
1635
1636 case RUN_CUSTOM_CODE:
1637
1638 DebuggerPerformRunTheCustomCode(DbgState, CurrentAction, EventTriggerDetail);
1639
1640 break;
1641
1642 default:
1643
1644 //
1645 // Invalid action type
1646 //
1647 break;
1648 }
1649 }
1650}
VOID DebuggerPerformRunTheCustomCode(PROCESSOR_DEBUGGING_STATE *DbgState, DEBUGGER_EVENT_ACTION *Action, DEBUGGER_TRIGGERED_EVENT_DETAILS *EventTriggerDetail)
Manage running the custom code action.
Definition Debugger.c:1791
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
VOID DebuggerPerformBreakToDebugger(PROCESSOR_DEBUGGING_STATE *DbgState, DEBUGGER_EVENT_ACTION *Action, DEBUGGER_TRIGGERED_EVENT_DETAILS *EventTriggerDetail)
Manage breaking to the debugger action.
Definition Debugger.c:1852

◆ DebuggerPerformBreakToDebugger()

VOID DebuggerPerformBreakToDebugger ( PROCESSOR_DEBUGGING_STATE * DbgState,
DEBUGGER_EVENT_ACTION * Action,
DEBUGGER_TRIGGERED_EVENT_DETAILS * EventTriggerDetail )

Manage breaking to the debugger action.

Parameters
DbgStateThe state of the debugger on the current core
TagTag of event
ActionAction object
EventTriggerDetailEvent trigger detail
Returns
VOID
1855{
1856 UNREFERENCED_PARAMETER(Action);
1857
1859 {
1860 //
1861 // The guest is already in vmx-root mode
1862 // Halt other cores
1863 //
1864
1866 DbgState,
1868 EventTriggerDetail);
1869 }
1870 else
1871 {
1872 //
1873 // The guest is on vmx non-root mode and this is an event
1874 //
1876 (UINT64)EventTriggerDetail,
1877 (UINT64)DbgState->Regs,
1878 (UINT64)NULL);
1879 }
1880}
#define DEBUGGER_VMCALL_VM_EXIT_HALT_SYSTEM_AS_A_RESULT_OF_TRIGGERING_EVENT
VMCALL to cause vm-exit and halt the system because of triggering an event.
Definition DebuggerVmcalls.h:29
_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
@ DEBUGGEE_PAUSING_REASON_DEBUGGEE_EVENT_TRIGGERED
Definition Connection.h:35
IMPORT_EXPORT_VMM BOOLEAN VmFuncVmxGetCurrentExecutionMode()
Get the current VMX operation state.
Definition Export.c:802
IMPORT_EXPORT_VMM NTSTATUS VmFuncVmxVmcall(UINT64 VmcallNumber, UINT64 OptionalParam1, UINT64 OptionalParam2, UINT64 OptionalParam3)
Export for running VMX VMCALLs.
Definition Export.c:957
GUEST_REGS * Regs
Definition State.h:167

◆ DebuggerPerformRunScript()

BOOLEAN DebuggerPerformRunScript ( PROCESSOR_DEBUGGING_STATE * DbgState,
DEBUGGER_EVENT_ACTION * Action,
DEBUGGEE_SCRIPT_PACKET * ScriptDetails,
DEBUGGER_TRIGGERED_EVENT_DETAILS * EventTriggerDetail )

Managing run script action.

Parameters
DbgStateThe state of the debugger on the current core
ActionAction object
ScriptDetailsDetails of script
EventTriggerDetailEvent trigger detail
Returns
BOOLEAN
1666{
1667 SYMBOL_BUFFER CodeBuffer = {0};
1668 ACTION_BUFFER ActionBuffer = {0};
1669 SYMBOL ErrorSymbol = {0};
1670 SCRIPT_ENGINE_GENERAL_REGISTERS ScriptGeneralRegisters = {0};
1671
1672 if (Action != NULL)
1673 {
1674 //
1675 // Fill the action buffer's calling stage
1676 //
1677 if (EventTriggerDetail->Stage == VMM_CALLBACK_CALLING_STAGE_POST_EVENT_EMULATION)
1678 {
1679 ActionBuffer.CallingStage = 1;
1680 }
1681 else
1682 {
1683 ActionBuffer.CallingStage = 0;
1684 }
1685
1686 //
1687 // Fill the action buffer
1688 //
1689 ActionBuffer.Context = (UINT64)EventTriggerDetail->Context;
1690 ActionBuffer.Tag = EventTriggerDetail->Tag;
1692 ActionBuffer.CurrentAction = (UINT64)Action;
1693
1694 //
1695 // Context point to the registers
1696 //
1697 CodeBuffer.Head = (PSYMBOL)Action->ScriptConfiguration.ScriptBuffer;
1698 CodeBuffer.Size = Action->ScriptConfiguration.ScriptLength;
1699 CodeBuffer.Pointer = Action->ScriptConfiguration.ScriptPointer;
1700 }
1701 else if (ScriptDetails != NULL)
1702 {
1703 //
1704 // Fill the action buffer's calling stage
1705 //
1706 if (EventTriggerDetail->Stage == VMM_CALLBACK_CALLING_STAGE_POST_EVENT_EMULATION)
1707 {
1708 ActionBuffer.CallingStage = 1;
1709 }
1710 else
1711 {
1712 ActionBuffer.CallingStage = 0;
1713 }
1714
1715 //
1716 // Fill the action buffer
1717 //
1718 ActionBuffer.Context = (UINT64)EventTriggerDetail->Context;
1719 ActionBuffer.Tag = EventTriggerDetail->Tag;
1720 ActionBuffer.ImmediatelySendTheResults = TRUE;
1721 ActionBuffer.CurrentAction = (UINT64)NULL;
1722
1723 //
1724 // Context point to the registers
1725 //
1726 CodeBuffer.Head = (SYMBOL *)((CHAR *)ScriptDetails + sizeof(DEBUGGEE_SCRIPT_PACKET));
1727 CodeBuffer.Size = ScriptDetails->ScriptBufferSize;
1728 CodeBuffer.Pointer = ScriptDetails->ScriptBufferPointer;
1729 }
1730 else
1731 {
1732 //
1733 // The parameters are wrong !
1734 //
1735 return FALSE;
1736 }
1737
1738 //
1739 // Fill the stack buffer for this run
1740 //
1741 ScriptGeneralRegisters.StackBuffer = DbgState->ScriptEngineCoreSpecificStackBuffer;
1742 ScriptGeneralRegisters.GlobalVariablesList = g_ScriptGlobalVariables;
1743 RtlZeroMemory(ScriptGeneralRegisters.StackBuffer, MAX_STACK_BUFFER_COUNT * sizeof(UINT64));
1744
1745 UINT64 EXECUTENUMBER = 0;
1746
1747 for (UINT64 i = 0; i < CodeBuffer.Pointer;)
1748 {
1749 //
1750 // If has error, show error message and abort.
1751 //
1752
1753 if (ScriptEngineExecute(DbgState->Regs,
1754 &ActionBuffer,
1755 &ScriptGeneralRegisters,
1756 &CodeBuffer,
1757 &i,
1758 &ErrorSymbol) == TRUE)
1759 {
1760 LogInfo("Err, ScriptEngineExecute, function = % s\n ",
1761 FunctionNames[ErrorSymbol.Value]);
1762 break;
1763 }
1764 else if (ScriptGeneralRegisters.StackIndx >= MAX_STACK_BUFFER_COUNT)
1765 {
1766 LogInfo("Err, stack buffer overflow (more information: https://docs.hyperdbg.org/tips-and-tricks/misc/customize-build/change-script-engine-limitations)\n");
1767 break;
1768 }
1769 else if (EXECUTENUMBER >= MAX_EXECUTION_COUNT)
1770 {
1771 LogInfo("Err, exceeding the max execution count (more information: https://docs.hyperdbg.org/tips-and-tricks/misc/customize-build/change-script-engine-limitations)\n");
1772 break;
1773 }
1774
1775 EXECUTENUMBER++;
1776 }
1777
1778 return TRUE;
1779}
BOOL ScriptEngineExecute(PGUEST_REGS GuestRegs, ACTION_BUFFER *ActionDetail, PSCRIPT_ENGINE_GENERAL_REGISTERS ScriptGeneralRegisters, SYMBOL_BUFFER *CodeBuffer, UINT64 *Indx, SYMBOL *ErrorOperator)
Execute the script buffer.
Definition ScriptEngineEval.c:297
struct _SCRIPT_ENGINE_GENERAL_REGISTERS SCRIPT_ENGINE_GENERAL_REGISTERS
List of different variables.
char CHAR
Definition BasicTypes.h:33
#define MAX_EXECUTION_COUNT
Maximum number of variables that can be used in the script engine.
Definition Constants.h:576
struct _DEBUGGEE_SCRIPT_PACKET DEBUGGEE_SCRIPT_PACKET
The structure of script packet in HyperDbg.
struct SYMBOL * PSYMBOL
#define LogInfo(format,...)
Define log variables.
Definition HyperDbgHyperLogIntrinsics.h:71
UINT32 ScriptBufferPointer
Definition RequestStructures.h:1585
UINT32 ScriptBufferSize
Definition RequestStructures.h:1584
UINT64 Tag
Definition DataTypes.h:226
VMM_CALLBACK_EVENT_CALLING_STAGE_TYPE Stage
Definition DataTypes.h:228
PVOID Context
Definition DataTypes.h:227
UINT64 * GlobalVariablesList
Definition BasicTypes.h:225
UINT64 StackIndx
Definition BasicTypes.h:226
UINT64 * StackBuffer
Definition BasicTypes.h:224
Definition ScriptEngineCommonDefinitions.h:35
long long unsigned Context
Definition ScriptEngineCommonDefinitions.h:39
long long unsigned Tag
Definition ScriptEngineCommonDefinitions.h:36
long long unsigned CurrentAction
Definition ScriptEngineCommonDefinitions.h:37
char CallingStage
Definition ScriptEngineCommonDefinitions.h:40
char ImmediatelySendTheResults
Definition ScriptEngineCommonDefinitions.h:38
Definition ScriptEngineCommonDefinitions.h:22
unsigned int Pointer
Definition ScriptEngineCommonDefinitions.h:24
PSYMBOL Head
Definition ScriptEngineCommonDefinitions.h:23
unsigned int Size
Definition ScriptEngineCommonDefinitions.h:25
Definition ScriptEngineCommonDefinitions.h:6
long long unsigned Value
Definition ScriptEngineCommonDefinitions.h:9

◆ DebuggerPerformRunTheCustomCode()

VOID DebuggerPerformRunTheCustomCode ( PROCESSOR_DEBUGGING_STATE * DbgState,
DEBUGGER_EVENT_ACTION * Action,
DEBUGGER_TRIGGERED_EVENT_DETAILS * EventTriggerDetail )

Manage running the custom code action.

Parameters
DbgStateThe state of the debugger on the current core
ActionAction object
EventTriggerDetailEvent trigger detail
Returns
VOID
1794{
1795 if (Action->CustomCodeBufferSize == 0)
1796 {
1797 //
1798 // Sth went wrong ! the buffer size for custom code shouldn't be zero
1799 //
1800 return;
1801 }
1802
1803 //
1804 // -----------------------------------------------------------------------------------------------------
1805 // Test
1806 //
1807 // LogInfo("%X Called from : %llx", Tag, Context);
1808 //
1809 //
1810 // LogInfo("Process Id : %x , Rax : %llx , R8 : %llx , Context : 0x%llx ", PsGetCurrentProcessId(), Regs->rax, Regs->r8, Context);
1811 // return;
1812 //
1813 // -----------------------------------------------------------------------------------------------------
1814 //
1815
1816 //
1817 // Run the custom code
1818 //
1819 if (Action->RequestedBuffer.RequestBufferSize == 0)
1820 {
1821 //
1822 // Because the user might change the nonvolatile registers, we save fastcall nonvolatile registers
1823 //
1824 AsmDebuggerCustomCodeHandler((UINT64)NULL,
1825 (UINT64)DbgState->Regs,
1826 (UINT64)EventTriggerDetail->Context,
1827 (UINT64)Action->CustomCodeBufferAddress);
1828 }
1829 else
1830 {
1831 //
1832 // Because the user might change the nonvolatile registers, we save fastcall nonvolatile registers
1833 //
1835 (UINT64)DbgState->Regs,
1836 (UINT64)EventTriggerDetail->Context,
1837 (UINT64)Action->CustomCodeBufferAddress);
1838 }
1839}
VOID AsmDebuggerCustomCodeHandler(UINT64 Param1, UINT64 Param2, UINT64 Param3, UINT64 Param4)
default custom code handler for debugger

◆ DebuggerQueryDebuggerStatus()

BOOLEAN DebuggerQueryDebuggerStatus ( )

Detect whether the user or kernel debugger is active or not.

Returns
BOOLEAN TRUE if any of the are activated and FALSE if not
2533{
2535 {
2536 return TRUE;
2537 }
2538 else
2539 {
2540 return FALSE;
2541 }
2542}
BOOLEAN g_UserDebuggerState
shows whether the user debugger is enabled or disabled
Definition Global.h:157
BOOLEAN g_KernelDebuggerState
shows whether the kernel debugger is enabled or disabled
Definition Global.h:151

◆ DebuggerQueryStateEvent()

BOOLEAN DebuggerQueryStateEvent ( UINT64 Tag)

returns whether an event is enabled/disabled by tag

this function won't check for Tag validity and if not found then returns false

Parameters
TagTag of target event
Returns
BOOLEAN TRUE if event enabled and FALSE if event not found
2371{
2372 PDEBUGGER_EVENT Event;
2373 //
2374 // Search all the cores for enable this event
2375 //
2376 Event = DebuggerGetEventByTag(Tag);
2377
2378 //
2379 // Check if tag is valid or not
2380 //
2381 if (Event == NULL)
2382 {
2383 return FALSE;
2384 }
2385
2386 return Event->Enabled;
2387}

◆ DebuggerRegisterEvent()

BOOLEAN DebuggerRegisterEvent ( PDEBUGGER_EVENT Event)

Register an event to a list of active events.

Parameters
EventEvent structure
Returns
BOOLEAN TRUE if it successfully registered and FALSE if not registered
1114{
1115 PLIST_ENTRY TargetEventList = NULL;
1116
1117 //
1118 // Register the event
1119 //
1120 TargetEventList = DebuggerGetEventListByEventType(Event->EventType);
1121
1122 if (TargetEventList != NULL)
1123 {
1124 InsertHeadList(TargetEventList, &(Event->EventsOfSameTypeList));
1125
1126 return TRUE;
1127 }
1128 else
1129 {
1130 return FALSE;
1131 }
1132}
LIST_ENTRY EventsOfSameTypeList
Definition Debugger.h:111

◆ DebuggerRemoveEvent()

BOOLEAN DebuggerRemoveEvent ( UINT64 Tag,
BOOLEAN PoolManagerAllocatedMemory )

Remove the event by its tags and also remove its actions and de-allocate their buffers.

it won't terminate their effects, so the events should be terminated first then we can remove them

Parameters
TagTarget event tag
PoolManagerAllocatedMemoryWhether the pools are allocated from the pool manager or original OS pools
Returns
BOOLEAN TRUE if it was successful and FALSE if not successful
2682{
2683 PDEBUGGER_EVENT Event;
2684
2685 //
2686 // First of all, we disable event
2687 //
2689 {
2690 //
2691 // Not found, tag is wrong !
2692 //
2693 return FALSE;
2694 }
2695
2696 //
2697 // When we're here, we are sure that the tag is valid
2698 // because if it was not valid, then we have to return
2699 // for the above function (DebuggerDisableEvent)
2700 //
2701 Event = DebuggerGetEventByTag(Tag);
2702
2703 //
2704 // Now we get the PDEBUGGER_EVENT so we have to remove
2705 // it from the event list
2706 //
2708 {
2709 return FALSE;
2710 }
2711
2712 //
2713 // Remove all of the actions and free its pools
2714 //
2715 DebuggerRemoveAllActionsFromEvent(Event, PoolManagerAllocatedMemory);
2716
2717 //
2718 // Free the pools of Event, when we free the pool,
2719 // ConditionsBufferAddress is also a part of the
2720 // event pool (ConditionBufferAddress and event
2721 // are both allocate in a same pool ) so both of
2722 // them are freed
2723 //
2724 if (PoolManagerAllocatedMemory)
2725 {
2726 PoolManagerFreePool((UINT64)Event);
2727 }
2728 else
2729 {
2730 PlatformMemFreePool(Event);
2731 }
2732
2733 return TRUE;
2734}
BOOLEAN DebuggerRemoveAllActionsFromEvent(PDEBUGGER_EVENT Event, BOOLEAN PoolManagerAllocatedMemory)
Remove the actions and de-allocate its buffer.
Definition Debugger.c:2608
BOOLEAN DebuggerRemoveEventFromEventList(UINT64 Tag)
Remove the event from event list by its tag.
Definition Debugger.c:2556

◆ DebuggerSetLastError()

VOID DebuggerSetLastError ( UINT32 LastError)

Debugger set the last error.

Parameters
LastErrorThe value of last error
Returns
VOID
45{
46 g_LastError = LastError;
47}

◆ DebuggerTerminateEvent()

BOOLEAN DebuggerTerminateEvent ( UINT64 Tag,
BOOLEAN InputFromVmxRoot )

Terminate one event's effect by its tag.

This function won't remove the event from the lists of event or de-allocated them, this should be called BEFORE the removing function

Parameters
TagTarget event's tag
InputFromVmxRootWhether the input comes from VMX root-mode or IOCTL
Returns
BOOLEAN if it was found and terminated without error then it returns TRUE, otherwise FALSE
3484{
3485 PDEBUGGER_EVENT Event;
3486 BOOLEAN Result = FALSE;
3487
3488 //
3489 // Find the event by its tag
3490 //
3491 Event = DebuggerGetEventByTag(Tag);
3492
3493 if (Event == NULL)
3494 {
3495 //
3496 // event, not found
3497 //
3498 return FALSE;
3499 }
3500
3501 //
3502 // Check the event type of our specific tag
3503 //
3504 switch (Event->EventType)
3505 {
3507 {
3508 //
3509 // Call external interrupt terminator
3510 //
3511 TerminateExternalInterruptEvent(Event, InputFromVmxRoot);
3512 Result = TRUE;
3513
3514 break;
3515 }
3520 case HIDDEN_HOOK_READ:
3521 case HIDDEN_HOOK_WRITE:
3523 {
3524 //
3525 // Call read and write and execute ept hook terminator
3526 //
3527 TerminateHiddenHookReadAndWriteAndExecuteEvent(Event, InputFromVmxRoot);
3528 Result = TRUE;
3529
3530 break;
3531 }
3533 {
3534 //
3535 // Call ept hook (hidden breakpoint) terminator
3536 //
3537 TerminateHiddenHookExecCcEvent(Event, InputFromVmxRoot);
3538 Result = TRUE;
3539
3540 break;
3541 }
3543 {
3544 //
3545 // Call ept hook (hidden inline hook) terminator
3546 //
3547 TerminateHiddenHookExecDetoursEvent(Event, InputFromVmxRoot);
3548 Result = TRUE;
3549
3550 break;
3551 }
3553 {
3554 //
3555 // Call rdmsr execution event terminator
3556 //
3557 TerminateRdmsrExecutionEvent(Event, InputFromVmxRoot);
3558 Result = TRUE;
3559
3560 break;
3561 }
3563 {
3564 //
3565 // Call wrmsr execution event terminator
3566 //
3567 TerminateWrmsrExecutionEvent(Event, InputFromVmxRoot);
3568 Result = TRUE;
3569
3570 break;
3571 }
3572 case EXCEPTION_OCCURRED:
3573 {
3574 //
3575 // Call exception events terminator
3576 //
3577 TerminateExceptionEvent(Event, InputFromVmxRoot);
3578 Result = TRUE;
3579
3580 break;
3581 }
3583 {
3584 //
3585 // Call IN instruction execution event terminator
3586 //
3587 TerminateInInstructionExecutionEvent(Event, InputFromVmxRoot);
3588 Result = TRUE;
3589
3590 break;
3591 }
3593 {
3594 //
3595 // Call OUT instruction execution event terminator
3596 //
3597 TerminateOutInstructionExecutionEvent(Event, InputFromVmxRoot);
3598 Result = TRUE;
3599
3600 break;
3601 }
3603 {
3604 //
3605 // Call syscall hook event terminator
3606 //
3607 TerminateSyscallHookEferEvent(Event, InputFromVmxRoot);
3608 Result = TRUE;
3609
3610 break;
3611 }
3613 {
3614 //
3615 // Call sysret hook event terminator
3616 //
3617 TerminateSysretHookEferEvent(Event, InputFromVmxRoot);
3618 Result = TRUE;
3619
3620 break;
3621 }
3623 {
3624 //
3625 // Call vmcall instruction execution event terminator
3626 //
3627 TerminateVmcallExecutionEvent(Event, InputFromVmxRoot);
3628 Result = TRUE;
3629
3630 break;
3631 }
3633 {
3634 //
3635 // Call mode execution trap event terminator
3636 //
3637 TerminateExecTrapModeChangedEvent(Event, InputFromVmxRoot);
3638 Result = TRUE;
3639
3640 break;
3641 }
3643 {
3644 //
3645 // Call rdtsc/rdtscp instruction execution event terminator
3646 //
3647 TerminateTscEvent(Event, InputFromVmxRoot);
3648 Result = TRUE;
3649
3650 break;
3651 }
3653 {
3654 //
3655 // Call rdtsc/rdtscp instructions execution event terminator
3656 //
3657 TerminatePmcEvent(Event, InputFromVmxRoot);
3658 Result = TRUE;
3659
3660 break;
3661 }
3663 {
3664 //
3665 // Call mov to debugger register event terminator
3666 //
3667 TerminateDebugRegistersEvent(Event, InputFromVmxRoot);
3668 Result = TRUE;
3669
3670 break;
3671 }
3673 {
3674 //
3675 // Call cpuid instruction execution event terminator
3676 //
3677 TerminateCpuidExecutionEvent(Event, InputFromVmxRoot);
3678 Result = TRUE;
3679
3680 break;
3681 }
3683 {
3684 //
3685 // Call mov to control register event terminator
3686 //
3687 TerminateControlRegistersEvent(Event, InputFromVmxRoot);
3688 Result = TRUE;
3689
3690 break;
3691 }
3693 {
3694 //
3695 // Call XSETBV instruction execution event terminator
3696 //
3697 TerminateXsetbvExecutionEvent(Event, InputFromVmxRoot);
3698 Result = TRUE;
3699
3700 break;
3701 }
3702 default:
3703 LogError("Err, unknown event for termination");
3704 Result = FALSE;
3705
3706 break;
3707 }
3708
3709 //
3710 // Return status
3711 //
3712 return Result;
3713}
VOID TerminateXsetbvExecutionEvent(PDEBUGGER_EVENT Event, BOOLEAN InputFromVmxRoot)
Termination function for XSETBV Instruction events.
Definition Termination.c:1831
VOID TerminateSysretHookEferEvent(PDEBUGGER_EVENT Event, BOOLEAN InputFromVmxRoot)
Termination function for SYSRET Instruction events.
Definition Termination.c:1216
VOID TerminateControlRegistersEvent(PDEBUGGER_EVENT Event, BOOLEAN InputFromVmxRoot)
Termination function for MOV to control registers events.
Definition Termination.c:957
VOID TerminatePmcEvent(PDEBUGGER_EVENT Event, BOOLEAN InputFromVmxRoot)
Termination function for RDPMC Instruction events.
Definition Termination.c:873
VOID TerminateExecTrapModeChangedEvent(PDEBUGGER_EVENT Event, BOOLEAN InputFromVmxRoot)
Termination function for user-mode, kernel-mode exec trap events.
Definition Termination.c:690
VOID TerminateInInstructionExecutionEvent(PDEBUGGER_EVENT Event, BOOLEAN InputFromVmxRoot)
Termination function for IN instruction events.
Definition Termination.c:465
VOID TerminateRdmsrExecutionEvent(PDEBUGGER_EVENT Event, BOOLEAN InputFromVmxRoot)
Termination function for msr read events.
Definition Termination.c:213
VOID TerminateTscEvent(PDEBUGGER_EVENT Event, BOOLEAN InputFromVmxRoot)
Termination function for RDTSC/RDTSCP Instruction events.
Definition Termination.c:789
VOID TerminateDebugRegistersEvent(PDEBUGGER_EVENT Event, BOOLEAN InputFromVmxRoot)
Termination function for MOV to debug registers events.
Definition Termination.c:1041
VOID TerminateExternalInterruptEvent(PDEBUGGER_EVENT Event, BOOLEAN InputFromVmxRoot)
Termination function for external-interrupts.
Definition Termination.c:24
VOID TerminateWrmsrExecutionEvent(PDEBUGGER_EVENT Event, BOOLEAN InputFromVmxRoot)
Termination function for msr write events.
Definition Termination.c:297
VOID TerminateHiddenHookExecDetoursEvent(PDEBUGGER_EVENT Event, BOOLEAN InputFromVmxRoot)
Termination function for hidden hook (detours).
Definition Termination.c:173
VOID TerminateHiddenHookExecCcEvent(PDEBUGGER_EVENT Event, BOOLEAN InputFromVmxRoot)
Termination function for hidden hook (hidden breakpoints).
Definition Termination.c:135
VOID TerminateOutInstructionExecutionEvent(PDEBUGGER_EVENT Event, BOOLEAN InputFromVmxRoot)
Termination function for OUT Instructions events.
Definition Termination.c:556
VOID TerminateExceptionEvent(PDEBUGGER_EVENT Event, BOOLEAN InputFromVmxRoot)
Termination function for exception events.
Definition Termination.c:381
VOID TerminateVmcallExecutionEvent(PDEBUGGER_EVENT Event, BOOLEAN InputFromVmxRoot)
Termination function for VMCALL Instruction events.
Definition Termination.c:647
VOID TerminateSyscallHookEferEvent(PDEBUGGER_EVENT Event, BOOLEAN InputFromVmxRoot)
Termination function for SYSCALL Instruction events.
Definition Termination.c:1125
VOID TerminateCpuidExecutionEvent(PDEBUGGER_EVENT Event, BOOLEAN InputFromVmxRoot)
Termination function for CPUID Instruction events.
Definition Termination.c:746
VOID TerminateHiddenHookReadAndWriteAndExecuteEvent(PDEBUGGER_EVENT Event, BOOLEAN InputFromVmxRoot)
Termination function for hidden hook read/write/execute.
Definition Termination.c:108

◆ DebuggerTriggerEvents()

VMM_CALLBACK_TRIGGERING_EVENT_STATUS_TYPE DebuggerTriggerEvents ( VMM_EVENT_TYPE_ENUM EventType,
VMM_CALLBACK_EVENT_CALLING_STAGE_TYPE CallingStage,
PVOID Context,
BOOLEAN * PostEventRequired,
GUEST_REGS * Regs )

Trigger events of a special type to be managed by debugger.

Parameters
EventTypeType of events
CallingStageStage of calling (pre-event or post-event)
ContextAn optional parameter (different in each event)
PostEventRequiredWhether the caller is requested to trigger a post-event event
RegsGuest gp-registers
Returns
VMM_CALLBACK_TRIGGERING_EVENT_STATUS_TYPE returns the status of handling events
1153{
1154 PROCESSOR_DEBUGGING_STATE * DbgState = NULL;
1155 DebuggerCheckForCondition * ConditionFunc;
1156 DEBUGGER_TRIGGERED_EVENT_DETAILS EventTriggerDetail = {0};
1157 PEPT_HOOKS_CONTEXT EptContext;
1158 PLIST_ENTRY TempList = 0;
1159 PLIST_ENTRY TempList2 = 0;
1160 const PVOID OriginalContext = Context;
1161
1162 //
1163 // Check if triggering debugging actions are allowed or not
1164 //
1166 {
1167 //
1168 // Debugger is not enabled
1169 //
1171 }
1172
1173 //
1174 // Find the debugging state structure
1175 //
1176 DbgState = &g_DbgState[KeGetCurrentProcessorNumberEx(NULL)];
1177
1178 //
1179 // Set the registers for debug state
1180 //
1181 DbgState->Regs = Regs;
1182
1183 //
1184 // Find the debugger events list base on the type of the event
1185 //
1186 TempList = DebuggerGetEventListByEventType(EventType);
1187 TempList2 = TempList;
1188
1189 if (TempList == NULL)
1190 {
1192 }
1193
1194 while (TempList2 != TempList->Flink)
1195 {
1196 TempList = TempList->Flink;
1197 PDEBUGGER_EVENT CurrentEvent = CONTAINING_RECORD(TempList, DEBUGGER_EVENT, EventsOfSameTypeList);
1198
1199 //
1200 // check if the event is enabled or not
1201 //
1202 if (!CurrentEvent->Enabled)
1203 {
1204 continue;
1205 }
1206
1207 //
1208 // Check if this event is for this core or not
1209 //
1210 if (CurrentEvent->CoreId != DEBUGGER_EVENT_APPLY_TO_ALL_CORES && CurrentEvent->CoreId != DbgState->CoreId)
1211 {
1212 //
1213 // This event is not related to either or core or all cores
1214 //
1215 continue;
1216 }
1217
1218 //
1219 // Check if this event is for this process or not
1220 //
1221 if (CurrentEvent->ProcessId != DEBUGGER_EVENT_APPLY_TO_ALL_PROCESSES && CurrentEvent->ProcessId != HANDLE_TO_UINT32(PsGetCurrentProcessId()))
1222 {
1223 //
1224 // This event is not related to either our process or all processes
1225 //
1226 continue;
1227 }
1228
1229 //
1230 // Check event type specific conditions, if the event is not mentioned
1231 // here, it means that it doesn't have any special condition
1232 //
1233 switch (CurrentEvent->EventType)
1234 {
1236
1237 //
1238 // For external interrupt exiting events we check whether the
1239 // vector match the event's vector or not
1240 //
1241 // Context is the physical address
1242 //
1243 if ((UINT64)Context != CurrentEvent->Options.OptionalParam1)
1244 {
1245 //
1246 // The interrupt is not for this event
1247 //
1248 continue;
1249 }
1250
1251 break;
1252
1257 case HIDDEN_HOOK_READ:
1258 case HIDDEN_HOOK_WRITE:
1260
1261 //
1262 // For hidden hook read/write/execute we check whether the address
1263 // is in the range of what user specified or not, this is because
1264 // we get the events for all hidden hooks in a page granularity
1265 //
1266
1267 //
1268 // Here the OriginalContext is used because the context
1269 // might be changed but the OriginalContext is constant
1270 //
1271 EptContext = (PEPT_HOOKS_CONTEXT)OriginalContext;
1272
1273 //
1274 // EPT context should be checked with hooking tag
1275 // The hooking tag is same as the event tag if both
1276 // of them match together
1277 //
1278 if (EptContext->HookingTag != CurrentEvent->Tag)
1279 {
1280 //
1281 // The value is not within our expected range
1282 //
1283 continue;
1284 }
1285 else
1286 {
1287 //
1288 // Fix the context to virtual address
1289 //
1290 Context = (PVOID)EptContext->VirtualAddress;
1291 }
1292
1293 break;
1294
1296
1297 //
1298 // Here we check if it's HIDDEN_HOOK_EXEC_CC then it means
1299 // so we have to make sure to perform its actions only if
1300 // the hook is triggered for the address described in
1301 // event, note that address in event is a virtual address
1302 //
1303 if ((UINT64)Context != CurrentEvent->Options.OptionalParam1)
1304 {
1305 //
1306 // Context is the virtual address
1307 //
1308
1309 //
1310 // The hook is not for this (virtual) address
1311 //
1312 continue;
1313 }
1314
1315 break;
1316
1318
1319 //
1320 // Here the OriginalContext is used because the context
1321 // might be changed but the OriginalContext is constant
1322 //
1323 EptContext = (PEPT_HOOKS_CONTEXT)OriginalContext;
1324
1325 //
1326 // Here we check if it's HIDDEN_HOOK_EXEC_DETOURS
1327 // then it means that it's detours hidden hook exec so we have
1328 // to make sure to perform its actions, only if the hook is triggered
1329 // for the address described in event, note that address in event is
1330 // a physical address and the address that the function that triggers
1331 // these events and sent here as the context is also converted to its
1332 // physical form
1333 // This way we are sure that no one can bypass our hook by remapping
1334 // address to another virtual address as everything is physical
1335 //
1336 if (EptContext->PhysicalAddress != CurrentEvent->Options.OptionalParam1)
1337 {
1338 //
1339 // Context is the physical address
1340 //
1341
1342 //
1343 // The hook is not for this (physical) address
1344 //
1345 continue;
1346 }
1347 else
1348 {
1349 //
1350 // Convert it to virtual address
1351 //
1352 Context = (PVOID)(EptContext->VirtualAddress);
1353 }
1354
1355 break;
1356
1359
1360 //
1361 // check if MSR exit is what we want or not
1362 //
1363 if (CurrentEvent->Options.OptionalParam1 != DEBUGGER_EVENT_MSR_READ_OR_WRITE_ALL_MSRS && CurrentEvent->Options.OptionalParam1 != (UINT64)Context)
1364 {
1365 //
1366 // The msr is not what we want
1367 //
1368 continue;
1369 }
1370
1371 break;
1372
1373 case EXCEPTION_OCCURRED:
1374
1375 //
1376 // check if exception is what we need or not
1377 //
1378 if (CurrentEvent->Options.OptionalParam1 != DEBUGGER_EVENT_EXCEPTIONS_ALL_FIRST_32_ENTRIES && CurrentEvent->Options.OptionalParam1 != (UINT64)Context)
1379 {
1380 //
1381 // The exception is not what we want
1382 //
1383 continue;
1384 }
1385
1386 break;
1387
1390
1391 //
1392 // check if I/O port is what we want or not
1393 //
1394 if (CurrentEvent->Options.OptionalParam1 != DEBUGGER_EVENT_ALL_IO_PORTS && CurrentEvent->Options.OptionalParam1 != (UINT64)Context)
1395 {
1396 //
1397 // The port is not what we want
1398 //
1399 continue;
1400 }
1401
1402 break;
1403
1405
1406 //
1407 // case SYSCALL_HOOK_EFER_SYSRET:
1408 //
1409 // I don't know how to find syscall number when sysret is executed so
1410 // that's why we don't support extra argument for sysret
1411 //
1412
1413 //
1414 // check syscall number
1415 //
1416 if (CurrentEvent->Options.OptionalParam1 != DEBUGGER_EVENT_SYSCALL_ALL_SYSRET_OR_SYSCALLS && CurrentEvent->Options.OptionalParam1 != (UINT64)Context)
1417 {
1418 //
1419 // The syscall number is not what we want
1420 //
1421 continue;
1422 }
1423
1424 break;
1425
1427
1428 //
1429 // check if CPUID is what we want or not
1430 //
1431 if (CurrentEvent->Options.OptionalParam1 != (UINT64)NULL /*FALSE*/ && CurrentEvent->Options.OptionalParam2 != (UINT64)Context)
1432 {
1433 //
1434 // The CPUID is not what we want (and the user didn't intend to get all CPUIDs)
1435 //
1436 continue;
1437 }
1438
1439 break;
1440
1442
1443 //
1444 // check if CR exit is what we want or not
1445 //
1446 if (CurrentEvent->Options.OptionalParam1 != (UINT64)Context)
1447 {
1448 //
1449 // The CR is not what we want
1450 //
1451 continue;
1452 }
1453
1454 break;
1455
1457
1458 //
1459 // check if the debugger needs user-to-kernel or kernel-to-user events
1460 //
1462 {
1467 {
1468 continue;
1469 }
1470 }
1471
1472 break;
1473
1475
1476 //
1477 // check if XSETBV is what we want or not
1478 //
1479 if (CurrentEvent->Options.OptionalParam1 != (UINT64)NULL /*FALSE*/ && CurrentEvent->Options.OptionalParam2 != (UINT64)Context)
1480 {
1481 //
1482 // The XCR is not what we want (and the user didn't intend to get all XSETBVs)
1483 //
1484 continue;
1485 }
1486
1487 break;
1488
1489 default: // All other events that don't have conditions
1490 break;
1491 }
1492
1493 //
1494 // Check the stage of calling (pre, all, or post event)
1495 //
1499 {
1500 //
1501 // Here it means that the current event is a post, or all event event
1502 // and the current stage of calling is for the pre-event events, thus
1503 // this event is not supposed to be ran at the current stage.
1504 // However, we'll set a flag so the caller will know that there is
1505 // a valid post-event available for the parameters related to this
1506 // event.
1507 // This mechanism notifies the caller to trigger the event after
1508 // emulation, we implement it in a way that the caller knows when
1509 // to trigger a post-event thus it optimizes the number of times
1510 // that the caller triggers the events and avoid unnecessary triggering
1511 // of the event (for post-event) but at the same time we have the
1512 // flexibility of having both pre-event and post-event concepts
1513 //
1514 *PostEventRequired = TRUE;
1515
1517 {
1518 //
1519 // If it's not an 'all' event and it is only the 'post' event,
1520 // then we ignore the trigger stage
1521 //
1522 continue;
1523 }
1524 }
1525
1526 //
1527 // Check if condition is met or not , if the condition
1528 // is not met then we have to avoid performing the actions
1529 //
1530 if (CurrentEvent->ConditionsBufferSize != 0)
1531 {
1532 //
1533 // Means that there is some conditions
1534 //
1535 ConditionFunc = (DebuggerCheckForCondition *)CurrentEvent->ConditionBufferAddress;
1536
1537 //
1538 // Run and check for results
1539 //
1540 // Because the user might change the nonvolatile registers, we save fastcall nonvolatile registers
1541 //
1542 if (AsmDebuggerConditionCodeHandler((UINT64)DbgState->Regs, (UINT64)Context, (UINT64)ConditionFunc) == 0)
1543 {
1544 //
1545 // The condition function returns null, mean that the
1546 // condition didn't met, we can ignore this event
1547 //
1548 continue;
1549 }
1550 }
1551
1552 //
1553 // Reset the event ignorance mechanism (apply 'sc on/off' to the events)
1554 //
1555 DbgState->ShortCircuitingEvent = CurrentEvent->EnableShortCircuiting;
1556
1557 //
1558 // Setup event trigger detail
1559 //
1560 EventTriggerDetail.Context = Context;
1561 EventTriggerDetail.Tag = CurrentEvent->Tag;
1562 EventTriggerDetail.Stage = CallingStage;
1563
1564 //
1565 // perform the actions
1566 //
1567 DebuggerPerformActions(DbgState, CurrentEvent, &EventTriggerDetail);
1568 }
1569
1570 //
1571 // Check if the event should be ignored or not
1572 //
1573 if (DbgState->ShortCircuitingEvent)
1574 {
1575 //
1576 // Reset the event ignorance (short-circuit) mechanism
1577 //
1578 DbgState->ShortCircuitingEvent = FALSE;
1579
1580 //
1581 // Event should be ignored
1582 //
1584 }
1585 else
1586 {
1587 //
1588 // Event shouldn't be ignored
1589 //
1591 }
1592}
UINT64 AsmDebuggerConditionCodeHandler(UINT64 Param1, UINT64 Param2, UINT64 Param3)
default condition code handler
VOID DebuggerPerformActions(PROCESSOR_DEBUGGING_STATE *DbgState, DEBUGGER_EVENT *Event, DEBUGGER_TRIGGERED_EVENT_DETAILS *EventTriggerDetail)
Run a special event's action(s).
Definition Debugger.c:1604
#define HANDLE_TO_UINT32(_var)
Definition MetaMacros.h:39
#define DEBUGGER_EVENT_ALL_IO_PORTS
Apply to all I/O ports.
Definition Constants.h:769
#define DEBUGGER_EVENT_SYSCALL_ALL_SYSRET_OR_SYSCALLS
Apply to all syscalls and sysrets.
Definition Constants.h:763
#define DEBUGGER_EVENT_EXCEPTIONS_ALL_FIRST_32_ENTRIES
Apply to all first 32 exceptions.
Definition Constants.h:757
#define DEBUGGER_EVENT_APPLY_TO_ALL_PROCESSES
Apply the event to all the processes.
Definition Constants.h:745
#define DEBUGGER_EVENT_MSR_READ_OR_WRITE_ALL_MSRS
Apply to all Model Specific Registers.
Definition Constants.h:751
struct _DEBUGGER_TRIGGERED_EVENT_DETAILS DEBUGGER_TRIGGERED_EVENT_DETAILS
The structure of detail of a triggered event in HyperDbg.
struct _EPT_HOOKS_CONTEXT * PEPT_HOOKS_CONTEXT
@ VMM_CALLBACK_TRIGGERING_EVENT_STATUS_SUCCESSFUL_IGNORE_EVENT
Definition Events.h:80
@ VMM_CALLBACK_TRIGGERING_EVENT_STATUS_SUCCESSFUL
Definition Events.h:79
@ VMM_CALLBACK_TRIGGERING_EVENT_STATUS_DEBUGGER_NOT_ENABLED
Definition Events.h:81
@ VMM_CALLBACK_TRIGGERING_EVENT_STATUS_INVALID_EVENT_TYPE
Definition Events.h:82
@ DEBUGGER_EVENT_MODE_TYPE_KERNEL_MODE
Definition Events.h:210
@ DEBUGGER_EVENT_MODE_TYPE_USER_MODE_AND_KERNEL_MODE
Definition Events.h:208
@ DEBUGGER_EVENT_MODE_TYPE_USER_MODE
Definition Events.h:209
BOOLEAN g_InterceptBreakpointsAndEventsForCommandsInRemoteComputer
To avoid getting stuck from getting hit from the breakpoints while executing the commands in the remo...
Definition Global.h:214
UINT64 DebuggerCheckForCondition(PGUEST_REGS Regs, PVOID Context)
The prototype that Condition codes are called.
Definition Debugger.h:160
UINT64 OptionalParam2
Definition Events.h:278
UINT64 HookingTag
Definition DataTypes.h:370
UINT64 VirtualAddress
Definition DataTypes.h:372
UINT64 PhysicalAddress
Definition DataTypes.h:371
UINT32 CoreId
Definition State.h:168
BOOLEAN ShortCircuitingEvent
Definition State.h:169

◆ DebuggerUninitialize()

VOID DebuggerUninitialize ( )

Uninitialize Debugger Structures and Routines.

Returns
VOID
355{
356 ULONG ProcessorsCount;
357 PROCESSOR_DEBUGGING_STATE * CurrentDebuggerState = NULL;
358
359 ProcessorsCount = KeQueryActiveProcessorCount(0);
360
361 //
362 // Free the Pool manager
363 //
365
366 //
367 // Free g_Events
368 //
370
371 //
372 // Free g_ScriptGlobalVariables
373 //
374 if (g_ScriptGlobalVariables != NULL)
375 {
378 }
379
380 //
381 // Free core specific local and temp variables
382 //
383 for (SIZE_T i = 0; i < ProcessorsCount; i++)
384 {
385 CurrentDebuggerState = &g_DbgState[i];
386
387 if (CurrentDebuggerState->ScriptEngineCoreSpecificStackBuffer != NULL)
388 {
390 CurrentDebuggerState->ScriptEngineCoreSpecificStackBuffer = NULL;
391 }
392 }
393
394 //
395 // Free g_DbgState
396 //
398}
VOID GlobalEventsFreeMemory(VOID)
Free event store memory.
Definition Allocations.c:88
VOID GlobalDebuggingStateFreeMemory(VOID)
Free debugging state memory.
Definition Allocations.c:49
VOID PoolManagerUninitialize()
Uninitialize the pool manager (free the buffers, etc.).
Definition PoolManager.c:93

◆ DebuggerUninitializeVmmOperations()

VOID DebuggerUninitializeVmmOperations ( )

Uninitialize Debugger VMM Operations (Events and other related operations).

Returns
VOID
300{
301 //
302 // *** Disable, terminate and clear all the events ***
303 //
304
305 //
306 // Because we want to delete all the objects and buffers (pools)
307 // after we finished termination, the debugger might still use
308 // the buffers for events and action, for solving this problem
309 // we first disable the tag(s) and this way the debugger no longer
310 // use that event and this way we can safely remove and deallocate
311 // the buffers later after termination
312 //
313
314 //
315 // Disable triggering events
316 //
318
319 //
320 // Clear all events (Check if the kernel debugger is enable
321 // and whether the instant event mechanism is working or not)
322 //
324 {
326 }
327 else
328 {
330 }
331
332 //
333 // Uninitialize kernel debugger
334 //
336
337 //
338 // Uninitialize user debugger
339 //
341
342 //
343 // Uninitialize NMI broadcasting mechanism
344 //
346}
#define EnableInstantEventMechanism
Enable or disable the instant event mechanism.
Definition Configuration.h:70
VOID KdUninitializeKernelDebugger()
uninitialize kernel debugger
Definition Kd.c:68
VOID UdUninitializeUserDebugger()
uninitialize user debugger
Definition Ud.c:90
IMPORT_EXPORT_VMM VOID VmFuncVmxBroadcastUninitialize()
Export for uninitialize the VMX Broadcast mechanism.
Definition Export.c:982