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

Headers for broadcast in VMX-root mode. More...

Go to the source code of this file.

Functions

VOID VmxBroadcastInitialize ()
 Initialize the VMX Broadcast mechanism.
VOID VmxBroadcastUninitialize ()
 Uninitialize the VMX Broadcast mechanism.
BOOLEAN VmxBroadcastHandleNmiCallback (PVOID Context, BOOLEAN Handled)
 Handles NMIs in kernel-mode.
BOOLEAN VmxBroadcastNmi (VIRTUAL_MACHINE_STATE *VCpu, NMI_BROADCAST_ACTION_TYPE VmxBroadcastAction)
 Broadcast NMI in vmx-root mode.
BOOLEAN VmxBroadcastNmiHandler (VIRTUAL_MACHINE_STATE *VCpu, BOOLEAN IsOnVmxNmiHandler)
 Handle broadcast NMIs in vmx-root mode.

Detailed Description

Headers for broadcast in VMX-root mode.

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

Function Documentation

◆ VmxBroadcastHandleNmiCallback()

BOOLEAN VmxBroadcastHandleNmiCallback ( PVOID Context,
BOOLEAN Handled )

Handles NMIs in kernel-mode.

Parameters
Context
Handled
Returns
BOOLEAN
93{
94 UNREFERENCED_PARAMETER(Context);
95
96 ULONG CurrentCore;
97 CurrentCore = KeGetCurrentProcessorNumberEx(NULL);
98 VIRTUAL_MACHINE_STATE * VCpu = &g_GuestState[CurrentCore];
99
100 //
101 // This mechanism tries to solve the problem of receiving NMIs
102 // when we're already in vmx-root mode, e.g., when we want to
103 // inject NMIs to other cores and those cores are already operating
104 // in vmx-root mode; however, this is not the approach to solve the
105 // problem. In order to solve this problem, we should create our own
106 // host IDT in vmx-root mode (Note that we should set VMCS_HOST_IDTR_BASE
107 // and there is no need to LIMIT as it's fixed at 0xffff for VMX
108 // operations).
109 // Because we want to use the debugging mechanism of the Windows
110 // we use the same IDT with the guest (guest and host IDT is the
111 // same), but in the future versions we solve this problem by our
112 // own ISR NMI handler in vmx-root mode
113 //
114
115 //
116 // We should check whether the NMI is in vmx-root mode or not
117 // if it's not in vmx-root mode then it's not related to us
118 //
119 if (!VmxBroadcastNmiHandler(VCpu, TRUE))
120 {
121 return Handled;
122 }
123 else
124 {
125 //
126 // If we're here then it related to us
127 // return true to show that it's handled
128 //
129 return TRUE;
130 }
131}
BOOLEAN VmxBroadcastNmiHandler(VIRTUAL_MACHINE_STATE *VCpu, BOOLEAN IsOnVmxNmiHandler)
Handle broadcast NMIs in vmx-root mode.
Definition VmxBroadcast.c:187
#define TRUE
Definition BasicTypes.h:114
unsigned long ULONG
Definition BasicTypes.h:31
struct _VIRTUAL_MACHINE_STATE VIRTUAL_MACHINE_STATE
The status of each core after and before VMX.
VIRTUAL_MACHINE_STATE * g_GuestState
Save the state and variables related to virtualization on each to logical core.
Definition GlobalVariables.h:38

◆ VmxBroadcastInitialize()

VOID VmxBroadcastInitialize ( )

Initialize the VMX Broadcast mechanism.

Returns
VOID
21{
22 //
23 // *** Initialize NMI broadcasting mechanism ***
24 //
25
26 //
27 // Initialize APIC
28 //
30
31#if USE_DEFAULT_OS_IDT_AS_HOST_IDT == TRUE
32
33 //
34 // Register NMI handler for vmx-root
35 //
37
38#endif // USE_DEFAULT_OS_IDT_AS_HOST_IDT == TRUE
39
40 //
41 // Broadcast on all core to cause exit for NMIs
42 //
44
45 //
46 // Indicate that NMI broadcasting is initialized
47 //
49}
BOOLEAN ApicInitialize()
Initialize APIC.
Definition Apic.c:366
BOOLEAN VmxBroadcastHandleNmiCallback(PVOID Context, BOOLEAN Handled)
Handles NMIs in kernel-mode.
Definition VmxBroadcast.c:92
VOID BroadcastEnableNmiExitingAllCores()
routines to set vm-exit on all NMIs on all cores
Definition Broadcast.c:91
PVOID g_NmiHandlerForKeDeregisterNmiCallback
NMI handler pointer for KeDeregisterNmiCallback.
Definition GlobalVariables.h:87
BOOLEAN g_NmiBroadcastingInitialized
check for broadcasting NMI mechanism support and its initialization
Definition GlobalVariables.h:81

◆ VmxBroadcastNmi()

BOOLEAN VmxBroadcastNmi ( VIRTUAL_MACHINE_STATE * VCpu,
NMI_BROADCAST_ACTION_TYPE VmxBroadcastAction )

Broadcast NMI in vmx-root mode.

caller to this function should take actions to the current core the NMI won't be triggered for the current core

