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

Implementation of Debugger functions. More...

#include "pch.h"

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 DebuggerInitialize ()
 Initialize Debugger Structures and Routines.
 
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.
 
PVOID DebuggerAllocateSafeRequestedBuffer (SIZE_T SizeOfRequestedSafeBuffer, PDEBUGGER_EVENT_AND_ACTION_RESULT ResultsToReturn, BOOLEAN InputFromVmxRoot)
 Allocates buffer for requested safe buffer.
 
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.
 
VOID DebuggerPerformActions (PROCESSOR_DEBUGGING_STATE *DbgState, DEBUGGER_EVENT *Event, DEBUGGER_TRIGGERED_EVENT_DETAILS *EventTriggerDetail)
 Run a special event's action(s)
 
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.
 
VOID DebuggerPerformBreakToDebugger (PROCESSOR_DEBUGGING_STATE *DbgState, DEBUGGER_EVENT_ACTION *Action, DEBUGGER_TRIGGERED_EVENT_DETAILS *EventTriggerDetail)
 Manage breaking to the debugger action.
 
PDEBUGGER_EVENT DebuggerGetEventByTag (UINT64 Tag)
 Find event object by tag.
 
BOOLEAN DebuggerEnableOrDisableAllEvents (BOOLEAN IsEnable)
 Enable or disable all events from all the types.
 
BOOLEAN DebuggerTerminateAllEvents (BOOLEAN InputFromVmxRoot)
 Terminate effect and configuration to vmx-root and non-root for all the events.
 
BOOLEAN DebuggerRemoveAllEvents (BOOLEAN PoolManagerAllocatedMemory)
 Remove all the events from all the lists and also de-allocate their structures and actions.
 
UINT32 DebuggerEventListCount (PLIST_ENTRY TargetEventList)
 Count the list of events in a special list.
 
PLIST_ENTRY DebuggerGetEventListByEventType (VMM_EVENT_TYPE_ENUM EventType)
 Get List of event based on event type.
 
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 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 DebuggerClearAllEvents (BOOLEAN InputFromVmxRoot, BOOLEAN PoolManagerAllocatedMemory)
 Clear all events.
 
BOOLEAN DebuggerIsTagValid (UINT64 Tag)
 Detect whether the tag exists or not.
 
BOOLEAN DebuggerQueryDebuggerStatus ()
 Detect whether the user or kernel debugger is active or not.
 
BOOLEAN DebuggerRemoveEventFromEventList (UINT64 Tag)
 Remove the event from event list by its tag.
 
BOOLEAN DebuggerRemoveAllActionsFromEvent (PDEBUGGER_EVENT Event, BOOLEAN PoolManagerAllocatedMemory)
 Remove the actions and de-allocate its buffer.
 
BOOLEAN DebuggerRemoveEvent (UINT64 Tag, BOOLEAN PoolManagerAllocatedMemory)
 Remove the event by its tags and also remove its actions and de-allocate their buffers.
 
BOOLEAN DebuggerValidateEvent (PDEBUGGER_GENERAL_EVENT_DETAIL EventDetails, PDEBUGGER_EVENT_AND_ACTION_RESULT ResultsToReturn, BOOLEAN InputFromVmxRoot)
 validating events
 
BOOLEAN DebuggerApplyEvent (PDEBUGGER_EVENT Event, PDEBUGGER_EVENT_AND_ACTION_RESULT ResultsToReturn, BOOLEAN InputFromVmxRoot)
 Applying events.
 
BOOLEAN DebuggerParseEvent (PDEBUGGER_GENERAL_EVENT_DETAIL EventDetails, PDEBUGGER_EVENT_AND_ACTION_RESULT ResultsToReturn, BOOLEAN InputFromVmxRoot)
 Routine for parsing events.
 
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.
 
BOOLEAN DebuggerTerminateEvent (UINT64 Tag, BOOLEAN InputFromVmxRoot)
 Terminate one event's effect by its tag.
 
BOOLEAN DebuggerParseEventsModification (PDEBUGGER_MODIFY_EVENTS DebuggerEventModificationRequest, BOOLEAN InputFromVmxRoot, BOOLEAN PoolManagerAllocatedMemory)
 Parse and validate requests to enable/disable/clear from the user-mode.
 

Detailed Description

Implementation of Debugger functions.

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

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
676{
678 SIZE_T ActionBufferSize;
679 PVOID RequestedBuffer = NULL;
680
681 //
682 // Allocate action + allocate code for custom code
683 //
684
685 if (InTheCaseOfCustomCode != NULL)
686 {
687 //
688 // We should allocate extra buffer for custom code
689 //
690 ActionBufferSize = sizeof(DEBUGGER_EVENT_ACTION) + InTheCaseOfCustomCode->CustomCodeBufferSize;
691 }
692 else if (InTheCaseOfRunScript != NULL)
693 {
694 //
695 // We should allocate extra buffer for script
696 //
697 ActionBufferSize = sizeof(DEBUGGER_EVENT_ACTION) + InTheCaseOfRunScript->ScriptLength;
698 }
699 else
700 {
701 //
702 // We shouldn't allocate extra buffer as there is no custom code
703 //
704 ActionBufferSize = sizeof(DEBUGGER_EVENT_ACTION);
705 }
706
707 //
708 // Allocate buffer for storing the action
709 //
710
711 if (InputFromVmxRoot)
712 {
713 //
714 // *** The buffer is coming from VMX-root mode ***
715 //
716
717 //
718 // If the buffer is smaller than regular instant events's action
719 //
720 if (REGULAR_INSTANT_EVENT_ACTION_BUFFER >= ActionBufferSize)
721 {
722 //
723 // The buffer fits into a regular instant event's action
724 //
726
727 if (!Action)
728 {
729 //
730 // Here we try again to see if we could store it into a big instant event's action buffer instead
731 //
733
734 if (!Action)
735 {
736 //
737 // Set the error
738 //
739 ResultsToReturn->IsSuccessful = FALSE;
741
742 //
743 // There is a problem with allocating event's action
744 //
745 return NULL;
746 }
747 }
748 }
749 else if (BIG_INSTANT_EVENT_ACTION_BUFFER >= ActionBufferSize)
750 {
751 //
752 // The buffer fits into a big instant event's action buffer
753 //
755
756 if (!Action)
757 {
758 //
759 // Set the error
760 //
761 ResultsToReturn->IsSuccessful = FALSE;
763
764 //
765 // There is a problem with allocating event's action buffer
766 //
767 return NULL;
768 }
769 }
770 else
771 {
772 //
773 // The buffer doesn't fit into any of the regular or big event's action preallocated buffers
774 //
775
776 //
777 // Set the error
778 //
779 ResultsToReturn->IsSuccessful = FALSE;
781
782 return NULL;
783 }
784 }
785 else
786 {
787 //
788 // If it's not coming from the VMX-root mode then we're allocating it from the OS buffers
789 //
790 Action = PlatformMemAllocateZeroedNonPagedPool(ActionBufferSize);
791
792 if (Action == NULL)
793 {
794 //
795 // Set the appropriate error
796 //
797 ResultsToReturn->IsSuccessful = FALSE;
799
800 //
801 // There was an error in allocation
802 //
803 return NULL;
804 }
805 }
806
807 //
808 // If the user needs a buffer to be passed to the debugger then
809 // we should allocate it here (Requested buffer is only available for custom code types)
810 //
811 if (ActionType == RUN_CUSTOM_CODE &&
812 InTheCaseOfCustomCode != NULL &&
813 InTheCaseOfCustomCode->OptionalRequestedBufferSize != 0)
814 {
815 //
816 // Check if the optional buffer is not more that the size
817 // we can send to usermode
818 //
819 if (InTheCaseOfCustomCode->OptionalRequestedBufferSize >= MaximumPacketsCapacity)
820 {
821 //
822 // There was an error
823 //
824 if (InputFromVmxRoot)
825 {
827 }
828 else
829 {
830 PlatformMemFreePool(Action);
831 }
832
833 //
834 // Set the appropriate error
835 //
836 ResultsToReturn->IsSuccessful = FALSE;
838
839 return NULL;
840 }
841
842 //
843 // User needs a buffer to play with
844 //
845 RequestedBuffer = DebuggerAllocateSafeRequestedBuffer(InTheCaseOfCustomCode->OptionalRequestedBufferSize, ResultsToReturn, InputFromVmxRoot);
846
847 if (!RequestedBuffer)
848 {
849 //
850 // There was an error in allocation
851 //
852 if (InputFromVmxRoot)
853 {
855 }
856 else
857 {
858 PlatformMemFreePool(Action);
859 }
860
861 //
862 // Not need to set error as the above function already adjust the error
863 //
864 return NULL;
865 }
866
867 //
868 // Add it to the action
869 //
871 Action->RequestedBuffer.RequestBufferSize = InTheCaseOfCustomCode->OptionalRequestedBufferSize;
872 Action->RequestedBuffer.RequstBufferAddress = (UINT64)RequestedBuffer;
873 }
874
875 //
876 // If the user needs a buffer to be passed to the debugger script then
877 // we should allocate it here (Requested buffer is only available for custom code types)
878 //
879 if (ActionType == RUN_SCRIPT &&
880 InTheCaseOfRunScript != NULL &&
881 InTheCaseOfRunScript->OptionalRequestedBufferSize != 0)
882 {
883 //
884 // Check if the optional buffer is not more that the size
885 // we can send to usermode
886 //
887 if (InTheCaseOfRunScript->OptionalRequestedBufferSize >= MaximumPacketsCapacity)
888 {
889 //
890 // There was an error
891 //
892 if (InputFromVmxRoot)
893 {
895 }
896 else
897 {
898 PlatformMemFreePool(Action);
899 }
900
901 //
902 // Set the appropriate error
903 //
904 ResultsToReturn->IsSuccessful = FALSE;
906
907 return NULL;
908 }
909
910 //
911 // User needs a buffer to play with
912 //
913 RequestedBuffer = DebuggerAllocateSafeRequestedBuffer(InTheCaseOfRunScript->OptionalRequestedBufferSize, ResultsToReturn, InputFromVmxRoot);
914
915 if (!RequestedBuffer)
916 {
917 //
918 // There was an error in allocation
919 //
920 if (InputFromVmxRoot)
921 {
923 }
924 else
925 {
926 PlatformMemFreePool(Action);
927 }
928
929 //
930 // Not need to set error as the above function already adjust the error
931 //
932 return NULL;
933 }
934
935 //
936 // Add it to the action
937 //
939 Action->RequestedBuffer.RequestBufferSize = InTheCaseOfRunScript->OptionalRequestedBufferSize;
940 Action->RequestedBuffer.RequstBufferAddress = (UINT64)RequestedBuffer;
941 }
942
943 if (ActionType == RUN_CUSTOM_CODE && InTheCaseOfCustomCode != NULL)
944 {
945 //
946 // Check if it's a Custom code without custom code buffer which is invalid
947 //
948 if (InTheCaseOfCustomCode != NULL && InTheCaseOfCustomCode->CustomCodeBufferSize == 0)
949 {
950 //
951 // There was an error
952 //
953 if (InputFromVmxRoot)
954 {
956
957 if (RequestedBuffer != NULL)
958 {
959 PoolManagerFreePool((UINT64)RequestedBuffer);
960 }
961 }
962 else
963 {
964 PlatformMemFreePool(Action);
965
966 if (RequestedBuffer != NULL)
967 {
968 PlatformMemFreePool(RequestedBuffer);
969 }
970 }
971
972 ResultsToReturn->IsSuccessful = FALSE;
974
975 return NULL;
976 }
977
978 //
979 // Move the custom code buffer to the end of the action
980 //
981 Action->CustomCodeBufferSize = InTheCaseOfCustomCode->CustomCodeBufferSize;
982 Action->CustomCodeBufferAddress = (PVOID)((UINT64)Action + sizeof(DEBUGGER_EVENT_ACTION));
983
984 //
985 // copy the custom code buffer to the end of the buffer of the action
986 //
987 memcpy(Action->CustomCodeBufferAddress, InTheCaseOfCustomCode->CustomCodeBufferAddress, InTheCaseOfCustomCode->CustomCodeBufferSize);
988 }
989
990 //
991 // If it's run script action type
992 //
993 else if (ActionType == RUN_SCRIPT && InTheCaseOfRunScript != NULL)
994 {
995 //
996 // Check the buffers of run script
997 //
998 if (InTheCaseOfRunScript->ScriptBuffer == NULL64_ZERO || InTheCaseOfRunScript->ScriptLength == NULL_ZERO)
999 {
1000 //
1001 // There was an error
1002 //
1003 if (InputFromVmxRoot)
1004 {
1005 PoolManagerFreePool((UINT64)Action);
1006
1007 if (RequestedBuffer != 0)
1008 {
1009 PoolManagerFreePool((UINT64)RequestedBuffer);
1010 }
1011 }
1012 else
1013 {
1014 PlatformMemFreePool(Action);
1015
1016 if (RequestedBuffer != 0)
1017 {
1018 PlatformMemFreePool(RequestedBuffer);
1019 }
1020 }
1021
1022 ResultsToReturn->IsSuccessful = FALSE;
1024
1025 return NULL;
1026 }
1027
1028 //
1029 // Allocate the buffer from a non-page pool on the script
1030 //
1031 Action->ScriptConfiguration.ScriptBuffer = (UINT64)((BYTE *)Action + sizeof(DEBUGGER_EVENT_ACTION));
1032
1033 //
1034 // Copy the memory of script to our non-paged pool
1035 //
1036 RtlCopyMemory((void *)Action->ScriptConfiguration.ScriptBuffer, (const void *)InTheCaseOfRunScript->ScriptBuffer, InTheCaseOfRunScript->ScriptLength);
1037
1038 //
1039 // Set other fields
1040 //
1041 Action->ScriptConfiguration.ScriptLength = InTheCaseOfRunScript->ScriptLength;
1042 Action->ScriptConfiguration.ScriptPointer = InTheCaseOfRunScript->ScriptPointer;
1044 }
1045
1046 //
1047 // Create an order code for the current action
1048 // and also increase the Count of action in event
1049 //
1050 Event->CountOfActions++;
1051 Action->ActionOrderCode = Event->CountOfActions;
1052
1053 //
1054 // Fill other parts of the action
1055 //
1056 Action->ImmediatelySendTheResults = SendTheResultsImmediately;
1057 Action->ActionType = ActionType;
1058 Action->Tag = Event->Tag;
1059
1060 //
1061 // Now we should add the action to the event's LIST_ENTRY of actions
1062 //
1063 InsertHeadList(&Event->ActionsListHead, &(Action->ActionsList));
1064
1065 return Action;
1066}
#define NULL_ZERO
Definition BasicTypes.h:51
unsigned char BYTE
Definition BasicTypes.h:24
#define NULL64_ZERO
Definition BasicTypes.h:52
#define TRUE
Definition BasicTypes.h:55
#define FALSE
Definition BasicTypes.h:54
unsigned __int64 UINT64
Definition BasicTypes.h:21
#define BIG_INSTANT_EVENT_ACTION_BUFFER
Pre-allocated size for a big action + custom code or script buffer.
Definition Constants.h:300
#define MaximumPacketsCapacity
Default buffer count of packets for message tracing.
Definition Constants.h:163
#define REGULAR_INSTANT_EVENT_ACTION_BUFFER
Pre-allocated size for a regular action + custom code or script buffer.
Definition Constants.h:294
@ INSTANT_BIG_EVENT_ACTION_BUFFER
Definition DataTypes.h:54
@ INSTANT_REGULAR_EVENT_ACTION_BUFFER
Definition DataTypes.h:53
PVOID DebuggerAllocateSafeRequestedBuffer(SIZE_T SizeOfRequestedSafeBuffer, PDEBUGGER_EVENT_AND_ACTION_RESULT ResultsToReturn, BOOLEAN InputFromVmxRoot)
Allocates buffer for requested safe buffer.
Definition Debugger.c:554
#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
VOID PlatformMemFreePool(PVOID BufferAddress)
Free (dellocate) a non-paged buffer.
Definition Mem.c:86
PVOID PlatformMemAllocateZeroedNonPagedPool(SIZE_T NumberOfBytes)
Allocate a non-paged buffer (zeroed)
Definition Mem.c:69
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:212
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:136
FORCEINLINE VOID InsertHeadList(_Inout_ PLIST_ENTRY ListHead, _Inout_ PLIST_ENTRY Entry)
Definition Windows.h:115
struct _DEBUGGER_EVENT_ACTION DEBUGGER_EVENT_ACTION
The structure of actions in HyperDbg.
@ RUN_CUSTOM_CODE
Definition Events.h:182
@ RUN_SCRIPT
Definition Events.h:181
NULL()
Definition test-case-generator.py:530
UINT32 ScriptPointer
Definition RequestStructures.h:828
UINT32 ScriptLength
Definition RequestStructures.h:827
UINT64 ScriptBuffer
Definition RequestStructures.h:826
UINT32 OptionalRequestedBufferSize
Definition RequestStructures.h:829
The structure of actions in HyperDbg.
Definition Debugger.h:79
DEBUGGER_EVENT_ACTION_RUN_SCRIPT_CONFIGURATION ScriptConfiguration
Definition Debugger.h:89
LIST_ENTRY ActionsList
Definition Debugger.h:82
PVOID CustomCodeBufferAddress
Definition Debugger.h:96
UINT32 CustomCodeBufferSize
Definition Debugger.h:95
DEBUGGER_EVENT_ACTION_TYPE_ENUM ActionType
Definition Debugger.h:83
UINT64 Tag
Definition Debugger.h:80
DEBUGGER_EVENT_REQUEST_BUFFER RequestedBuffer
Definition Debugger.h:92
BOOLEAN ImmediatelySendTheResults
Definition Debugger.h:84
UINT32 ActionOrderCode
Definition Debugger.h:81
UINT32 Error
Definition Events.h:425
BOOLEAN IsSuccessful
Definition Events.h:424
UINT32 RequestBufferSize
Definition RequestStructures.h:841
BOOLEAN EnabledRequestBuffer
Definition RequestStructures.h:840
UINT64 RequstBufferAddress
Definition RequestStructures.h:842
UINT32 CustomCodeBufferSize
Definition RequestStructures.h:852
UINT32 OptionalRequestedBufferSize
Definition RequestStructures.h:854
PVOID CustomCodeBufferAddress
Definition RequestStructures.h:853
LIST_ENTRY ActionsListHead
Definition Debugger.h:120
UINT32 CountOfActions
Definition Debugger.h:121
UINT64 Tag
Definition Debugger.h:109

