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

VMX Instruction and operation headers. More...

Go to the source code of this file.

Classes

union  _HYPERCALL_INPUT_VALUE
 Hypercalls for Hyper-V. More...

Macros

#define VMCS_SIZE   4096
 VMCS Region Size.
#define VMXON_SIZE   4096
 VMXON Region Size.
#define HYPERV_CPUID_VENDOR_AND_MAX_FUNCTIONS   0x40000000
 CPUID RCX(s) - Based on Hyper-V.
#define HYPERV_CPUID_INTERFACE   0x40000001
#define HYPERV_CPUID_VERSION   0x40000002
#define HYPERV_CPUID_FEATURES   0x40000003
#define HYPERV_CPUID_ENLIGHTMENT_INFO   0x40000004
#define HYPERV_CPUID_IMPLEMENT_LIMITS   0x40000005
#define HYPERV_HYPERVISOR_PRESENT_BIT   0x80000000
#define HYPERV_CPUID_MIN   0x40000005
#define HYPERV_CPUID_MAX   0x4000ffff
#define GUEST_INTR_STATE_STI   0x00000001
 GUEST_INTERRUPTIBILITY_INFO flags.
#define GUEST_INTR_STATE_MOV_SS   0x00000002
#define GUEST_INTR_STATE_SMI   0x00000004
#define GUEST_INTR_STATE_NMI   0x00000008
#define GUEST_INTR_STATE_ENCLAVE_INTR   0x00000010
#define SHADOW_INT_MOV_SS   0x01
 Interrupt shadow states.
#define SHADOW_INT_STI   0x02
#define VMM_STACK_SIZE   0x8000
 Stack Size.
#define IS_VALID_DEBUG_REGISTER(DebugRegister)
#define HYPERV_CPUID_VENDOR_MICROSOFT_EBX   0x7263694d
 Hyper-V CPUID leaves.
#define HYPERV_CPUID_VENDOR_MICROSOFT_ECX   0x666f736f
#define HYPERV_CPUID_VENDOR_MICROSOFT_EDX   0x76482074
#define VMCS_GUEST_DEBUGCTL_HIGH   0x00002803
#define VIRTUAL_PROCESSOR_ID   0x00000000

Typedefs

typedef union _HYPERCALL_INPUT_VALUE HYPERCALL_INPUT_VALUE
 Hypercalls for Hyper-V.
typedef union _HYPERCALL_INPUT_VALUEPHYPERCALL_INPUT_VALUE
typedef enum _MOV_TO_DEBUG_REG MOV_TO_DEBUG_REG
 MOV to debug registers states.

Enumerations

enum  HYPERCALL_CODE {
  HvSwitchVirtualAddressSpace = 0x0001 , HvFlushVirtualAddressSpace = 0x0002 , HvFlushVirtualAddressList = 0x0003 , HvGetLogicalProcessorRunTime = 0x0004 ,
  HvCallNotifyLongSpinWait = 0x0008 , HvCallParkedVirtualProcessors = 0x0009 , HvCallSyntheticClusterIpi = 0x000B , HvCallModifyVtlProtectionMask = 0x000C ,
  HvCallEnablePartitionVtl = 0x000D , HvCallDisablePartitionVtl = 0x000E , HvCallEnableVpVtl = 0x000F , HvCallDisableVpVtl = 0x0010 ,
  HvCallVtlCall = 0x0011 , HvCallVtlReturn = 0x0012 , HvCallFlushVirtualAddressSpaceEx = 0x0013 , HvCallFlushVirtualAddressListEx = 0x0014 ,
  HvCallSendSyntheticClusterIpiEx = 0x0015 , HvCreatePartition = 0x0040 , HvInitializePartition = 0x0041 , HvFinalizePartition = 0x0042 ,
  HvDeletePartition = 0x0043 , HvGetPartitionProperty = 0x0044 , HvSetPartitionProperty = 0x0045 , HvGetPartitionId = 0x0046 ,
  HvGetNextChildPartition = 0x0047 , HvDepositMemory = 0x0048 , HvWithdrawMemory = 0x0049 , HvGetMemoryBalance = 0x004A ,
  HvMapGpaPages = 0x004B , HvUnmapGpaPages = 0x004C , HvInstallIntercept = 0x004D , HvCreateVp = 0x004E ,
  HvDeleteVp = 0x004F , HvGetVpRegisters = 0x0050 , HvSetVpRegisters = 0x0051 , HvTranslateVirtualAddress = 0x0052 ,
  HvReadGpa = 0x0053 , HvWriteGpa = 0x0054 , HvClearVirtualInterrupt = 0x0056 , HvDeletePort = 0x0058 ,
  HvConnectPort = 0x0059 , HvGetPortProperty = 0x005A , HvDisconnectPort = 0x005B , HvPostMessage = 0x005C ,
  HvSignalEvent = 0x005D , HvSavePartitionState = 0x005E , HvRestorePartitionState = 0x005F , HvInitializeEventLogBufferGroup = 0x0060 ,
  HvFinalizeEventLogBufferGroup = 0x0061 , HvCreateEventLogBuffer = 0x0062 , HvDeleteEventLogBuffer = 0x0063 , HvMapEventLogBuffer = 0x0064 ,
  HvUnmapEventLogBuffer = 0x0065 , HvSetEventLogGroupSources = 0x0066 , HvReleaseEventLogBuffer = 0x0067 , HvFlushEventLogBuffer = 0x0068 ,
  HvPostDebugData = 0x0069 , HvRetrieveDebugData = 0x006A , HvResetDebugSession = 0x006B , HvMapStatsPage = 0x006C ,
  HvUnmapStatsPage = 0x006D , HvCallMapSparseGpaPages = 0x006E , HvCallSetSystemProperty = 0x006F , HvCallSetPortProperty = 0x0070 ,
  HvCallAddLogicalProcessor = 0x0076 , HvCallRemoveLogicalProcessor = 0x0077 , HvCallQueryNumaDistance = 0x0078 , HvCallSetLogicalProcessorProperty = 0x0079 ,
  HvCallGetLogicalProcessorProperty = 0x007A , HvCallGetSystemProperty = 0x007B , HvCallMapDeviceInterrupt = 0x007C , HvCallUnmapDeviceInterrupt = 0x007D ,
  HvCallRetargetDeviceInterrupt = 0x007E , HvCallMapDevicePages = 0x0080 , HvCallUnmapDevicePages = 0x0081 , HvCallAttachDevice = 0x0082 ,
  HvCallDetachDevice = 0x0083 , HvCallNotifyStandbyTransition = 0x0084 , HvCallPrepareForSleep = 0x0085 , HvCallPrepareForHibernate = 0x0086 ,
  HvCallNotifyPartitionEvent = 0x0087 , HvCallGetLogicalProcessorRegisters = 0x0088 , HvCallSetLogicalProcessorRegisters = 0x0089 , HvCallQueryAssotiatedLpsforMca = 0x008A ,
  HvCallNotifyRingEmpty = 0x008B , HvCallInjectSyntheticMachineCheck = 0x008C , HvCallScrubPartition = 0x008D , HvCallCollectLivedump = 0x008E ,
  HvCallDisableHypervisor = 0x008F , HvCallModifySparseGpaPages = 0x0090 , HvCallRegisterInterceptResult = 0x0091 , HvCallUnregisterInterceptResult = 0x0092 ,
  HvCallAssertVirtualInterrupt = 0x0094 , HvCallCreatePort = 0x0095 , HvCallConnectPort = 0x0096 , HvCallGetSpaPageList = 0x0097 ,
  HvCallStartVirtualProcessor = 0x009A , HvCallGetVpIndexFromApicId = 0x009A , HvCallFlushGuestPhysicalAddressSpace = 0x00AF , HvCallFlushGuestPhysicalAddressList = 0x00B0
}
 Hyper-V Hypercalls. More...
enum  _MOV_TO_DEBUG_REG { AccessToDebugRegister = 0 , AccessFromDebugRegister = 1 }
 MOV to debug registers states. More...

Functions

BOOLEAN VmxIsTopLevelHypervisorHyperV ()
 checks if the current top level hypervisor is Hyper-V
BOOLEAN VmxCheckVmxSupport ()
 Check whether VMX Feature is supported or not.
BOOLEAN VmxInitialize ()
 Initialize the VMX operation.
BOOLEAN VmxPerformVirtualizationOnAllCores ()
 Initialize essential VMX Operation tasks.
BOOLEAN VmxTerminate ()
 Broadcast to terminate VMX on all logical cores.
BOOLEAN VmxPerformVirtualizationOnSpecificCore ()
 Allocates Vmx regions for all logical cores (Vmxon region and Vmcs region).
BOOLEAN VmxLoadVmcs (_In_ VIRTUAL_MACHINE_STATE *VCpu)
BOOLEAN VmxClearVmcsState (_In_ VIRTUAL_MACHINE_STATE *VCpu)
BOOLEAN VmxCheckIsOnVmxRoot ()
 It can deterministically check whether the caller is on vmx-root mode or not.
BOOLEAN VmxVirtualizeCurrentSystem (PVOID GuestStack)
 Initialize VMX Operation.
BOOLEAN VmxSetupVmcs (_In_ VIRTUAL_MACHINE_STATE *VCpu, _In_ PVOID GuestStack)
VOID VmxPerformVmptrst ()
 Implementation of VMPTRST instruction.
VOID VmxPerformVmresume ()
 Resume VM using the VMRESUME instruction.
VOID VmxPerformVmxoff (VIRTUAL_MACHINE_STATE *VCpu)
 Prepare and execute Vmxoff instruction.
VOID VmxPerformTermination ()
 Terminate Vmx on all logical cores.
VOID VmxHandleXsetbv (VIRTUAL_MACHINE_STATE *VCpu)
 Handling XSETBV Instruction vm-exits.
VOID VmxHandleVmxPreemptionTimerVmexit (VIRTUAL_MACHINE_STATE *VCpu)
 Handling VMX Preemption Timer vm-exits.
VOID VmxHandleTripleFaults (VIRTUAL_MACHINE_STATE *VCpu)
 Handling triple fault VM-exits.
VOID VmxFixCr4AndCr0Bits ()
 Fix values for cr0 and cr4 bits.
VOID VmxCompatibleMicroSleep (UINT64 ns)
 VMX-root compatible micro sleep.
UINT64 VmxReturnStackPointerForVmxoff ()
 Get the RIP of guest (VMCS_GUEST_RIP) in the case of return from VMXOFF.
UINT64 VmxReturnInstructionPointerForVmxoff ()
 Get the RIP of guest (VMCS_GUEST_RIP) in the case of return from VMXOFF.
BOOLEAN VmxGetCurrentExecutionMode ()
 Check current execution mode (vmx-root and non-root).
BOOLEAN VmxGetCurrentLaunchState ()
 Check if the VMX is launched or not.
UINT32 VmxCompatibleStrlen (const CHAR *S)
 implementation of vmx-root mode compatible strlen
UINT32 VmxCompatibleWcslen (const WCHAR *S)
 implementation of vmx-root mode compatible wcslen
INT32 VmxCompatibleStrcmp (const CHAR *Address1, const CHAR *Address2, SIZE_T Num, BOOLEAN IsStrncmp)
 implementation of vmx-root mode compatible strcmp and strncmp
INT32 VmxCompatibleWcscmp (const WCHAR *Address1, const WCHAR *Address2, SIZE_T Num, BOOLEAN IsWcsncmp)
 implementation of vmx-root mode compatible wcscmp and wcsncmp
