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

Implement allocations for VMX Regions (VMXON Region, VMCS, MSR Bitmap and etc.). More...

#include "pch.h"

Functions

_Use_decl_annotations_ BOOLEAN VmxAllocateVmxonRegion (VIRTUAL_MACHINE_STATE *VCpu)
 Allocates Vmxon region and set the Revision ID based on IA32_VMX_BASIC_MSR.
_Use_decl_annotations_ BOOLEAN VmxAllocateVmcsRegion (VIRTUAL_MACHINE_STATE *VCpu)
 Allocate Vmcs region and set the Revision ID based on IA32_VMX_BASIC_MSR.
BOOLEAN VmxAllocateVmmStack (_Inout_ VIRTUAL_MACHINE_STATE *VCpu)
 Allocate VMM Stack.
BOOLEAN VmxAllocateMsrBitmap (_Inout_ VIRTUAL_MACHINE_STATE *VCpu)
 Allocate a buffer for Msr Bitmap.
BOOLEAN VmxAllocateIoBitmaps (_Inout_ VIRTUAL_MACHINE_STATE *VCpu)
 Allocate a buffer for I/O Bitmap.
UINT64 * VmxAllocateInvalidMsrBimap ()
 Allocates a buffer and tests for the MSRs that cause #GP.
BOOLEAN VmxAllocateHostIdt (_Inout_ VIRTUAL_MACHINE_STATE *VCpu)
 Allocate a buffer for host IDT.
BOOLEAN VmxAllocateHostGdt (_Inout_ VIRTUAL_MACHINE_STATE *VCpu)
 Allocate a buffer for host GDT.
BOOLEAN VmxAllocateHostTss (_Inout_ VIRTUAL_MACHINE_STATE *VCpu)
 Allocate a buffer for host TSS.
BOOLEAN VmxAllocateHostInterruptStack (_Inout_ VIRTUAL_MACHINE_STATE *VCpu)
 Allocate a buffer for host interrupt stack.

Detailed Description

Implement allocations for VMX Regions (VMXON Region, VMCS, MSR Bitmap and etc.).

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

Function Documentation

◆ VmxAllocateHostGdt()

BOOLEAN VmxAllocateHostGdt ( _Inout_ VIRTUAL_MACHINE_STATE * VCpu)

Allocate a buffer for host GDT.

Parameters
VCpu
Returns
BOOLEAN Returns true if allocation was successful otherwise returns false
334{
335 UINT32 GdtSize = HOST_GDT_DESCRIPTOR_COUNT * sizeof(SEGMENT_DESCRIPTOR_64);
336
337 //
338 // Make sure the memory is aligned
339 //
340 if (PAGE_SIZE > GdtSize)
341 {
342 GdtSize = PAGE_SIZE;
343 }
344
345 //
346 // Allocate aligned memory for host GDT
347 //
348 VCpu->HostGdt = (UINT64)PlatformMemAllocateZeroedNonPagedPool(GdtSize); // should be aligned
349
350 if (VCpu->HostGdt == NULL64_ZERO)
351 {
352 LogError("Err, insufficient memory in allocating host GDT");
353 return FALSE;
354 }
355
356 LogDebugInfo("Host GDT virtual address : 0x%llx", VCpu->HostGdt);
357
358 return TRUE;
359}
PVOID PlatformMemAllocateZeroedNonPagedPool(SIZE_T NumberOfBytes)
Allocates zeroed non-paged pool memory.
Definition PlatformMem.c:248
#define HOST_GDT_DESCRIPTOR_COUNT
Maximum number of entries in GDT.
Definition Segmentation.h:29
#define NULL64_ZERO
Definition BasicTypes.h:111
#define TRUE
Definition BasicTypes.h:114
#define FALSE
Definition BasicTypes.h:113
unsigned int UINT32
Definition BasicTypes.h:54
#define LogDebugInfo(format,...)
Log, initialize boot information and debug information.
Definition HyperDbgHyperLogIntrinsics.h:155
#define LogError(format,...)
Log in the case of error.
Definition HyperDbgHyperLogIntrinsics.h:113
#define PAGE_SIZE
Size of each page (4096 bytes).
Definition common.h:80

◆ VmxAllocateHostIdt()