◆ DebuggerAllocateSafeRequestedBuffer()

PVOID DebuggerAllocateSafeRequestedBuffer ( SIZE_T SizeOfRequestedSafeBuffer,
PDEBUGGER_EVENT_AND_ACTION_RESULT ResultsToReturn,
BOOLEAN InputFromVmxRoot )

Allocates buffer for requested safe buffer.

Parameters
SizeOfRequestedSafeBufferThe size of the requested safe buffer
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
PVOID
557{
558 PVOID RequestedBuffer = NULL;
559
560 //
561 // Check whether the buffer comes from VMX-root mode or non-root mode
562 //
563 if (InputFromVmxRoot)
564 {
565 //
566 // *** The buffer is coming from VMX-root mode ***
567 //
568
569 //
570 // If the requested safe buffer is smaller than regular safe buffers
571 //
572 if (REGULAR_INSTANT_EVENT_REQUESTED_SAFE_BUFFER >= SizeOfRequestedSafeBuffer)
573 {
574 //
575 // The buffer fits into a regular safe requested buffer
576 //
578
579 if (!RequestedBuffer)
580 {
581 //
582 // Here we try again to see if we could store it into a big instant event safe requested buffer instead
583 //
585
586 if (!RequestedBuffer)
587 {
588 //
589 // Set the error
590 //
591 ResultsToReturn->IsSuccessful = FALSE;
593
594 //
595 // There is a problem with allocating requested safe buffer
596 //
597 return NULL;
598 }
599 }
600 }
601 else if (BIG_INSTANT_EVENT_REQUESTED_SAFE_BUFFER >= SizeOfRequestedSafeBuffer)
602 {
603 //
604 // The buffer fits into a big instant requested safe buffer
605 //
607
608 if (!RequestedBuffer)
609 {
610 //
611 // Set the error
612 //
613 ResultsToReturn->IsSuccessful = FALSE;
615
616 //
617 // There is a problem with allocating event
618 //
619 return NULL;
620 }
621 }
622 else
623 {
624 //
625 // The buffer doesn't fit into any of the regular or big safe requested buffers
626 //
627
628 //
629 // Set the error
630 //
631 ResultsToReturn->IsSuccessful = FALSE;
633
634 return NULL;
635 }
636 }
637 else
638 {
639 RequestedBuffer = PlatformMemAllocateZeroedNonPagedPool(SizeOfRequestedSafeBuffer);
640
641 if (!RequestedBuffer)
642 {
643 ResultsToReturn->IsSuccessful = FALSE;
645
646 return NULL;
647 }
648 }
649
650 return RequestedBuffer;
651}
#define REGULAR_INSTANT_EVENT_REQUESTED_SAFE_BUFFER
Pre-allocated size for a regular requested safe buffer.
Definition Constants.h:306
#define BIG_INSTANT_EVENT_REQUESTED_SAFE_BUFFER
Pre-allocated size for a big requested safe buffer.
Definition Constants.h:312
@ INSTANT_REGULAR_SAFE_BUFFER_FOR_EVENTS
Definition DataTypes.h:59
@ INSTANT_BIG_SAFE_BUFFER_FOR_EVENTS
Definition DataTypes.h:60
#define DEBUGGER_ERROR_INSTANT_EVENT_BIG_REQUESTED_SAFE_BUFFER_NOT_FOUND
error, the requested safe buffer does not exists (big)
Definition ErrorCodes.h:489
#define DEBUGGER_ERROR_UNABLE_TO_ALLOCATE_REQUESTED_SAFE_BUFFER
error, enable to create requested safe buffer (cannot allocate buffer)
Definition ErrorCodes.h:501
#define DEBUGGER_ERROR_INSTANT_EVENT_PREALLOCATED_BUFFER_IS_NOT_ENOUGH_FOR_REQUESTED_SAFE_BUFFER
error, the preallocated buffer is not enough for storing safe requested buffer
Definition ErrorCodes.h:495
#define DEBUGGER_ERROR_INSTANT_EVENT_REGULAR_REQUESTED_SAFE_BUFFER_NOT_FOUND
error, the requested safe buffer does not exist (regular)
Definition ErrorCodes.h:483

◆ 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
2887{
2888 //
2889 // Now we should configure the cpu to generate the events
2890 //
2891 switch (Event->EventType)
2892 {
2897 case HIDDEN_HOOK_READ:
2898 case HIDDEN_HOOK_WRITE:
2900 {
2901 //
2902 // Apply the monitor memory hook events
2903 //
2904 if (!ApplyEventMonitorEvent(Event, ResultsToReturn, InputFromVmxRoot))
2905 {
2906 goto ClearTheEventAfterCreatingEvent;
2907 }
2908
2909 break;
2910 }
2912 {
2913 //
2914 // Apply the EPT hidden hook (hidden breakpoint) events
2915 //
2916 if (!ApplyEventEptHookExecCcEvent(Event, ResultsToReturn, InputFromVmxRoot))
2917 {
2918 goto ClearTheEventAfterCreatingEvent;
2919 }
2920
2921 break;
2922 }
2924 {
2925 //
2926 // Apply the EPT hook trampoline (inline hook) events
2927 //
2928 if (!ApplyEventEpthookInlineEvent(Event, ResultsToReturn, InputFromVmxRoot))
2929 {
2930 goto ClearTheEventAfterCreatingEvent;
2931 }
2932
2933 break;
2934 }
2936 {
2937 //
2938 // Apply the RDMSR execution exiting events
2939 //
2940 ApplyEventRdmsrExecutionEvent(Event, ResultsToReturn, InputFromVmxRoot);
2941
2942 break;
2943 }
2945 {
2946 //
2947 // Apply the WRMSR execution exiting events
2948 //
2949 ApplyEventWrmsrExecutionEvent(Event, ResultsToReturn, InputFromVmxRoot);
2950
2951 break;
2952 }
2955 {
2956 //
2957 // Apply the IN/OUT instructions execution exiting events
2958 //
2959 ApplyEventInOutExecutionEvent(Event, ResultsToReturn, InputFromVmxRoot);
2960
2961 break;
2962 }
2964 {
2965 //
2966 // Apply the RDTSC/RDTSCP instructions execution exiting events
2967 //
2968 ApplyEventTscExecutionEvent(Event, ResultsToReturn, InputFromVmxRoot);
2969
2970 break;
2971 }
2973 {
2974 //
2975 // Apply the RDPMC instruction execution exiting events
2976 //
2977 ApplyEventRdpmcExecutionEvent(Event, ResultsToReturn, InputFromVmxRoot);
2978
2979 break;
2980 }
2982 {
2983 //
2984 // Apply the mov 2 debug register exiting events
2985 //
2986 ApplyEventMov2DebugRegExecutionEvent(Event, ResultsToReturn, InputFromVmxRoot);
2987
2988 break;
2989 }
2991 {
2992 //
2993 // Apply the control register access exiting events
2994 //
2995 ApplyEventControlRegisterAccessedEvent(Event, ResultsToReturn, InputFromVmxRoot);
2996
2997 break;
2998 }
2999 case EXCEPTION_OCCURRED:
3000 {
3001 //
3002 // Apply the exception events
3003 //
3004 ApplyEventExceptionEvent(Event, ResultsToReturn, InputFromVmxRoot);
3005
3006 break;
3007 }
3009 {
3010 //
3011 // Apply the interrupt events
3012 //
3013 ApplyEventInterruptEvent(Event, ResultsToReturn, InputFromVmxRoot);
3014
3015 break;
3016 }
3018 {
3019 //
3020 // Apply the EFER SYSCALL hook events
3021 //
3022 ApplyEventEferSyscallHookEvent(Event, ResultsToReturn, InputFromVmxRoot);
3023
3024 break;
3025 }
3027 {
3028 //
3029 // Apply the EFER SYSRET hook events
3030 //
3031 ApplyEventEferSysretHookEvent(Event, ResultsToReturn, InputFromVmxRoot);
3032
3033 break;
3034 }
3036 {
3037 //
3038 // Apply the VMCALL instruction interception events
3039 //
3040 ApplyEventVmcallExecutionEvent(Event, ResultsToReturn, InputFromVmxRoot);
3041
3042 break;
3043 }
3045 {
3046 //
3047 // Apply the trap mode change and single instruction trace events
3048 //
3049 if (!ApplyEventTrapModeChangeEvent(Event, ResultsToReturn, InputFromVmxRoot))
3050 {
3051 goto ClearTheEventAfterCreatingEvent;
3052 }
3053
3054 break;
3055 }
3057 {
3058 //
3059 // Apply the CPUID instruction execution events
3060 //
3061 ApplyEventCpuidExecutionEvent(Event, ResultsToReturn, InputFromVmxRoot);
3062
3063 break;
3064 }
3066 {
3067 //
3068 // Apply the tracing events
3069 //
3070 ApplyEventTracingEvent(Event, ResultsToReturn, InputFromVmxRoot);
3071
3072 break;
3073 }
3074 default:
3075 {
3076 //
3077 // Set the error
3078 //
3079 ResultsToReturn->IsSuccessful = FALSE;
3081 goto ClearTheEventAfterCreatingEvent;
3082
3083 break;
3084 }
3085 }
3086
3087 //
3088 // Set the status
3089 //
3090 ResultsToReturn->IsSuccessful = TRUE;
3091 ResultsToReturn->Error = 0;
3092
3093 //
3094 // Event was applied successfully
3095 //
3096 return TRUE;
3097
3098ClearTheEventAfterCreatingEvent:
3099
3100 return FALSE;
3101}
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:1272
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 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:1299
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
@ 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:111

◆ 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
2438{
2439 //
2440 // Because we want to delete all the objects and buffers (pools)
2441 // after we finished termination, the debugger might still use
2442 // the buffers for events and action, for solving this problem
2443 // we first disable the tag(s) and this way the debugger no longer
2444 // use that event and this way we can safely remove and deallocate
2445 // the buffers later after termination
2446 //
2447
2448 //
2449 // First, disable all events
2450 //
2452
2453 //
2454 // Second, terminate all events
2455 //
2456 DebuggerTerminateAllEvents(InputFromVmxRoot);
2457
2458 //
2459 // Third, remove all events
2460 //
2461 DebuggerRemoveAllEvents(PoolManagerAllocatedMemory);
2462}
BOOLEAN DebuggerEnableOrDisableAllEvents(BOOLEAN IsEnable)
Enable or disable all events from all the types.
Definition Debugger.c:1901
BOOLEAN DebuggerRemoveAllEvents(BOOLEAN PoolManagerAllocatedMemory)
Remove all the events from all the lists and also de-allocate their structures and actions.
Definition Debugger.c:2010
BOOLEAN DebuggerTerminateAllEvents(BOOLEAN InputFromVmxRoot)
Terminate effect and configuration to vmx-root and non-root for all the events.
Definition Debugger.c:1958

◆ 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
2401{
2402 //
2403 // Because we want to delete all the objects and buffers (pools)
2404 // after we finished termination, the debugger might still use
2405 // the buffers for events and action, for solving this problem
2406 // we first disable the tag(s) and this way the debugger no longer
2407 // use that event and this way we can safely remove and deallocate
2408 // the buffers later after termination
2409 //
2410
2411 //
2412 // First, disable just one event
2413 //
2415
2416 //
2417 // Second, terminate it
2418 //
2419 DebuggerTerminateEvent(Tag, InputFromVmxRoot);
2420
2421 //
2422 // Third, remove it from the list
2423 //
2424 return DebuggerRemoveEvent(Tag, PoolManagerAllocatedMemory);
2425}
BOOLEAN DebuggerTerminateEvent(UINT64 Tag, BOOLEAN InputFromVmxRoot)
Terminate one event's effect by its tag.
Definition Debugger.c:3436
BOOLEAN DebuggerDisableEvent(UINT64 Tag)
Disable an event by tag.
Definition Debugger.c:2363
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:2643
POOL_TYPE SIZE_T ULONG Tag
Definition Hooks.h:168