Parameters
VCpuThe virtual processor's state
VmxBroadcastAction
Returns
BOOLEAN
144{
145 ULONG ProcessorsCount;
146
147 //
148 // Check if NMI broadcasting is initialized
149 //
151 {
152 return FALSE;
153 }
154
155 ProcessorsCount = KeQueryActiveProcessorCount(0);
156
157 //
158 // Indicate that we're waiting for NMI
159 //
160 for (SIZE_T i = 0; i < ProcessorsCount; i++)
161 {
162 if (i != VCpu->CoreId)
163 {
164 SpinlockInterlockedCompareExchange((volatile LONG *)&g_GuestState[i].NmiBroadcastingState.NmiBroadcastAction,
165 VmxBroadcastAction,
167 }
168 }
169
170 //
171 // Broadcast NMI through APIC (xAPIC or x2APIC)
172 //
174
175 return TRUE;
176}
VOID ApicTriggerGenericNmi()
Trigger NMI on X2APIC or APIC based on Current system.
Definition Apic.c:283
VOID SpinlockInterlockedCompareExchange(LONG volatile *Destination, LONG Exchange, LONG Comperand)
Interlocked spinlock that tries to change the value and makes sure that it changed the target value.
Definition Spinlock.c:90
long LONG
Definition BasicTypes.h:28
#define FALSE
Definition BasicTypes.h:113
@ NMI_BROADCAST_ACTION_NONE
Definition State.h:51
UINT32 CoreId
Definition State.h:328

◆ VmxBroadcastNmiHandler()

BOOLEAN VmxBroadcastNmiHandler ( VIRTUAL_MACHINE_STATE * VCpu,
BOOLEAN IsOnVmxNmiHandler )

Handle broadcast NMIs in vmx-root mode.

Parameters
VCpuThe virtual processor's state
IsOnVmxNmiHandler
Returns
BOOLEAN Shows whether it's handled by this routine or not
188{
189 NMI_BROADCAST_ACTION_TYPE BroadcastAction;
190 BOOLEAN IsHandled = FALSE;
191
192 //
193 // Check if NMI relates to us or not
194 // Set NMI broadcasting action to none (clear the action)
195 //
196 BroadcastAction = InterlockedExchange((volatile LONG *)&VCpu->NmiBroadcastingState.NmiBroadcastAction, NMI_BROADCAST_ACTION_NONE);
197
198 if (BroadcastAction == NMI_BROADCAST_ACTION_NONE)
199 {
200 IsHandled = FALSE;
201 goto ReturnIsHandled;
202 }
203
204 //
205 // *** It's relating to us ***
206 //
207
208 switch (BroadcastAction)
209 {
211
212 //
213 // Use for stress testing of the broadcasting mechanism
214 //
215 IsHandled = TRUE;
216
217 break;
218
220
221 //
222 // Handle NMI of halt the other cores
223 //
224 VmmCallbackNmiBroadcastRequestHandler(VCpu->CoreId, IsOnVmxNmiHandler);
225 IsHandled = TRUE;
226
227 break;
228
230
231 //
232 // Invalidate EPT cache (single-context)
233 //
235
236 IsHandled = TRUE;
237
238 break;
239
241
242 //
243 // Invalidate EPT cache (all contexts)
244 //
246 IsHandled = TRUE;
247
248 break;
249
250 default:
251
252 IsHandled = FALSE;
253 LogError("Err, invalid NMI reason received");
254
255 break;
256 }
257
258ReturnIsHandled:
259 return IsHandled;
260}
VOID VmmCallbackNmiBroadcastRequestHandler(UINT32 CoreId, BOOLEAN IsOnVmxNmiHandler)
routine callback to handle NMI requests
Definition Callback.c:98
UCHAR EptInveptAllContexts()
Invalidates all contexts in EPT cache table.
Definition Invept.c:54
UCHAR EptInveptSingleContext(_In_ UINT64 EptPointer)
Invalidates a single context in ept cache table.
Definition Invept.c:40
UCHAR BOOLEAN
Definition BasicTypes.h:35
#define LogError(format,...)
Log in the case of error.
Definition HyperDbgHyperLogIntrinsics.h:113
enum _NMI_BROADCAST_ACTION_TYPE NMI_BROADCAST_ACTION_TYPE
Types of actions for NMI broadcasting.
@ NMI_BROADCAST_ACTION_REQUEST
Definition State.h:53
@ NMI_BROADCAST_ACTION_INVALIDATE_EPT_CACHE_SINGLE_CONTEXT
Definition State.h:54
@ NMI_BROADCAST_ACTION_TEST
Definition State.h:52
@ NMI_BROADCAST_ACTION_INVALIDATE_EPT_CACHE_ALL_CONTEXTS
Definition State.h:55
volatile NMI_BROADCAST_ACTION_TYPE NmiBroadcastAction
Definition State.h:302
NMI_BROADCASTING_STATE NmiBroadcastingState
Definition State.h:351
EPT_POINTER EptPointer
Definition State.h:363

◆ VmxBroadcastUninitialize()

VOID VmxBroadcastUninitialize ( )

Uninitialize the VMX Broadcast mechanism.

Returns
VOID
58{
59 //
60 // *** Uninitialize NMI broadcasting mechanism ***
61 //
63
64#if USE_DEFAULT_OS_IDT_AS_HOST_IDT == TRUE
65
66 //
67 // De-register NMI handler
68 //
69 KeDeregisterNmiCallback(g_NmiHandlerForKeDeregisterNmiCallback);
70
71#endif // USE_DEFAULT_OS_IDT_AS_HOST_IDT == TRUE
72
73 //
74 // Broadcast on all core to cause not to exit for NMIs
75 //
77
78 //
79 // Uinitialize APIC related function
80 //
82}
VOID ApicUninitialize()
Uninitialize APIC.
Definition Apic.c:429
VOID BroadcastDisableNmiExitingAllCores()
routines to set vm-exit on all NMIs on all cores
Definition Broadcast.c:105