BOOLEAN VmxAllocateHostIdt ( _Inout_ VIRTUAL_MACHINE_STATE * VCpu)

Allocate a buffer for host IDT.

Parameters
VCpu
Returns
BOOLEAN Returns true if allocation was successful otherwise returns false
299{
300 UINT32 IdtSize = HOST_IDT_DESCRIPTOR_COUNT * sizeof(SEGMENT_DESCRIPTOR_INTERRUPT_GATE_64);
301
302 //
303 // Make sure the memory is aligned
304 //
305 if (PAGE_SIZE > IdtSize)
306 {
307 IdtSize = PAGE_SIZE;
308 }
309
310 //
311 // Allocate aligned memory for host IDT
312 //
313 VCpu->HostIdt = (UINT64)PlatformMemAllocateZeroedNonPagedPool(IdtSize); // should be aligned
314
315 if (VCpu->HostIdt == NULL64_ZERO)
316 {
317 LogError("Err, insufficient memory in allocating host IDT");
318 return FALSE;
319 }
320
321 LogDebugInfo("Host IDT virtual address : 0x%llx", VCpu->HostIdt);
322
323 return TRUE;
324}
#define HOST_IDT_DESCRIPTOR_COUNT
Maximum number of interrupt entries in IDT.
Definition IdtEmulation.h:29

◆ VmxAllocateHostInterruptStack()

BOOLEAN VmxAllocateHostInterruptStack ( _Inout_ VIRTUAL_MACHINE_STATE * VCpu)

Allocate a buffer for host interrupt stack.

Parameters
VCpu
Returns
BOOLEAN Returns true if allocation was successful otherwise returns false
396{
397 VCpu->HostInterruptStack = (UINT64)PlatformMemAllocateZeroedNonPagedPool(HOST_INTERRUPT_STACK_SIZE);
398
399 if (VCpu->HostInterruptStack == NULL64_ZERO)
400 {
401 LogError("Err, insufficient memory in allocating host interrupt stack");
402 return FALSE;
403 }
404
405 LogDebugInfo("Host interrupt stack virtual address : 0x%llx", VCpu->HostInterruptStack);
406
407 return TRUE;
408}
#define HOST_INTERRUPT_STACK_SIZE
Size of host interrupt stack.
Definition Segmentation.h:35

◆ VmxAllocateHostTss()

BOOLEAN VmxAllocateHostTss ( _Inout_ VIRTUAL_MACHINE_STATE * VCpu)

Allocate a buffer for host TSS.

Parameters
VCpu
Returns
BOOLEAN Returns true if allocation was successful otherwise returns false
369{
370 UINT32 TssSize = PAGE_SIZE; // Make sure the memory is aligned
371
372 //
373 // Allocate aligned memory for host TSS
374 //
375 VCpu->HostTss = (UINT64)PlatformMemAllocateZeroedNonPagedPool(TssSize); // should be aligned
376
377 if (VCpu->HostTss == NULL64_ZERO)
378 {
379 LogError("Err, insufficient memory in allocating host TSS");
380 return FALSE;
381 }
382
383 LogDebugInfo("Host TSS virtual address : 0x%llx", VCpu->HostTss);
384
385 return TRUE;
386}

◆ VmxAllocateInvalidMsrBimap()

UINT64 * VmxAllocateInvalidMsrBimap ( )

Allocates a buffer and tests for the MSRs that cause #GP.

Returns
UINT64 Allocated buffer for MSR Bitmap
266{
267 UINT64 * InvalidMsrBitmap;
268
269 InvalidMsrBitmap = PlatformMemAllocateZeroedNonPagedPool(0x1000 / 0x8);
270
271 if (InvalidMsrBitmap == NULL)
272 {
273 return NULL;
274 }
275
276 for (UINT32 i = 0; i < 0x1000; ++i)
277 {
278 __try
279 {
280 CpuReadMsr(i);
281 }
282 __except (EXCEPTION_EXECUTE_HANDLER)
283 {
284 SetBit(i, (ULONG *)InvalidMsrBitmap);
285 }
286 }
287
288 return InvalidMsrBitmap;
289}
VOID SetBit(INT BitNumber, ULONG *Addr)
set the bit
Definition Bitwise.c:46
UINT64 CpuReadMsr(ULONG MsrAddress)
Read an MSR.
Definition PlatformIntrinsics.c:213
unsigned long ULONG
Definition BasicTypes.h:31
NULL()
Definition test-case-generator.py:530