◆ 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
393{
394 PDEBUGGER_EVENT Event = NULL;
395 UINT32 EventBufferSize = sizeof(DEBUGGER_EVENT) + ConditionsBufferSize;
396
397 //
398 // Initialize the event structure
399 //
400 if (InputFromVmxRoot)
401 {
402 //
403 // *** The buffer is coming from VMX-root mode ***
404 //
405
406 //
407 // If the buffer is smaller than regular instant events
408 //
409 if (REGULAR_INSTANT_EVENT_CONDITIONAL_BUFFER >= EventBufferSize)
410 {
411 //
412 // The buffer fits into a regular instant event
413 //
415
416 if (!Event)
417 {
418 //
419 // Here we try again to see if we could store it into a big instant event instead
420 //
422
423 if (!Event)
424 {
425 //
426 // Set the error
427 //
428 ResultsToReturn->IsSuccessful = FALSE;
430
431 //
432 // There is a problem with allocating event
433 //
434 return NULL;
435 }
436 }
437 }
438 else if (BIG_INSTANT_EVENT_CONDITIONAL_BUFFER >= EventBufferSize)
439 {
440 //
441 // The buffer fits into a big instant event
442 //
444
445 if (!Event)
446 {
447 //
448 // Set the error
449 //
450 ResultsToReturn->IsSuccessful = FALSE;
452
453 //
454 // There is a problem with allocating event
455 //
456 return NULL;
457 }
458 }
459 else
460 {
461 //
462 // The buffer doesn't fit into any of the regular or big event's preallocated buffers
463 //
464
465 //
466 // Set the error
467 //
468 ResultsToReturn->IsSuccessful = FALSE;
470
471 return NULL;
472 }
473 }
474 else
475 {
476 //
477 // If it's not coming from the VMX-root mode then we're allocating it from the OS buffers
478 //
479 Event = PlatformMemAllocateZeroedNonPagedPool(EventBufferSize);
480
481 if (!Event)
482 {
483 //
484 // Set the error
485 //
486 ResultsToReturn->IsSuccessful = FALSE;
488
489 //
490 // There is a problem with allocating event
491 //
492 return NULL;
493 }
494 }
495
496 Event->CoreId = CoreId;
497 Event->ProcessId = ProcessId;
498 Event->Enabled = Enabled;
499 Event->EventType = EventType;
500 Event->Tag = Tag;
501 Event->CountOfActions = 0; // currently there is no action
502
503 //
504 // Copy Options
505 //
506 memcpy(&Event->InitOptions, Options, sizeof(DEBUGGER_EVENT_OPTIONS));
507
508 //
509 // check if this event is conditional or not
510 //
511 if (ConditionBuffer != 0)
512 {
513 //
514 // It's conditional
515 //
516 Event->ConditionsBufferSize = ConditionsBufferSize;
517 Event->ConditionBufferAddress = (PVOID)((UINT64)Event + sizeof(DEBUGGER_EVENT));
518
519 //
520 // copy the condition buffer to the end of the buffer of the event
521 //
522 memcpy(Event->ConditionBufferAddress, ConditionBuffer, ConditionsBufferSize);
523 }
524 else
525 {
526 //
527 // It's unconditioanl
528 //
529 Event->ConditionsBufferSize = 0;
530 }
531
532 //
533 // Make the action lists ready
534 //
536
537 //
538 // Return our event
539 //
540 return Event;
541}
unsigned int UINT32
Definition BasicTypes.h:48
#define REGULAR_INSTANT_EVENT_CONDITIONAL_BUFFER
Pre-allocated size for a regular event + conditions buffer.
Definition Constants.h:282
#define BIG_INSTANT_EVENT_CONDITIONAL_BUFFER
Pre-allocated size for a big event + conditions buffer.
Definition Constants.h:288
@ INSTANT_BIG_EVENT_BUFFER
Definition DataTypes.h:52
@ INSTANT_REGULAR_EVENT_BUFFER
Definition DataTypes.h:51
#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
FORCEINLINE VOID InitializeListHead(_Out_ PLIST_ENTRY ListHead)
Definition Windows.h:41
struct _DEBUGGER_EVENT DEBUGGER_EVENT
The structure of events in HyperDbg.
request for performing a short-circuiting event
Definition Events.h:271
The structure of events in HyperDbg.
Definition Debugger.h:108
UINT32 ConditionsBufferSize
Definition Debugger.h:133
PVOID ConditionBufferAddress
Definition Debugger.h:134
DEBUGGER_EVENT_OPTIONS InitOptions
Definition Debugger.h:129
UINT32 CoreId
Definition Debugger.h:113
BOOLEAN Enabled
Definition Debugger.h:112
UINT32 ProcessId
Definition Debugger.h:117

◆ 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
2364{
2365 PDEBUGGER_EVENT Event;
2366
2367 //
2368 // Search all the cores for enable this event
2369 //
2370 Event = DebuggerGetEventByTag(Tag);
2371
2372 //
2373 // Check if tag is valid or not
2374 //
2375 if (Event == NULL)
2376 {
2377 return FALSE;
2378 }
2379
2380 //
2381 // Disable the event
2382 //
2383 Event->Enabled = FALSE;
2384
2385 return TRUE;
2386}
PDEBUGGER_EVENT DebuggerGetEventByTag(UINT64 Tag)
Find event object by tag.
Definition Debugger.c:1858

◆ 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
2303{
2304 PDEBUGGER_EVENT Event;
2305 //
2306 // Search all the cores for enable this event
2307 //
2308 Event = DebuggerGetEventByTag(Tag);
2309
2310 //
2311 // Check if tag is valid or not
2312 //
2313 if (Event == NULL)
2314 {
2315 return FALSE;
2316 }
2317
2318 //
2319 // Enable the event
2320 //
2321 Event->Enabled = TRUE;
2322
2323 return TRUE;
2324}

◆ 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
1902{
1903 BOOLEAN FindAtLeastOneEvent = FALSE;
1904 PLIST_ENTRY TempList = 0;
1905 PLIST_ENTRY TempList2 = 0;
1906
1907 //
1908 // We have to iterate through all events
1909 //
1910 for (size_t i = 0; i < sizeof(DEBUGGER_CORE_EVENTS) / sizeof(LIST_ENTRY); i++)
1911 {
1912 TempList = (PLIST_ENTRY)((UINT64)(g_Events) + (i * sizeof(LIST_ENTRY)));
1913 TempList2 = TempList;
1914
1915 while (TempList2 != TempList->Flink)
1916 {
1917 TempList = TempList->Flink;
1918 PDEBUGGER_EVENT CurrentEvent = CONTAINING_RECORD(TempList, DEBUGGER_EVENT, EventsOfSameTypeList);
1919
1920 //
1921 // Check if we find at least one event or not
1922 //
1923 if (!FindAtLeastOneEvent)
1924 {
1925 FindAtLeastOneEvent = TRUE;
1926 }
1927
1928 //
1929 // Enable or disable event
1930 // (We could directly modify the "enabled" flag here, however
1931 // in the case of any possible callback for enabling/disabling let's
1932 // modify the state of being enable all of them in a single place)
1933 //
1934 if (IsEnable)
1935 {
1936 DebuggerEnableEvent(CurrentEvent->Tag);
1937 }
1938 else
1939 {
1940 DebuggerDisableEvent(CurrentEvent->Tag);
1941 }
1942 }
1943 }
1944
1945 return FindAtLeastOneEvent;
1946}
UCHAR BOOLEAN
Definition BasicTypes.h:39
BOOLEAN DebuggerEnableEvent(UINT64 Tag)
Enable an event by tag.
Definition Debugger.c:2302
struct _DEBUGGER_CORE_EVENTS DEBUGGER_CORE_EVENTS
List of all the different events.
DEBUGGER_CORE_EVENTS * g_Events
events list (for debugger)
Definition Global.h:48

◆ 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
2055{
2056 PLIST_ENTRY TempList = 0;
2057 UINT32 Counter = 0;
2058
2059 //
2060 // We have to iterate through all events of this list
2061 //
2062 TempList = TargetEventList;
2063
2064 while (TargetEventList != TempList->Flink)
2065 {
2066 TempList = TempList->Flink;
2067 /* PDEBUGGER_EVENT CurrentEvent = CONTAINING_RECORD(TempList, DEBUGGER_EVENT, EventsOfSameTypeList); */
2068
2069 //
2070 // Increase the counter
2071 //
2072 Counter++;
2073 }
2074
2075 return Counter;
2076}

◆ 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
2195{
2196 PLIST_ENTRY TempList = 0;
2197 UINT32 Counter = 0;
2198
2199 //
2200 // We have to iterate through all events of this list
2201 //
2202 TempList = TargetEventList;
2203
2204 while (TargetEventList != TempList->Flink)
2205 {
2206 TempList = TempList->Flink;
2207 PDEBUGGER_EVENT CurrentEvent = CONTAINING_RECORD(TempList, DEBUGGER_EVENT, EventsOfSameTypeList);
2208
2209 if (CurrentEvent->CoreId == DEBUGGER_EVENT_APPLY_TO_ALL_CORES || CurrentEvent->CoreId == TargetCore)
2210 {
2211 //
2212 // Increase the counter
2213 //
2214 Counter++;
2215 }
2216 }
2217
2218 return Counter;
2219}
#define DEBUGGER_EVENT_APPLY_TO_ALL_CORES
Apply the event to all the cores.
Definition Constants.h:611

◆ 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
2233{
2234 PLIST_ENTRY TempList = 0;
2235 UINT32 Counter = 0;
2236
2237 PLIST_ENTRY TargetEventList = DebuggerGetEventListByEventType(EventType);
2238
2239 //
2240 // We have to iterate through all events of this list
2241 //
2242 TempList = TargetEventList;
2243
2244 while (TargetEventList != TempList->Flink)
2245 {
2246 TempList = TempList->Flink;
2247 PDEBUGGER_EVENT CurrentEvent = CONTAINING_RECORD(TempList, DEBUGGER_EVENT, EventsOfSameTypeList);
2248
2249 if (CurrentEvent->CoreId == DEBUGGER_EVENT_APPLY_TO_ALL_CORES || CurrentEvent->CoreId == TargetCore)
2250 {
2251 //
2252 // Increase the counter
2253 //
2254 Counter++;
2255 }
2256 }
2257
2258 return Counter;
2259}
PLIST_ENTRY DebuggerGetEventListByEventType(VMM_EVENT_TYPE_ENUM EventType)
Get List of event based on event type.
Definition Debugger.c:2085

◆ 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
2271{
2272 PLIST_ENTRY TempList = 0;
2273 UINT32 ExceptionMask = 0;
2274
2275 //
2276 // We have to iterate through all events of this list
2277 //
2279
2280 while (&g_Events->ExceptionOccurredEventsHead != TempList->Flink)
2281 {
2282 TempList = TempList->Flink;
2283 PDEBUGGER_EVENT CurrentEvent = CONTAINING_RECORD(TempList, DEBUGGER_EVENT, EventsOfSameTypeList);
2284
2285 if (CurrentEvent->CoreId == DEBUGGER_EVENT_APPLY_TO_ALL_CORES || CurrentEvent->CoreId == CoreIndex)
2286 {
2287 ExceptionMask |= CurrentEvent->Options.OptionalParam1;
2288 }
2289 }
2290
2291 return ExceptionMask;
2292}
LIST_ENTRY ExceptionOccurredEventsHead
Definition Debugger.h:59
UINT64 OptionalParam1
Definition Events.h:272
DEBUGGER_EVENT_OPTIONS Options
Definition Debugger.h:131

◆ 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
1859{
1860 PLIST_ENTRY TempList = 0;
1861 PLIST_ENTRY TempList2 = 0;
1862
1863 //
1864 // We have to iterate through all events
1865 //
1866 for (size_t i = 0; i < sizeof(DEBUGGER_CORE_EVENTS) / sizeof(LIST_ENTRY); i++)
1867 {
1868 TempList = (PLIST_ENTRY)((UINT64)(g_Events) + (i * sizeof(LIST_ENTRY)));
1869 TempList2 = TempList;
1870
1871 while (TempList2 != TempList->Flink)
1872 {
1873 TempList = TempList->Flink;
1874 PDEBUGGER_EVENT CurrentEvent = CONTAINING_RECORD(TempList, DEBUGGER_EVENT, EventsOfSameTypeList);
1875
1876 //
1877 // Check if we find the event or not
1878 //
1879 if (CurrentEvent->Tag == Tag)
1880 {
1881 return CurrentEvent;
1882 }
1883 }
1884 }
1885
1886 //
1887 // We didn't find anything, so return null
1888 //
1889 return NULL;
1890}

◆ DebuggerGetEventListByEventType()

PLIST_ENTRY DebuggerGetEventListByEventType ( VMM_EVENT_TYPE_ENUM EventType)

Get List of event based on event type.

Parameters
EventTypetype of event
Returns
PLIST_ENTRY
2086{
2087 PLIST_ENTRY ResultList = NULL;
2088 //
2089 // Register the event
2090 //
2091 switch (EventType)
2092 {
2095 break;
2098 break;
2101 break;
2104 break;
2105 case HIDDEN_HOOK_READ:
2106 ResultList = &g_Events->HiddenHookReadEventsHead;
2107 break;
2108 case HIDDEN_HOOK_WRITE:
2109 ResultList = &g_Events->HiddenHookWriteEventsHead;
2110 break;
2113 break;
2116 break;
2118 ResultList = &g_Events->EptHookExecCcEventsHead;
2119 break;
2122 break;
2125 break;
2128 break;
2131 break;
2134 break;
2135 case EXCEPTION_OCCURRED:
2137 break;
2140 break;
2143 break;
2146 break;
2149 break;
2152 break;
2155 break;
2158 break;
2161 break;
2164 break;
2167 break;
2170 break;
2171 default:
2172
2173 //
2174 // Wrong event type
2175 //
2176 LogError("Err, wrong event type is specified");
2177 ResultList = NULL;
2178 break;
2179 }
2180
2181 return ResultList;
2182}
#define LogError(format,...)
Log in the case of error.
Definition HyperDbgHyperLogIntrinsics.h:113
@ CONTROL_REGISTER_3_MODIFIED
Definition Events.h:164
LIST_ENTRY HiddenHookReadAndExecuteEventsHead
Definition Debugger.h:47
LIST_ENTRY EptHookExecCcEventsHead
Definition Debugger.h:53
LIST_ENTRY PmcInstructionExecutionEventsHead
Definition Debugger.h:61
LIST_ENTRY OutInstructionExecutionEventsHead
Definition Debugger.h:63
LIST_ENTRY HiddenHookReadAndWriteEventsHead
Definition Debugger.h:46
LIST_ENTRY ControlRegister3ModifiedEventsHead
Definition Debugger.h:69
LIST_ENTRY HiddenHookReadEventsHead
Definition Debugger.h:49
LIST_ENTRY ExternalInterruptOccurredEventsHead
Definition Debugger.h:65
LIST_ENTRY HiddenHookReadAndWriteAndExecuteEventsHead
Definition Debugger.h:45
LIST_ENTRY EptHook2sExecDetourEventsHead
Definition Debugger.h:52
LIST_ENTRY RdmsrInstructionExecutionEventsHead
Definition Debugger.h:57
LIST_ENTRY HiddenHookExecuteEventsHead
Definition Debugger.h:51
LIST_ENTRY VmcallInstructionExecutionEventsHead
Definition Debugger.h:66
LIST_ENTRY ControlRegisterModifiedEventsHead
Definition Debugger.h:70
LIST_ENTRY SyscallHooksEferSyscallEventsHead
Definition Debugger.h:54
LIST_ENTRY InInstructionExecutionEventsHead
Definition Debugger.h:62
LIST_ENTRY HiddenHookWriteEventsHead
Definition Debugger.h:50
LIST_ENTRY TrapExecutionInstructionTraceEventsHead
Definition Debugger.h:68
LIST_ENTRY WrmsrInstructionExecutionEventsHead
Definition Debugger.h:58
LIST_ENTRY DebugRegistersAccessedEventsHead
Definition Debugger.h:64
LIST_ENTRY HiddenHookWriteAndExecuteEventsHead
Definition Debugger.h:48
LIST_ENTRY CpuidInstructionExecutionEventsHead
Definition Debugger.h:56
LIST_ENTRY TscInstructionExecutionEventsHead
Definition Debugger.h:60
LIST_ENTRY TrapExecutionModeChangedEventsHead
Definition Debugger.h:67
LIST_ENTRY SyscallHooksEferSysretEventsHead
Definition Debugger.h:55