INT32 VmxCompatibleMemcmp (const CHAR *Address1, const CHAR *Address2, SIZE_T Count)
 implementation of vmx-root mode compatible memcmp

Detailed Description

VMX Instruction and operation headers.

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

Macro Definition Documentation

◆ GUEST_INTR_STATE_ENCLAVE_INTR

#define GUEST_INTR_STATE_ENCLAVE_INTR   0x00000010

◆ GUEST_INTR_STATE_MOV_SS

#define GUEST_INTR_STATE_MOV_SS   0x00000002

◆ GUEST_INTR_STATE_NMI

#define GUEST_INTR_STATE_NMI   0x00000008

◆ GUEST_INTR_STATE_SMI

#define GUEST_INTR_STATE_SMI   0x00000004

◆ GUEST_INTR_STATE_STI

#define GUEST_INTR_STATE_STI   0x00000001

GUEST_INTERRUPTIBILITY_INFO flags.

◆ HYPERV_CPUID_ENLIGHTMENT_INFO

#define HYPERV_CPUID_ENLIGHTMENT_INFO   0x40000004

◆ HYPERV_CPUID_FEATURES

#define HYPERV_CPUID_FEATURES   0x40000003

◆ HYPERV_CPUID_IMPLEMENT_LIMITS

#define HYPERV_CPUID_IMPLEMENT_LIMITS   0x40000005

◆ HYPERV_CPUID_INTERFACE

#define HYPERV_CPUID_INTERFACE   0x40000001

◆ HYPERV_CPUID_MAX

#define HYPERV_CPUID_MAX   0x4000ffff

◆ HYPERV_CPUID_MIN

#define HYPERV_CPUID_MIN   0x40000005

◆ HYPERV_CPUID_VENDOR_AND_MAX_FUNCTIONS

#define HYPERV_CPUID_VENDOR_AND_MAX_FUNCTIONS   0x40000000

CPUID RCX(s) - Based on Hyper-V.

◆ HYPERV_CPUID_VENDOR_MICROSOFT_EBX

#define HYPERV_CPUID_VENDOR_MICROSOFT_EBX   0x7263694d

Hyper-V CPUID leaves.

◆ HYPERV_CPUID_VENDOR_MICROSOFT_ECX

#define HYPERV_CPUID_VENDOR_MICROSOFT_ECX   0x666f736f

◆ HYPERV_CPUID_VENDOR_MICROSOFT_EDX

#define HYPERV_CPUID_VENDOR_MICROSOFT_EDX   0x76482074

◆ HYPERV_CPUID_VERSION

#define HYPERV_CPUID_VERSION   0x40000002

◆ HYPERV_HYPERVISOR_PRESENT_BIT

#define HYPERV_HYPERVISOR_PRESENT_BIT   0x80000000

◆ IS_VALID_DEBUG_REGISTER

#define IS_VALID_DEBUG_REGISTER ( DebugRegister)
Value:
(((DebugRegister <= VMX_EXIT_QUALIFICATION_REGISTER_DR0) && (DebugRegister <= VMX_EXIT_QUALIFICATION_REGISTER_DR7)) && (DebugRegister != 0x00000004 && DebugRegister != 0x00000005))
67#define IS_VALID_DEBUG_REGISTER(DebugRegister) \
68 (((DebugRegister <= VMX_EXIT_QUALIFICATION_REGISTER_DR0) && (DebugRegister <= VMX_EXIT_QUALIFICATION_REGISTER_DR7)) && (DebugRegister != 0x00000004 && DebugRegister != 0x00000005))

◆ SHADOW_INT_MOV_SS

#define SHADOW_INT_MOV_SS   0x01

Interrupt shadow states.

◆ SHADOW_INT_STI

#define SHADOW_INT_STI   0x02

◆ VIRTUAL_PROCESSOR_ID

#define VIRTUAL_PROCESSOR_ID   0x00000000

◆ VMCS_GUEST_DEBUGCTL_HIGH

#define VMCS_GUEST_DEBUGCTL_HIGH   0x00002803

Guest IA32_DEBUGCTL.

◆ VMCS_SIZE

#define VMCS_SIZE   4096

VMCS Region Size.

◆ VMM_STACK_SIZE

#define VMM_STACK_SIZE   0x8000

Stack Size.

◆ VMXON_SIZE

#define VMXON_SIZE   4096

VMXON Region Size.

Typedef Documentation

◆ HYPERCALL_INPUT_VALUE

Hypercalls for Hyper-V.

◆ MOV_TO_DEBUG_REG

MOV to debug registers states.

◆ PHYPERCALL_INPUT_VALUE

Enumeration Type Documentation

◆ _MOV_TO_DEBUG_REG

MOV to debug registers states.