◆ VmxAllocateIoBitmaps()

BOOLEAN VmxAllocateIoBitmaps ( _Inout_ VIRTUAL_MACHINE_STATE * VCpu)

Allocate a buffer for I/O Bitmap.

Parameters
VCpu
Returns
BOOLEAN Returns true if allocation was successful otherwise returns false
223{
224 //
225 // Allocate memory for I/O Bitmap (A)
226 //
227 VCpu->IoBitmapVirtualAddressA = (UINT64)PlatformMemAllocateZeroedNonPagedPool(PAGE_SIZE); // should be aligned
228
229 if (VCpu->IoBitmapVirtualAddressA == NULL64_ZERO)
230 {
231 LogError("Err, insufficient memory in allocating I/O Bitmaps A");
232 return FALSE;
233 }
234
235 VCpu->IoBitmapPhysicalAddressA = VirtualAddressToPhysicalAddress((PVOID)VCpu->IoBitmapVirtualAddressA);
236
237 LogDebugInfo("I/O Bitmap A Virtual Address : 0x%llx", VCpu->IoBitmapVirtualAddressA);
238 LogDebugInfo("I/O Bitmap A Physical Address : 0x%llx", VCpu->IoBitmapPhysicalAddressA);
239
240 //
241 // Allocate memory for I/O Bitmap (B)
242 //
243 VCpu->IoBitmapVirtualAddressB = (UINT64)PlatformMemAllocateZeroedNonPagedPool(PAGE_SIZE); // should be aligned
244
245 if (VCpu->IoBitmapVirtualAddressB == NULL64_ZERO)
246 {
247 LogError("Err, insufficient memory in allocating I/O Bitmaps B");
248 return FALSE;
249 }
250
251 VCpu->IoBitmapPhysicalAddressB = VirtualAddressToPhysicalAddress((PVOID)VCpu->IoBitmapVirtualAddressB);
252
253 LogDebugInfo("I/O Bitmap B virtual address : 0x%llx", VCpu->IoBitmapVirtualAddressB);
254 LogDebugInfo("I/O Bitmap B physical address : 0x%llx", VCpu->IoBitmapPhysicalAddressB);
255
256 return TRUE;
257}
void * PVOID
Definition BasicTypes.h:56
IMPORT_EXPORT_VMM UINT64 VirtualAddressToPhysicalAddress(_In_ PVOID VirtualAddress)
Converts Virtual Address to Physical Address.
Definition Conversion.c:154

◆ VmxAllocateMsrBitmap()

BOOLEAN VmxAllocateMsrBitmap ( _Inout_ VIRTUAL_MACHINE_STATE * VCpu)

Allocate a buffer for Msr Bitmap.

Parameters
VCpuThe virtual processor's state
Returns
BOOLEAN Returns true if allocation was successful otherwise returns false
194{
195 //
196 // Allocate memory for MSR Bitmap
197 // Should be aligned
198 //
199 VCpu->MsrBitmapVirtualAddress = (UINT64)PlatformMemAllocateZeroedNonPagedPool(PAGE_SIZE);
200
201 if (VCpu->MsrBitmapVirtualAddress == NULL64_ZERO)
202 {
203 LogError("Err, insufficient memory in allocating MSR Bitmaps");
204 return FALSE;
205 }
206
207 VCpu->MsrBitmapPhysicalAddress = VirtualAddressToPhysicalAddress((PVOID)VCpu->MsrBitmapVirtualAddress);
208
209 LogDebugInfo("MSR Bitmap virtual address : 0x%llx", VCpu->MsrBitmapVirtualAddress);
210 LogDebugInfo("MSR Bitmap physical address : 0x%llx", VCpu->MsrBitmapPhysicalAddress);
211
212 return TRUE;
213}

◆ VmxAllocateVmcsRegion()

_Use_decl_annotations_ BOOLEAN VmxAllocateVmcsRegion ( VIRTUAL_MACHINE_STATE * VCpu)