◆ 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:79

◆ 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:23

◆ DebuggerInitialize()

BOOLEAN DebuggerInitialize ( )

Initialize Debugger Structures and Routines.

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 // Also allocate the debugging state
63 //
65 {
66 return FALSE;
67 }
68
69 //
70 // Allocate buffer for saving events
71 //
73 {
74 return FALSE;
75 }
76
77 //
78 // Set the core's IDs
79 //
80 for (UINT32 i = 0; i < ProcessorsCount; i++)
81 {
82 g_DbgState[i].CoreId = i;
83 }
84
85 //
86 // Initialize lists relating to the debugger events store
87 //
114
115 //
116 // Enabled Debugger Events
117 //
119
120 //
121 // Set initial state of triggering events for VMCALLs
122 //
124
125 //
126 // Set initial state of triggering events for VMCALLs
127 //
129
130 //
131 // Initialize script engines global variables holder
132 //
134 {
136 }
137
139 {
140 //
141 // Out of resource, initialization of script engine's global variable holders failed
142 //
143 return FALSE;
144 }
145
146 //
147 // Zero the global variables memory
148 //
149 RtlZeroMemory(g_ScriptGlobalVariables, MAX_VAR_COUNT * sizeof(UINT64));
150
151 //
152 // Zero the TRAP FLAG state memory
153 //
154 RtlZeroMemory(&g_TrapFlagState, sizeof(DEBUGGER_TRAP_FLAG_STATE));
155
156 //
157 // Initialize the local and temp variables
158 //
159 for (size_t i = 0; i < ProcessorsCount; i++)
160 {
161 CurrentDebuggerState = &g_DbgState[i];
162
163 if (!CurrentDebuggerState->ScriptEngineCoreSpecificLocalVariable)
164 {
166 }
167
168 if (!CurrentDebuggerState->ScriptEngineCoreSpecificLocalVariable)
169 {
170 //
171 // Out of resource, initialization of script engine's local variable holders failed
172 //
173 return FALSE;
174 }
175
176 if (!CurrentDebuggerState->ScriptEngineCoreSpecificTempVariable)
177 {
179 }
180
181 if (!CurrentDebuggerState->ScriptEngineCoreSpecificTempVariable)
182 {
183 //
184 // Out of resource, initialization of script engine's local variable holders failed
185 //
186 return FALSE;
187 }
188
189 if (!CurrentDebuggerState->ScriptEngineCoreSpecificStackBuffer)
190 {
192
193 if (CurrentDebuggerState->ScriptEngineCoreSpecificStackBuffer)
194 {
195 PSYMBOL_BUFFER StackBuffer = (PSYMBOL_BUFFER)CurrentDebuggerState->ScriptEngineCoreSpecificStackBuffer;
196 StackBuffer->Pointer = 0;
197 StackBuffer->Size = 0;
198 StackBuffer->Message = NULL;
200 if (!StackBuffer->Head)
201 {
202 return FALSE;
203 }
204 RtlZeroMemory(StackBuffer->Head, MAX_STACK_BUFFER_COUNT * sizeof(SYMBOL));
205 }
206 }
207
208 if (!CurrentDebuggerState->ScriptEngineCoreSpecificStackBuffer)
209 {
210 return FALSE;
211 }
212
213 //
214 // Zero the local and temp variables memory
215 //
216 RtlZeroMemory(CurrentDebuggerState->ScriptEngineCoreSpecificLocalVariable, MAX_VAR_COUNT * sizeof(UINT64));
217 RtlZeroMemory(CurrentDebuggerState->ScriptEngineCoreSpecificTempVariable, MAX_TEMP_COUNT * sizeof(UINT64));
218 }
219
220 //
221 // Initialize NMI broadcasting mechanism
222 //
224
225 //
226 // Initialize attaching mechanism,
227 // we'll use the functionalities of the attaching in reading modules
228 // of user mode applications (other than attaching mechanism itself)
229 //
230 if (!AttachingInitialize())
231 {
232 return FALSE;
233 }
234
235 //
236 // Pre-allocate pools for possible EPT hooks
237 //
239
241 {
242 LogWarning("Warning, cannot allocate the pre-allocated pools for EPT hooks");
243
244 //
245 // BTW, won't fail the starting phase because of this
246 //
247 }
248
249 return TRUE;
250}
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
unsigned long ULONG
Definition BasicTypes.h:37
VOID ConfigureEptHookReservePreallocatedPoolsForEptHooks(UINT32 Count)
Allocate (reserve) pages for storing EPT hooks page hooks.
Definition Configuration.c:239
#define MAXIMUM_NUMBER_OF_INITIAL_PREALLOCATED_EPT_HOOKS
Maximum number of initial pre-allocated EPT hooks.
Definition Constants.h:260
#define MAX_VAR_COUNT
Definition Constants.h:574
#define MAX_TEMP_COUNT
Definition Constants.h:566
#define MAX_STACK_BUFFER_COUNT
Definition Constants.h:568
VOID VmFuncSetTriggerEventForVmcalls(BOOLEAN Set)
Set triggering events for VMCALLs.
Definition Export.c:575
VOID VmFuncSetTriggerEventForCpuids(BOOLEAN Set)
Set triggering events for CPUIDs.
Definition Export.c:587
VOID VmFuncVmxBroadcastInitialize()
Export for initialize the VMX Broadcast mechanism.
Definition Export.c:697
#define LogWarning(format,...)
Log in the case of warning.
Definition HyperDbgHyperLogIntrinsics.h:99
PVOID PlatformMemAllocateNonPagedPool(SIZE_T NumberOfBytes)
Allocate a non-paged buffer.
Definition Mem.c:41
BOOLEAN PoolManagerCheckAndPerformAllocationAndDeallocation()
This function performs allocations from VMX non-root based on g_RequestNewAllocation.
Definition PoolManager.c:302
struct SYMBOL_BUFFER * PSYMBOL_BUFFER
DEBUGGER_TRAP_FLAG_STATE g_TrapFlagState
State of the trap-flag.
Definition Global.h:29
PROCESSOR_DEBUGGING_STATE * g_DbgState
Save the state and variables related to debugging on each to logical core.
Definition Global.h:17
UINT64 * g_ScriptGlobalVariables
Holder of script engines global variables.
Definition Global.h:23
BOOLEAN g_EnableDebuggerEvents
Determines whether the debugger events should be active or not.
Definition Global.h:85
The status of RFLAGS.TF masking.
Definition State.h:126
Saves the debugger state.
Definition State.h:165
UINT32 CoreId
Definition State.h:169
UINT64 * ScriptEngineCoreSpecificTempVariable
Definition State.h:185
UINT64 * ScriptEngineCoreSpecificStackBuffer
Definition State.h:186
UINT64 * ScriptEngineCoreSpecificLocalVariable
Definition State.h:184
Definition ScriptEngineCommonDefinitions.h:21
Definition ScriptEngineCommonDefinitions.h:6

◆ 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
2472{
2473 PDEBUGGER_EVENT Event;
2474
2475 //
2476 // Search this event
2477 //
2478 Event = DebuggerGetEventByTag(Tag);
2479
2480 //
2481 // Check if tag is valid or not
2482 //
2483 if (Event == NULL)
2484 {
2485 return FALSE;
2486 }
2487
2488 return TRUE;
2489}

