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

Broadcast mechanism in vmx-root. More...

#include "pch.h"

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

Broadcast mechanism in vmx-root.

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}
#define TRUE
Definition BasicTypes.h:55
unsigned long ULONG
Definition BasicTypes.h:37
VIRTUAL_MACHINE_STATE * g_GuestState
Save the state and variables related to virtualization on each to logical core.
Definition GlobalVariables.h:38
BOOLEAN VmxBroadcastNmiHandler(VIRTUAL_MACHINE_STATE *VCpu, BOOLEAN IsOnVmxNmiHandler)
Handle broadcast NMIs in vmx-root mode.
Definition VmxBroadcast.c:187
NTKERNELAPI _In_opt_ PVOID Context
Definition Dpc.h:25
The status of each core after and before VMX.
Definition State.h:290

◆ 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:65
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:94
BOOLEAN g_NmiBroadcastingInitialized
check for broadcasting NMI mechanism support and its initialization
Definition GlobalVariables.h:88
BOOLEAN VmxBroadcastHandleNmiCallback(PVOID Context, BOOLEAN Handled)
Handles NMIs in kernel-mode.
Definition VmxBroadcast.c:92

◆ 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:47
#define FALSE
Definition BasicTypes.h:54
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:88
@ NMI_BROADCAST_ACTION_NONE
Definition State.h:50
UINT32 CoreId
Definition State.h:306

◆ 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}
UCHAR BOOLEAN
Definition BasicTypes.h:39
VOID VmmCallbackNmiBroadcastRequestHandler(UINT32 CoreId, BOOLEAN IsOnVmxNmiHandler)
routine callback to handle NMI requests
Definition Callback.c:247
#define LogError(format,...)
Log in the case of error.
Definition HyperDbgHyperLogIntrinsics.h:113
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
enum _NMI_BROADCAST_ACTION_TYPE NMI_BROADCAST_ACTION_TYPE
Types of actions for NMI broadcasting.
@ NMI_BROADCAST_ACTION_REQUEST
Definition State.h:52
@ NMI_BROADCAST_ACTION_INVALIDATE_EPT_CACHE_SINGLE_CONTEXT
Definition State.h:53
@ NMI_BROADCAST_ACTION_TEST
Definition State.h:51
@ NMI_BROADCAST_ACTION_INVALIDATE_EPT_CACHE_ALL_CONTEXTS
Definition State.h:54
volatile NMI_BROADCAST_ACTION_TYPE NmiBroadcastAction
Definition State.h:281
NMI_BROADCASTING_STATE NmiBroadcastingState
Definition State.h:329
EPT_POINTER EptPointer
Definition State.h:341

◆ 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:98
VOID BroadcastDisableNmiExitingAllCores()
routines to set vm-exit on all NMIs on all cores
Definition Broadcast.c:105