Allocate Vmcs region and set the Revision ID based on IA32_VMX_BASIC_MSR.

Parameters
CurrentGuestState
Returns
BOOLEAN Returns true if allocation was successful and vmptrld executed without error otherwise returns false
105{
106 IA32_VMX_BASIC_REGISTER VmxBasicMsr = {0};
107 SIZE_T VmcsSize;
108 UINT8 * VmcsRegion;
109 UINT64 VmcsPhysicalAddr;
110 UINT64 AlignedVmcsRegion;
111 UINT64 AlignedVmcsRegionPhysicalAddr;
112
113#ifdef HYPERDBG_ENV_WINDOWS
114 //
115 // at IRQL > DISPATCH_LEVEL memory allocation routines don't work
116 //
117 if (KeGetCurrentIrql() > DISPATCH_LEVEL)
118 KeRaiseIrqlToDpcLevel();
119#endif // HYPERDBG_ENV_WINDOWS
120
121 //
122 // Allocating a 4-KByte Contiguous Memory region
123 //
124 VmcsSize = 2 * VMCS_SIZE;
126 if (VmcsRegion == NULL)
127 {
128 LogError("Err, couldn't allocate Buffer for VMCS region");
129 return FALSE;
130 }
131
132 VmcsPhysicalAddr = VirtualAddressToPhysicalAddress(VmcsRegion);
133
134 AlignedVmcsRegion = (UINT64)((ULONG_PTR)(VmcsRegion + ALIGNMENT_PAGE_SIZE - 1) & ~(ALIGNMENT_PAGE_SIZE - 1));
135 LogDebugInfo("VMCS region address : %llx", AlignedVmcsRegion);
136
137 AlignedVmcsRegionPhysicalAddr = (UINT64)((ULONG_PTR)(VmcsPhysicalAddr + ALIGNMENT_PAGE_SIZE - 1) & ~(ALIGNMENT_PAGE_SIZE - 1));
138 LogDebugInfo("VMCS region physical address : %llx", AlignedVmcsRegionPhysicalAddr);
139
140 //
141 // get IA32_VMX_BASIC_MSR RevisionId
142 //
143 VmxBasicMsr.AsUInt = CpuReadMsr(IA32_VMX_BASIC);
144 LogDebugInfo("Revision Identifier (IA32_VMX_BASIC - MSR 0x480) : 0x%x", VmxBasicMsr.VmcsRevisionId);
145
146 //
147 // Changing Revision Identifier
148 //
149 *(UINT64 *)AlignedVmcsRegion = VmxBasicMsr.VmcsRevisionId;
150
151 VCpu->VmcsRegionPhysicalAddress = AlignedVmcsRegionPhysicalAddr;
152 //
153 // We save the allocated buffer (not the aligned buffer)
154 // because we want to free it in vmx termination
155 //
156 VCpu->VmcsRegionVirtualAddress = (UINT64)VmcsRegion;
157
158 return TRUE;
159}
PVOID PlatformMemAllocateContiguousZeroedMemory(SIZE_T NumberOfBytes)
... Backward Compatibility / Specific APIs ...
Definition PlatformMem.c:184
#define VMCS_SIZE
VMCS Region Size.
Definition Vmx.h:22
unsigned char UINT8
Definition BasicTypes.h:52
#define DISPATCH_LEVEL
Definition Constants.h:610
#define ALIGNMENT_PAGE_SIZE
Alignment Size.
Definition Common.h:24
UINT64 VmcsRegionPhysicalAddress
Definition State.h:334
UINT64 VmcsRegionVirtualAddress
Definition State.h:335

◆ VmxAllocateVmmStack()

BOOLEAN VmxAllocateVmmStack ( _Inout_ VIRTUAL_MACHINE_STATE * VCpu)

Allocate VMM Stack.

Parameters
VCpuThe virtual processor's state
Returns
BOOLEAN Returns true if allocation was successful otherwise returns false
169{
170 //
171 // Allocate stack for the VM Exit Handler
172 //
174
175 if (VCpu->VmmStack == NULL64_ZERO)
176 {
177 LogError("Err, insufficient memory in allocating vmm stack");
178 return FALSE;
179 }
180
181 LogDebugInfo("VMM Stack for logical processor : 0x%llx", VCpu->VmmStack);
182
183 return TRUE;
184}
#define VMM_STACK_SIZE
Stack Size.
Definition Vmx.h:65