◆ 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
3263{
3264 DEBUGGER_EVENT_ACTION * Action = NULL;
3265
3266 //
3267 // Check if Tag is valid or not
3268 //
3269 PDEBUGGER_EVENT Event = DebuggerGetEventByTag(ActionDetails->EventTag);
3270
3271 if (Event == NULL)
3272 {
3273 //
3274 // Set the appropriate error
3275 //
3276 ResultsToReturn->IsSuccessful = FALSE;
3277 ResultsToReturn->Error = DEBUGGER_ERROR_TAG_NOT_EXISTS;
3278
3279 //
3280 // Show that the
3281 //
3282 return FALSE;
3283 }
3284
3285 if (ActionDetails->ActionType == RUN_CUSTOM_CODE)
3286 {
3287 //
3288 // Check if buffer is not invalid
3289 //
3290 if (ActionDetails->CustomCodeBufferSize == 0)
3291 {
3292 //
3293 // Set the appropriate error
3294 //
3295 ResultsToReturn->IsSuccessful = FALSE;
3297
3298 //
3299 // Show that the
3300 //
3301 return FALSE;
3302 }
3303
3304 //
3305 // Add action for RUN_CUSTOM_CODE
3306 //
3307 DEBUGGER_EVENT_REQUEST_CUSTOM_CODE CustomCode = {0};
3308
3309 CustomCode.CustomCodeBufferSize = ActionDetails->CustomCodeBufferSize;
3310 CustomCode.CustomCodeBufferAddress = (PVOID)((UINT64)ActionDetails + sizeof(DEBUGGER_GENERAL_ACTION));
3311 CustomCode.OptionalRequestedBufferSize = ActionDetails->PreAllocatedBuffer;
3312
3313 //
3314 // Add action to event
3315 //
3316 Action = DebuggerAddActionToEvent(Event,
3318 ActionDetails->ImmediateMessagePassing,
3319 &CustomCode,
3320 NULL,
3321 ResultsToReturn,
3322 InputFromVmxRoot);
3323
3324 if (!Action)
3325 {
3326 //
3327 // Show that there was an error (error is set by the above function)
3328 //
3329 return FALSE;
3330 }
3331 }
3332 else if (ActionDetails->ActionType == RUN_SCRIPT)
3333 {
3334 //
3335 // Check if buffer is not invalid
3336 //
3337 if (ActionDetails->ScriptBufferSize == 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_SCRIPT
3353 //
3355 UserScriptConfig.ScriptBuffer = (UINT64)ActionDetails + sizeof(DEBUGGER_GENERAL_ACTION);
3356 UserScriptConfig.ScriptLength = ActionDetails->ScriptBufferSize;
3357 UserScriptConfig.ScriptPointer = ActionDetails->ScriptBufferPointer;
3358 UserScriptConfig.OptionalRequestedBufferSize = ActionDetails->PreAllocatedBuffer;
3359
3360 Action = DebuggerAddActionToEvent(Event,
3361 RUN_SCRIPT,
3362 ActionDetails->ImmediateMessagePassing,
3363 NULL,
3364 &UserScriptConfig,
3365 ResultsToReturn,
3366 InputFromVmxRoot);
3367
3368 if (!Action)
3369 {
3370 //
3371 // Show that there was an error (error is set by the above function)
3372 //
3373 return FALSE;
3374 }
3375 }
3376 else if (ActionDetails->ActionType == BREAK_TO_DEBUGGER)
3377 {
3378 //
3379 // Add action BREAK_TO_DEBUGGER to event
3380 //
3381 Action = DebuggerAddActionToEvent(Event,
3383 ActionDetails->ImmediateMessagePassing,
3384 NULL,
3385 NULL,
3386 ResultsToReturn,
3387 InputFromVmxRoot);
3388
3389 if (!Action)
3390 {
3391 //
3392 // Show that there was an error (error is set by the above function)
3393 //
3394 return FALSE;
3395 }
3396 }
3397 else
3398 {
3399 //
3400 // Set the appropriate error
3401 //
3402 ResultsToReturn->IsSuccessful = FALSE;
3403 ResultsToReturn->Error = DEBUGGER_ERROR_INVALID_ACTION_TYPE;
3404
3405 //
3406 // Show that there was an error
3407 //
3408 return FALSE;
3409 }
3410
3411 //
3412 // Enable the event
3413 //
3414 DebuggerEnableEvent(Event->Tag);
3415
3416 ResultsToReturn->IsSuccessful = TRUE;
3417 ResultsToReturn->Error = 0;
3418
3419 return TRUE;
3420}
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:669
#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:180
struct _DEBUGGER_GENERAL_ACTION DEBUGGER_GENERAL_ACTION
Each event can have multiple actions.
Used for run the script.
Definition RequestStructures.h:825
used in the case of custom code requests to the debugger
Definition RequestStructures.h:851
Each event can have multiple actions.
Definition Events.h:406
UINT32 CustomCodeBufferSize
Definition Events.h:412
UINT32 ScriptBufferSize
Definition Events.h:413
DEBUGGER_EVENT_ACTION_TYPE_ENUM ActionType
Definition Events.h:408
UINT32 ScriptBufferPointer
Definition Events.h:414
UINT32 PreAllocatedBuffer
Definition Events.h:410
BOOLEAN ImmediateMessagePassing
Definition Events.h:409
UINT64 EventTag
Definition Events.h:407

◆ 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
3119{
3120 PDEBUGGER_EVENT Event;
3121
3122 //
3123 // ----------------------------------------------------------------------------------
3124 // *** Validating the Event's parameters ***
3125 // ----------------------------------------------------------------------------------
3126 //
3127
3128 //
3129 // Validate the event parameters
3130 //
3131 if (!DebuggerValidateEvent(EventDetails, ResultsToReturn, InputFromVmxRoot))
3132 {
3133 //
3134 // Input event is not valid
3135 //
3136 return FALSE;
3137 }
3138
3139 //
3140 // ----------------------------------------------------------------------------------
3141 // *** Create Event ***
3142 // ----------------------------------------------------------------------------------
3143 //
3144
3145 //
3146 // We initialize event with disabled mode as it doesn't have action yet
3147 //
3148 if (EventDetails->ConditionBufferSize != 0)
3149 {
3150 //
3151 // Conditional Event
3152 //
3153 Event = DebuggerCreateEvent(FALSE,
3154 EventDetails->CoreId,
3155 EventDetails->ProcessId,
3156 EventDetails->EventType,
3157 EventDetails->Tag,
3158 &EventDetails->Options,
3159 EventDetails->ConditionBufferSize,
3160 (PVOID)((UINT64)EventDetails + sizeof(DEBUGGER_GENERAL_EVENT_DETAIL)),
3161 ResultsToReturn,
3162 InputFromVmxRoot);
3163 }
3164 else
3165 {
3166 //
3167 // Unconditional Event
3168 //
3169 Event = DebuggerCreateEvent(FALSE,
3170 EventDetails->CoreId,
3171 EventDetails->ProcessId,
3172 EventDetails->EventType,
3173 EventDetails->Tag,
3174 &EventDetails->Options,
3175 0,
3176 NULL,
3177 ResultsToReturn,
3178 InputFromVmxRoot);
3179 }
3180
3181 if (Event == NULL)
3182 {
3183 //
3184 // Error is already set in the creation function
3185 //
3186 return FALSE;
3187 }
3188
3189 //
3190 // Register the event
3191 //
3192 DebuggerRegisterEvent(Event);
3193
3194 //
3195 // ----------------------------------------------------------------------------------
3196 // *** Apply & Enable Event ***
3197 // ----------------------------------------------------------------------------------
3198 //
3199 if (DebuggerApplyEvent(Event, ResultsToReturn, InputFromVmxRoot))
3200 {
3201 //
3202 // *** Set the short-circuiting state ***
3203 //
3204 Event->EnableShortCircuiting = EventDetails->EnableShortCircuiting;
3205
3206 //
3207 // Set the event stage (pre- post- event)
3208 //
3210 {
3212 }
3214 {
3216 }
3217 else
3218 {
3219 //
3220 // Any other value results to be pre-event
3221 //
3223 }
3224
3225 return TRUE;
3226 }
3227 else
3228 {
3229 //
3230 // Remove the event as it was not successful
3231 // The same input as of input from VMX-root is
3232 // selected here because we apply it directly in the
3233 // above function and based on this input we can
3234 // conclude whether the pool is allocated from the
3235 // pool manager or not
3236 //
3237 if (Event != NULL)
3238 {
3239 DebuggerRemoveEvent(Event->Tag, InputFromVmxRoot);
3240 }
3241
3242 return FALSE;
3243 }
3244}
@ VMM_CALLBACK_CALLING_STAGE_ALL_EVENT_EMULATION
Definition DataTypes.h:95
@ VMM_CALLBACK_CALLING_STAGE_PRE_EVENT_EMULATION
Definition DataTypes.h:93
@ VMM_CALLBACK_CALLING_STAGE_POST_EVENT_EMULATION
Definition DataTypes.h:94
BOOLEAN DebuggerApplyEvent(PDEBUGGER_EVENT Event, PDEBUGGER_EVENT_AND_ACTION_RESULT ResultsToReturn, BOOLEAN InputFromVmxRoot)
Applying events.
Definition Debugger.c:2884
BOOLEAN DebuggerRegisterEvent(PDEBUGGER_EVENT Event)
Register an event to a list of active events.
Definition Debugger.c:1075
BOOLEAN DebuggerValidateEvent(PDEBUGGER_GENERAL_EVENT_DETAIL EventDetails, PDEBUGGER_EVENT_AND_ACTION_RESULT ResultsToReturn, BOOLEAN InputFromVmxRoot)
validating events
Definition Debugger.c:2710
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:383
VMM_CALLBACK_EVENT_CALLING_STAGE_TYPE EventMode
Definition Debugger.h:126
BOOLEAN EnableShortCircuiting
Definition Debugger.h:123
Each command is like the following struct, it also used for tracing works in user mode and sending it...
Definition Events.h:350
DEBUGGER_EVENT_OPTIONS Options
Definition Events.h:391
BOOLEAN EnableShortCircuiting
Definition Events.h:366
VMM_EVENT_TYPE_ENUM EventType
Definition Events.h:389
UINT64 Tag
Definition Events.h:388
VMM_CALLBACK_EVENT_CALLING_STAGE_TYPE EventStage
Definition Events.h:369
UINT32 ConditionBufferSize
Definition Events.h:395
UINT32 ProcessId
Definition Events.h:360
UINT32 CoreId
Definition Events.h:357

◆ 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
3674{
3675 BOOLEAN IsForAllEvents = FALSE;
3676
3677 //
3678 // Check if the tag is valid or not
3679 //
3680 if (DebuggerEventModificationRequest->Tag == DEBUGGER_MODIFY_EVENTS_APPLY_TO_ALL_TAG)
3681 {
3682 IsForAllEvents = TRUE;
3683 }
3684 else if (!DebuggerIsTagValid(DebuggerEventModificationRequest->Tag))
3685 {
3686 //
3687 // Tag is invalid
3688 //
3689 DebuggerEventModificationRequest->KernelStatus = DEBUGGER_ERROR_MODIFY_EVENTS_INVALID_TAG;
3690
3691 return FALSE;
3692 }
3693
3694 //
3695 // ***************************************************************************
3696 //
3697
3698 //
3699 // Check if it's a ENABLE, DISABLE or CLEAR
3700 //
3701 if (DebuggerEventModificationRequest->TypeOfAction == DEBUGGER_MODIFY_EVENTS_ENABLE)
3702 {
3703 if (IsForAllEvents)
3704 {
3705 //
3706 // Enable all events
3707 //
3709 }
3710 else
3711 {
3712 //
3713 // Enable just one event
3714 //
3715 DebuggerEnableEvent(DebuggerEventModificationRequest->Tag);
3716 }
3717 }
3718 else if (DebuggerEventModificationRequest->TypeOfAction == DEBUGGER_MODIFY_EVENTS_DISABLE)
3719 {
3720 if (IsForAllEvents)
3721 {
3722 //
3723 // Disable all events
3724 //
3726 }
3727 else
3728 {
3729 //
3730 // Disable just one event
3731 //
3732 DebuggerDisableEvent(DebuggerEventModificationRequest->Tag);
3733 }
3734 }
3735 else if (DebuggerEventModificationRequest->TypeOfAction == DEBUGGER_MODIFY_EVENTS_CLEAR)
3736 {
3737 if (IsForAllEvents)
3738 {
3739 //
3740 // Clear all events
3741 //
3742 DebuggerClearAllEvents(InputFromVmxRoot, PoolManagerAllocatedMemory);
3743 }
3744 else
3745 {
3746 //
3747 // Clear just one event
3748 //
3749 DebuggerClearEvent(DebuggerEventModificationRequest->Tag, InputFromVmxRoot, PoolManagerAllocatedMemory);
3750 }
3751 }
3752 else if (DebuggerEventModificationRequest->TypeOfAction == DEBUGGER_MODIFY_EVENTS_QUERY_STATE)
3753 {
3754 //
3755 // check if tag is valid or not
3756 //
3757 if (!DebuggerIsTagValid(DebuggerEventModificationRequest->Tag))
3758 {
3759 DebuggerEventModificationRequest->KernelStatus = DEBUGGER_ERROR_TAG_NOT_EXISTS;
3760 return FALSE;
3761 }
3762
3763 //
3764 // Set event state
3765 //
3766 if (DebuggerQueryStateEvent(DebuggerEventModificationRequest->Tag))
3767 {
3768 DebuggerEventModificationRequest->IsEnabled = TRUE;
3769 }
3770 else
3771 {
3772 DebuggerEventModificationRequest->IsEnabled = FALSE;
3773 }
3774 }
3775 else
3776 {
3777 //
3778 // Invalid parameter specified in TypeOfAction
3779 //
3780 DebuggerEventModificationRequest->KernelStatus = DEBUGGER_ERROR_MODIFY_EVENTS_INVALID_TYPE_OF_ACTION;
3781
3782 return FALSE;
3783 }
3784
3785 //
3786 // The function was successful
3787 //
3788 DebuggerEventModificationRequest->KernelStatus = DEBUGGER_OPERATION_WAS_SUCCESSFUL;
3789 return TRUE;
3790}
#define DEBUGGER_MODIFY_EVENTS_APPLY_TO_ALL_TAG
Apply event modifications to all tags.
Definition Constants.h:586
BOOLEAN DebuggerIsTagValid(UINT64 Tag)
Detect whether the tag exists or not.
Definition Debugger.c:2471
BOOLEAN DebuggerQueryStateEvent(UINT64 Tag)
returns whether an event is enabled/disabled by tag
Definition Debugger.c:2336
BOOLEAN DebuggerClearEvent(UINT64 Tag, BOOLEAN InputFromVmxRoot, BOOLEAN PoolManagerAllocatedMemory)
Clear an event by tag.
Definition Debugger.c:2400
VOID DebuggerClearAllEvents(BOOLEAN InputFromVmxRoot, BOOLEAN PoolManagerAllocatedMemory)
Clear all events.
Definition Debugger.c:2437
#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:232
@ DEBUGGER_MODIFY_EVENTS_DISABLE
Definition Events.h:233
@ DEBUGGER_MODIFY_EVENTS_QUERY_STATE
Definition Events.h:231
@ DEBUGGER_MODIFY_EVENTS_CLEAR
Definition Events.h:234
DEBUGGER_MODIFY_EVENTS_TYPE TypeOfAction
Definition Events.h:246
BOOLEAN IsEnabled
Definition Events.h:247
UINT64 KernelStatus
Definition Events.h:244
UINT64 Tag
Definition Events.h:243

◆ 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
1553{
1554 PLIST_ENTRY TempList = 0;
1555
1556 //
1557 // Find and run all the actions in this Event
1558 //
1559 TempList = &Event->ActionsListHead;
1560 while (&Event->ActionsListHead != TempList->Flink)
1561 {
1562 TempList = TempList->Flink;
1563 PDEBUGGER_EVENT_ACTION CurrentAction = CONTAINING_RECORD(TempList, DEBUGGER_EVENT_ACTION, ActionsList);
1564
1565 //
1566 // Perform the action
1567 //
1568 switch (CurrentAction->ActionType)
1569 {
1570 case BREAK_TO_DEBUGGER:
1571
1572 DebuggerPerformBreakToDebugger(DbgState, CurrentAction, EventTriggerDetail);
1573
1574 break;
1575
1576 case RUN_SCRIPT:
1577
1578 DebuggerPerformRunScript(DbgState, CurrentAction, NULL, EventTriggerDetail);
1579
1580 break;
1581
1582 case RUN_CUSTOM_CODE:
1583
1584 DebuggerPerformRunTheCustomCode(DbgState, CurrentAction, EventTriggerDetail);
1585
1586 break;
1587
1588 default:
1589
1590 //
1591 // Invalid action type
1592 //
1593 break;
1594 }
1595 }
1596}
VOID DebuggerPerformRunTheCustomCode(PROCESSOR_DEBUGGING_STATE *DbgState, DEBUGGER_EVENT_ACTION *Action, DEBUGGER_TRIGGERED_EVENT_DETAILS *EventTriggerDetail)
Manage running the custom code action.
Definition Debugger.c:1760
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:1608
VOID DebuggerPerformBreakToDebugger(PROCESSOR_DEBUGGING_STATE *DbgState, DEBUGGER_EVENT_ACTION *Action, DEBUGGER_TRIGGERED_EVENT_DETAILS *EventTriggerDetail)
Manage breaking to the debugger action.
Definition Debugger.c:1821

◆ 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
1824{
1825 UNREFERENCED_PARAMETER(Action);
1826
1828 {
1829 //
1830 // The guest is already in vmx-root mode
1831 // Halt other cores
1832 //
1833
1835 DbgState,
1837 EventTriggerDetail);
1838 }
1839 else
1840 {
1841 //
1842 // The guest is on vmx non-root mode and this is an event
1843 //
1845 (UINT64)EventTriggerDetail,
1846 (UINT64)DbgState->Regs,
1847 (UINT64)NULL);
1848 }
1849}
@ DEBUGGEE_PAUSING_REASON_DEBUGGEE_EVENT_TRIGGERED
Definition Connection.h:35
#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
NTSTATUS VmFuncVmxVmcall(unsigned long long VmcallNumber, unsigned long long OptionalParam1, unsigned long long OptionalParam2, unsigned long long OptionalParam3)
Export for running VMX VMCALLs.
Definition Export.c:683
BOOLEAN VmFuncVmxGetCurrentExecutionMode()
Get the current VMX operation state.
Definition Export.c:552
_Use_decl_annotations_ VOID KdHandleBreakpointAndDebugBreakpoints(PROCESSOR_DEBUGGING_STATE *DbgState, DEBUGGEE_PAUSING_REASON Reason, PDEBUGGER_TRIGGERED_EVENT_DETAILS EventDetails)
Handle #DBs and #BPs for kernel debugger.
Definition Kd.c:1214
GUEST_REGS * Regs
Definition State.h:168