Enumerator
AccessToDebugRegister 
AccessFromDebugRegister 
229{
enum _MOV_TO_DEBUG_REG MOV_TO_DEBUG_REG
MOV to debug registers states.
@ AccessFromDebugRegister
Definition Vmx.h:231
@ AccessToDebugRegister
Definition Vmx.h:230

◆ HYPERCALL_CODE

Hyper-V Hypercalls.

Enumerator
HvSwitchVirtualAddressSpace 
HvFlushVirtualAddressSpace 
HvFlushVirtualAddressList 
HvGetLogicalProcessorRunTime 
HvCallNotifyLongSpinWait 
HvCallParkedVirtualProcessors 
HvCallSyntheticClusterIpi 
HvCallModifyVtlProtectionMask 
HvCallEnablePartitionVtl 
HvCallDisablePartitionVtl 
HvCallEnableVpVtl 
HvCallDisableVpVtl 
HvCallVtlCall 
HvCallVtlReturn 
HvCallFlushVirtualAddressSpaceEx 
HvCallFlushVirtualAddressListEx 
HvCallSendSyntheticClusterIpiEx 
HvCreatePartition 
HvInitializePartition 
HvFinalizePartition 
HvDeletePartition 
HvGetPartitionProperty 
HvSetPartitionProperty 
HvGetPartitionId 
HvGetNextChildPartition 
HvDepositMemory 
HvWithdrawMemory 
HvGetMemoryBalance 
HvMapGpaPages 
HvUnmapGpaPages 
HvInstallIntercept 
HvCreateVp 
HvDeleteVp 
HvGetVpRegisters 
HvSetVpRegisters 
HvTranslateVirtualAddress 
HvReadGpa 
HvWriteGpa 
HvClearVirtualInterrupt 
HvDeletePort 
HvConnectPort 
HvGetPortProperty 
HvDisconnectPort 
HvPostMessage 
HvSignalEvent 
HvSavePartitionState 
HvRestorePartitionState 
HvInitializeEventLogBufferGroup 
HvFinalizeEventLogBufferGroup 
HvCreateEventLogBuffer 
HvDeleteEventLogBuffer 
HvMapEventLogBuffer 
HvUnmapEventLogBuffer 
HvSetEventLogGroupSources 
HvReleaseEventLogBuffer 
HvFlushEventLogBuffer 
HvPostDebugData 
HvRetrieveDebugData 
HvResetDebugSession 
HvMapStatsPage 
HvUnmapStatsPage 
HvCallMapSparseGpaPages 
HvCallSetSystemProperty 
HvCallSetPortProperty 
HvCallAddLogicalProcessor 
HvCallRemoveLogicalProcessor 
HvCallQueryNumaDistance 
HvCallSetLogicalProcessorProperty 
HvCallGetLogicalProcessorProperty 
HvCallGetSystemProperty 
HvCallMapDeviceInterrupt 
HvCallUnmapDeviceInterrupt 
HvCallRetargetDeviceInterrupt 
HvCallMapDevicePages 
HvCallUnmapDevicePages 
HvCallAttachDevice 
HvCallDetachDevice 
HvCallNotifyStandbyTransition 
HvCallPrepareForSleep 
HvCallPrepareForHibernate 
HvCallNotifyPartitionEvent 
HvCallGetLogicalProcessorRegisters 
HvCallSetLogicalProcessorRegisters 
HvCallQueryAssotiatedLpsforMca 
HvCallNotifyRingEmpty 
HvCallInjectSyntheticMachineCheck 
HvCallScrubPartition 
HvCallCollectLivedump 
HvCallDisableHypervisor 
HvCallModifySparseGpaPages 
HvCallRegisterInterceptResult 
HvCallUnregisterInterceptResult 
HvCallAssertVirtualInterrupt 
HvCallCreatePort 
HvCallConnectPort 
HvCallGetSpaPageList 
HvCallStartVirtualProcessor 
HvCallGetVpIndexFromApicId 
HvCallFlushGuestPhysicalAddressSpace 
HvCallFlushGuestPhysicalAddressList 
97{
102 // 0x0005..0x0007 are reserved
109 HvCallEnableVpVtl = 0x000F,
110 HvCallDisableVpVtl = 0x0010,
111 HvCallVtlCall = 0x0011,
112 HvCallVtlReturn = 0x0012,
116 // 0x0016..0x003F are reserved
117 HvCreatePartition = 0x0040,
118 HvInitializePartition = 0x0041,
119 HvFinalizePartition = 0x0042,
120 HvDeletePartition = 0x0043,
121 HvGetPartitionProperty = 0x0044,
122 HvSetPartitionProperty = 0x0045,
123 HvGetPartitionId = 0x0046,
125 HvDepositMemory = 0x0048,
126 HvWithdrawMemory = 0x0049,
127 HvGetMemoryBalance = 0x004A,
128 HvMapGpaPages = 0x004B,
129 HvUnmapGpaPages = 0x004C,
130 HvInstallIntercept = 0x004D,
131 HvCreateVp = 0x004E,
132 HvDeleteVp = 0x004F,
133 HvGetVpRegisters = 0x0050,
134 HvSetVpRegisters = 0x0051,
136 HvReadGpa = 0x0053,
137 HvWriteGpa = 0x0054,
138 // 0x0055 is deprecated
140 // 0x0057 is deprecated
141 HvDeletePort = 0x0058,
142 HvConnectPort = 0x0059,
143 HvGetPortProperty = 0x005A,
144 HvDisconnectPort = 0x005B,
145 HvPostMessage = 0x005C,
146 HvSignalEvent = 0x005D,
147 HvSavePartitionState = 0x005E,
151 HvCreateEventLogBuffer = 0x0062,
152 HvDeleteEventLogBuffer = 0x0063,
153 HvMapEventLogBuffer = 0x0064,
154 HvUnmapEventLogBuffer = 0x0065,
157 HvFlushEventLogBuffer = 0x0068,
158 HvPostDebugData = 0x0069,
159 HvRetrieveDebugData = 0x006A,
160 HvResetDebugSession = 0x006B,
161 HvMapStatsPage = 0x006C,
162 HvUnmapStatsPage = 0x006D,
165 HvCallSetPortProperty = 0x0070,
166 // 0x0071..0x0075 are reserved
176 // 0x007F is reserved
177 HvCallMapDevicePages = 0x0080,
178 HvCallUnmapDevicePages = 0x0081,
179 HvCallAttachDevice = 0x0082,
180 HvCallDetachDevice = 0x0083,
182 HvCallPrepareForSleep = 0x0085,
188 HvCallNotifyRingEmpty = 0x008B,
190 HvCallScrubPartition = 0x008D,
191 HvCallCollectLivedump = 0x008E,
197 HvCallCreatePort = 0x0095,
198 HvCallConnectPort = 0x0096,
199 HvCallGetSpaPageList = 0x0097,
200 // 0x0098 is reserved
203 // 0x009A..0x00AE are reserved
206};
@ HvUnmapStatsPage
Definition Vmx.h:162
@ HvClearVirtualInterrupt
Definition Vmx.h:139
@ HvGetPartitionId
Definition Vmx.h:123
@ HvCallParkedVirtualProcessors
Definition Vmx.h:104
@ HvCallConnectPort
Definition Vmx.h:198
@ HvCallEnableVpVtl
Definition Vmx.h:109
@ HvInstallIntercept
Definition Vmx.h:130
@ HvMapGpaPages
Definition Vmx.h:128
@ HvSwitchVirtualAddressSpace
Definition Vmx.h:98
@ HvCallMapSparseGpaPages
Definition Vmx.h:163
@ HvCallSendSyntheticClusterIpiEx
Definition Vmx.h:115
@ HvInitializePartition
Definition Vmx.h:118
@ HvCallPrepareForHibernate
Definition Vmx.h:183
@ HvCallQueryNumaDistance
Definition Vmx.h:169
@ HvCallVtlReturn
Definition Vmx.h:112
@ HvFinalizeEventLogBufferGroup
Definition Vmx.h:150
@ HvCallEnablePartitionVtl
Definition Vmx.h:107
@ HvCallAddLogicalProcessor
Definition Vmx.h:167
@ HvCallMapDevicePages
Definition Vmx.h:177
@ HvCallCreatePort
Definition Vmx.h:197
@ HvDepositMemory
Definition Vmx.h:125
@ HvCallGetLogicalProcessorRegisters
Definition Vmx.h:185
@ HvCallSetSystemProperty
Definition Vmx.h:164
@ HvCallFlushVirtualAddressListEx
Definition Vmx.h:114
@ HvCallRegisterInterceptResult
Definition Vmx.h:194
@ HvDeleteVp
Definition Vmx.h:132
@ HvSavePartitionState
Definition Vmx.h:147
@ HvReadGpa
Definition Vmx.h:136
@ HvCallModifyVtlProtectionMask
Definition Vmx.h:106
@ HvCallNotifyStandbyTransition
Definition Vmx.h:181
@ HvCallGetSpaPageList
Definition Vmx.h:199
@ HvGetLogicalProcessorRunTime
Definition Vmx.h:101
@ HvFlushEventLogBuffer
Definition Vmx.h:157
@ HvCallModifySparseGpaPages
Definition Vmx.h:193
@ HvDeletePort
Definition Vmx.h:141
@ HvCallDisablePartitionVtl
Definition Vmx.h:108
@ HvCallUnmapDevicePages
Definition Vmx.h:178
@ HvCallRemoveLogicalProcessor
Definition Vmx.h:168
@ HvCallRetargetDeviceInterrupt
Definition Vmx.h:175
@ HvCallSetPortProperty
Definition Vmx.h:165
@ HvSetEventLogGroupSources
Definition Vmx.h:155
@ HvCreatePartition
Definition Vmx.h:117
@ HvDeleteEventLogBuffer
Definition Vmx.h:152
@ HvGetPartitionProperty
Definition Vmx.h:121
@ HvCallVtlCall
Definition Vmx.h:111
@ HvCallPrepareForSleep
Definition Vmx.h:182
@ HvWithdrawMemory
Definition Vmx.h:126
@ HvFinalizePartition
Definition Vmx.h:119
@ HvCallNotifyPartitionEvent
Definition Vmx.h:184
@ HvSetVpRegisters
Definition Vmx.h:134
@ HvMapStatsPage
Definition Vmx.h:161
@ HvSetPartitionProperty
Definition Vmx.h:122
@ HvCallCollectLivedump
Definition Vmx.h:191
@ HvCallGetLogicalProcessorProperty
Definition Vmx.h:171
@ HvPostMessage
Definition Vmx.h:145
@ HvFlushVirtualAddressList
Definition Vmx.h:100
@ HvCallGetVpIndexFromApicId
Definition Vmx.h:202
@ HvCallSyntheticClusterIpi
Definition Vmx.h:105
@ HvCallScrubPartition
Definition Vmx.h:190
@ HvCallSetLogicalProcessorProperty
Definition Vmx.h:170
@ HvSignalEvent
Definition Vmx.h:146
@ HvUnmapEventLogBuffer
Definition Vmx.h:154
@ HvCallDisableVpVtl
Definition Vmx.h:110
@ HvInitializeEventLogBufferGroup
Definition Vmx.h:149
@ HvCreateVp
Definition Vmx.h:131
@ HvCallUnmapDeviceInterrupt
Definition Vmx.h:174
@ HvCallStartVirtualProcessor
Definition Vmx.h:201
@ HvGetNextChildPartition
Definition Vmx.h:124
@ HvCallMapDeviceInterrupt
Definition Vmx.h:173
@ HvResetDebugSession
Definition Vmx.h:160
@ HvCallDetachDevice
Definition Vmx.h:180
@ HvRetrieveDebugData
Definition Vmx.h:159
@ HvDeletePartition
Definition Vmx.h:120
@ HvCallUnregisterInterceptResult
Definition Vmx.h:195
@ HvCallNotifyRingEmpty
Definition Vmx.h:188
@ HvGetVpRegisters
Definition Vmx.h:133
@ HvFlushVirtualAddressSpace
Definition Vmx.h:99
@ HvDisconnectPort
Definition Vmx.h:144
@ HvCallAttachDevice
Definition Vmx.h:179
@ HvCallDisableHypervisor
Definition Vmx.h:192
@ HvPostDebugData
Definition Vmx.h:158
@ HvCallQueryAssotiatedLpsforMca
Definition Vmx.h:187
@ HvGetMemoryBalance
Definition Vmx.h:127
@ HvTranslateVirtualAddress
Definition Vmx.h:135
@ HvCallGetSystemProperty
Definition Vmx.h:172
@ HvUnmapGpaPages
Definition Vmx.h:129
@ HvCreateEventLogBuffer
Definition Vmx.h:151
@ HvConnectPort
Definition Vmx.h:142
@ HvCallAssertVirtualInterrupt
Definition Vmx.h:196
@ HvCallFlushVirtualAddressSpaceEx
Definition Vmx.h:113
@ HvCallSetLogicalProcessorRegisters
Definition Vmx.h:186
@ HvGetPortProperty
Definition Vmx.h:143
@ HvWriteGpa
Definition Vmx.h:137
@ HvCallNotifyLongSpinWait
Definition Vmx.h:103
@ HvReleaseEventLogBuffer
Definition Vmx.h:156
@ HvCallFlushGuestPhysicalAddressList
Definition Vmx.h:205
@ HvCallFlushGuestPhysicalAddressSpace
Definition Vmx.h:204
@ HvRestorePartitionState
Definition Vmx.h:148
@ HvCallInjectSyntheticMachineCheck
Definition Vmx.h:189
@ HvMapEventLogBuffer
Definition Vmx.h:153

Function Documentation

◆ VmxCheckIsOnVmxRoot()

BOOLEAN VmxCheckIsOnVmxRoot ( )

It can deterministically check whether the caller is on vmx-root mode or not.

Returns
BOOLEAN Returns true if current operation mode is vmx-root and false if current operation mode is vmx non-root
439{
440 UINT64 VmcsLink = 0;
441
442 __try
443 {
444 if (!VmxVmread64P(VMCS_GUEST_VMCS_LINK_POINTER, &VmcsLink))
445 {
446 if (VmcsLink != 0)
447 {
448 return TRUE;
449 }
450 }
451 }
452 __except (1)
453 {
454 }
455
456 return FALSE;
457}
UCHAR VmxVmread64P(size_t Field, UINT64 *FieldValue)
VMX VMREAD instruction (64-bit, pointer variant).
Definition PlatformIntrinsicsVmx.c:207
#define TRUE
Definition BasicTypes.h:114
#define FALSE
Definition BasicTypes.h:113

◆ VmxCheckVmxSupport()

BOOLEAN VmxCheckVmxSupport ( )

Check whether VMX Feature is supported or not.

Returns
BOOLEAN Returns true if vmx is supported or false if it's not supported
21{
22 CPUID Data = {0};
23 IA32_FEATURE_CONTROL_REGISTER FeatureControlMsr = {0};
24
25 //
26 // Gets Processor Info and Feature Bits
27 //
28 CpuCpuId((INT *)&Data, 1);
29
30 //
31 // Check For VMX Bit CPUID.ECX[5]
32 //
33 if (!_bittest((const LONG *)&Data.ecx, 5))
34 {
35 //
36 // returns FALSE if vmx is not supported
37 //
38 return FALSE;
39 }
40
41 FeatureControlMsr.AsUInt = CpuReadMsr(IA32_FEATURE_CONTROL);
42
43 //
44 // Commented because of https://stackoverflow.com/questions/34900224/
45 // and https://github.com/HyperDbg/HyperDbg/issues/24
46 // the problem is when writing to IA32_FEATURE_CONTROL MSR, the lock bit
47 // of this MSR Is not set to 0 on most computers, if the user enabled VT-X
48 // from the BIOS the VMXON will be already set so checking lock bit and
49 // then writing to EnableVmxon again is not meaningful since its already
50 // there
51 //
52
53 //
54 // if (FeatureControlMsr.Fields.Lock == 0)
55 // {
56 // FeatureControlMsr.Fields.Lock = TRUE;
57 // FeatureControlMsr.Fields.EnableVmxon = TRUE;
58 // CpuWriteMsr(IA32_FEATURE_CONTROL, FeatureControlMsr.Flags);
59 // }
60
61 if (FeatureControlMsr.EnableVmxOutsideSmx == FALSE)
62 {
63 LogError("Err, you should enable vt-x from BIOS");
64 return FALSE;
65 }
66
67 return TRUE;
68}
VOID CpuCpuId(INT32 *CpuInfo, INT32 FunctionId)
Execute CPUID.
Definition PlatformIntrinsics.c:255
UINT64 CpuReadMsr(ULONG MsrAddress)
Read an MSR.
Definition PlatformIntrinsics.c:213
long LONG
Definition BasicTypes.h:28
int INT
Definition BasicTypes.h:43
#define LogError(format,...)
Log in the case of error.
Definition HyperDbgHyperLogIntrinsics.h:113
struct _CPUID CPUID
CPUID Registers.
Start of Optional Data
Definition script_buffer.hex.txt:8

◆ VmxClearVmcsState()

BOOLEAN VmxClearVmcsState ( _In_ VIRTUAL_MACHINE_STATE * VCpu)

◆ VmxCompatibleMemcmp()

INT32 VmxCompatibleMemcmp ( const CHAR * Address1,
const CHAR * Address2,
SIZE_T Count )

implementation of vmx-root mode compatible memcmp

Parameters
Address1
Address2
Count
Returns
INT32 0x2 indicates error, otherwise the same result as memcmp in string.h
1675{
1676 CHAR C1 = NULL_ZERO, C2 = NULL_ZERO;
1677 INT32 Result = 0;
1678 UINT64 AlignedAddress1, AlignedAddress2;
1679 CR3_TYPE GuestCr3;
1680 CR3_TYPE OriginalCr3;
1681
1682 AlignedAddress1 = (UINT64)PAGE_ALIGN((UINT64)Address1);
1683 AlignedAddress2 = (UINT64)PAGE_ALIGN((UINT64)Address2);
1684
1685 //
1686 // Find the current process cr3
1687 //
1689
1690 //
1691 // Move to new cr3
1692 //
1693 OriginalCr3.Flags = CpuReadCr3();
1694 CpuWriteCr3(GuestCr3.Flags);
1695
1696 //
1697 // First check
1698 //
1699 if (!CheckAccessValidityAndSafety(AlignedAddress1, sizeof(WCHAR)) || !CheckAccessValidityAndSafety(AlignedAddress2, sizeof(WCHAR)))
1700 {
1701 //
1702 // Error
1703 //
1704
1705 //
1706 // Move back to original cr3
1707 //
1708 CpuWriteCr3(OriginalCr3.Flags);
1709 return 0x2;
1710 }
1711
1712 while (Count-- > 0 && !Result)
1713 {
1714 /*
1715 C1 = *Address1;
1716 */
1717 MemoryMapperReadMemorySafe((UINT64)Address1, &C1, sizeof(CHAR));
1718
1719 /*
1720 C2 = *Address2;
1721 */
1722 MemoryMapperReadMemorySafe((UINT64)Address2, &C2, sizeof(CHAR));
1723
1724 Address1++;
1725 Address2++;
1726
1727 if (!((UINT64)AlignedAddress1 & (PAGE_SIZE - 1)))
1728 {
1729 if (!CheckAccessValidityAndSafety((UINT64)AlignedAddress1, sizeof(WCHAR)))
1730 {
1731 //
1732 // Error
1733 //
1734
1735 //
1736 // Move back to original cr3
1737 //
1738 CpuWriteCr3(OriginalCr3.Flags);
1739 return 0x2;
1740 }
1741 }
1742
1743 if (!((UINT64)AlignedAddress2 & (PAGE_SIZE - 1)))
1744 {
1745 if (!CheckAccessValidityAndSafety((UINT64)AlignedAddress2, sizeof(WCHAR)))
1746 {
1747 //
1748 // Error
1749 //
1750
1751 //
1752 // Move back to original cr3
1753 //
1754 CpuWriteCr3(OriginalCr3.Flags);
1755 return 0x2;
1756 }
1757 }
1758
1759 Result = C1 - C2;
1760 }
1761
1762 if (Result < 0)
1763 {
1764 Result = -1;
1765 }
1766 else if (Result > 0)
1767 {
1768 Result = 1;
1769 }
1770
1771 //
1772 // Move back to original cr3
1773 //
1774 CpuWriteCr3(OriginalCr3.Flags);
1775 return Result;
1776}
ULONG_PTR CpuReadCr3(VOID)
Read CR3.
Definition PlatformIntrinsics.c:100
VOID CpuWriteCr3(ULONG_PTR Cr3Value)
Write CR3.
Definition PlatformIntrinsics.c:119
signed int INT32
Definition BasicTypes.h:50
#define NULL_ZERO
Definition BasicTypes.h:110
struct _CR3_TYPE CR3_TYPE
CR3 Structure.
char CHAR
Definition BasicTypes.h:33
IMPORT_EXPORT_VMM BOOLEAN CheckAccessValidityAndSafety(UINT64 TargetAddress, UINT32 Size)
Check the safety to access the memory.
Definition AddressCheck.c:318
IMPORT_EXPORT_VMM BOOLEAN MemoryMapperReadMemorySafe(_In_ UINT64 VaAddressToRead, _Inout_ PVOID BufferToSaveMemory, _In_ SIZE_T SizeToRead)
IMPORT_EXPORT_VMM CR3_TYPE LayoutGetCurrentProcessCr3()
Get cr3 of the target running process.
Definition Layout.c:55
#define PAGE_SIZE
Size of each page (4096 bytes).
Definition common.h:80
#define PAGE_ALIGN(Va)
Aligning a page.
Definition common.h:86
UINT64 Flags
Definition BasicTypes.h:239

◆ VmxCompatibleMicroSleep()

VOID VmxCompatibleMicroSleep ( UINT64 Us)

VMX-root compatible micro sleep.

Parameters
UsDelay in micro seconds
Returns
VOID
1372{
1373 LARGE_INTEGER Start, End, Frequency;
1374 KeQueryPerformanceCounter(&Frequency);
1375
1376 LONGLONG Ticks = (Frequency.QuadPart / 1000000) * Us;
1377
1378 Start = KeQueryPerformanceCounter(NULL);
1379
1380 while (TRUE)
1381 {
1382 End = KeQueryPerformanceCounter(NULL);
1383 if (End.QuadPart - Start.QuadPart > Ticks)
1384 break;
1385 }
1386}

◆ VmxCompatibleStrcmp()

INT32 VmxCompatibleStrcmp ( const CHAR * Address1,
const CHAR * Address2,
SIZE_T Num,
BOOLEAN IsStrncmp )

implementation of vmx-root mode compatible strcmp and strncmp

Parameters
Address1
Address2
Numparam IsStrncmp
Returns
INT32 0x2 indicates error, otherwise the same result as strcmp in string.h
1402{
1403 CHAR C1 = NULL_ZERO, C2 = NULL_ZERO;
1404 INT32 Result = 0;
1405 UINT32 Count = 0;
1406 UINT64 AlignedAddress1, AlignedAddress2;
1407 CR3_TYPE GuestCr3;
1408 CR3_TYPE OriginalCr3;
1409
1410 AlignedAddress1 = (UINT64)PAGE_ALIGN((UINT64)Address1);
1411 AlignedAddress2 = (UINT64)PAGE_ALIGN((UINT64)Address2);
1412
1413 //
1414 // Find the current process cr3
1415 //
1417
1418 //
1419 // Move to new cr3
1420 //
1421 OriginalCr3.Flags = CpuReadCr3();
1422 CpuWriteCr3(GuestCr3.Flags);
1423
1424 //
1425 // First check
1426 //
1427 if (!CheckAccessValidityAndSafety(AlignedAddress1, sizeof(CHAR)) || !CheckAccessValidityAndSafety(AlignedAddress2, sizeof(CHAR)))
1428 {
1429 //
1430 // Error
1431 //
1432
1433 //
1434 // Move back to original cr3
1435 //
1436 CpuWriteCr3(OriginalCr3.Flags);
1437 return 0x2;
1438 }
1439
1440 do
1441 {
1442 //
1443 // Check to see if we have byte number constraints
1444 //
1445 if (IsStrncmp)
1446 {
1447 if (Count == Num)
1448 {
1449 //
1450 // Maximum number of bytes reached
1451 //
1452 break;
1453 }
1454 else
1455 {
1456 //
1457 // Maximum number of bytes not reached
1458 //
1459 Count++;
1460 }
1461 }
1462
1463 /*
1464 C1 = *Address1;
1465 */
1466 MemoryMapperReadMemorySafe((UINT64)Address1, &C1, sizeof(CHAR));
1467
1468 /*
1469 C2 = *Address2;
1470 */
1471 MemoryMapperReadMemorySafe((UINT64)Address2, &C2, sizeof(CHAR));
1472
1473 Address1++;
1474 Address2++;
1475
1476 if (!((UINT64)AlignedAddress1 & (PAGE_SIZE - 1)))
1477 {
1478 if (!CheckAccessValidityAndSafety((UINT64)AlignedAddress1, sizeof(CHAR)))
1479 {
1480 //
1481 // Error
1482 //
1483
1484 //
1485 // Move back to original cr3
1486 //
1487 CpuWriteCr3(OriginalCr3.Flags);
1488 return 0x2;
1489 }
1490 }
1491
1492 if (!((UINT64)AlignedAddress2 & (PAGE_SIZE - 1)))
1493 {
1494 if (!CheckAccessValidityAndSafety((UINT64)AlignedAddress2, sizeof(CHAR)))
1495 {
1496 //
1497 // Error
1498 //
1499
1500 //
1501 // Move back to original cr3
1502 //
1503 CpuWriteCr3(OriginalCr3.Flags);
1504 return 0x2;
1505 }
1506 }
1507 Result = C1 - C2;
1508 } while (!Result && C2);
1509
1510 if (Result < 0)
1511 {
1512 Result = -1;
1513 }
1514 else if (Result > 0)
1515 {
1516 Result = 1;
1517 }
1518
1519 //
1520 // Move back to original cr3
1521 //
1522 CpuWriteCr3(OriginalCr3.Flags);
1523 return Result;
1524}
unsigned int UINT32
Definition BasicTypes.h:54
@ Num
Definition commands.h:167

◆ VmxCompatibleStrlen()

UINT32 VmxCompatibleStrlen ( const CHAR * S)

implementation of vmx-root mode compatible strlen

Parameters
S
Returns
UINT32 If 0x0 indicates an error, otherwise length of the string
1193{
1194 CHAR Temp = NULL_ZERO;
1195 UINT32 Count = 0;
1196 UINT64 AlignedAddress;
1197 CR3_TYPE GuestCr3;
1198 CR3_TYPE OriginalCr3;
1199
1200 AlignedAddress = (UINT64)PAGE_ALIGN((UINT64)S);
1201
1202 //
1203 // Find the current process cr3
1204 //
1206
1207 //
1208 // Move to new cr3
1209 //
1210 OriginalCr3.Flags = CpuReadCr3();
1211 CpuWriteCr3(GuestCr3.Flags);
1212
1213 //
1214 // First check
1215 //
1216 if (!CheckAccessValidityAndSafety(AlignedAddress, sizeof(CHAR)))
1217 {
1218 //
1219 // Error
1220 //
1221
1222 //
1223 // Move back to original cr3
1224 //
1225 CpuWriteCr3(OriginalCr3.Flags);
1226 return 0;
1227 }
1228
1229 while (TRUE)
1230 {
1231 /*
1232 Temp = *S;
1233 */
1234 MemoryMapperReadMemorySafe((UINT64)S, &Temp, sizeof(CHAR));
1235
1236 if (Temp != '\0')
1237 {
1238 Count++;
1239 S++;
1240 }
1241 else
1242 {
1243 //
1244 // Move back to original cr3
1245 //
1246 CpuWriteCr3(OriginalCr3.Flags);
1247 return Count;
1248 }
1249
1250 if (!((UINT64)S & (PAGE_SIZE - 1)))
1251 {
1252 if (!CheckAccessValidityAndSafety((UINT64)S, sizeof(CHAR)))
1253 {
1254 //
1255 // Error
1256 //
1257
1258 //
1259 // Move back to original cr3
1260 //
1261 CpuWriteCr3(OriginalCr3.Flags);
1262 return 0;
1263 }
1264 }
1265 }
1266
1267 //
1268 // Move back to original cr3
1269 //
1270 CpuWriteCr3(OriginalCr3.Flags);
1271}
ThreeOpFunc1 interlocked_compare_exchange ThreeOpFunc2 event_inject_error_code memcpy memcpy_pa TwoOpFunc1 ed eb eq interlocked_exchange interlocked_exchange_add eb_pa ed_pa eq_pa TwoOpFunc2 spinlock_lock_custom_wait event_inject OneOpFunc1 poi db dd dw dq neg hi low not check_address disassemble_len disassemble_len32 disassemble_len64 interlocked_increment interlocked_decrement reference physical_to_virtual virtual_to_physical poi_pa hi_pa low_pa db_pa dd_pa dw_pa dq_pa lbr_restore_by_filter OneOpFunc2 print formats event_enable event_disable event_clear test_statement spinlock_lock spinlock_unlock event_sc microsleep OneOpFunc3 strlen TwoOpFunc3 strcmp ThreeOpFunc3 memcmp strncmp ThreeOpFunc4 wcsncmp OneOpFunc4 wcslen TwoOpFunc4 wcscmp ZeroOpFunc1 pause flush event_trace_step event_trace_step_in event_trace_step_out event_trace_instrumentation_step event_trace_instrumentation_step_in ZeroOpFunc2 rdtsc rdtscp lbr_save lbr_dump lbr_print lbr_restore lbr_check VarArgFunc1 printf OperatorsTwoOperand or xor and asr asl add sub mul div mod gt lt egt elt equal neq OperatorsOneOperand inc dec reference AssignmentOperator add_assignment sub_assignment mul_assignment div_assignment mod_assignment asl_assignment asr_assignment and_assignment xor_assignment or_assignment SemantiRules jmp jz jnz mov start_of_do_while start_of_do_while_commands end_of_do_while start_of_for for_inc_dec start_of_for_ommands end_of_if ignore_lvalue push pop call ret Registers rax eax ax ah al rcx ecx cx ch cl rdx edx dx dh dl rbx ebx bx bh bl rsp esp sp spl rbp ebp bp bpl rsi esi si sil rdi edi di dil r8 r8d r8w r8h r8l r9 r9d r9w r9h r9l r10 r10d r10w r10h r10l r11 r11d r11w r11h r11l r12 r12d r12w r12h r12l r13 r13d r13w r13h r13l r14 r14d r14w r14h r14l r15 r15d r15w r15h r15l ds es fs gs cs ss rflags eflags flags cf pf af zf sf tf if df of iopl nt rf vm ac vif vip id rip eip ip idtr ldtr gdtr tr cr0 cr2 cr3 cr4 cr8 dr0 dr1 dr2 dr3 dr6 dr7 PseudoRegisters pid tid pname core proc thread peb teb ip buffer context event_tag event_id event_stage date time S STATEMENT S S
Definition Grammar.txt:57

◆ VmxCompatibleWcscmp()

INT32 VmxCompatibleWcscmp ( const WCHAR * Address1,
const WCHAR * Address2,
SIZE_T Num,
BOOLEAN IsWcsncmp )

implementation of vmx-root mode compatible wcscmp and wcsncmp

Parameters
Address1
Address2
Num
IsWcsncmp
Returns
INT32 0x2 indicates error, otherwise the same result as wcscmp in string.h
1540{
1541 WCHAR C1 = NULL_ZERO, C2 = NULL_ZERO;
1542 INT32 Result = 0;
1543 UINT32 Count = 0;
1544 UINT64 AlignedAddress1, AlignedAddress2;
1545 CR3_TYPE GuestCr3;
1546 CR3_TYPE OriginalCr3;
1547
1548 AlignedAddress1 = (UINT64)PAGE_ALIGN((UINT64)Address1);
1549 AlignedAddress2 = (UINT64)PAGE_ALIGN((UINT64)Address2);
1550
1551 //
1552 // Find the current process cr3
1553 //
1555
1556 //
1557 // Move to new cr3
1558 //
1559 OriginalCr3.Flags = CpuReadCr3();
1560 CpuWriteCr3(GuestCr3.Flags);
1561
1562 //
1563 // First check
1564 //
1565 if (!CheckAccessValidityAndSafety(AlignedAddress1, sizeof(WCHAR)) || !CheckAccessValidityAndSafety(AlignedAddress2, sizeof(WCHAR)))
1566 {
1567 //
1568 // Error
1569 //
1570
1571 //
1572 // Move back to original cr3
1573 //
1574 CpuWriteCr3(OriginalCr3.Flags);
1575 return 0x2;
1576 }
1577
1578 do
1579 {
1580 //
1581 // Check to see if we have byte number constraints
1582 //
1583 if (IsWcsncmp)
1584 {
1585 if (Count == Num)
1586 {
1587 //
1588 // Maximum number of bytes reached
1589 //
1590 break;
1591 }
1592 else
1593 {
1594 //
1595 // Maximum number of bytes not reached
1596 //
1597 Count++;
1598 }
1599 }
1600
1601 /*
1602 C1 = *Address1;
1603 */
1604 MemoryMapperReadMemorySafe((UINT64)Address1, &C1, sizeof(WCHAR));
1605
1606 /*
1607 C2 = *Address2;
1608 */
1609 MemoryMapperReadMemorySafe((UINT64)Address2, &C2, sizeof(WCHAR));
1610
1611 Address1++;
1612 Address2++;
1613
1614 if (!((UINT64)AlignedAddress1 & (PAGE_SIZE - 1)))
1615 {
1616 if (!CheckAccessValidityAndSafety((UINT64)AlignedAddress1, sizeof(WCHAR)))
1617 {
1618 //
1619 // Error
1620 //
1621
1622 //
1623 // Move back to original cr3
1624 //
1625 CpuWriteCr3(OriginalCr3.Flags);
1626 return 0x2;
1627 }
1628 }
1629
1630 if (!((UINT64)AlignedAddress2 & (PAGE_SIZE - 1)))
1631 {
1632 if (!CheckAccessValidityAndSafety((UINT64)AlignedAddress2, sizeof(WCHAR)))
1633 {
1634 //
1635 // Error
1636 //
1637
1638 //
1639 // Move back to original cr3
1640 //
1641 CpuWriteCr3(OriginalCr3.Flags);
1642 return 0x2;
1643 }
1644 }
1645
1646 Result = C1 - C2;
1647 } while (!Result && C2);
1648
1649 if (Result < 0)
1650 {
1651 Result = -1;
1652 }
1653 else if (Result > 0)
1654 {
1655 Result = 1;
1656 }
1657
1658 //
1659 // Move back to original cr3
1660 //
1661 CpuWriteCr3(OriginalCr3.Flags);
1662 return Result;
1663}

◆ VmxCompatibleWcslen()

UINT32 VmxCompatibleWcslen ( const WCHAR * S)

implementation of vmx-root mode compatible wcslen

Parameters
S
Returns
UINT32 If 0x0 indicates an error, otherwise length of the string
1282{
1283 WCHAR Temp = NULL_ZERO;
1284 UINT32 Count = 0;
1285 UINT64 AlignedAddress;
1286 CR3_TYPE GuestCr3;
1287 CR3_TYPE OriginalCr3;
1288
1289 AlignedAddress = (UINT64)PAGE_ALIGN((UINT64)S);
1290
1291 //
1292 // Find the current process cr3
1293 //
1295
1296 //
1297 // Move to new cr3
1298 //
1299 OriginalCr3.Flags = CpuReadCr3();
1300 CpuWriteCr3(GuestCr3.Flags);
1301
1302 AlignedAddress = (UINT64)PAGE_ALIGN((UINT64)S);
1303
1304 //
1305 // First check
1306 //
1307 if (!CheckAccessValidityAndSafety(AlignedAddress, sizeof(WCHAR)))
1308 {
1309 //
1310 // Error
1311 //
1312
1313 //
1314 // Move back to original cr3
1315 //
1316 CpuWriteCr3(OriginalCr3.Flags);
1317 return 0;
1318 }
1319
1320 while (TRUE)
1321 {
1322 /*
1323 Temp = *S;
1324 */
1325 MemoryMapperReadMemorySafe((UINT64)S, &Temp, sizeof(WCHAR));
1326
1327 if (Temp != '\0\0')
1328 {
1329 Count++;
1330 S++;
1331 }
1332 else
1333 {
1334 //
1335 // Move back to original cr3
1336 //
1337 CpuWriteCr3(OriginalCr3.Flags);
1338 return Count;
1339 }
1340
1341 if (!((UINT64)S & (PAGE_SIZE - 1)))
1342 {
1343 if (!CheckAccessValidityAndSafety((UINT64)S, sizeof(WCHAR)))
1344 {
1345 //
1346 // Error
1347 //
1348
1349 //
1350 // Move back to original cr3
1351 //
1352 CpuWriteCr3(OriginalCr3.Flags);
1353 return 0;
1354 }
1355 }
1356 }
1357
1358 //
1359 // Move back to original cr3
1360 //
1361 CpuWriteCr3(OriginalCr3.Flags);
1362}

◆ VmxFixCr4AndCr0Bits()

VOID VmxFixCr4AndCr0Bits ( )

Fix values for cr0 and cr4 bits.

The Cr4 And Cr0 Bits During VMX Operation Preventing Them From Any Change (https://revers.engineering/day-2-entering-vmx-operation/)

Returns
VOID
404{
405 CR_FIXED CrFixed = {0};
406 CR4 Cr4 = {0};
407 CR0 Cr0 = {0};
408
409 //
410 // Fix Cr0
411 //
412 CrFixed.Flags = CpuReadMsr(IA32_VMX_CR0_FIXED0);
413 Cr0.AsUInt = CpuReadCr0();
414 Cr0.AsUInt |= CrFixed.Fields.Low;
415 CrFixed.Flags = CpuReadMsr(IA32_VMX_CR0_FIXED1);
416 Cr0.AsUInt &= CrFixed.Fields.Low;
417 CpuWriteCr0(Cr0.AsUInt);
418
419 //
420 // Fix Cr4
421 //
422 CrFixed.Flags = CpuReadMsr(IA32_VMX_CR4_FIXED0);
423 Cr4.AsUInt = CpuReadCr4();
424 Cr4.AsUInt |= CrFixed.Fields.Low;
425 CrFixed.Flags = CpuReadMsr(IA32_VMX_CR4_FIXED1);
426 Cr4.AsUInt &= CrFixed.Fields.Low;
427 CpuWriteCr4(Cr4.AsUInt);
428}
VOID CpuWriteCr4(ULONG_PTR Cr4Value)
Write CR4.
Definition PlatformIntrinsics.c:155
ULONG_PTR CpuReadCr4(VOID)
Read CR4.
Definition PlatformIntrinsics.c:136
ULONG_PTR CpuReadCr0(VOID)
Read CR0.
Definition PlatformIntrinsics.c:28
VOID CpuWriteCr0(ULONG_PTR Cr0Value)
Write CR0.
Definition PlatformIntrinsics.c:47
union _CR_FIXED CR_FIXED
UINT64 Flags
Definition Common.h:93
ULONG Low
Definition Common.h:97
struct _CR_FIXED::@007200302366232112033323335144251163245112120214 Fields

◆ VmxGetCurrentExecutionMode()

BOOLEAN VmxGetCurrentExecutionMode ( )

Check current execution mode (vmx-root and non-root).

Returns
BOOLEAN Returns true if the execution is on vmx-root, otherwise false
77{
78 if (g_GuestState)
79 {
80 ULONG CurrentCore = KeGetCurrentProcessorNumberEx(NULL);
81 VIRTUAL_MACHINE_STATE * CurrentVmState = &g_GuestState[CurrentCore];
82
84 }
85 else
86 {
87 //
88 // The structure for guest state is not initialized, thus, we're in VMX non-root
89 //
91 }
92}
unsigned long ULONG
Definition BasicTypes.h:31
@ VmxExecutionModeNonRoot
Definition DataTypes.h:115
@ VmxExecutionModeRoot
Definition DataTypes.h:116
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
BOOLEAN IsOnVmxRootMode
Definition State.h:312

◆ VmxGetCurrentLaunchState()

BOOLEAN VmxGetCurrentLaunchState ( )

Check if the VMX is launched or not.

Returns
BOOLEAN Returns true if it's launched, otherwise false
101{
102 ULONG CurrentCore = KeGetCurrentProcessorNumberEx(NULL);
103 VIRTUAL_MACHINE_STATE * CurrentVmState = &g_GuestState[CurrentCore];
104
105 return CurrentVmState->HasLaunched;
106}
BOOLEAN HasLaunched
Definition State.h:314

◆ VmxHandleTripleFaults()

VOID VmxHandleTripleFaults ( VIRTUAL_MACHINE_STATE * VCpu)

Handling triple fault VM-exits.

Parameters
VCpuThe virtual processor's state
Returns
VOID
71{
72 LogError("Err, triple fault error occurred!");
73
74 //
75 // This error cannot be recovered, produce debug results
76 //
78
79 //
80 // We won't further continue after this error
81 //
82 DbgBreakPoint();
83}
VOID CommonWriteDebugInformation(VIRTUAL_MACHINE_STATE *VCpu)
Produce debug information from unrecoverable bugs.
Definition Common.c:149

◆ VmxHandleVmxPreemptionTimerVmexit()

VOID VmxHandleVmxPreemptionTimerVmexit ( VIRTUAL_MACHINE_STATE * VCpu)

Handling VMX Preemption Timer vm-exits.

Parameters
VCpuThe virtual processor's state
Returns
VOID
54{
55 LogError("Why vm-exit for VMX preemption timer happened?");
56
57 //
58 // Not increase the RIP by default
59 //
61}
VOID HvSuppressRipIncrement(VIRTUAL_MACHINE_STATE *VCpu)
Suppress the incrementation of RIP.
Definition Hv.c:320

◆ VmxHandleXsetbv()

VOID VmxHandleXsetbv ( VIRTUAL_MACHINE_STATE * VCpu)

Handling XSETBV Instruction vm-exits.

Parameters
VCpu
Returns
VOID
22{
23 CPUID_EAX_01 CpuidInfo;
25 UINT32 XCrIndex = VCpu->Regs->rcx & 0xffffffff;
26 XCR0 XCr0 = {.AsUInt = VCpu->Regs->rdx << 32 | VCpu->Regs->rax};
27 CR4 GuestCr4 = {.AsUInt = GetGuestCr4()};
28
29 if (XCrIndex != 0 || GuestCs.Attributes.DescriptorPrivilegeLevel != 0 || !CommonIsXCr0Valid(XCr0))
30 {
32 return;
33 }
34
35 CommonCpuidInstruction(CPUID_VERSION_INFORMATION, 0, (INT32 *)&CpuidInfo);
36
37 if (CpuidInfo.CpuidFeatureInformationEcx.XsaveXrstorInstruction == 0 || GuestCr4.OsXsave == 0)
38 {
40 return;
41 }
42
43 _xsetbv(XCrIndex, XCr0.AsUInt);
44}
VOID EventInjectUndefinedOpcode(VIRTUAL_MACHINE_STATE *VCpu)
Inject UD to the guest (Invalid Opcode - Undefined Opcode).
Definition Events.c:79
VOID EventInjectGeneralProtection()
Inject GP to the guest (Event Injection).
Definition Events.c:62
struct _VMX_SEGMENT_SELECTOR VMX_SEGMENT_SELECTOR
Segment selector.
IMPORT_EXPORT_VMM UINT64 GetGuestCr4()
Get the Guest Cr4 value.
Definition ManageRegs.c:507
IMPORT_EXPORT_VMM VMX_SEGMENT_SELECTOR GetGuestCs()
Get the Guest Cs Selector.
Definition ManageRegs.c:49
BOOLEAN CommonIsXCr0Valid(XCR0 XCr0)
Check correctness of the XCR0 register value.
Definition Common.c:202
VOID CommonCpuidInstruction(UINT32 Func, UINT32 SubFunc, INT *CpuInfo)
Get cpuid results.
Definition Common.c:85
GUEST_REGS * Regs
Definition State.h:326
VMX_SEGMENT_ACCESS_RIGHTS_TYPE Attributes
Definition DataTypes.h:487
UINT64 rax
Definition BasicTypes.h:141
UINT64 rcx
Definition BasicTypes.h:142
UINT64 rdx
Definition BasicTypes.h:143
UINT32 DescriptorPrivilegeLevel
Definition DataTypes.h:442

◆ VmxInitialize()

BOOLEAN VmxInitialize ( )

Initialize the VMX operation.

Returns
BOOLEAN Returns true if vmx initialized successfully
115{
116 ULONG ProcessorsCount;
117
118 //
119 // ****** Start Virtualizing Current System ******
120 //
121
122 //
123 // Initiating EPTP and VMX
124 //
126 {
127 //
128 // there was error somewhere in initializing
129 //
130 return FALSE;
131 }
132
133 ProcessorsCount = KeQueryActiveProcessorCount(0);
134
135 for (SIZE_T ProcessorID = 0; ProcessorID < ProcessorsCount; ProcessorID++)
136 {
137 //
138 // *** Launching VM for Test (in the all logical processor) ***
139 //
140
141 VIRTUAL_MACHINE_STATE * GuestState = &g_GuestState[ProcessorID];
142
143 //
144 // Allocating VMM Stack
145 //
146 if (!VmxAllocateVmmStack(GuestState))
147 {
148 //
149 // Some error in allocating Vmm Stack
150 //
151 return FALSE;
152 }
153
154 //
155 // Allocating MSR Bit
156 //
157 if (!VmxAllocateMsrBitmap(GuestState))
158 {
159 //
160 // Some error in allocating Msr Bitmaps
161 //
162 return FALSE;
163 }
164
165 //
166 // Allocating I/O Bit
167 //
168 if (!VmxAllocateIoBitmaps(GuestState))
169 {
170 //
171 // Some error in allocating I/O Bitmaps
172 //
173 return FALSE;
174 }
175
176#if USE_DEFAULT_OS_IDT_AS_HOST_IDT == FALSE
177
178 //
179 // Allocating Host IDT
180 //
181 if (!VmxAllocateHostIdt(GuestState))
182 {
183 //
184 // Some error in allocating Host IDT
185 //
186 return FALSE;
187 }
188#endif // USE_DEFAULT_OS_IDT_AS_HOST_IDT == FALSE
189
190#if USE_DEFAULT_OS_GDT_AS_HOST_GDT == FALSE
191
192 //
193 // Allocating Host GDT
194 //
195 if (!VmxAllocateHostGdt(GuestState))
196 {
197 //
198 // Some error in allocating Host GDT
199 //
200 return FALSE;
201 }
202
203 //
204 // Allocating Host TSS
205 //
206 if (!VmxAllocateHostTss(GuestState))
207 {
208 //
209 // Some error in allocating Host TSS
210 //
211 return FALSE;
212 }
213
214#endif // USE_DEFAULT_OS_GDT_AS_HOST_GDT == FALSE
215
216#if USE_INTERRUPT_STACK_TABLE == TRUE
217
218 //
219 // Allocating Host Interrupt Stack
220 //
221 if (!VmxAllocateHostInterruptStack(GuestState))
222 {
223 //
224 // Some error in allocating Interrupt Stack
225 //
226 return FALSE;
227 }
228
229#endif // USE_INTERRUPT_STACK_TABLE == TRUE
230 }
231
232 //
233 // Create a bitmap of the MSRs that cause #GP
234 //
236
237 if (g_MsrBitmapInvalidMsrs == NULL)
238 {
239 return FALSE;
240 }
241
242 //
243 // As we want to support more than 32 processor (64 logical-core)
244 // we let windows execute our routine for us
245 //
246 KeGenericCallDpc(DpcRoutineInitializeGuest, 0x0);
247
248 //
249 // Check if everything is ok then return true otherwise false
250 //
251 if (AsmVmxVmcall(VMCALL_TEST, 0x22, 0x333, 0x4444) == STATUS_SUCCESS)
252 {
253 return TRUE;
254 }
255 else
256 {
257 return FALSE;
258 }
259}
NTSTATUS AsmVmxVmcall(UINT64 VmcallNumber, UINT64 OptionalParam1, UINT64 OptionalParam2, UINT64 OptionalParam3)
Request Vmcall.
#define VMCALL_TEST
VMCALL to test hypervisor.
Definition Vmcall.h:22
BOOLEAN VmxPerformVirtualizationOnAllCores()
Initialize essential VMX Operation tasks.
Definition Vmx.c:267
BOOLEAN VmxAllocateHostIdt(_Inout_ VIRTUAL_MACHINE_STATE *VCpu)
Allocate a buffer for host IDT.
Definition VmxRegions.c:298
UINT64 * VmxAllocateInvalidMsrBimap()
Allocates a buffer and tests for the MSRs that cause GP.
Definition VmxRegions.c:265
BOOLEAN VmxAllocateIoBitmaps(_Inout_ VIRTUAL_MACHINE_STATE *VCpu)
Allocate a buffer for I/O Bitmap.
Definition VmxRegions.c:222
BOOLEAN VmxAllocateMsrBitmap(_Inout_ VIRTUAL_MACHINE_STATE *VCpu)
Allocate a buffer for Msr Bitmap.
Definition VmxRegions.c:193
BOOLEAN VmxAllocateHostInterruptStack(_Inout_ VIRTUAL_MACHINE_STATE *VCpu)
Allocate a buffer for host interrupt stack.
Definition VmxRegions.c:395
BOOLEAN VmxAllocateVmmStack(_Inout_ VIRTUAL_MACHINE_STATE *VCpu)
Allocate VMM Stack.
Definition VmxRegions.c:168
BOOLEAN VmxAllocateHostGdt(_Inout_ VIRTUAL_MACHINE_STATE *VCpu)
Allocate a buffer for host GDT.
Definition VmxRegions.c:333
BOOLEAN VmxAllocateHostTss(_Inout_ VIRTUAL_MACHINE_STATE *VCpu)
Allocate a buffer for host TSS.
Definition VmxRegions.c:368
VOID DpcRoutineInitializeGuest(KDPC *Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVOID SystemArgument2)
The broadcast function which initialize the guest.
Definition DpcRoutines.c:1509
UINT64 * g_MsrBitmapInvalidMsrs
Bitmap of MSRs that cause GP.
Definition GlobalVariables.h:100

◆ VmxIsTopLevelHypervisorHyperV()

BOOLEAN VmxIsTopLevelHypervisorHyperV ( )

checks if the current top level hypervisor is Hyper-V

Returns
BOOLEAN TRUE indicates that the current top level hypervisor is Hyper-V, FALSE otherwise.
1786{
1787 INT32 ProcessorFeatures[4] = {0};
1789
1790 if (!((ULONG)(ProcessorFeatures[2]) & HYPERV_HYPERVISOR_PRESENT_BIT))
1791 {
1792 return FALSE;
1793 }
1794
1795 INT32 HypervisorVendor[4] = {0};
1797
1798 return (ULONG)(HypervisorVendor[1]) == HYPERV_CPUID_VENDOR_MICROSOFT_EBX &&
1799 (ULONG)(HypervisorVendor[2]) == HYPERV_CPUID_VENDOR_MICROSOFT_ECX &&
1800 (ULONG)(HypervisorVendor[3]) == HYPERV_CPUID_VENDOR_MICROSOFT_EDX;
1801}
VOID CpuCpuIdEx(INT32 *CpuInfo, INT32 FunctionId, INT32 SubFunctionId)
Execute CPUID with sub-leaf.
Definition PlatformIntrinsics.c:274
#define HYPERV_CPUID_VENDOR_MICROSOFT_ECX
Definition Vmx.h:211
#define HYPERV_CPUID_VENDOR_MICROSOFT_EBX
Hyper-V CPUID leaves.
Definition Vmx.h:210
#define HYPERV_CPUID_VENDOR_AND_MAX_FUNCTIONS
CPUID RCX(s) - Based on Hyper-V.
Definition Vmx.h:34
#define HYPERV_HYPERVISOR_PRESENT_BIT
Definition Vmx.h:40
#define HYPERV_CPUID_VENDOR_MICROSOFT_EDX
Definition Vmx.h:212
#define CPUID_PROCESSOR_AND_PROCESSOR_FEATURE_IDENTIFIERS
CPUID Features.
Definition Constants.h:701

◆ VmxLoadVmcs()

BOOLEAN VmxLoadVmcs ( _In_ VIRTUAL_MACHINE_STATE * VCpu)

◆ VmxPerformTermination()

VOID VmxPerformTermination ( )

Terminate Vmx on all logical cores.

Returns
VOID
1105{
1106 ULONG ProcessorsCount;
1107
1108 LogDebugInfo("Terminating VMX...\n");
1109
1110 //
1111 // Get number of processors
1112 //
1113 ProcessorsCount = KeQueryActiveProcessorCount(0);
1114
1115 //
1116 // ******* Terminating Vmx *******
1117 //
1118
1119 //
1120 // Unhide (disable and de-allocate) transparent-mode
1121 //
1123 {
1125 }
1126
1127 //
1128 // Remove All the hooks if any
1129 //
1131
1132 //
1133 // Restore the state of execution trap hooks
1134 //
1136
1137 //
1138 // Broadcast to terminate Vmx
1139 //
1140 KeGenericCallDpc(DpcRoutineTerminateGuest, 0x0);
1141
1142 //
1143 // ****** De-allocatee global variables ******
1144 //
1145
1146 //
1147 // Free the buffer related to MSRs that cause #GP
1148 //
1151
1152 //
1153 // Free Identity Page Table
1154 //
1155 for (SIZE_T i = 0; i < ProcessorsCount; i++)
1156 {
1157 if (g_GuestState[i].EptPageTable != NULL)
1158 {
1159 MmFreeContiguousMemory(g_GuestState[i].EptPageTable);
1160 }
1161
1162 g_GuestState[i].EptPageTable = NULL;
1163 }
1164
1165 //
1166 // Free EptState
1167 //
1169 g_EptState = NULL;
1170
1171 //
1172 // Uninitialize memory mapper
1173 //
1175
1176 //
1177 // Free g_GuestState
1178 //
1180
1181 LogDebugInfo("VMX operation turned off successfully");
1182}
VOID EptHookUnHookAll()
Remove all hooks from the hooked pages list and invalidate TLB @detailsShould be called from Vmx Non-...
Definition EptHook.c:2451
VOID ExecTrapUninitialize()
Uinitialize the needed structure for the reversing machine.
Definition ExecTrap.c:432
VOID GlobalGuestStateFreeMemory(VOID)
Free guest state memory.
Definition GlobalVariableManagement.c:52
VOID MemoryMapperUninitialize()
uninitialize the Memory Mapper
Definition MemoryMapper.c:716
PVOID PlatformMemFreePool(PVOID BufferAddress)
Frees a memory pool.
Definition PlatformMem.c:269
#define LogDebugInfo(format,...)
Log, initialize boot information and debug information.
Definition HyperDbgHyperLogIntrinsics.h:155
IMPORT_EXPORT_VMM BOOLEAN TransparentUnhideDebuggerWrapper(DEBUGGER_HIDE_AND_TRANSPARENT_DEBUGGER_MODE *TransparentModeRequest)
Deactivate transparent-mode.
Definition HyperEvade.c:125
VOID DpcRoutineTerminateGuest(KDPC *Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVOID SystemArgument2)
The broadcast function which terminate the guest.
Definition DpcRoutines.c:1535
EPT_STATE * g_EptState
Save the state and variables related to EPT.
Definition GlobalVariables.h:50
BOOLEAN g_CheckForFootprints
Shows whether the footprints (anti-debugging and anti-hypervisor) should be checked or not.
Definition GlobalVariables.h:131
NULL()
Definition test-case-generator.py:530

◆ VmxPerformVirtualizationOnAllCores()

BOOLEAN VmxPerformVirtualizationOnAllCores ( )

Initialize essential VMX Operation tasks.

Returns
BOOLEAN Returns true if vmx is successfully initialized
268{
269 PAGED_CODE();
270
271 if (!VmxCheckVmxSupport())
272 {
273 LogError("Err, VMX is not supported in this machine");
274 return FALSE;
275 }
276
277 //
278 // Check if the top level hypervisor is Hyper-V or not
279 //
281 {
282 //
283 // The top-level hypervisor is hyper-v
284 //
286
287 LogDebugInfo(" Hyper-V is detected as the top-level hypervisor");
288 }
289 else
290 {
291 LogDebugInfo(" Hyper-V is not detected as the top-level hypervisor");
292 }
293
294 //
295 // Allocate global variable to hold Ept State
296 //
298
299 if (!g_EptState)
300 {
301 LogError("Err, insufficient memory");
302 return FALSE;
303 }
304
305 //
306 // Initialize the list of hooked pages detail
307 //
308 InitializeListHead(&g_EptState->HookedPagesList);
309
310 //
311 // Check whether EPT is supported or not
312 //
313 if (!EptCheckFeatures())
314 {
315 LogError("Err, your processor doesn't support all EPT features");
316 return FALSE;
317 }
318 else
319 {
320 //
321 // Our processor supports EPT, now let's build MTRR
322 //
323 LogDebugInfo("Your processor supports all EPT features");
324
325 //
326 // Build MTRR Map
327 //
328 if (!EptBuildMtrrMap())
329 {
330 LogError("Err, could not build MTRR memory map");
331 return FALSE;
332 }
333
334 LogDebugInfo("MTRR memory map built successfully");
335 }
336
338 {
339 //
340 // There were some errors in EptLogicalProcessorInitialize
341 //
342 return FALSE;
343 }
344
345 //
346 // Broadcast to run vmx-specific task to virtualize cores
347 //
349
350 //
351 // Everything is ok, let's return true
352 //
353 return TRUE;
354}
BOOLEAN EptLogicalProcessorInitialize(VOID)
Initialize EPT for an individual logical processor.
Definition Ept.c:865
BOOLEAN EptBuildMtrrMap(VOID)
Build MTRR Map of current physical addresses.
Definition Ept.c:167
BOOLEAN EptCheckFeatures(VOID)
Check whether EPT features are present or not.
Definition Ept.c:22
struct _EPT_STATE EPT_STATE
Main structure for saving the state of EPT among the project.
PVOID PlatformMemAllocateZeroedNonPagedPool(SIZE_T NumberOfBytes)
Allocates zeroed non-paged pool memory.
Definition PlatformMem.c:248
BOOLEAN VmxIsTopLevelHypervisorHyperV()
checks if the current top level hypervisor is Hyper-V
Definition Vmx.c:1785
BOOLEAN VmxCheckVmxSupport()
Check whether VMX Feature is supported or not.
Definition Vmx.c:20
VOID BroadcastVmxVirtualizationAllCores()
routines to broadcast virtualization and vmx initialization on all cores
Definition Broadcast.c:21
BOOLEAN g_IsTopLevelHypervisorHyperV
Whether the top level hypervisor is Hyper-V or not.
Definition GlobalVariables.h:220

◆ VmxPerformVirtualizationOnSpecificCore()

BOOLEAN VmxPerformVirtualizationOnSpecificCore ( )

Allocates Vmx regions for all logical cores (Vmxon region and Vmcs region).

Returns
BOOLEAN
363{
364 ULONG CurrentCore = KeGetCurrentProcessorNumberEx(NULL);
365 VIRTUAL_MACHINE_STATE * VCpu = &g_GuestState[CurrentCore];
366
367 LogDebugInfo("Allocating vmx regions for logical core %d", CurrentCore);
368
369 //
370 // Enabling VMX Operation
371 //
373
374 //
375 // Fix Cr4 and Cr0 bits during VMX operation
376 //
378
379 LogDebugInfo("VMX-Operation enabled successfully");
380
381 if (!VmxAllocateVmxonRegion(VCpu))
382 {
383 LogError("Err, allocating memory for vmxon region was not successful");
384 return FALSE;
385 }
386 if (!VmxAllocateVmcsRegion(VCpu))
387 {
388 LogError("Err, allocating memory for vmcs region was not successful");
389 return FALSE;
390 }
391
392 return TRUE;
393}
VOID AsmEnableVmxOperation()
Enable VMX Operation.
VOID VmxFixCr4AndCr0Bits()
Fix values for cr0 and cr4 bits.
Definition Vmx.c:403
_Use_decl_annotations_ BOOLEAN VmxAllocateVmxonRegion(VIRTUAL_MACHINE_STATE *VCpu)
Allocates Vmxon region and set the Revision ID based on IA32_VMX_BASIC_MSR.
Definition VmxRegions.c:23
_Use_decl_annotations_ BOOLEAN VmxAllocateVmcsRegion(VIRTUAL_MACHINE_STATE *VCpu)
Allocate Vmcs region and set the Revision ID based on IA32_VMX_BASIC_MSR.
Definition VmxRegions.c:104

◆ VmxPerformVmptrst()

VOID VmxPerformVmptrst ( )

Implementation of VMPTRST instruction.

Returns
VOID
611{
612 PHYSICAL_ADDRESS VmcsPhysicalAddr;
613 VmcsPhysicalAddr.QuadPart = 0;
614 VmxVmptrst((UINT64 *)&VmcsPhysicalAddr);
615
616 LogDebugInfo("VMPTRST result : %llx", VmcsPhysicalAddr);
617}
VOID VmxVmptrst(UINT64 *VmcsPhysicalAddress)
VMX VMPTRST instruction.
Definition PlatformIntrinsicsVmx.c:339

◆ VmxPerformVmresume()

VOID VmxPerformVmresume ( )

Resume VM using the VMRESUME instruction.

Returns
VOID
907{
908 UINT32 ErrorCode = 0;
909
910 VmxVmresume();
911
912 //
913 // if VMRESUME succeed will never be here !
914 //
915
916 VmxVmread32P(VMCS_VM_INSTRUCTION_ERROR, &ErrorCode);
917
918 VmxVmxoff();
919
920 //
921 // It's such a bad error because we don't where to go !
922 // prefer to break
923 //
924
925 LogError("Err, in executing VMRESUME, status : 0x%llx, last VM-exit reason: 0x%x",
926 ErrorCode,
927 g_GuestState[KeGetCurrentProcessorNumberEx(NULL)].ExitReason);
928}
VOID VmxVmxoff(VOID)
VMX VMXOFF instruction.
Definition PlatformIntrinsicsVmx.c:373
UCHAR VmxVmread32P(size_t Field, UINT32 *FieldValue)
VMX VMREAD instruction (32-bit, pointer variant).
Definition PlatformIntrinsicsVmx.c:227
VOID VmxVmresume(VOID)
VMX VMRESUME instruction.
Definition PlatformIntrinsicsVmx.c:356

◆ VmxPerformVmxoff()

VOID VmxPerformVmxoff ( VIRTUAL_MACHINE_STATE * VCpu)

Prepare and execute Vmxoff instruction.

Parameters
VCpuThe virtual processor's state
Returns
VOID
992{
993 UINT64 GuestRSP = 0; // Save a pointer to guest rsp for times that we want to return to previous guest stateS
994 UINT64 GuestRIP = 0; // Save a pointer to guest rip for times that we want to return to previous guest state
995 UINT64 GuestCr3 = 0;
996 UINT64 ExitInstructionLength = 0;
997
998 //
999 // According to SimpleVisor :
1000 // Our callback routine may have interrupted an arbitrary user process,
1001 // and therefore not a thread running with a system-wide page directory.
1002 // Therefore if we return back to the original caller after turning off
1003 // VMX, it will keep our current "host" CR3 value which we set on entry
1004 // to the PML4 of the SYSTEM process. We want to return back with the
1005 // correct value of the "guest" CR3, so that the currently executing
1006 // process continues to run with its expected address space mappings.
1007 //
1008
1009 VmxVmread64P(VMCS_GUEST_CR3, &GuestCr3);
1010 CpuWriteCr3(GuestCr3);
1011
1012 //
1013 // Read guest rsp and rip
1014 //
1015 VmxVmread64P(VMCS_GUEST_RIP, &GuestRIP);
1016 VmxVmread64P(VMCS_GUEST_RSP, &GuestRSP);
1017
1018 //
1019 // Read instruction length
1020 //
1021 VmxVmread64P(VMCS_VMEXIT_INSTRUCTION_LENGTH, &ExitInstructionLength);
1022 GuestRIP += ExitInstructionLength;
1023
1024 //
1025 // Set the previous register states
1026 //
1027 VCpu->VmxoffState.GuestRip = GuestRIP;
1028 VCpu->VmxoffState.GuestRsp = GuestRSP;
1029
1030 //
1031 // Notify the Vmexit handler that VMX already turned off
1032 //
1034
1035 //
1036 // Restore the previous FS, GS , GDTR and IDTR register as patchguard might find the modified
1037 //
1039
1040 //
1041 // Restore XMM registers
1042 // We restore XMM registers here because we are going to execute vmxoff instruction
1043 // which enables interrupts and we don't want to lose the XMM registers
1044 // since immediately after vmxoff, an interrupt might occur and context switch
1045 // might change the XMM registers
1046 //
1047 AsmVmxoffRestoreXmmRegs((UINT64)VCpu->XmmRegs);
1048
1049 //
1050 // Before using vmxoff, you first need to use vmclear on any VMCSes that you want to be able to use again.
1051 // See sections 24.1 and 24.11 of the SDM.
1052 //
1053 VmxClearVmcsState(VCpu);
1054
1055 //
1056 // Execute Vmxoff
1057 //
1058 VmxVmxoff();
1059
1060 //
1061 // *** Note: After executing VMXOFF, XMM registers should not be used anymore
1062 // Since we already restored them ***
1063 //
1064
1065 //
1066 // Indicate the current core is not currently virtualized
1067 //
1068 VCpu->HasLaunched = FALSE;
1069
1070 //
1071 // Now that VMX is OFF, we have to unset vmx-enable bit on cr4
1072 //
1074}
VOID HvRestoreRegisters()
Reset GDTR/IDTR and other old when you do vmxoff as the patchguard will detect them left modified.
Definition Hv.c:491
VOID AsmVmxoffRestoreXmmRegs(UINT64 XmmRegs)
Restore XMM registers.
_Use_decl_annotations_ BOOLEAN VmxClearVmcsState(VIRTUAL_MACHINE_STATE *VCpu)
Clearing Vmcs status using vmclear instruction.
Definition Vmx.c:628
#define REG_CR4_VMXE
Definition Constants.h:649
GUEST_XMM_REGS * XmmRegs
Definition State.h:327
VMX_VMXOFF_STATE VmxoffState
Definition State.h:350
UINT64 GuestRip
Definition State.h:169
UINT64 GuestRsp
Definition State.h:170
BOOLEAN IsVmxoffExecuted
Definition State.h:168

◆ VmxReturnInstructionPointerForVmxoff()

UINT64 VmxReturnInstructionPointerForVmxoff ( )

Get the RIP of guest (VMCS_GUEST_RIP) in the case of return from VMXOFF.

Returns
UINT64 Returns the instruction pointer, to change in the case of Vmxoff
1094{
1095 return g_GuestState[KeGetCurrentProcessorNumberEx(NULL)].VmxoffState.GuestRip;
1096}

◆ VmxReturnStackPointerForVmxoff()

UINT64 VmxReturnStackPointerForVmxoff ( )

Get the RIP of guest (VMCS_GUEST_RIP) in the case of return from VMXOFF.

Returns
UINT64 Returns the stack pointer, to change in the case of Vmxoff
1083{
1084 return g_GuestState[KeGetCurrentProcessorNumberEx(NULL)].VmxoffState.GuestRsp;
1085}

◆ VmxSetupVmcs()

BOOLEAN VmxSetupVmcs ( _In_ VIRTUAL_MACHINE_STATE * VCpu,
_In_ PVOID GuestStack )

◆ VmxTerminate()

BOOLEAN VmxTerminate ( )

Broadcast to terminate VMX on all logical cores.

Returns
BOOLEAN Returns true if vmxoff successfully executed in vmcall or otherwise returns false
562{
563 NTSTATUS Status = STATUS_SUCCESS;
564 ULONG CurrentCore = KeGetCurrentProcessorNumberEx(NULL);
565 VIRTUAL_MACHINE_STATE * VCpu = &g_GuestState[CurrentCore];
566
567 //
568 // Execute Vmcall to to turn off vmx from Vmx root mode
569 //
571
572 if (Status == STATUS_SUCCESS)
573 {
574 LogDebugInfo("VMX terminated on logical core %d\n", CurrentCore);
575
576 //
577 // Free the destination memory
578 //
579 MmFreeContiguousMemory((PVOID)VCpu->VmxonRegionVirtualAddress);
580 MmFreeContiguousMemory((PVOID)VCpu->VmcsRegionVirtualAddress);
585#if USE_DEFAULT_OS_IDT_AS_HOST_IDT == FALSE
587#endif // USE_DEFAULT_OS_IDT_AS_HOST_IDT == FALSE
588
589#if USE_DEFAULT_OS_GDT_AS_HOST_GDT == FALSE
592#endif // USE_DEFAULT_OS_GDT_AS_HOST_GDT == FALSE
593
594#if USE_INTERRUPT_STACK_TABLE == TRUE
596#endif // USE_INTERRUPT_STACK_TABLE == FALSE
597
598 return TRUE;
599 }
600
601 return FALSE;
602}
#define VMCALL_VMXOFF
VMCALL to Call VMXOFF to turn off the hypervisor.
Definition Vmcall.h:28
void * PVOID
Definition BasicTypes.h:56
#define NULL64_ZERO
Definition BasicTypes.h:111
UINT64 VmxonRegionVirtualAddress
Definition State.h:333
UINT64 HostInterruptStack
Definition State.h:358
UINT64 HostGdt
Definition State.h:356
UINT64 IoBitmapVirtualAddressB
Definition State.h:341
UINT64 MsrBitmapVirtualAddress
Definition State.h:337
UINT64 VmmStack
Definition State.h:336
UINT64 HostTss
Definition State.h:357
UINT64 HostIdt
Definition State.h:355
UINT64 IoBitmapVirtualAddressA
Definition State.h:339
UINT64 VmcsRegionVirtualAddress
Definition State.h:335

◆ VmxVirtualizeCurrentSystem()

BOOLEAN VmxVirtualizeCurrentSystem ( PVOID GuestStack)

Initialize VMX Operation.

Parameters
GuestStackGuest stack for the this core (VMCS_GUEST_RSP)
Returns
BOOLEAN This function won't return true as when Vmlaunch is executed the rest of the function never executes but returning FALSE is an indication of error
468{
469 UINT64 ErrorCode = 0;
470 ULONG CurrentCore = KeGetCurrentProcessorNumberEx(NULL);
471 VIRTUAL_MACHINE_STATE * VCpu = &g_GuestState[CurrentCore];
472
473 LogDebugInfo("Virtualizing current system (logical core : 0x%x)", CurrentCore);
474
475#if USE_DEFAULT_OS_IDT_AS_HOST_IDT == FALSE
476
477 //
478 // Prepare Host IDT
479 //
481#endif // USE_DEFAULT_OS_IDT_AS_HOST_IDT == FALSE
482
483#if USE_DEFAULT_OS_GDT_AS_HOST_GDT == FALSE
484
485 //
486 // Prepare Host GDT and TSS
487 //
488 SegmentPrepareHostGdt((SEGMENT_DESCRIPTOR_32 *)AsmGetGdtBase(),
490 AsmGetTr(),
491 VCpu->HostInterruptStack,
492 (SEGMENT_DESCRIPTOR_32 *)VCpu->HostGdt,
493 (TASK_STATE_SEGMENT_64 *)VCpu->HostTss);
494
495#endif // USE_DEFAULT_OS_GDT_AS_HOST_GDT == FALSE
496
497 //
498 // Clear the VMCS State
499 //
500 if (!VmxClearVmcsState(VCpu))
501 {
502 LogError("Err, failed to clear vmcs");
503 return FALSE;
504 }
505
506 //
507 // Load VMCS (Set the Current VMCS)
508 //
509 if (!VmxLoadVmcs(VCpu))
510 {
511 LogError("Err, failed to load vmcs");
512 return FALSE;
513 }
514
515 LogDebugInfo("Setting up VMCS for current logical core");
516
517 VmxSetupVmcs(VCpu, GuestStack);
518
519 LogDebugInfo("Executing VMLAUNCH on logical core %d", CurrentCore);
520
521 //
522 // Setting the state to indicate current core is currently virtualized
523 //
524
525 VCpu->HasLaunched = TRUE;
526
527 VmxVmlaunch();
528
529 //
530 // ******** if Vmlaunch succeed will never be here ! ********
531 //
532
533 //
534 // If failed, then indicate that current core is not currently virtualized
535 //
536 VCpu->HasLaunched = FALSE;
537
538 //
539 // Read error code firstly
540 //
541 VmxVmread64P(VMCS_VM_INSTRUCTION_ERROR, &ErrorCode);
542
543 LogError("Err, unable to execute VMLAUNCH, status : 0x%llx", ErrorCode);
544
545 //
546 // Then Execute Vmxoff
547 //
548 VmxVmxoff();
549 LogError("Err, VMXOFF Executed Successfully but it was because of an error");
550
551 return FALSE;
552}
VOID IdtEmulationPrepareHostIdt(_Inout_ VIRTUAL_MACHINE_STATE *VCpu)
Prepare Host IDT.
Definition IdtEmulation.c:117
UINT16 AsmGetGdtLimit()
Get GDT Limit.
UINT64 AsmGetGdtBase()
get GDT base
UINT16 AsmGetTr()
Get TR Register.
VOID VmxVmlaunch(VOID)
VMX VMLAUNCH instruction.
Definition PlatformIntrinsicsVmx.c:390
VOID SegmentPrepareHostGdt(SEGMENT_DESCRIPTOR_32 *OsGdtBase, UINT16 OsGdtLimit, UINT16 TrSelector, UINT64 HostStack, SEGMENT_DESCRIPTOR_32 *AllocatedHostGdt, TASK_STATE_SEGMENT_64 *AllocatedHostTss)
Initialize the host GDT.
Definition Segmentation.c:95
_Use_decl_annotations_ BOOLEAN VmxLoadVmcs(VIRTUAL_MACHINE_STATE *VCpu)
Implementation of VMPTRLD instruction.
Definition Vmx.c:661
_Use_decl_annotations_ BOOLEAN VmxSetupVmcs(VIRTUAL_MACHINE_STATE *VCpu, PVOID GuestStack)
Create and Configure a Vmcs Layout.
Definition Vmx.c:684