◆ VmxAllocateVmxonRegion()

_Use_decl_annotations_ BOOLEAN VmxAllocateVmxonRegion ( VIRTUAL_MACHINE_STATE * VCpu)

Allocates Vmxon region and set the Revision ID based on IA32_VMX_BASIC_MSR.

Parameters
CurrentGuestState
Returns
BOOLEAN Returns true if allocation was successful and vmxon executed without error otherwise returns false
24{
25 IA32_VMX_BASIC_REGISTER VmxBasicMsr = {0};
26 SIZE_T VmxonSize;
27 UINT8 VmxonStatus;
28 UINT8 * VmxonRegion;
29 UINT64 VmxonRegionPhysicalAddr;
30 UINT64 AlignedVmxonRegion;
31 UINT64 AlignedVmxonRegionPhysicalAddr;
32
33#ifdef HYPERDBG_ENV_WINDOWS
34 //
35 // at IRQL > DISPATCH_LEVEL memory allocation routines don't work
36 //
37 if (KeGetCurrentIrql() > DISPATCH_LEVEL)
38 KeRaiseIrqlToDpcLevel();
39#endif // HYPERDBG_ENV_WINDOWS
40
41 //
42 // Allocating a 4-KByte Contiguous Memory region
43 //
44 VmxonSize = 2 * VMXON_SIZE;
46 if (VmxonRegion == NULL)
47 {
48 LogError("Err, couldn't allocate buffer for VMXON region");
49 return FALSE;
50 }
51
52 VmxonRegionPhysicalAddr = VirtualAddressToPhysicalAddress(VmxonRegion);
53
54 AlignedVmxonRegion = (UINT64)((ULONG_PTR)(VmxonRegion + ALIGNMENT_PAGE_SIZE - 1) & ~(ALIGNMENT_PAGE_SIZE - 1));
55 LogDebugInfo("VMXON Region Address : %llx", AlignedVmxonRegion);
56
57 //
58 // 4 kb >= buffers are aligned, just a double check to ensure if it's aligned
59 //
60 AlignedVmxonRegionPhysicalAddr = (UINT64)((ULONG_PTR)(VmxonRegionPhysicalAddr + ALIGNMENT_PAGE_SIZE - 1) & ~(ALIGNMENT_PAGE_SIZE - 1));
61 LogDebugInfo("VMXON Region Physical Address : %llx", AlignedVmxonRegionPhysicalAddr);
62
63 //
64 // get IA32_VMX_BASIC_MSR RevisionId
65 //
66 VmxBasicMsr.AsUInt = CpuReadMsr(IA32_VMX_BASIC);
67 LogDebugInfo("Revision Identifier (IA32_VMX_BASIC - MSR 0x480) : 0x%x", VmxBasicMsr.VmcsRevisionId);
68
69 //
70 // Changing Revision Identifier
71 //
72 *(UINT64 *)AlignedVmxonRegion = VmxBasicMsr.VmcsRevisionId;
73
74 //
75 // Execute Vmxon instruction
76 //
77 VmxonStatus = VmxVmxon(&AlignedVmxonRegionPhysicalAddr);
78
79 if (VmxonStatus)
80 {
81 LogError("Err, executing vmxon instruction failed with status : %d", VmxonStatus);
82 return FALSE;
83 }
84
85 VCpu->VmxonRegionPhysicalAddress = AlignedVmxonRegionPhysicalAddr;
86
87 //
88 // We save the allocated buffer (not the aligned buffer) because we want to free it in vmx termination
89 //
90 VCpu->VmxonRegionVirtualAddress = (UINT64)VmxonRegion;
91
92 return TRUE;
93}
UCHAR VmxVmxon(UINT64 *VmxonRegionPhysicalAddress)
VMX VMXON instruction.
Definition PlatformIntrinsicsVmx.c:447
#define VMXON_SIZE
VMXON Region Size.
Definition Vmx.h:28
UINT64 VmxonRegionVirtualAddress
Definition State.h:333
UINT64 VmxonRegionPhysicalAddress
Definition State.h:332