◆ 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
1612{
1613 SYMBOL_BUFFER CodeBuffer = {0};
1614 ACTION_BUFFER ActionBuffer = {0};
1615 SYMBOL ErrorSymbol = {0};
1616 SCRIPT_ENGINE_VARIABLES_LIST VariablesList = {0};
1617
1618 if (Action != NULL)
1619 {
1620 //
1621 // Fill the action buffer's calling stage
1622 //
1623 if (EventTriggerDetail->Stage == VMM_CALLBACK_CALLING_STAGE_POST_EVENT_EMULATION)
1624 {
1625 ActionBuffer.CallingStage = 1;
1626 }
1627 else
1628 {
1629 ActionBuffer.CallingStage = 0;
1630 }
1631
1632 //
1633 // Fill the action buffer
1634 //
1635 ActionBuffer.Context = (UINT64)EventTriggerDetail->Context;
1636 ActionBuffer.Tag = EventTriggerDetail->Tag;
1638 ActionBuffer.CurrentAction = (UINT64)Action;
1639
1640 //
1641 // Context point to the registers
1642 //
1643 CodeBuffer.Head = (PSYMBOL)Action->ScriptConfiguration.ScriptBuffer;
1644 CodeBuffer.Size = Action->ScriptConfiguration.ScriptLength;
1645 CodeBuffer.Pointer = Action->ScriptConfiguration.ScriptPointer;
1646 }
1647 else if (ScriptDetails != NULL)
1648 {
1649 //
1650 // Fill the action buffer's calling stage
1651 //
1652 if (EventTriggerDetail->Stage == VMM_CALLBACK_CALLING_STAGE_POST_EVENT_EMULATION)
1653 {
1654 ActionBuffer.CallingStage = 1;
1655 }
1656 else
1657 {
1658 ActionBuffer.CallingStage = 0;
1659 }
1660
1661 //
1662 // Fill the action buffer
1663 //
1664 ActionBuffer.Context = (UINT64)EventTriggerDetail->Context;
1665 ActionBuffer.Tag = EventTriggerDetail->Tag;
1666 ActionBuffer.ImmediatelySendTheResults = TRUE;
1667 ActionBuffer.CurrentAction = (UINT64)NULL;
1668
1669 //
1670 // Context point to the registers
1671 //
1672 CodeBuffer.Head = (SYMBOL *)((CHAR *)ScriptDetails + sizeof(DEBUGGEE_SCRIPT_PACKET));
1673 CodeBuffer.Size = ScriptDetails->ScriptBufferSize;
1674 CodeBuffer.Pointer = ScriptDetails->ScriptBufferPointer;
1675 }
1676 else
1677 {
1678 //
1679 // The parameters are wrong !
1680 //
1681 return FALSE;
1682 }
1683
1684 //
1685 // Fill the variables list for this run
1686 //
1688 RtlZeroMemory(DbgState->ScriptEngineCoreSpecificLocalVariable, MAX_VAR_COUNT * sizeof(UINT64));
1689 RtlZeroMemory(DbgState->ScriptEngineCoreSpecificTempVariable, MAX_TEMP_COUNT * sizeof(UINT64));
1691 VariablesList.TempList = DbgState->ScriptEngineCoreSpecificTempVariable;
1692
1694 if (!StackBuffer || !StackBuffer->Head)
1695 {
1696 //
1697 // Not allocate memroy to stack buffer
1698 //
1699 return FALSE;
1700 }
1701
1702 StackBuffer->Pointer = 0;
1703 StackBuffer->Size = 0;
1704 StackBuffer->Message = NULL;
1705 RtlZeroMemory(StackBuffer->Head, MAX_STACK_BUFFER_COUNT * sizeof(SYMBOL));
1706
1707 UINT64 StackIndx = 0;
1708 UINT64 StackBaseIndx = 0;
1709 UINT64 EXECUTENUMBER = 0;
1710 UINT64 ReturnValue = 0;
1711
1712 for (UINT64 i = 0; i < CodeBuffer.Pointer;)
1713 {
1714 //
1715 // If has error, show error message and abort.
1716 //
1717
1718 if (ScriptEngineExecute(DbgState->Regs,
1719 &ActionBuffer,
1720 &VariablesList,
1721 &CodeBuffer,
1722 &i,
1723 StackBuffer,
1724 &StackIndx,
1725 &StackBaseIndx,
1726 &ErrorSymbol,
1727 &ReturnValue) == TRUE)
1728 {
1729 LogInfo("err, ScriptEngineExecute, function = % s\n ",
1730 FunctionNames[ErrorSymbol.Value]);
1731 break;
1732 }
1733 else if (StackIndx >= MAX_STACK_BUFFER_COUNT)
1734 {
1735 LogInfo("err, stack buffer overflow\n");
1736 break;
1737 }
1738 else if (EXECUTENUMBER >= MAX_EXECUTION_COUNT)
1739 {
1740 LogInfo("err, exceeding the max execution count\n");
1741 break;
1742 }
1743
1744 EXECUTENUMBER++;
1745 }
1746
1747 return TRUE;
1748}
char CHAR
Definition BasicTypes.h:31
#define MAX_EXECUTION_COUNT
Definition Constants.h:570
#define LogInfo(format,...)
Define log variables.
Definition HyperDbgHyperLogIntrinsics.h:71
struct _DEBUGGEE_SCRIPT_PACKET DEBUGGEE_SCRIPT_PACKET
The structure of script packet in HyperDbg.
struct SYMBOL * PSYMBOL
BOOL ScriptEngineExecute(PGUEST_REGS GuestRegs, ACTION_BUFFER *ActionDetail, SCRIPT_ENGINE_VARIABLES_LIST *VariablesList, SYMBOL_BUFFER *CodeBuffer, UINT64 *Indx, SYMBOL_BUFFER *StackBuffer, UINT64 *StackIndx, UINT64 *StackBaseIndx, SYMBOL *ErrorOperator, UINT64 *ReturnValue)
Execute the script buffer.
Definition ScriptEngineEval.c:288
UINT32 ScriptBufferPointer
Definition RequestStructures.h:1124
UINT32 ScriptBufferSize
Definition RequestStructures.h:1123
UINT64 Tag
Definition DataTypes.h:193
VMM_CALLBACK_EVENT_CALLING_STAGE_TYPE Stage
Definition DataTypes.h:195
PVOID Context
Definition DataTypes.h:194
List of different variables.
Definition BasicTypes.h:118
UINT64 * GlobalVariablesList
Definition BasicTypes.h:120
UINT64 * LocalVariablesList
Definition BasicTypes.h:121
UINT64 * TempList
Definition BasicTypes.h:119
Definition ScriptEngineCommonDefinitions.h:34
long long unsigned Context
Definition ScriptEngineCommonDefinitions.h:38
long long unsigned Tag
Definition ScriptEngineCommonDefinitions.h:35
long long unsigned CurrentAction
Definition ScriptEngineCommonDefinitions.h:36
char CallingStage
Definition ScriptEngineCommonDefinitions.h:39
char ImmediatelySendTheResults
Definition ScriptEngineCommonDefinitions.h:37
unsigned int Pointer
Definition ScriptEngineCommonDefinitions.h:23
PSYMBOL Head
Definition ScriptEngineCommonDefinitions.h:22
unsigned int Size
Definition ScriptEngineCommonDefinitions.h:24
long long unsigned Value
Definition ScriptEngineCommonDefinitions.h:10

◆ 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
1763{
1764 if (Action->CustomCodeBufferSize == 0)
1765 {
1766 //
1767 // Sth went wrong ! the buffer size for custom code shouldn't be zero
1768 //
1769 return;
1770 }
1771
1772 //
1773 // -----------------------------------------------------------------------------------------------------
1774 // Test
1775 //
1776 // LogInfo("%X Called from : %llx", Tag, Context);
1777 //
1778 //
1779 // LogInfo("Process Id : %x , Rax : %llx , R8 : %llx , Context : 0x%llx ", PsGetCurrentProcessId(), Regs->rax, Regs->r8, Context);
1780 // return;
1781 //
1782 // -----------------------------------------------------------------------------------------------------
1783 //
1784
1785 //
1786 // Run the custom code
1787 //
1788 if (Action->RequestedBuffer.RequestBufferSize == 0)
1789 {
1790 //
1791 // Because the user might change the nonvolatile registers, we save fastcall nonvolatile registers
1792 //
1794 (UINT64)DbgState->Regs,
1795 (UINT64)EventTriggerDetail->Context,
1797 }
1798 else
1799 {
1800 //
1801 // Because the user might change the nonvolatile registers, we save fastcall nonvolatile registers
1802 //
1804 (UINT64)DbgState->Regs,
1805 (UINT64)EventTriggerDetail->Context,
1807 }
1808}
void AsmDebuggerCustomCodeHandler(unsigned long long Param1, unsigned long long Param2, unsigned long long Param3, unsigned long long 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
2499{
2501 {
2502 return TRUE;
2503 }
2504 else
2505 {
2506 return FALSE;
2507 }
2508}
BOOLEAN g_UserDebuggerState
shows whether the user debugger is enabled or disabled
Definition Global.h:109
BOOLEAN g_KernelDebuggerState
shows whether the kernel debugger is enabled or disabled
Definition Global.h:103

◆ 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
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 return Event->Enabled;
2353}

◆ 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
1076{
1077 PLIST_ENTRY TargetEventList = NULL;
1078
1079 //
1080 // Register the event
1081 //
1082 TargetEventList = DebuggerGetEventListByEventType(Event->EventType);
1083
1084 if (TargetEventList != NULL)
1085 {
1086 InsertHeadList(TargetEventList, &(Event->EventsOfSameTypeList));
1087
1088 return TRUE;
1089 }
1090 else
1091 {
1092 return FALSE;
1093 }
1094}
LIST_ENTRY EventsOfSameTypeList
Definition Debugger.h:110

◆ DebuggerRemoveAllActionsFromEvent()

BOOLEAN DebuggerRemoveAllActionsFromEvent ( PDEBUGGER_EVENT Event,
BOOLEAN PoolManagerAllocatedMemory )

Remove the actions and de-allocate its buffer.

should not be called from vmx-root mode, also it won't terminate their effects, so the events should be terminated first then we can remove them *

Parameters
EventEvent Object
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
2575{
2576 PLIST_ENTRY TempList = 0;
2577 PLIST_ENTRY TempList2 = 0;
2578
2579 //
2580 // Remove all actions
2581 //
2582 TempList = &Event->ActionsListHead;
2583 TempList2 = TempList;
2584
2585 while (TempList2 != TempList->Flink)
2586 {
2587 TempList = TempList->Flink;
2588 PDEBUGGER_EVENT_ACTION CurrentAction = CONTAINING_RECORD(TempList, DEBUGGER_EVENT_ACTION, ActionsList);
2589
2590 //
2591 // Check if it has a OptionalRequestedBuffer probably for
2592 // CustomCode
2593 //
2594 if (CurrentAction->RequestedBuffer.RequestBufferSize != 0 && CurrentAction->RequestedBuffer.RequstBufferAddress != (UINT64)NULL)
2595 {
2596 //
2597 // There is a buffer
2598 //
2599 if (PoolManagerAllocatedMemory)
2600 {
2602 }
2603 else
2604 {
2606 }
2607 }
2608
2609 //
2610 // Remove the action and free the pool,
2611 // if it's a custom buffer then the buffer
2612 // is appended to the Action
2613 //
2614 if (PoolManagerAllocatedMemory)
2615 {
2616 PoolManagerFreePool((UINT64)CurrentAction);
2617 }
2618 else
2619 {
2620 PlatformMemFreePool(CurrentAction);
2621 }
2622 }
2623 //
2624 // Remember to free the pool
2625 //
2626 return TRUE;
2627}

◆ DebuggerRemoveAllEvents()

BOOLEAN DebuggerRemoveAllEvents ( BOOLEAN PoolManagerAllocatedMemory)

Remove all the events from all the lists and also de-allocate their structures and actions.

should not be called from vmx-root mode, also it won't terminate their effects, so the events should be terminated first then we can remove them

Parameters
PoolManagerAllocatedMemoryWhether the pools are allocated from the pool manager or original OS pools
Returns
BOOLEAN if at least one event removed then it returns true, and otherwise false
2011{
2012 BOOLEAN FindAtLeastOneEvent = FALSE;
2013 PLIST_ENTRY TempList = 0;
2014 PLIST_ENTRY TempList2 = 0;
2015
2016 //
2017 // We have to iterate through all events
2018 //
2019 for (size_t i = 0; i < sizeof(DEBUGGER_CORE_EVENTS) / sizeof(LIST_ENTRY); i++)
2020 {
2021 TempList = (PLIST_ENTRY)((UINT64)(g_Events) + (i * sizeof(LIST_ENTRY)));
2022 TempList2 = TempList;
2023
2024 while (TempList2 != TempList->Flink)
2025 {
2026 TempList = TempList->Flink;
2027 PDEBUGGER_EVENT CurrentEvent = CONTAINING_RECORD(TempList, DEBUGGER_EVENT, EventsOfSameTypeList);
2028
2029 //
2030 // Check if we find at least one event or not
2031 //
2032 if (!FindAtLeastOneEvent)
2033 {
2034 FindAtLeastOneEvent = TRUE;
2035 }
2036
2037 //
2038 // Remove the current event
2039 //
2040 DebuggerRemoveEvent(CurrentEvent->Tag, PoolManagerAllocatedMemory);
2041 }
2042 }
2043
2044 return FindAtLeastOneEvent;
2045}

◆ 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
2644{
2645 PDEBUGGER_EVENT Event;
2646
2647 //
2648 // First of all, we disable event
2649 //
2651 {
2652 //
2653 // Not found, tag is wrong !
2654 //
2655 return FALSE;
2656 }
2657
2658 //
2659 // When we're here, we are sure that the tag is valid
2660 // because if it was not valid, then we have to return
2661 // for the above function (DebuggerDisableEvent)
2662 //
2663 Event = DebuggerGetEventByTag(Tag);
2664
2665 //
2666 // Now we get the PDEBUGGER_EVENT so we have to remove
2667 // it from the event list
2668 //
2670 {
2671 return FALSE;
2672 }
2673
2674 //
2675 // Remove all of the actions and free its pools
2676 //
2677 DebuggerRemoveAllActionsFromEvent(Event, PoolManagerAllocatedMemory);
2678
2679 //
2680 // Free the pools of Event, when we free the pool,
2681 // ConditionsBufferAddress is also a part of the
2682 // event pool (ConditionBufferAddress and event
2683 // are both allocate in a same pool ) so both of
2684 // them are freed
2685 //
2686 if (PoolManagerAllocatedMemory)
2687 {
2689 }
2690 else
2691 {
2692 PlatformMemFreePool(Event);
2693 }
2694
2695 return TRUE;
2696}
BOOLEAN DebuggerRemoveAllActionsFromEvent(PDEBUGGER_EVENT Event, BOOLEAN PoolManagerAllocatedMemory)
Remove the actions and de-allocate its buffer.
Definition Debugger.c:2574
BOOLEAN DebuggerRemoveEventFromEventList(UINT64 Tag)
Remove the event from event list by its tag.
Definition Debugger.c:2522

◆ DebuggerRemoveEventFromEventList()

BOOLEAN DebuggerRemoveEventFromEventList ( UINT64 Tag)

Remove the event from event list by its tag.

should not be called from vmx-root mode, also it won't terminate their effects, so the events should be terminated first then we can remove them

Parameters
TagTarget events tag
Returns
BOOLEAN If the event was removed then TRUE and FALSE if not found
2523{
2524 PLIST_ENTRY TempList = 0;
2525 PLIST_ENTRY TempList2 = 0;
2526
2527 //
2528 // We have to iterate through all events
2529 //
2530 for (size_t i = 0; i < sizeof(DEBUGGER_CORE_EVENTS) / sizeof(LIST_ENTRY); i++)
2531 {
2532 TempList = (PLIST_ENTRY)((UINT64)(g_Events) + (i * sizeof(LIST_ENTRY)));
2533 TempList2 = TempList;
2534
2535 while (TempList2 != TempList->Flink)
2536 {
2537 TempList = TempList->Flink;
2538 PDEBUGGER_EVENT CurrentEvent = CONTAINING_RECORD(TempList, DEBUGGER_EVENT, EventsOfSameTypeList);
2539
2540 //
2541 // Check if we find the event or not
2542 //
2543 if (CurrentEvent->Tag == Tag)
2544 {
2545 //
2546 // We have to remove the event from the list
2547 //
2548 RemoveEntryList(&CurrentEvent->EventsOfSameTypeList);
2549 return TRUE;
2550 }
2551 }
2552 }
2553
2554 //
2555 // We didn't find anything, so return null
2556 //
2557 return FALSE;
2558}
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition Windows.h:56

◆ DebuggerSetLastError()

VOID DebuggerSetLastError ( UINT32 LastError)

Debugger set the last error.

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

◆ DebuggerTerminateAllEvents()

BOOLEAN DebuggerTerminateAllEvents ( BOOLEAN InputFromVmxRoot)

Terminate effect and configuration to vmx-root and non-root for all the events.

Parameters
InputFromVmxRootWhether the input comes from VMX root-mode or IOCTL
Returns
BOOLEAN if at least one event terminated then it returns true, and otherwise false
1959{
1960 BOOLEAN FindAtLeastOneEvent = FALSE;
1961 PLIST_ENTRY TempList = 0;
1962 PLIST_ENTRY TempList2 = 0;
1963
1964 //
1965 // We have to iterate through all events
1966 //
1967 for (size_t i = 0; i < sizeof(DEBUGGER_CORE_EVENTS) / sizeof(LIST_ENTRY); i++)
1968 {
1969 TempList = (PLIST_ENTRY)((UINT64)(g_Events) + (i * sizeof(LIST_ENTRY)));
1970 TempList2 = TempList;
1971
1972 while (TempList2 != TempList->Flink)
1973 {
1974 TempList = TempList->Flink;
1975 PDEBUGGER_EVENT CurrentEvent = CONTAINING_RECORD(TempList, DEBUGGER_EVENT, EventsOfSameTypeList);
1976
1977 //
1978 // Check if we find at least one event or not
1979 //
1980 if (!FindAtLeastOneEvent)
1981 {
1982 FindAtLeastOneEvent = TRUE;
1983 }
1984
1985 //
1986 // Terminate the current event
1987 //
1988 DebuggerTerminateEvent(CurrentEvent->Tag, InputFromVmxRoot);
1989 }
1990 }
1991
1992 return FindAtLeastOneEvent;
1993}

◆ 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
3437{
3438 PDEBUGGER_EVENT Event;
3439 BOOLEAN Result = FALSE;
3440
3441 //
3442 // Find the event by its tag
3443 //
3444 Event = DebuggerGetEventByTag(Tag);
3445
3446 if (Event == NULL)
3447 {
3448 //
3449 // event, not found
3450 //
3451 return FALSE;
3452 }
3453
3454 //
3455 // Check the event type of our specific tag
3456 //
3457 switch (Event->EventType)
3458 {
3460 {
3461 //
3462 // Call external interrupt terminator
3463 //
3464 TerminateExternalInterruptEvent(Event, InputFromVmxRoot);
3465 Result = TRUE;
3466
3467 break;
3468 }
3473 case HIDDEN_HOOK_READ:
3474 case HIDDEN_HOOK_WRITE:
3476 {
3477 //
3478 // Call read and write and execute ept hook terminator
3479 //
3480 TerminateHiddenHookReadAndWriteAndExecuteEvent(Event, InputFromVmxRoot);
3481 Result = TRUE;
3482
3483 break;
3484 }
3486 {
3487 //
3488 // Call ept hook (hidden breakpoint) terminator
3489 //
3490 TerminateHiddenHookExecCcEvent(Event, InputFromVmxRoot);
3491 Result = TRUE;
3492
3493 break;
3494 }
3496 {
3497 //
3498 // Call ept hook (hidden inline hook) terminator
3499 //
3500 TerminateHiddenHookExecDetoursEvent(Event, InputFromVmxRoot);
3501 Result = TRUE;
3502
3503 break;
3504 }
3506 {
3507 //
3508 // Call rdmsr execution event terminator
3509 //
3510 TerminateRdmsrExecutionEvent(Event, InputFromVmxRoot);
3511 Result = TRUE;
3512
3513 break;
3514 }
3516 {
3517 //
3518 // Call wrmsr execution event terminator
3519 //
3520 TerminateWrmsrExecutionEvent(Event, InputFromVmxRoot);
3521 Result = TRUE;
3522
3523 break;
3524 }
3525 case EXCEPTION_OCCURRED:
3526 {
3527 //
3528 // Call exception events terminator
3529 //
3530 TerminateExceptionEvent(Event, InputFromVmxRoot);
3531 Result = TRUE;
3532
3533 break;
3534 }
3536 {
3537 //
3538 // Call IN instruction execution event terminator
3539 //
3540 TerminateInInstructionExecutionEvent(Event, InputFromVmxRoot);
3541 Result = TRUE;
3542
3543 break;
3544 }
3546 {
3547 //
3548 // Call OUT instruction execution event terminator
3549 //
3550 TerminateOutInstructionExecutionEvent(Event, InputFromVmxRoot);
3551 Result = TRUE;
3552
3553 break;
3554 }
3556 {
3557 //
3558 // Call syscall hook event terminator
3559 //
3560 TerminateSyscallHookEferEvent(Event, InputFromVmxRoot);
3561 Result = TRUE;
3562
3563 break;
3564 }
3566 {
3567 //
3568 // Call sysret hook event terminator
3569 //
3570 TerminateSysretHookEferEvent(Event, InputFromVmxRoot);
3571 Result = TRUE;
3572
3573 break;
3574 }
3576 {
3577 //
3578 // Call vmcall instruction execution event terminator
3579 //
3580 TerminateVmcallExecutionEvent(Event, InputFromVmxRoot);
3581 Result = TRUE;
3582
3583 break;
3584 }
3586 {
3587 //
3588 // Call mode execution trap event terminator
3589 //
3590 TerminateExecTrapModeChangedEvent(Event, InputFromVmxRoot);
3591 Result = TRUE;
3592
3593 break;
3594 }
3596 {
3597 //
3598 // Call rdtsc/rdtscp instruction execution event terminator
3599 //
3600 TerminateTscEvent(Event, InputFromVmxRoot);
3601 Result = TRUE;
3602
3603 break;
3604 }
3606 {
3607 //
3608 // Call rdtsc/rdtscp instructions execution event terminator
3609 //
3610 TerminatePmcEvent(Event, InputFromVmxRoot);
3611 Result = TRUE;
3612
3613 break;
3614 }
3616 {
3617 //
3618 // Call mov to debugger register event terminator
3619 //
3620 TerminateDebugRegistersEvent(Event, InputFromVmxRoot);
3621 Result = TRUE;
3622
3623 break;
3624 }
3626 {
3627 //
3628 // Call cpuid instruction execution event terminator
3629 //
3630 TerminateCpuidExecutionEvent(Event, InputFromVmxRoot);
3631 Result = TRUE;
3632
3633 break;
3634 }
3636 {
3637 //
3638 // Call mov to control register event terminator
3639 //
3640 TerminateControlRegistersEvent(Event, InputFromVmxRoot);
3641 Result = TRUE;
3642
3643 break;
3644 }
3645 default:
3646 LogError("Err, unknown event for termination");
3647 Result = FALSE;
3648
3649 break;
3650 }
3651
3652 //
3653 // Return status
3654 //
3655 return Result;
3656}
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
1115{
1116 PROCESSOR_DEBUGGING_STATE * DbgState = NULL;
1117 DebuggerCheckForCondition * ConditionFunc;
1118 DEBUGGER_TRIGGERED_EVENT_DETAILS EventTriggerDetail = {0};
1119 PEPT_HOOKS_CONTEXT EptContext;
1120 PLIST_ENTRY TempList = 0;
1121 PLIST_ENTRY TempList2 = 0;
1122 const PVOID OriginalContext = Context;
1123
1124 //
1125 // Check if triggering debugging actions are allowed or not
1126 //
1128 {
1129 //
1130 // Debugger is not enabled
1131 //
1133 }
1134
1135 //
1136 // Find the debugging state structure
1137 //
1138 DbgState = &g_DbgState[KeGetCurrentProcessorNumberEx(NULL)];
1139
1140 //
1141 // Set the registers for debug state
1142 //
1143 DbgState->Regs = Regs;
1144
1145 //
1146 // Find the debugger events list base on the type of the event
1147 //
1148 TempList = DebuggerGetEventListByEventType(EventType);
1149 TempList2 = TempList;
1150
1151 if (TempList == NULL)
1152 {
1154 }
1155
1156 while (TempList2 != TempList->Flink)
1157 {
1158 TempList = TempList->Flink;
1159 PDEBUGGER_EVENT CurrentEvent = CONTAINING_RECORD(TempList, DEBUGGER_EVENT, EventsOfSameTypeList);
1160
1161 //
1162 // check if the event is enabled or not
1163 //
1164 if (!CurrentEvent->Enabled)
1165 {
1166 continue;
1167 }
1168
1169 //
1170 // Check if this event is for this core or not
1171 //
1172 if (CurrentEvent->CoreId != DEBUGGER_EVENT_APPLY_TO_ALL_CORES && CurrentEvent->CoreId != DbgState->CoreId)
1173 {
1174 //
1175 // This event is not related to either or core or all cores
1176 //
1177 continue;
1178 }
1179
1180 //
1181 // Check if this event is for this process or not
1182 //
1183 if (CurrentEvent->ProcessId != DEBUGGER_EVENT_APPLY_TO_ALL_PROCESSES && CurrentEvent->ProcessId != HANDLE_TO_UINT32(PsGetCurrentProcessId()))
1184 {
1185 //
1186 // This event is not related to either our process or all processes
1187 //
1188 continue;
1189 }
1190
1191 //
1192 // Check event type specific conditions
1193 //
1194 switch (CurrentEvent->EventType)
1195 {
1197
1198 //
1199 // For external interrupt exiting events we check whether the
1200 // vector match the event's vector or not
1201 //
1202 // Context is the physical address
1203 //
1204 if ((UINT64)Context != CurrentEvent->Options.OptionalParam1)
1205 {
1206 //
1207 // The interrupt is not for this event
1208 //
1209 continue;
1210 }
1211
1212 break;
1213
1218 case HIDDEN_HOOK_READ:
1219 case HIDDEN_HOOK_WRITE:
1221
1222 //
1223 // For hidden hook read/write/execute we check whether the address
1224 // is in the range of what user specified or not, this is because
1225 // we get the events for all hidden hooks in a page granularity
1226 //
1227
1228 //
1229 // Here the OriginalContext is used because the context
1230 // might be changed but the OriginalContext is constant
1231 //
1232 EptContext = (PEPT_HOOKS_CONTEXT)OriginalContext;
1233
1234 //
1235 // EPT context should be checked with hooking tag
1236 // The hooking tag is same as the event tag if both
1237 // of them match together
1238 //
1239 if (EptContext->HookingTag != CurrentEvent->Tag)
1240 {
1241 //
1242 // The value is not within our expected range
1243 //
1244 continue;
1245 }
1246 else
1247 {
1248 //
1249 // Fix the context to virtual address
1250 //
1251 Context = (PVOID)EptContext->VirtualAddress;
1252 }
1253
1254 break;
1255
1257
1258 //
1259 // Here we check if it's HIDDEN_HOOK_EXEC_CC then it means
1260 // so we have to make sure to perform its actions only if
1261 // the hook is triggered for the address described in
1262 // event, note that address in event is a virtual address
1263 //
1264 if ((UINT64)Context != CurrentEvent->Options.OptionalParam1)
1265 {
1266 //
1267 // Context is the virtual address
1268 //
1269
1270 //
1271 // The hook is not for this (virtual) address
1272 //
1273 continue;
1274 }
1275
1276 break;
1277
1279
1280 //
1281 // Here the OriginalContext is used because the context
1282 // might be changed but the OriginalContext is constant
1283 //
1284 EptContext = (PEPT_HOOKS_CONTEXT)OriginalContext;
1285
1286 //
1287 // Here we check if it's HIDDEN_HOOK_EXEC_DETOURS
1288 // then it means that it's detours hidden hook exec so we have
1289 // to make sure to perform its actions, only if the hook is triggered
1290 // for the address described in event, note that address in event is
1291 // a physical address and the address that the function that triggers
1292 // these events and sent here as the context is also converted to its
1293 // physical form
1294 // This way we are sure that no one can bypass our hook by remapping
1295 // address to another virtual address as everything is physical
1296 //
1297 if (EptContext->PhysicalAddress != CurrentEvent->Options.OptionalParam1)
1298 {
1299 //
1300 // Context is the physical address
1301 //
1302
1303 //
1304 // The hook is not for this (physical) address
1305 //
1306 continue;
1307 }
1308 else
1309 {
1310 //
1311 // Convert it to virtual address
1312 //
1313 Context = (PVOID)(EptContext->VirtualAddress);
1314 }
1315
1316 break;
1317
1320
1321 //
1322 // check if MSR exit is what we want or not
1323 //
1325 {
1326 //
1327 // The msr is not what we want
1328 //
1329 continue;
1330 }
1331
1332 break;
1333
1334 case EXCEPTION_OCCURRED:
1335
1336 //
1337 // check if exception is what we need or not
1338 //
1340 {
1341 //
1342 // The exception is not what we want
1343 //
1344 continue;
1345 }
1346
1347 break;
1348
1351
1352 //
1353 // check if I/O port is what we want or not
1354 //
1355 if (CurrentEvent->Options.OptionalParam1 != DEBUGGER_EVENT_ALL_IO_PORTS && CurrentEvent->Options.OptionalParam1 != (UINT64)Context)
1356 {
1357 //
1358 // The port is not what we want
1359 //
1360 continue;
1361 }
1362
1363 break;
1364
1366
1367 //
1368 // case SYSCALL_HOOK_EFER_SYSRET:
1369 //
1370 // I don't know how to find syscall number when sysret is executed so
1371 // that's why we don't support extra argument for sysret
1372 //
1373
1374 //
1375 // check syscall number
1376 //
1378 {
1379 //
1380 // The syscall number is not what we want
1381 //
1382 continue;
1383 }
1384
1385 break;
1386
1388
1389 //
1390 // check if CPUID is what we want or not
1391 //
1392 if (CurrentEvent->Options.OptionalParam1 != (UINT64)NULL /*FALSE*/ && CurrentEvent->Options.OptionalParam2 != (UINT64)Context)
1393 {
1394 //
1395 // The CPUID is not what we want (and the user didn't intend to get all CPUIDs)
1396 //
1397 continue;
1398 }
1399
1400 break;
1401
1403
1404 //
1405 // check if CR exit is what we want or not
1406 //
1407 if (CurrentEvent->Options.OptionalParam1 != (UINT64)Context)
1408 {
1409 //
1410 // The CR is not what we want
1411 //
1412 continue;
1413 }
1414
1415 break;
1416
1418
1419 //
1420 // check if the debugger needs user-to-kernel or kernel-to-user events
1421 //
1423 {
1428 {
1429 continue;
1430 }
1431 }
1432
1433 break;
1434
1435 default:
1436 break;
1437 }
1438
1439 //
1440 // Check the stage of calling (pre, all, or post event)
1441 //
1445 {
1446 //
1447 // Here it means that the current event is a post, or all event event
1448 // and the current stage of calling is for the pre-event events, thus
1449 // this event is not supposed to be ran at the current stage.
1450 // However, we'll set a flag so the caller will know that there is
1451 // a valid post-event available for the parameters related to this
1452 // event.
1453 // This mechanism notifies the caller to trigger the event after
1454 // emulation, we implement it in a way that the caller knows when
1455 // to trigger a post-event thus it optimizes the number of times
1456 // that the caller triggers the events and avoid unnecessary triggering
1457 // of the event (for post-event) but at the same time we have the
1458 // flexibility of having both pre-event and post-event concepts
1459 //
1460 *PostEventRequired = TRUE;
1461
1463 {
1464 //
1465 // If it's not an 'all' event and it is only the 'post' event,
1466 // then we ignore the trigger stage
1467 //
1468 continue;
1469 }
1470 }
1471
1472 //
1473 // Check if condition is met or not , if the condition
1474 // is not met then we have to avoid performing the actions
1475 //
1476 if (CurrentEvent->ConditionsBufferSize != 0)
1477 {
1478 //
1479 // Means that there is some conditions
1480 //
1481 ConditionFunc = (DebuggerCheckForCondition *)CurrentEvent->ConditionBufferAddress;
1482
1483 //
1484 // Run and check for results
1485 //
1486 // Because the user might change the nonvolatile registers, we save fastcall nonvolatile registers
1487 //
1488 if (AsmDebuggerConditionCodeHandler((UINT64)DbgState->Regs, (UINT64)Context, (UINT64)ConditionFunc) == 0)
1489 {
1490 //
1491 // The condition function returns null, mean that the
1492 // condition didn't met, we can ignore this event
1493 //
1494 continue;
1495 }
1496 }
1497
1498 //
1499 // Reset the event ignorance mechanism (apply 'sc on/off' to the events)
1500 //
1501 DbgState->ShortCircuitingEvent = CurrentEvent->EnableShortCircuiting;
1502
1503 //
1504 // Setup event trigger detail
1505 //
1506 EventTriggerDetail.Context = Context;
1507 EventTriggerDetail.Tag = CurrentEvent->Tag;
1508 EventTriggerDetail.Stage = CallingStage;
1509
1510 //
1511 // perform the actions
1512 //
1513 DebuggerPerformActions(DbgState, CurrentEvent, &EventTriggerDetail);
1514 }
1515
1516 //
1517 // Check if the event should be ignored or not
1518 //
1519 if (DbgState->ShortCircuitingEvent)
1520 {
1521 //
1522 // Reset the event ignorance (short-circuit) mechanism
1523 //
1524 DbgState->ShortCircuitingEvent = FALSE;
1525
1526 //
1527 // Event should be ignored
1528 //
1530 }
1531 else
1532 {
1533 //
1534 // Event shouldn't be ignored
1535 //
1537 }
1538}
unsigned long long AsmDebuggerConditionCodeHandler(unsigned long long Param1, unsigned long long Param2, unsigned long long Param3)
default condition code handler
#define DEBUGGER_EVENT_ALL_IO_PORTS
Apply to all I/O ports.
Definition Constants.h:641
#define DEBUGGER_EVENT_SYSCALL_ALL_SYSRET_OR_SYSCALLS
Apply to all syscalls and sysrets.
Definition Constants.h:635
#define DEBUGGER_EVENT_EXCEPTIONS_ALL_FIRST_32_ENTRIES
Apply to all first 32 exceptions.
Definition Constants.h:629
#define DEBUGGER_EVENT_APPLY_TO_ALL_PROCESSES
Apply the event to all the processes.
Definition Constants.h:617
#define DEBUGGER_EVENT_MSR_READ_OR_WRITE_ALL_MSRS
Apply to all Model Specific Registers.
Definition Constants.h:623
struct _EPT_HOOKS_CONTEXT * PEPT_HOOKS_CONTEXT
VOID DebuggerPerformActions(PROCESSOR_DEBUGGING_STATE *DbgState, DEBUGGER_EVENT *Event, DEBUGGER_TRIGGERED_EVENT_DETAILS *EventTriggerDetail)
Run a special event's action(s)
Definition Debugger.c:1550
#define HANDLE_TO_UINT32(_var)
Definition MetaMacros.h:39
NTKERNELAPI _In_opt_ PVOID Context
Definition Dpc.h:25
UINT64 DebuggerCheckForCondition(PGUEST_REGS Regs, PVOID Context)
The prototype that Condition codes are called.
Definition Debugger.h:159
BOOLEAN g_InterceptBreakpointsAndEventsForCommandsInRemoteComputer
To avoid getting stuck from getting hit from the breakpoints while executing the commands in the remo...
Definition Global.h:166
@ 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:207
@ DEBUGGER_EVENT_MODE_TYPE_USER_MODE_AND_KERNEL_MODE
Definition Events.h:205
@ DEBUGGER_EVENT_MODE_TYPE_USER_MODE
Definition Events.h:206
UINT64 OptionalParam2
Definition Events.h:273
The structure of detail of a triggered event in HyperDbg.
Definition DataTypes.h:192
Temporary $context used in some EPT hook commands.
Definition DataTypes.h:320
UINT64 HookingTag
Definition DataTypes.h:321
UINT64 VirtualAddress
Definition DataTypes.h:323
UINT64 PhysicalAddress
Definition DataTypes.h:322
BOOLEAN ShortCircuitingEvent
Definition State.h:170

◆ DebuggerUninitialize()

VOID DebuggerUninitialize ( )

Uninitialize Debugger Structures and Routines.

258{
259 ULONG ProcessorsCount;
260 PROCESSOR_DEBUGGING_STATE * CurrentDebuggerState = NULL;
261
262 ProcessorsCount = KeQueryActiveProcessorCount(0);
263
264 //
265 // *** Disable, terminate and clear all the events ***
266 //
267
268 //
269 // Because we want to delete all the objects and buffers (pools)
270 // after we finished termination, the debugger might still use
271 // the buffers for events and action, for solving this problem
272 // we first disable the tag(s) and this way the debugger no longer
273 // use that event and this way we can safely remove and deallocate
274 // the buffers later after termination
275 //
276
277 //
278 // Disable triggering events
279 //
281
282 //
283 // Clear all events (Check if the kernel debugger is enable
284 // and whether the instant event mechanism is working or not)
285 //
287 {
289 }
290 else
291 {
293 }
294
295 //
296 // Uninitialize kernel debugger
297 //
299
300 //
301 // Uninitialize user debugger
302 //
304
305 //
306 // Uninitialize NMI broadcasting mechanism
307 //
309
310 //
311 // Free g_Events
312 //
314
315 //
316 // Free g_ScriptGlobalVariables
317 //
318 if (g_ScriptGlobalVariables != NULL)
319 {
322 }
323
324 //
325 // Free core specific local and temp variables
326 //
327 for (SIZE_T i = 0; i < ProcessorsCount; i++)
328 {
329 CurrentDebuggerState = &g_DbgState[i];
330
331 if (CurrentDebuggerState->ScriptEngineCoreSpecificLocalVariable != NULL)
332 {
334 CurrentDebuggerState->ScriptEngineCoreSpecificLocalVariable = NULL;
335 }
336
337 if (CurrentDebuggerState->ScriptEngineCoreSpecificTempVariable != NULL)
338 {
340 CurrentDebuggerState->ScriptEngineCoreSpecificTempVariable = NULL;
341 }
342
343 if (CurrentDebuggerState->ScriptEngineCoreSpecificStackBuffer != NULL)
344 {
345 PSYMBOL_BUFFER StackBuffer = (PSYMBOL_BUFFER)CurrentDebuggerState->ScriptEngineCoreSpecificStackBuffer;
346 if ((StackBuffer)->Head != NULL)
347 {
348 PlatformMemFreePool(StackBuffer->Head);
349 }
350
352 CurrentDebuggerState->ScriptEngineCoreSpecificStackBuffer = NULL;
353 }
354 }
355
356 //
357 // Free g_DbgState
358 //
360}
VOID GlobalEventsFreeMemory(VOID)
Free event store memory.
Definition Allocations.c:88
VOID GlobalDebuggingStateFreeMemory(VOID)
Free debugging state memory.
Definition Allocations.c:49
#define EnableInstantEventMechanism
Enable or disable the instant event mechanism.
Definition Configuration.h:75
VOID VmFuncVmxBroadcastUninitialize()
Export for uninitialize the VMX Broadcast mechanism.
Definition Export.c:708
VOID KdUninitializeKernelDebugger()
uninitialize kernel debugger
Definition Kd.c:81
VOID UdUninitializeUserDebugger()
uninitialize user debugger
Definition Ud.c:77

◆ DebuggerValidateEvent()

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

validating events

Parameters
EventDetailsThe structure that describes event that came from the user-mode or VMX-root 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 otherwise returns FALSE
2713{
2714 //
2715 // Check whether the event mode (calling stage) to see whether
2716 // short-cicuiting event is used along with the post-event,
2717 // it is because using the short-circuiting mechanism with
2718 // post-events doesn't make sense; it's not supported!
2719 //
2722 EventDetails->EnableShortCircuiting == TRUE)
2723 {
2724 ResultsToReturn->IsSuccessful = FALSE;
2726 return FALSE;
2727 }
2728
2729 //
2730 // Check whether the core Id is valid or not, we read cores count
2731 // here because we use it in later parts
2732 //
2733 if (EventDetails->CoreId != DEBUGGER_EVENT_APPLY_TO_ALL_CORES)
2734 {
2735 //
2736 // Check if the core number is not invalid
2737 //
2738 if (!CommonValidateCoreNumber(EventDetails->CoreId))
2739 {
2740 //
2741 // CoreId is invalid (Set the error)
2742 //
2743 ResultsToReturn->IsSuccessful = FALSE;
2744 ResultsToReturn->Error = DEBUGGER_ERROR_INVALID_CORE_ID;
2745 return FALSE;
2746 }
2747 }
2748
2749 //
2750 // Check if process id is valid or not, we won't touch process id here
2751 // because some of the events use the exact value of DEBUGGER_EVENT_APPLY_TO_ALL_PROCESSES
2752 //
2753 if (EventDetails->ProcessId != DEBUGGER_EVENT_APPLY_TO_ALL_PROCESSES && EventDetails->ProcessId != 0)
2754 {
2755 //
2756 // Here we prefer not to validate the process id, if it's applied from VMX-root mode
2757 //
2758 if (!InputFromVmxRoot)
2759 {
2760 //
2761 // The used specified a special pid, let's check if it's valid or not
2762 //
2763 if (!CommonIsProcessExist(EventDetails->ProcessId))
2764 {
2765 ResultsToReturn->IsSuccessful = FALSE;
2766 ResultsToReturn->Error = DEBUGGER_ERROR_INVALID_PROCESS_ID;
2767 return FALSE;
2768 }
2769 }
2770 }
2771
2772 //
2773 // *** Event specific validations ***
2774 //
2775 switch (EventDetails->EventType)
2776 {
2777 case EXCEPTION_OCCURRED:
2778 {
2779 //
2780 // Check if exception parameters are valid
2781 //
2782 if (!ValidateEventException(EventDetails, ResultsToReturn, InputFromVmxRoot))
2783 {
2784 //
2785 // Event parameters are not valid, let break the further execution at this stage
2786 //
2787 return FALSE;
2788 }
2789
2790 break;
2791 }
2793 {
2794 //
2795 // Check if interrupt parameters are valid
2796 //
2797 if (!ValidateEventInterrupt(EventDetails, ResultsToReturn, InputFromVmxRoot))
2798 {
2799 //
2800 // Event parameters are not valid, let break the further execution at this stage
2801 //
2802 return FALSE;
2803 }
2804
2805 break;
2806 }
2808 {
2809 //
2810 // Check if trap exec mode parameters are valid
2811 //
2812 if (!ValidateEventTrapExec(EventDetails, ResultsToReturn, InputFromVmxRoot))
2813 {
2814 //
2815 // Event parameters are not valid, let break the further execution at this stage
2816 //
2817 return FALSE;
2818 }
2819
2820 break;
2821 }
2824 {
2825 //
2826 // Check if EPT hook exec (hidden breakpoint and inline hook) parameters are valid
2827 //
2828 if (!ValidateEventEptHookHiddenBreakpointAndInlineHooks(EventDetails, ResultsToReturn, InputFromVmxRoot))
2829 {
2830 //
2831 // Event parameters are not valid, let break the further execution at this stage
2832 //
2833 return FALSE;
2834 }
2835
2836 break;
2837 }
2842 case HIDDEN_HOOK_READ:
2843 case HIDDEN_HOOK_WRITE:
2845 {
2846 //
2847 // Check if EPT memory monitor hook parameters are valid
2848 //
2849 if (!ValidateEventMonitor(EventDetails, ResultsToReturn, InputFromVmxRoot))
2850 {
2851 //
2852 // Event parameters are not valid, let break the further execution at this stage
2853 //
2854 return FALSE;
2855 }
2856
2857 break;
2858 }
2859 default:
2860
2861 //
2862 // Other not specified events doesn't have any special validation
2863 //
2864 break;
2865 }
2866
2867 //
2868 // As we reached, all the checks are passed and it means the event is valid
2869 //
2870 return TRUE;
2871}
#define DEBUGGER_ERROR_INVALID_CORE_ID
error, the core id is invalid
Definition ErrorCodes.h:69
#define DEBUGGER_ERROR_USING_SHORT_CIRCUITING_EVENT_WITH_POST_EVENT_MODE_IS_FORBIDDEDN
error, using short-circuiting event with post-event mode is not supported in HyperDbg
Definition ErrorCodes.h:393
#define DEBUGGER_ERROR_INVALID_PROCESS_ID
error, the process id is invalid
Definition ErrorCodes.h:220
BOOLEAN ValidateEventInterrupt(PDEBUGGER_GENERAL_EVENT_DETAIL EventDetails, PDEBUGGER_EVENT_AND_ACTION_RESULT ResultsToReturn, BOOLEAN InputFromVmxRoot)
Validating interrupt events.
Definition ValidateEvents.c:176
BOOLEAN ValidateEventException(PDEBUGGER_GENERAL_EVENT_DETAIL EventDetails, PDEBUGGER_EVENT_AND_ACTION_RESULT ResultsToReturn, BOOLEAN InputFromVmxRoot)
Validating exception events.
Definition ValidateEvents.c:137
BOOLEAN ValidateEventEptHookHiddenBreakpointAndInlineHooks(PDEBUGGER_GENERAL_EVENT_DETAIL EventDetails, PDEBUGGER_EVENT_AND_ACTION_RESULT ResultsToReturn, BOOLEAN InputFromVmxRoot)
Validating EPT hook exec (hidden breakpoint and inline hook) events.
Definition ValidateEvents.c:251
BOOLEAN ValidateEventTrapExec(PDEBUGGER_GENERAL_EVENT_DETAIL EventDetails, PDEBUGGER_EVENT_AND_ACTION_RESULT ResultsToReturn, BOOLEAN InputFromVmxRoot)
Validating trap exec events.
Definition ValidateEvents.c:213
BOOLEAN ValidateEventMonitor(PDEBUGGER_GENERAL_EVENT_DETAIL EventDetails, PDEBUGGER_EVENT_AND_ACTION_RESULT ResultsToReturn, BOOLEAN InputFromVmxRoot)
Validating monitor memory hook events.
Definition ValidateEvents.c:26
_Use_decl_annotations_ BOOLEAN CommonValidateCoreNumber(UINT32 CoreNumber)
Validate core number.
Definition Common.c:256
BOOLEAN CommonIsProcessExist(UINT32 ProcId)
Checks whether the process with ProcId exists or not.
Definition Common.c:24