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 PIN_BASED_VM_EXECUTION_CONTROLS_EXTERNAL_INTERRUPT   0x00000001
 PIN-Based Execution.
 
#define PIN_BASED_VM_EXECUTION_CONTROLS_NMI_EXITING   0x00000008
 
#define PIN_BASED_VM_EXECUTION_CONTROLS_VIRTUAL_NMI   0x00000020
 
#define PIN_BASED_VM_EXECUTION_CONTROLS_ACTIVE_VMX_TIMER   0x00000040
 
#define PIN_BASED_VM_EXECUTION_CONTROLS_PROCESS_POSTED_INTERRUPTS   0x00000080
 
#define CPU_BASED_VIRTUAL_INTR_PENDING   0x00000004
 CPU-Based Controls.
 
#define CPU_BASED_USE_TSC_OFFSETTING   0x00000008
 
#define CPU_BASED_HLT_EXITING   0x00000080
 
#define CPU_BASED_INVLPG_EXITING   0x00000200
 
#define CPU_BASED_MWAIT_EXITING   0x00000400
 
#define CPU_BASED_RDPMC_EXITING   0x00000800
 
#define CPU_BASED_RDTSC_EXITING   0x00001000
 
#define CPU_BASED_CR3_LOAD_EXITING   0x00008000
 
#define CPU_BASED_CR3_STORE_EXITING   0x00010000
 
#define CPU_BASED_CR8_LOAD_EXITING   0x00080000
 
#define CPU_BASED_CR8_STORE_EXITING   0x00100000
 
#define CPU_BASED_TPR_SHADOW   0x00200000
 
#define CPU_BASED_VIRTUAL_NMI_PENDING   0x00400000
 
#define CPU_BASED_MOV_DR_EXITING   0x00800000
 
#define CPU_BASED_UNCOND_IO_EXITING   0x01000000
 
#define CPU_BASED_ACTIVATE_IO_BITMAP   0x02000000
 
#define CPU_BASED_MONITOR_TRAP_FLAG   0x08000000
 
#define CPU_BASED_ACTIVATE_MSR_BITMAP   0x10000000
 
#define CPU_BASED_MONITOR_EXITING   0x20000000
 
#define CPU_BASED_PAUSE_EXITING   0x40000000
 
#define CPU_BASED_ACTIVATE_SECONDARY_CONTROLS   0x80000000
 
#define CPU_BASED_CTL2_ENABLE_EPT   0x2
 Secondary CPU-Based Controls.
 
#define CPU_BASED_CTL2_RDTSCP   0x8
 
#define CPU_BASED_CTL2_ENABLE_VPID   0x20
 
#define CPU_BASED_CTL2_UNRESTRICTED_GUEST   0x80
 
#define CPU_BASED_CTL2_VIRTUAL_INTERRUPT_DELIVERY   0x200
 
#define CPU_BASED_CTL2_ENABLE_INVPCID   0x1000
 
#define CPU_BASED_CTL2_ENABLE_VMFUNC   0x2000
 
#define CPU_BASED_CTL2_ENABLE_XSAVE_XRSTORS   0x100000
 
#define VM_EXIT_SAVE_DEBUG_CONTROLS   0x00000004
 VM-exit Control Bits.
 
#define VM_EXIT_HOST_ADDR_SPACE_SIZE   0x00000200
 
#define VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL   0x00001000
 
#define VM_EXIT_ACK_INTR_ON_EXIT   0x00008000
 
#define VM_EXIT_SAVE_IA32_PAT   0x00040000
 
#define VM_EXIT_LOAD_IA32_PAT   0x00080000
 
#define VM_EXIT_SAVE_IA32_EFER   0x00100000
 
#define VM_EXIT_LOAD_IA32_EFER   0x00200000
 
#define VM_EXIT_SAVE_VMX_PREEMPTION_TIMER   0x00400000
 
#define VM_ENTRY_LOAD_DEBUG_CONTROLS   0x00000004
 VM-entry Control Bits.
 
#define VM_ENTRY_IA32E_MODE   0x00000200
 
#define VM_ENTRY_SMM   0x00000400
 
#define VM_ENTRY_DEACT_DUAL_MONITOR   0x00000800
 
#define VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL   0x00002000
 
#define VM_ENTRY_LOAD_IA32_PAT   0x00004000
 
#define VM_ENTRY_LOAD_IA32_EFER   0x00008000
 
#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)    (((DebugRegister <= VMX_EXIT_QUALIFICATION_REGISTER_DR0) && (DebugRegister <= VMX_EXIT_QUALIFICATION_REGISTER_DR7)) && (DebugRegister != 0x00000004 && DebugRegister != 0x00000005))
 
#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

UCHAR VmxVmread64 (size_t Field, UINT64 FieldValue)
 VMX VMREAD instruction (64-bit)
 
UCHAR VmxVmread32 (size_t Field, UINT32 FieldValue)
 VMX VMREAD instruction (32-bit)
 
UCHAR VmxVmread16 (size_t Field, UINT16 FieldValue)
 VMX VMREAD instruction (16-bit)
 
UCHAR VmxVmread64P (size_t Field, UINT64 *FieldValue)
 VMX VMREAD instruction (64-bit)
 
UCHAR VmxVmread32P (size_t Field, UINT32 *FieldValue)
 VMX VMREAD instruction (32-bit)
 
UCHAR VmxVmread16P (size_t Field, UINT16 *FieldValue)
 VMX VMREAD instruction (16-bit)
 
UCHAR VmxVmwrite64 (size_t Field, UINT64 FieldValue)
 VMX VMWRITE instruction (64-bit)
 
UCHAR VmxVmwrite32 (size_t Field, UINT32 FieldValue)
 VMX VMWRITE instruction (32-bit)
 
UCHAR VmxVmwrite16 (size_t Field, UINT16 FieldValue)
 VMX VMWRITE instruction (16-bit)
 
VOID VmxVmptrst ()
 Implementation of VMPTRST instruction.
 
VOID VmxVmresume ()
 Resume VM using VMRESUME instruction.
 
VOID VmxVmxoff (VIRTUAL_MACHINE_STATE *VCpu)
 Prepare and execute Vmxoff instruction.
 
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.
 
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.
 
BOOLEAN VmxPerformVirtualizationOnSpecificCore ()
 Allocates Vmx regions for all logical cores (Vmxon region and Vmcs region)
 
VOID VmxFixCr4AndCr0Bits ()
 Fix values for cr0 and cr4 bits.
 
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)
 
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_t *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_t *Address1, const wchar_t *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

◆ CPU_BASED_ACTIVATE_IO_BITMAP

#define CPU_BASED_ACTIVATE_IO_BITMAP   0x02000000

◆ CPU_BASED_ACTIVATE_MSR_BITMAP

#define CPU_BASED_ACTIVATE_MSR_BITMAP   0x10000000

◆ CPU_BASED_ACTIVATE_SECONDARY_CONTROLS

#define CPU_BASED_ACTIVATE_SECONDARY_CONTROLS   0x80000000

◆ CPU_BASED_CR3_LOAD_EXITING

#define CPU_BASED_CR3_LOAD_EXITING   0x00008000

◆ CPU_BASED_CR3_STORE_EXITING

#define CPU_BASED_CR3_STORE_EXITING   0x00010000

◆ CPU_BASED_CR8_LOAD_EXITING

#define CPU_BASED_CR8_LOAD_EXITING   0x00080000

◆ CPU_BASED_CR8_STORE_EXITING

#define CPU_BASED_CR8_STORE_EXITING   0x00100000

◆ CPU_BASED_CTL2_ENABLE_EPT

#define CPU_BASED_CTL2_ENABLE_EPT   0x2

Secondary CPU-Based Controls.

◆ CPU_BASED_CTL2_ENABLE_INVPCID

#define CPU_BASED_CTL2_ENABLE_INVPCID   0x1000

◆ CPU_BASED_CTL2_ENABLE_VMFUNC

#define CPU_BASED_CTL2_ENABLE_VMFUNC   0x2000

◆ CPU_BASED_CTL2_ENABLE_VPID

#define CPU_BASED_CTL2_ENABLE_VPID   0x20

◆ CPU_BASED_CTL2_ENABLE_XSAVE_XRSTORS

#define CPU_BASED_CTL2_ENABLE_XSAVE_XRSTORS   0x100000

◆ CPU_BASED_CTL2_RDTSCP

#define CPU_BASED_CTL2_RDTSCP   0x8

◆ CPU_BASED_CTL2_UNRESTRICTED_GUEST

#define CPU_BASED_CTL2_UNRESTRICTED_GUEST   0x80

◆ CPU_BASED_CTL2_VIRTUAL_INTERRUPT_DELIVERY

#define CPU_BASED_CTL2_VIRTUAL_INTERRUPT_DELIVERY   0x200

◆ CPU_BASED_HLT_EXITING

#define CPU_BASED_HLT_EXITING   0x00000080

◆ CPU_BASED_INVLPG_EXITING

#define CPU_BASED_INVLPG_EXITING   0x00000200

◆ CPU_BASED_MONITOR_EXITING

#define CPU_BASED_MONITOR_EXITING   0x20000000

◆ CPU_BASED_MONITOR_TRAP_FLAG

#define CPU_BASED_MONITOR_TRAP_FLAG   0x08000000

◆ CPU_BASED_MOV_DR_EXITING

#define CPU_BASED_MOV_DR_EXITING   0x00800000

◆ CPU_BASED_MWAIT_EXITING

#define CPU_BASED_MWAIT_EXITING   0x00000400

◆ CPU_BASED_PAUSE_EXITING

#define CPU_BASED_PAUSE_EXITING   0x40000000

◆ CPU_BASED_RDPMC_EXITING

#define CPU_BASED_RDPMC_EXITING   0x00000800

◆ CPU_BASED_RDTSC_EXITING

#define CPU_BASED_RDTSC_EXITING   0x00001000

◆ CPU_BASED_TPR_SHADOW

#define CPU_BASED_TPR_SHADOW   0x00200000

◆ CPU_BASED_UNCOND_IO_EXITING

#define CPU_BASED_UNCOND_IO_EXITING   0x01000000

◆ CPU_BASED_USE_TSC_OFFSETTING

#define CPU_BASED_USE_TSC_OFFSETTING   0x00000008

◆ CPU_BASED_VIRTUAL_INTR_PENDING

#define CPU_BASED_VIRTUAL_INTR_PENDING   0x00000004

CPU-Based Controls.

◆ CPU_BASED_VIRTUAL_NMI_PENDING

#define CPU_BASED_VIRTUAL_NMI_PENDING   0x00400000

◆ 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_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)     (((DebugRegister <= VMX_EXIT_QUALIFICATION_REGISTER_DR0) && (DebugRegister <= VMX_EXIT_QUALIFICATION_REGISTER_DR7)) && (DebugRegister != 0x00000004 && DebugRegister != 0x00000005))
142#define IS_VALID_DEBUG_REGISTER(DebugRegister) \
143 (((DebugRegister <= VMX_EXIT_QUALIFICATION_REGISTER_DR0) && (DebugRegister <= VMX_EXIT_QUALIFICATION_REGISTER_DR7)) && (DebugRegister != 0x00000004 && DebugRegister != 0x00000005))

◆ PIN_BASED_VM_EXECUTION_CONTROLS_ACTIVE_VMX_TIMER

#define PIN_BASED_VM_EXECUTION_CONTROLS_ACTIVE_VMX_TIMER   0x00000040

◆ PIN_BASED_VM_EXECUTION_CONTROLS_EXTERNAL_INTERRUPT

#define PIN_BASED_VM_EXECUTION_CONTROLS_EXTERNAL_INTERRUPT   0x00000001

PIN-Based Execution.

◆ PIN_BASED_VM_EXECUTION_CONTROLS_NMI_EXITING

#define PIN_BASED_VM_EXECUTION_CONTROLS_NMI_EXITING   0x00000008

◆ PIN_BASED_VM_EXECUTION_CONTROLS_PROCESS_POSTED_INTERRUPTS

#define PIN_BASED_VM_EXECUTION_CONTROLS_PROCESS_POSTED_INTERRUPTS   0x00000080

◆ PIN_BASED_VM_EXECUTION_CONTROLS_VIRTUAL_NMI

#define PIN_BASED_VM_EXECUTION_CONTROLS_VIRTUAL_NMI   0x00000020

◆ 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

◆ VM_ENTRY_DEACT_DUAL_MONITOR

#define VM_ENTRY_DEACT_DUAL_MONITOR   0x00000800

◆ VM_ENTRY_IA32E_MODE

#define VM_ENTRY_IA32E_MODE   0x00000200

◆ VM_ENTRY_LOAD_DEBUG_CONTROLS

#define VM_ENTRY_LOAD_DEBUG_CONTROLS   0x00000004

VM-entry Control Bits.

◆ VM_ENTRY_LOAD_IA32_EFER

#define VM_ENTRY_LOAD_IA32_EFER   0x00008000

◆ VM_ENTRY_LOAD_IA32_PAT

#define VM_ENTRY_LOAD_IA32_PAT   0x00004000

◆ VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL

#define VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL   0x00002000

◆ VM_ENTRY_SMM

#define VM_ENTRY_SMM   0x00000400

◆ VM_EXIT_ACK_INTR_ON_EXIT

#define VM_EXIT_ACK_INTR_ON_EXIT   0x00008000

◆ VM_EXIT_HOST_ADDR_SPACE_SIZE

#define VM_EXIT_HOST_ADDR_SPACE_SIZE   0x00000200

◆ VM_EXIT_LOAD_IA32_EFER

#define VM_EXIT_LOAD_IA32_EFER   0x00200000

◆ VM_EXIT_LOAD_IA32_PAT

#define VM_EXIT_LOAD_IA32_PAT   0x00080000

◆ VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL

#define VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL   0x00001000

◆ VM_EXIT_SAVE_DEBUG_CONTROLS

#define VM_EXIT_SAVE_DEBUG_CONTROLS   0x00000004

VM-exit Control Bits.

◆ VM_EXIT_SAVE_IA32_EFER

#define VM_EXIT_SAVE_IA32_EFER   0x00100000

◆ VM_EXIT_SAVE_IA32_PAT

#define VM_EXIT_SAVE_IA32_PAT   0x00040000

◆ VM_EXIT_SAVE_VMX_PREEMPTION_TIMER

#define VM_EXIT_SAVE_VMX_PREEMPTION_TIMER   0x00400000

◆ 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 
298{
enum _MOV_TO_DEBUG_REG MOV_TO_DEBUG_REG
MOV to debug registers states.
@ AccessFromDebugRegister
Definition Vmx.h:300
@ AccessToDebugRegister
Definition Vmx.h:299

◆ 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 
172{
177 // 0x0005..0x0007 are reserved
184 HvCallEnableVpVtl = 0x000F,
185 HvCallDisableVpVtl = 0x0010,
186 HvCallVtlCall = 0x0011,
187 HvCallVtlReturn = 0x0012,
191 // 0x0016..0x003F are reserved
192 HvCreatePartition = 0x0040,
193 HvInitializePartition = 0x0041,
194 HvFinalizePartition = 0x0042,
195 HvDeletePartition = 0x0043,
196 HvGetPartitionProperty = 0x0044,
197 HvSetPartitionProperty = 0x0045,
198 HvGetPartitionId = 0x0046,
200 HvDepositMemory = 0x0048,
201 HvWithdrawMemory = 0x0049,
202 HvGetMemoryBalance = 0x004A,
203 HvMapGpaPages = 0x004B,
204 HvUnmapGpaPages = 0x004C,
205 HvInstallIntercept = 0x004D,
206 HvCreateVp = 0x004E,
207 HvDeleteVp = 0x004F,
208 HvGetVpRegisters = 0x0050,
209 HvSetVpRegisters = 0x0051,
211 HvReadGpa = 0x0053,
212 HvWriteGpa = 0x0054,
213 // 0x0055 is deprecated
215 // 0x0057 is deprecated
216 HvDeletePort = 0x0058,
217 HvConnectPort = 0x0059,
218 HvGetPortProperty = 0x005A,
219 HvDisconnectPort = 0x005B,
220 HvPostMessage = 0x005C,
221 HvSignalEvent = 0x005D,
222 HvSavePartitionState = 0x005E,
226 HvCreateEventLogBuffer = 0x0062,
227 HvDeleteEventLogBuffer = 0x0063,
228 HvMapEventLogBuffer = 0x0064,
229 HvUnmapEventLogBuffer = 0x0065,
232 HvFlushEventLogBuffer = 0x0068,
233 HvPostDebugData = 0x0069,
234 HvRetrieveDebugData = 0x006A,
235 HvResetDebugSession = 0x006B,
236 HvMapStatsPage = 0x006C,
237 HvUnmapStatsPage = 0x006D,
240 HvCallSetPortProperty = 0x0070,
241 // 0x0071..0x0075 are reserved
251 // 0x007F is reserved
252 HvCallMapDevicePages = 0x0080,
253 HvCallUnmapDevicePages = 0x0081,
254 HvCallAttachDevice = 0x0082,
255 HvCallDetachDevice = 0x0083,
257 HvCallPrepareForSleep = 0x0085,
263 HvCallNotifyRingEmpty = 0x008B,
265 HvCallScrubPartition = 0x008D,
266 HvCallCollectLivedump = 0x008E,
272 HvCallCreatePort = 0x0095,
273 HvCallConnectPort = 0x0096,
274 HvCallGetSpaPageList = 0x0097,
275 // 0x0098 is reserved
278 // 0x009A..0x00AE are reserved
281};
@ HvUnmapStatsPage
Definition Vmx.h:237
@ HvClearVirtualInterrupt
Definition Vmx.h:214
@ HvGetPartitionId
Definition Vmx.h:198
@ HvCallParkedVirtualProcessors
Definition Vmx.h:179
@ HvCallConnectPort
Definition Vmx.h:273
@ HvCallEnableVpVtl
Definition Vmx.h:184
@ HvInstallIntercept
Definition Vmx.h:205
@ HvMapGpaPages
Definition Vmx.h:203
@ HvSwitchVirtualAddressSpace
Definition Vmx.h:173
@ HvCallMapSparseGpaPages
Definition Vmx.h:238
@ HvCallSendSyntheticClusterIpiEx
Definition Vmx.h:190
@ HvInitializePartition
Definition Vmx.h:193
@ HvCallPrepareForHibernate
Definition Vmx.h:258
@ HvCallQueryNumaDistance
Definition Vmx.h:244
@ HvCallVtlReturn
Definition Vmx.h:187
@ HvFinalizeEventLogBufferGroup
Definition Vmx.h:225
@ HvCallEnablePartitionVtl
Definition Vmx.h:182
@ HvCallAddLogicalProcessor
Definition Vmx.h:242
@ HvCallMapDevicePages
Definition Vmx.h:252
@ HvCallCreatePort
Definition Vmx.h:272
@ HvDepositMemory
Definition Vmx.h:200
@ HvCallGetLogicalProcessorRegisters
Definition Vmx.h:260
@ HvCallSetSystemProperty
Definition Vmx.h:239
@ HvCallFlushVirtualAddressListEx
Definition Vmx.h:189
@ HvCallRegisterInterceptResult
Definition Vmx.h:269
@ HvDeleteVp
Definition Vmx.h:207
@ HvSavePartitionState
Definition Vmx.h:222
@ HvReadGpa
Definition Vmx.h:211
@ HvCallModifyVtlProtectionMask
Definition Vmx.h:181
@ HvCallNotifyStandbyTransition
Definition Vmx.h:256
@ HvCallGetSpaPageList
Definition Vmx.h:274
@ HvGetLogicalProcessorRunTime
Definition Vmx.h:176
@ HvFlushEventLogBuffer
Definition Vmx.h:232
@ HvCallModifySparseGpaPages
Definition Vmx.h:268
@ HvDeletePort
Definition Vmx.h:216
@ HvCallDisablePartitionVtl
Definition Vmx.h:183
@ HvCallUnmapDevicePages
Definition Vmx.h:253
@ HvCallRemoveLogicalProcessor
Definition Vmx.h:243
@ HvCallRetargetDeviceInterrupt
Definition Vmx.h:250
@ HvCallSetPortProperty
Definition Vmx.h:240
@ HvSetEventLogGroupSources
Definition Vmx.h:230
@ HvCreatePartition
Definition Vmx.h:192
@ HvDeleteEventLogBuffer
Definition Vmx.h:227
@ HvGetPartitionProperty
Definition Vmx.h:196
@ HvCallVtlCall
Definition Vmx.h:186
@ HvCallPrepareForSleep
Definition Vmx.h:257
@ HvWithdrawMemory
Definition Vmx.h:201
@ HvFinalizePartition
Definition Vmx.h:194
@ HvCallNotifyPartitionEvent
Definition Vmx.h:259
@ HvSetVpRegisters
Definition Vmx.h:209
@ HvMapStatsPage
Definition Vmx.h:236
@ HvSetPartitionProperty
Definition Vmx.h:197
@ HvCallCollectLivedump
Definition Vmx.h:266
@ HvCallGetLogicalProcessorProperty
Definition Vmx.h:246
@ HvPostMessage
Definition Vmx.h:220
@ HvFlushVirtualAddressList
Definition Vmx.h:175
@ HvCallGetVpIndexFromApicId
Definition Vmx.h:277
@ HvCallSyntheticClusterIpi
Definition Vmx.h:180
@ HvCallScrubPartition
Definition Vmx.h:265
@ HvCallSetLogicalProcessorProperty
Definition Vmx.h:245
@ HvSignalEvent
Definition Vmx.h:221
@ HvUnmapEventLogBuffer
Definition Vmx.h:229
@ HvCallDisableVpVtl
Definition Vmx.h:185
@ HvInitializeEventLogBufferGroup
Definition Vmx.h:224
@ HvCreateVp
Definition Vmx.h:206
@ HvCallUnmapDeviceInterrupt
Definition Vmx.h:249
@ HvCallStartVirtualProcessor
Definition Vmx.h:276
@ HvGetNextChildPartition
Definition Vmx.h:199
@ HvCallMapDeviceInterrupt
Definition Vmx.h:248
@ HvResetDebugSession
Definition Vmx.h:235
@ HvCallDetachDevice
Definition Vmx.h:255
@ HvRetrieveDebugData
Definition Vmx.h:234
@ HvDeletePartition
Definition Vmx.h:195
@ HvCallUnregisterInterceptResult
Definition Vmx.h:270
@ HvCallNotifyRingEmpty
Definition Vmx.h:263
@ HvGetVpRegisters
Definition Vmx.h:208
@ HvFlushVirtualAddressSpace
Definition Vmx.h:174
@ HvDisconnectPort
Definition Vmx.h:219
@ HvCallAttachDevice
Definition Vmx.h:254
@ HvCallDisableHypervisor
Definition Vmx.h:267
@ HvPostDebugData
Definition Vmx.h:233
@ HvCallQueryAssotiatedLpsforMca
Definition Vmx.h:262
@ HvGetMemoryBalance
Definition Vmx.h:202
@ HvTranslateVirtualAddress
Definition Vmx.h:210
@ HvCallGetSystemProperty
Definition Vmx.h:247
@ HvUnmapGpaPages
Definition Vmx.h:204
@ HvCreateEventLogBuffer
Definition Vmx.h:226
@ HvConnectPort
Definition Vmx.h:217
@ HvCallAssertVirtualInterrupt
Definition Vmx.h:271
@ HvCallFlushVirtualAddressSpaceEx
Definition Vmx.h:188
@ HvCallSetLogicalProcessorRegisters
Definition Vmx.h:261
@ HvGetPortProperty
Definition Vmx.h:218
@ HvWriteGpa
Definition Vmx.h:212
@ HvCallNotifyLongSpinWait
Definition Vmx.h:178
@ HvReleaseEventLogBuffer
Definition Vmx.h:231
@ HvCallFlushGuestPhysicalAddressList
Definition Vmx.h:280
@ HvCallFlushGuestPhysicalAddressSpace
Definition Vmx.h:279
@ HvRestorePartitionState
Definition Vmx.h:223
@ HvCallInjectSyntheticMachineCheck
Definition Vmx.h:264
@ HvMapEventLogBuffer
Definition Vmx.h:228

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
577{
578 UINT64 VmcsLink = 0;
579
580 __try
581 {
582 if (!__vmx_vmread(VMCS_GUEST_VMCS_LINK_POINTER, &VmcsLink))
583 {
584 if (VmcsLink != 0)
585 {
586 return TRUE;
587 }
588 }
589 }
590 __except (1)
591 {
592 }
593
594 return FALSE;
595}
#define TRUE
Definition BasicTypes.h:55
#define FALSE
Definition BasicTypes.h:54
unsigned __int64 UINT64
Definition BasicTypes.h:21

◆ 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
167{
168 CPUID Data = {0};
169 IA32_FEATURE_CONTROL_REGISTER FeatureControlMsr = {0};
170
171 //
172 // Gets Processor Info and Feature Bits
173 //
174 __cpuid((int *)&Data, 1);
175
176 //
177 // Check For VMX Bit CPUID.ECX[5]
178 //
179 if (!_bittest((const LONG *)&Data.ecx, 5))
180 {
181 //
182 // returns FALSE if vmx is not supported
183 //
184 return FALSE;
185 }
186
187 FeatureControlMsr.AsUInt = __readmsr(IA32_FEATURE_CONTROL);
188
189 //
190 // Commented because of https://stackoverflow.com/questions/34900224/
191 // and https://github.com/HyperDbg/HyperDbg/issues/24
192 // the problem is when writing to IA32_FEATURE_CONTROL MSR, the lock bit
193 // of this MSR Is not set to 0 on most computers, if the user enabled VT-X
194 // from the BIOS the VMXON will be already set so checking lock bit and
195 // then writing to EnableVmxon again is not meaningful since its already
196 // there
197 //
198
199 //
200 // if (FeatureControlMsr.Fields.Lock == 0)
201 // {
202 // FeatureControlMsr.Fields.Lock = TRUE;
203 // FeatureControlMsr.Fields.EnableVmxon = TRUE;
204 // __writemsr(IA32_FEATURE_CONTROL, FeatureControlMsr.Flags);
205 // }
206
207 if (FeatureControlMsr.EnableVmxOutsideSmx == FALSE)
208 {
209 LogError("Err, you should enable vt-x from BIOS");
210 return FALSE;
211 }
212
213 return TRUE;
214}
#define LogError(format,...)
Log in the case of error.
Definition HyperDbgHyperLogIntrinsics.h:113
Start of Optional Data
Definition script_buffer.hex.txt:8
CPUID Registers.
Definition Common.h:236

◆ 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
1749{
1750 CHAR C1 = NULL_ZERO, C2 = NULL_ZERO;
1751 INT32 Result = 0;
1752 UINT64 AlignedAddress1, AlignedAddress2;
1753 CR3_TYPE GuestCr3;
1754 CR3_TYPE OriginalCr3;
1755
1756 AlignedAddress1 = (UINT64)PAGE_ALIGN((UINT64)Address1);
1757 AlignedAddress2 = (UINT64)PAGE_ALIGN((UINT64)Address2);
1758
1759 //
1760 // Find the current process cr3
1761 //
1763
1764 //
1765 // Move to new cr3
1766 //
1767 OriginalCr3.Flags = __readcr3();
1768 __writecr3(GuestCr3.Flags);
1769
1770 //
1771 // First check
1772 //
1773 if (!CheckAccessValidityAndSafety(AlignedAddress1, sizeof(wchar_t)) || !CheckAccessValidityAndSafety(AlignedAddress2, sizeof(wchar_t)))
1774 {
1775 //
1776 // Error
1777 //
1778
1779 //
1780 // Move back to original cr3
1781 //
1782 __writecr3(OriginalCr3.Flags);
1783 return 0x2;
1784 }
1785
1786 while (Count-- > 0 && !Result)
1787 {
1788 /*
1789 C1 = *Address1;
1790 */
1791 MemoryMapperReadMemorySafe((UINT64)Address1, &C1, sizeof(CHAR));
1792
1793 /*
1794 C2 = *Address2;
1795 */
1796 MemoryMapperReadMemorySafe((UINT64)Address2, &C2, sizeof(CHAR));
1797
1798 Address1++;
1799 Address2++;
1800
1801 if (!((UINT64)AlignedAddress1 & (PAGE_SIZE - 1)))
1802 {
1803 if (!CheckAccessValidityAndSafety((UINT64)AlignedAddress1, sizeof(wchar_t)))
1804 {
1805 //
1806 // Error
1807 //
1808
1809 //
1810 // Move back to original cr3
1811 //
1812 __writecr3(OriginalCr3.Flags);
1813 return 0x2;
1814 }
1815 }
1816
1817 if (!((UINT64)AlignedAddress2 & (PAGE_SIZE - 1)))
1818 {
1819 if (!CheckAccessValidityAndSafety((UINT64)AlignedAddress2, sizeof(wchar_t)))
1820 {
1821 //
1822 // Error
1823 //
1824
1825 //
1826 // Move back to original cr3
1827 //
1828 __writecr3(OriginalCr3.Flags);
1829 return 0x2;
1830 }
1831 }
1832
1833 Result = C1 - C2;
1834 }
1835
1836 if (Result < 0)
1837 {
1838 Result = -1;
1839 }
1840 else if (Result > 0)
1841 {
1842 Result = 1;
1843 }
1844
1845 //
1846 // Move back to original cr3
1847 //
1848 __writecr3(OriginalCr3.Flags);
1849 return Result;
1850}
BOOLEAN CheckAccessValidityAndSafety(UINT64 TargetAddress, UINT32 Size)
Check the safety to access the memory.
Definition AddressCheck.c:156
signed int INT32
Definition BasicTypes.h:44
#define NULL_ZERO
Definition BasicTypes.h:51
char CHAR
Definition BasicTypes.h:31
CR3_TYPE LayoutGetCurrentProcessCr3()
Get cr3 of the target running process.
Definition Layout.c:55
_Use_decl_annotations_ BOOLEAN MemoryMapperReadMemorySafe(UINT64 VaAddressToRead, PVOID BufferToSaveMemory, SIZE_T SizeToRead)
Read memory safely by mapping the buffer (It's a wrapper)
Definition MemoryMapper.c:1101
#define PAGE_SIZE
Size of each page (4096 bytes)
Definition common.h:69
#define PAGE_ALIGN(Va)
Aligning a page.
Definition common.h:75
CR3 Structure.
Definition BasicTypes.h:130
UINT64 Flags
Definition BasicTypes.h:133

◆ 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
1476{
1477 CHAR C1 = NULL_ZERO, C2 = NULL_ZERO;
1478 INT32 Result = 0;
1479 UINT32 Count = 0;
1480 UINT64 AlignedAddress1, AlignedAddress2;
1481 CR3_TYPE GuestCr3;
1482 CR3_TYPE OriginalCr3;
1483
1484 AlignedAddress1 = (UINT64)PAGE_ALIGN((UINT64)Address1);
1485 AlignedAddress2 = (UINT64)PAGE_ALIGN((UINT64)Address2);
1486
1487 //
1488 // Find the current process cr3
1489 //
1491
1492 //
1493 // Move to new cr3
1494 //
1495 OriginalCr3.Flags = __readcr3();
1496 __writecr3(GuestCr3.Flags);
1497
1498 //
1499 // First check
1500 //
1501 if (!CheckAccessValidityAndSafety(AlignedAddress1, sizeof(CHAR)) || !CheckAccessValidityAndSafety(AlignedAddress2, sizeof(CHAR)))
1502 {
1503 //
1504 // Error
1505 //
1506
1507 //
1508 // Move back to original cr3
1509 //
1510 __writecr3(OriginalCr3.Flags);
1511 return 0x2;
1512 }
1513
1514 do
1515 {
1516 //
1517 // Check to see if we have byte number constraints
1518 //
1519 if (IsStrncmp)
1520 {
1521 if (Count == Num)
1522 {
1523 //
1524 // Maximum number of bytes reached
1525 //
1526 break;
1527 }
1528 else
1529 {
1530 //
1531 // Maximum number of bytes not reached
1532 //
1533 Count++;
1534 }
1535 }
1536
1537 /*
1538 C1 = *Address1;
1539 */
1540 MemoryMapperReadMemorySafe((UINT64)Address1, &C1, sizeof(CHAR));
1541
1542 /*
1543 C2 = *Address2;
1544 */
1545 MemoryMapperReadMemorySafe((UINT64)Address2, &C2, sizeof(CHAR));
1546
1547 Address1++;
1548 Address2++;
1549
1550 if (!((UINT64)AlignedAddress1 & (PAGE_SIZE - 1)))
1551 {
1552 if (!CheckAccessValidityAndSafety((UINT64)AlignedAddress1, sizeof(CHAR)))
1553 {
1554 //
1555 // Error
1556 //
1557
1558 //
1559 // Move back to original cr3
1560 //
1561 __writecr3(OriginalCr3.Flags);
1562 return 0x2;
1563 }
1564 }
1565
1566 if (!((UINT64)AlignedAddress2 & (PAGE_SIZE - 1)))
1567 {
1568 if (!CheckAccessValidityAndSafety((UINT64)AlignedAddress2, sizeof(CHAR)))
1569 {
1570 //
1571 // Error
1572 //
1573
1574 //
1575 // Move back to original cr3
1576 //
1577 __writecr3(OriginalCr3.Flags);
1578 return 0x2;
1579 }
1580 }
1581 Result = C1 - C2;
1582 } while (!Result && C2);
1583
1584 if (Result < 0)
1585 {
1586 Result = -1;
1587 }
1588 else if (Result > 0)
1589 {
1590 Result = 1;
1591 }
1592
1593 //
1594 // Move back to original cr3
1595 //
1596 __writecr3(OriginalCr3.Flags);
1597 return Result;
1598}
unsigned int UINT32
Definition BasicTypes.h:48

◆ 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
1291{
1292 CHAR Temp = NULL_ZERO;
1293 UINT32 Count = 0;
1294 UINT64 AlignedAddress;
1295 CR3_TYPE GuestCr3;
1296 CR3_TYPE OriginalCr3;
1297
1298 AlignedAddress = (UINT64)PAGE_ALIGN((UINT64)S);
1299
1300 //
1301 // Find the current process cr3
1302 //
1304
1305 //
1306 // Move to new cr3
1307 //
1308 OriginalCr3.Flags = __readcr3();
1309 __writecr3(GuestCr3.Flags);
1310
1311 //
1312 // First check
1313 //
1314 if (!CheckAccessValidityAndSafety(AlignedAddress, sizeof(CHAR)))
1315 {
1316 //
1317 // Error
1318 //
1319
1320 //
1321 // Move back to original cr3
1322 //
1323 __writecr3(OriginalCr3.Flags);
1324 return 0;
1325 }
1326
1327 while (TRUE)
1328 {
1329 /*
1330 Temp = *S;
1331 */
1332 MemoryMapperReadMemorySafe((UINT64)S, &Temp, sizeof(CHAR));
1333
1334 if (Temp != '\0')
1335 {
1336 Count++;
1337 S++;
1338 }
1339 else
1340 {
1341 //
1342 // Move back to original cr3
1343 //
1344 __writecr3(OriginalCr3.Flags);
1345 return Count;
1346 }
1347
1348 if (!((UINT64)S & (PAGE_SIZE - 1)))
1349 {
1350 if (!CheckAccessValidityAndSafety((UINT64)S, sizeof(CHAR)))
1351 {
1352 //
1353 // Error
1354 //
1355
1356 //
1357 // Move back to original cr3
1358 //
1359 __writecr3(OriginalCr3.Flags);
1360 return 0;
1361 }
1362 }
1363 }
1364
1365 //
1366 // Move back to original cr3
1367 //
1368 __writecr3(OriginalCr3.Flags);
1369}
ThreeOpFunc1 interlocked_compare_exchange ThreeOpFunc2 event_inject_error_code memcpy TwoOpFunc1 ed eb eq interlocked_exchange interlocked_exchange_add 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 OneOpFunc2 print formats event_enable event_disable event_clear test_statement spinlock_lock spinlock_unlock event_sc 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 VarArgFunc1 printf OperatorsTwoOperand or xor and asr asl add sub mul div mod gt lt egt elt equal neq OperatorsOneOperand inc dec reference dereference SemantiRules start_of_if jmp jz jnz jmp_to_end_and_jzcompleted end_of_if start_of_while end_of_while vargstart 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:51

◆ VmxCompatibleWcscmp()

INT32 VmxCompatibleWcscmp ( const wchar_t * Address1,
const wchar_t * 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
1614{
1615 wchar_t C1 = NULL_ZERO, C2 = NULL_ZERO;
1616 INT32 Result = 0;
1617 UINT32 Count = 0;
1618 UINT64 AlignedAddress1, AlignedAddress2;
1619 CR3_TYPE GuestCr3;
1620 CR3_TYPE OriginalCr3;
1621
1622 AlignedAddress1 = (UINT64)PAGE_ALIGN((UINT64)Address1);
1623 AlignedAddress2 = (UINT64)PAGE_ALIGN((UINT64)Address2);
1624
1625 //
1626 // Find the current process cr3
1627 //
1629
1630 //
1631 // Move to new cr3
1632 //
1633 OriginalCr3.Flags = __readcr3();
1634 __writecr3(GuestCr3.Flags);
1635
1636 //
1637 // First check
1638 //
1639 if (!CheckAccessValidityAndSafety(AlignedAddress1, sizeof(wchar_t)) || !CheckAccessValidityAndSafety(AlignedAddress2, sizeof(wchar_t)))
1640 {
1641 //
1642 // Error
1643 //
1644
1645 //
1646 // Move back to original cr3
1647 //
1648 __writecr3(OriginalCr3.Flags);
1649 return 0x2;
1650 }
1651
1652 do
1653 {
1654 //
1655 // Check to see if we have byte number constraints
1656 //
1657 if (IsWcsncmp)
1658 {
1659 if (Count == Num)
1660 {
1661 //
1662 // Maximum number of bytes reached
1663 //
1664 break;
1665 }
1666 else
1667 {
1668 //
1669 // Maximum number of bytes not reached
1670 //
1671 Count++;
1672 }
1673 }
1674
1675 /*
1676 C1 = *Address1;
1677 */
1678 MemoryMapperReadMemorySafe((UINT64)Address1, &C1, sizeof(wchar_t));
1679
1680 /*
1681 C2 = *Address2;
1682 */
1683 MemoryMapperReadMemorySafe((UINT64)Address2, &C2, sizeof(wchar_t));
1684
1685 Address1++;
1686 Address2++;
1687
1688 if (!((UINT64)AlignedAddress1 & (PAGE_SIZE - 1)))
1689 {
1690 if (!CheckAccessValidityAndSafety((UINT64)AlignedAddress1, sizeof(wchar_t)))
1691 {
1692 //
1693 // Error
1694 //
1695
1696 //
1697 // Move back to original cr3
1698 //
1699 __writecr3(OriginalCr3.Flags);
1700 return 0x2;
1701 }
1702 }
1703
1704 if (!((UINT64)AlignedAddress2 & (PAGE_SIZE - 1)))
1705 {
1706 if (!CheckAccessValidityAndSafety((UINT64)AlignedAddress2, sizeof(wchar_t)))
1707 {
1708 //
1709 // Error
1710 //
1711
1712 //
1713 // Move back to original cr3
1714 //
1715 __writecr3(OriginalCr3.Flags);
1716 return 0x2;
1717 }
1718 }
1719
1720 Result = C1 - C2;
1721 } while (!Result && C2);
1722
1723 if (Result < 0)
1724 {
1725 Result = -1;
1726 }
1727 else if (Result > 0)
1728 {
1729 Result = 1;
1730 }
1731
1732 //
1733 // Move back to original cr3
1734 //
1735 __writecr3(OriginalCr3.Flags);
1736 return Result;
1737}

◆ VmxCompatibleWcslen()

UINT32 VmxCompatibleWcslen ( const wchar_t * S)

implementation of vmx-root mode compatible wcslen

Parameters
S
Returns
UINT32 If 0x0 indicates an error, otherwise length of the string
1380{
1381 wchar_t Temp = NULL_ZERO;
1382 UINT32 Count = 0;
1383 UINT64 AlignedAddress;
1384 CR3_TYPE GuestCr3;
1385 CR3_TYPE OriginalCr3;
1386
1387 AlignedAddress = (UINT64)PAGE_ALIGN((UINT64)S);
1388
1389 //
1390 // Find the current process cr3
1391 //
1393
1394 //
1395 // Move to new cr3
1396 //
1397 OriginalCr3.Flags = __readcr3();
1398 __writecr3(GuestCr3.Flags);
1399
1400 AlignedAddress = (UINT64)PAGE_ALIGN((UINT64)S);
1401
1402 //
1403 // First check
1404 //
1405 if (!CheckAccessValidityAndSafety(AlignedAddress, sizeof(wchar_t)))
1406 {
1407 //
1408 // Error
1409 //
1410
1411 //
1412 // Move back to original cr3
1413 //
1414 __writecr3(OriginalCr3.Flags);
1415 return 0;
1416 }
1417
1418 while (TRUE)
1419 {
1420 /*
1421 Temp = *S;
1422 */
1423 MemoryMapperReadMemorySafe((UINT64)S, &Temp, sizeof(wchar_t));
1424
1425 if (Temp != '\0\0')
1426 {
1427 Count++;
1428 S++;
1429 }
1430 else
1431 {
1432 //
1433 // Move back to original cr3
1434 //
1435 __writecr3(OriginalCr3.Flags);
1436 return Count;
1437 }
1438
1439 if (!((UINT64)S & (PAGE_SIZE - 1)))
1440 {
1441 if (!CheckAccessValidityAndSafety((UINT64)S, sizeof(wchar_t)))
1442 {
1443 //
1444 // Error
1445 //
1446
1447 //
1448 // Move back to original cr3
1449 //
1450 __writecr3(OriginalCr3.Flags);
1451 return 0;
1452 }
1453 }
1454 }
1455
1456 //
1457 // Move back to original cr3
1458 //
1459 __writecr3(OriginalCr3.Flags);
1460}

◆ 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
542{
543 CR_FIXED CrFixed = {0};
544 CR4 Cr4 = {0};
545 CR0 Cr0 = {0};
546
547 //
548 // Fix Cr0
549 //
550 CrFixed.Flags = __readmsr(IA32_VMX_CR0_FIXED0);
551 Cr0.AsUInt = __readcr0();
552 Cr0.AsUInt |= CrFixed.Fields.Low;
553 CrFixed.Flags = __readmsr(IA32_VMX_CR0_FIXED1);
554 Cr0.AsUInt &= CrFixed.Fields.Low;
555 __writecr0(Cr0.AsUInt);
556
557 //
558 // Fix Cr4
559 //
560 CrFixed.Flags = __readmsr(IA32_VMX_CR4_FIXED0);
561 Cr4.AsUInt = __readcr4();
562 Cr4.AsUInt |= CrFixed.Fields.Low;
563 CrFixed.Flags = __readmsr(IA32_VMX_CR4_FIXED1);
564 Cr4.AsUInt &= CrFixed.Fields.Low;
565 __writecr4(Cr4.AsUInt);
566}
Definition Common.h:244
unsigned long Low
Definition Common.h:249
struct _CR_FIXED::@0 Fields
UINT64 Flags
Definition Common.h:245

◆ 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
223{
224 if (g_GuestState)
225 {
226 ULONG CurrentCore = KeGetCurrentProcessorNumberEx(NULL);
227 VIRTUAL_MACHINE_STATE * CurrentVmState = &g_GuestState[CurrentCore];
228
230 }
231 else
232 {
233 //
234 // The structure for guest state is not initialized, thus, we're in VMX non-root
235 //
237 }
238}
unsigned long ULONG
Definition BasicTypes.h:37
@ VmxExecutionModeNonRoot
Definition DataTypes.h:82
@ VmxExecutionModeRoot
Definition DataTypes.h:83
VIRTUAL_MACHINE_STATE * g_GuestState
Save the state and variables related to virtualization on each to logical core.
Definition GlobalVariables.h:38
The status of each core after and before VMX.
Definition State.h:290
BOOLEAN IsOnVmxRootMode
Definition State.h:291

◆ VmxGetCurrentLaunchState()

BOOLEAN VmxGetCurrentLaunchState ( )

Check if the VMX is launched or not.

Returns
BOOLEAN Returns true if it's launched, otherwise false
247{
248 ULONG CurrentCore = KeGetCurrentProcessorNumberEx(NULL);
249 VIRTUAL_MACHINE_STATE * CurrentVmState = &g_GuestState[CurrentCore];
250
251 return CurrentVmState->HasLaunched;
252}
BOOLEAN HasLaunched
Definition State.h:293

◆ VmxHandleTripleFaults()

VOID VmxHandleTripleFaults ( VIRTUAL_MACHINE_STATE * VCpu)

Handling triple fault VM-exits.

Parameters
VCpuThe virtual processor's state
Returns
VOID
51{
52 LogError("Err, triple fault error occurred!");
53
54 //
55 // This error cannot be recovered, produce debug results
56 //
58
59 //
60 // We won't further continue after this error
61 //
62 DbgBreakPoint();
63}
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
34{
35 LogError("Why vm-exit for VMX preemption timer happened?");
36
37 //
38 // Not increase the RIP by default
39 //
41}
VOID HvSuppressRipIncrement(VIRTUAL_MACHINE_STATE *VCpu)
Suppress the incrementation of RIP.
Definition Hv.c:324

◆ VmxHandleXsetbv()

VOID VmxHandleXsetbv ( VIRTUAL_MACHINE_STATE * VCpu)

Handling XSETBV Instruction vm-exits.

Parameters
VCpu
Returns
VOID
22{
23 _xsetbv(VCpu->Regs->rcx & 0xffffffff, VCpu->Regs->rdx << 32 | VCpu->Regs->rax);
24}
GUEST_REGS * Regs
Definition State.h:305
UINT64 rax
Definition BasicTypes.h:75
UINT64 rcx
Definition BasicTypes.h:76
UINT64 rdx
Definition BasicTypes.h:77

◆ VmxInitialize()

BOOLEAN VmxInitialize ( )

Initialize the VMX operation.

Returns
BOOLEAN Returns true if vmx initialized successfully
261{
262 ULONG ProcessorsCount;
263
264 //
265 // ****** Start Virtualizing Current System ******
266 //
267
268 //
269 // Initiating EPTP and VMX
270 //
272 {
273 //
274 // there was error somewhere in initializing
275 //
276 return FALSE;
277 }
278
279 ProcessorsCount = KeQueryActiveProcessorCount(0);
280
281 for (size_t ProcessorID = 0; ProcessorID < ProcessorsCount; ProcessorID++)
282 {
283 //
284 // *** Launching VM for Test (in the all logical processor) ***
285 //
286
287 VIRTUAL_MACHINE_STATE * GuestState = &g_GuestState[ProcessorID];
288
289 //
290 // Allocating VMM Stack
291 //
292 if (!VmxAllocateVmmStack(GuestState))
293 {
294 //
295 // Some error in allocating Vmm Stack
296 //
297 return FALSE;
298 }
299
300 //
301 // Allocating MSR Bit
302 //
303 if (!VmxAllocateMsrBitmap(GuestState))
304 {
305 //
306 // Some error in allocating Msr Bitmaps
307 //
308 return FALSE;
309 }
310
311 //
312 // Allocating I/O Bit
313 //
314 if (!VmxAllocateIoBitmaps(GuestState))
315 {
316 //
317 // Some error in allocating I/O Bitmaps
318 //
319 return FALSE;
320 }
321
322#if USE_DEFAULT_OS_IDT_AS_HOST_IDT == FALSE
323
324 //
325 // Allocating Host IDT
326 //
327 if (!VmxAllocateHostIdt(GuestState))
328 {
329 //
330 // Some error in allocating Host IDT
331 //
332 return FALSE;
333 }
334#endif // USE_DEFAULT_OS_IDT_AS_HOST_IDT == FALSE
335
336#if USE_DEFAULT_OS_GDT_AS_HOST_GDT == FALSE
337
338 //
339 // Allocating Host GDT
340 //
341 if (!VmxAllocateHostGdt(GuestState))
342 {
343 //
344 // Some error in allocating Host GDT
345 //
346 return FALSE;
347 }
348
349 //
350 // Allocating Host TSS
351 //
352 if (!VmxAllocateHostTss(GuestState))
353 {
354 //
355 // Some error in allocating Host TSS
356 //
357 return FALSE;
358 }
359
360#endif // USE_DEFAULT_OS_GDT_AS_HOST_GDT == FALSE
361
362#if USE_INTERRUPT_STACK_TABLE == TRUE
363
364 //
365 // Allocating Host Interrupt Stack
366 //
367 if (!VmxAllocateHostInterruptStack(GuestState))
368 {
369 //
370 // Some error in allocating Interrupt Stack
371 //
372 return FALSE;
373 }
374
375#endif // USE_INTERRUPT_STACK_TABLE == TRUE
376 }
377
378 //
379 // Create a bitmap of the MSRs that cause #GP
380 //
382
383 if (g_MsrBitmapInvalidMsrs == NULL)
384 {
385 return FALSE;
386 }
387
388 //
389 // As we want to support more than 32 processor (64 logical-core)
390 // we let windows execute our routine for us
391 //
392 KeGenericCallDpc(DpcRoutineInitializeGuest, 0x0);
393
394 //
395 // Check if everything is ok then return true otherwise false
396 //
397 if (AsmVmxVmcall(VMCALL_TEST, 0x22, 0x333, 0x4444) == STATUS_SUCCESS)
398 {
399 return TRUE;
400 }
401 else
402 {
403 return FALSE;
404 }
405}
UINT64 * g_MsrBitmapInvalidMsrs
Bitmap of MSRs that cause #GP.
Definition GlobalVariables.h:107
NTSTATUS AsmVmxVmcall(unsigned long long VmcallNumber, unsigned long long OptionalParam1, unsigned long long OptionalParam2, long long OptionalParam3)
Request Vmcall.
#define VMCALL_TEST
VMCALL to test hypervisor.
Definition Vmcall.h:22
BOOLEAN VmxPerformVirtualizationOnAllCores()
Initialize essential VMX Operation tasks.
Definition Vmx.c:413
BOOLEAN VmxAllocateHostIdt(_Inout_ VIRTUAL_MACHINE_STATE *VCpu)
Allocate a buffer for host IDT.
Definition VmxRegions.c:297
UINT64 * VmxAllocateInvalidMsrBimap()
Allocates a buffer and tests for the MSRs that cause #GP.
Definition VmxRegions.c:264
BOOLEAN VmxAllocateIoBitmaps(_Inout_ VIRTUAL_MACHINE_STATE *VCpu)
Allocate a buffer for I/O Bitmap.
Definition VmxRegions.c:221
BOOLEAN VmxAllocateMsrBitmap(_Inout_ VIRTUAL_MACHINE_STATE *VCpu)
Allocate a buffer for Msr Bitmap.
Definition VmxRegions.c:192
BOOLEAN VmxAllocateHostInterruptStack(_Inout_ VIRTUAL_MACHINE_STATE *VCpu)
Allocate a buffer for host interrupt stack.
Definition VmxRegions.c:394
BOOLEAN VmxAllocateVmmStack(_Inout_ VIRTUAL_MACHINE_STATE *VCpu)
Allocate VMM Stack.
Definition VmxRegions.c:167
BOOLEAN VmxAllocateHostGdt(_Inout_ VIRTUAL_MACHINE_STATE *VCpu)
Allocate a buffer for host GDT.
Definition VmxRegions.c:332
BOOLEAN VmxAllocateHostTss(_Inout_ VIRTUAL_MACHINE_STATE *VCpu)
Allocate a buffer for host TSS.
Definition VmxRegions.c:367
VOID DpcRoutineInitializeGuest(KDPC *Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVOID SystemArgument2)
The broadcast function which initialize the guest.
Definition DpcRoutines.c:1714

◆ VmxLoadVmcs()

BOOLEAN VmxLoadVmcs ( _In_ VIRTUAL_MACHINE_STATE * VCpu)

◆ VmxPerformTermination()

VOID VmxPerformTermination ( )

Terminate Vmx on all logical cores.

Returns
VOID
1201{
1202 ULONG ProcessorsCount;
1203
1204 LogDebugInfo("Terminating VMX...\n");
1205
1206 //
1207 // Get number of processors
1208 //
1209 ProcessorsCount = KeQueryActiveProcessorCount(0);
1210
1211 //
1212 // ******* Terminating Vmx *******
1213 //
1214
1215 //
1216 // Unhide (disable and de-allocate) transparent-mode
1217 //
1219
1220 //
1221 // Remove All the hooks if any
1222 //
1224
1225 //
1226 // Restore the state of execution trap hooks
1227 //
1229
1230 //
1231 // Broadcast to terminate Vmx
1232 //
1233 KeGenericCallDpc(DpcRoutineTerminateGuest, 0x0);
1234
1235 //
1236 // ****** De-allocatee global variables ******
1237 //
1238
1239 //
1240 // Free the buffer related to MSRs that cause #GP
1241 //
1244
1245 //
1246 // Free Identity Page Table
1247 //
1248 for (size_t i = 0; i < ProcessorsCount; i++)
1249 {
1250 if (g_GuestState[i].EptPageTable != NULL)
1251 {
1252 MmFreeContiguousMemory(g_GuestState[i].EptPageTable);
1253 }
1254
1256 }
1257
1258 //
1259 // Free EptState
1260 //
1262 g_EptState = NULL;
1263
1264 //
1265 // Free the Pool manager
1266 //
1268
1269 //
1270 // Uninitialize memory mapper
1271 //
1273
1274 //
1275 // Free g_GuestState
1276 //
1278
1279 LogDebugInfo("VMX operation turned off successfully");
1280}
VOID EptHookUnHookAll()
Remove all hooks from the hooked pages list and invalidate TLB @detailsShould be called from Vmx Non-...
Definition EptHook.c:2431
VOID ExecTrapUninitialize()
Uinitialize the needed structure for the reversing machine.
Definition ExecTrap.c:605
VOID GlobalGuestStateFreeMemory(VOID)
Free guest state memory.
Definition GlobalVariableManagement.c:52
EPT_STATE * g_EptState
Save the state and variables related to EPT.
Definition GlobalVariables.h:50
#define LogDebugInfo(format,...)
Log, initialize boot information and debug information.
Definition HyperDbgHyperLogIntrinsics.h:155
VOID PlatformMemFreePool(PVOID BufferAddress)
Free (dellocate) a non-paged buffer.
Definition Mem.c:86
VOID MemoryMapperUninitialize()
uninitialize the Memory Mapper
Definition MemoryMapper.c:716
VOID PoolManagerUninitialize()
Uninitialize the pool manager (free the buffers, etc.)
Definition PoolManager.c:87
NTSTATUS TransparentUnhideDebugger()
Deactivate transparent-mode.
Definition Transparency.c:425
VOID DpcRoutineTerminateGuest(KDPC *Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVOID SystemArgument2)
The broadcast function which terminate the guest.
Definition DpcRoutines.c:1745
NULL()
Definition test-case-generator.py:530
PVMM_EPT_PAGE_TABLE EptPageTable
Definition State.h:342

◆ VmxPerformVirtualizationOnAllCores()

BOOLEAN VmxPerformVirtualizationOnAllCores ( )

Initialize essential VMX Operation tasks.

Returns
BOOLEAN Returns true if vmx is successfully initialized
414{
415 PAGED_CODE();
416
417 if (!VmxCheckVmxSupport())
418 {
419 LogError("Err, VMX is not supported in this machine");
420 return FALSE;
421 }
422
423 //
424 // Allocate global variable to hold Ept State
425 //
427
428 if (!g_EptState)
429 {
430 LogError("Err, insufficient memory");
431 return FALSE;
432 }
433
434 //
435 // Initialize the list of hooked pages detail
436 //
438
439 //
440 // Check whether EPT is supported or not
441 //
442 if (!EptCheckFeatures())
443 {
444 LogError("Err, your processor doesn't support all EPT features");
445 return FALSE;
446 }
447 else
448 {
449 //
450 // Our processor supports EPT, now let's build MTRR
451 //
452 LogDebugInfo("Your processor supports all EPT features");
453
454 //
455 // Build MTRR Map
456 //
457 if (!EptBuildMtrrMap())
458 {
459 LogError("Err, could not build MTRR memory map");
460 return FALSE;
461 }
462
463 LogDebugInfo("MTRR memory map built successfully");
464 }
465
466 //
467 // Initialize Pool Manager
468 //
470 {
471 LogError("Err, could not initialize pool manager");
472 return FALSE;
473 }
474
476 {
477 //
478 // There were some errors in EptLogicalProcessorInitialize
479 //
480 return FALSE;
481 }
482
483 //
484 // Broadcast to run vmx-specific task to virtualize cores
485 //
487
488 //
489 // Everything is ok, let's return true
490 //
491 return TRUE;
492}
VOID BroadcastVmxVirtualizationAllCores()
routines to broadcast virtualization and vmx initialization on all cores
Definition Broadcast.c:21
BOOLEAN EptLogicalProcessorInitialize(VOID)
Initialize EPT for an individual logical processor.
Definition Ept.c:759
BOOLEAN EptBuildMtrrMap(VOID)
Build MTRR Map of current physical addresses.
Definition Ept.c:156
BOOLEAN EptCheckFeatures(VOID)
Check whether EPT features are present or not.
Definition Ept.c:22
PVOID PlatformMemAllocateZeroedNonPagedPool(SIZE_T NumberOfBytes)
Allocate a non-paged buffer (zeroed)
Definition Mem.c:69
BOOLEAN PoolManagerInitialize()
Initializes the pool manager.
Definition PoolManager.c:53
BOOLEAN VmxCheckVmxSupport()
Check whether VMX Feature is supported or not.
Definition Vmx.c:166
FORCEINLINE VOID InitializeListHead(_Out_ PLIST_ENTRY ListHead)
Definition Windows.h:41
Main structure for saving the state of EPT among the project.
Definition Ept.h:117
LIST_ENTRY HookedPagesList
Definition Ept.h:118

◆ VmxPerformVirtualizationOnSpecificCore()

BOOLEAN VmxPerformVirtualizationOnSpecificCore ( )

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

Returns
BOOLEAN
501{
502 ULONG CurrentCore = KeGetCurrentProcessorNumberEx(NULL);
503 VIRTUAL_MACHINE_STATE * VCpu = &g_GuestState[CurrentCore];
504
505 LogDebugInfo("Allocating vmx regions for logical core %d", CurrentCore);
506
507 //
508 // Enabling VMX Operation
509 //
511
512 //
513 // Fix Cr4 and Cr0 bits during VMX operation
514 //
516
517 LogDebugInfo("VMX-Operation enabled successfully");
518
519 if (!VmxAllocateVmxonRegion(VCpu))
520 {
521 LogError("Err, allocating memory for vmxon region was not successful");
522 return FALSE;
523 }
524 if (!VmxAllocateVmcsRegion(VCpu))
525 {
526 LogError("Err, allocating memory for vmcs region was not successful");
527 return FALSE;
528 }
529
530 return TRUE;
531}
void AsmEnableVmxOperation()
Enable VMX Operation.
VOID VmxFixCr4AndCr0Bits()
Fix values for cr0 and cr4 bits.
Definition Vmx.c:541
_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:103

◆ 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
1190{
1191 return g_GuestState[KeGetCurrentProcessorNumberEx(NULL)].VmxoffState.GuestRip;
1192}
VMX_VMXOFF_STATE VmxoffState
Definition State.h:328
UINT64 GuestRip
Definition State.h:153

◆ 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
1179{
1180 return g_GuestState[KeGetCurrentProcessorNumberEx(NULL)].VmxoffState.GuestRsp;
1181}
UINT64 GuestRsp
Definition State.h:154

◆ 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
700{
701 NTSTATUS Status = STATUS_SUCCESS;
702 ULONG CurrentCore = KeGetCurrentProcessorNumberEx(NULL);
703 VIRTUAL_MACHINE_STATE * VCpu = &g_GuestState[CurrentCore];
704
705 //
706 // Execute Vmcall to to turn off vmx from Vmx root mode
707 //
709
710 if (Status == STATUS_SUCCESS)
711 {
712 LogDebugInfo("VMX terminated on logical core %d\n", CurrentCore);
713
714 //
715 // Free the destination memory
716 //
717 MmFreeContiguousMemory((PVOID)VCpu->VmxonRegionVirtualAddress);
718 MmFreeContiguousMemory((PVOID)VCpu->VmcsRegionVirtualAddress);
719 PlatformMemFreePool((PVOID)VCpu->VmmStack);
723#if USE_DEFAULT_OS_IDT_AS_HOST_IDT == FALSE
724 PlatformMemFreePool((PVOID)VCpu->HostIdt);
725#endif // USE_DEFAULT_OS_IDT_AS_HOST_IDT == FALSE
726
727#if USE_DEFAULT_OS_GDT_AS_HOST_GDT == FALSE
728 PlatformMemFreePool((PVOID)VCpu->HostGdt);
729 PlatformMemFreePool((PVOID)VCpu->HostTss);
730#endif // USE_DEFAULT_OS_GDT_AS_HOST_GDT == FALSE
731
732#if USE_INTERRUPT_STACK_TABLE == TRUE
734#endif // USE_INTERRUPT_STACK_TABLE == FALSE
735
736 return TRUE;
737 }
738
739 return FALSE;
740}
#define NULL64_ZERO
Definition BasicTypes.h:52
#define VMCALL_VMXOFF
VMCALL to Call VMXOFF to turn off the hypervisor.
Definition Vmcall.h:28
UINT64 VmxonRegionVirtualAddress
Definition State.h:311
UINT64 HostInterruptStack
Definition State.h:336
UINT64 HostGdt
Definition State.h:334
UINT64 IoBitmapVirtualAddressB
Definition State.h:319
UINT64 MsrBitmapVirtualAddress
Definition State.h:315
UINT64 VmmStack
Definition State.h:314
UINT64 HostTss
Definition State.h:335
UINT64 HostIdt
Definition State.h:333
UINT64 IoBitmapVirtualAddressA
Definition State.h:317
UINT64 VmcsRegionVirtualAddress
Definition State.h:313

◆ 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
606{
607 UINT64 ErrorCode = 0;
608 ULONG CurrentCore = KeGetCurrentProcessorNumberEx(NULL);
609 VIRTUAL_MACHINE_STATE * VCpu = &g_GuestState[CurrentCore];
610
611 LogDebugInfo("Virtualizing current system (logical core : 0x%x)", CurrentCore);
612
613#if USE_DEFAULT_OS_IDT_AS_HOST_IDT == FALSE
614
615 //
616 // Prepare Host IDT
617 //
619#endif // USE_DEFAULT_OS_IDT_AS_HOST_IDT == FALSE
620
621#if USE_DEFAULT_OS_GDT_AS_HOST_GDT == FALSE
622
623 //
624 // Prepare Host GDT and TSS
625 //
626 SegmentPrepareHostGdt((SEGMENT_DESCRIPTOR_32 *)AsmGetGdtBase(),
628 AsmGetTr(),
629 VCpu->HostInterruptStack,
630 (SEGMENT_DESCRIPTOR_32 *)VCpu->HostGdt,
631 (TASK_STATE_SEGMENT_64 *)VCpu->HostTss);
632
633#endif // USE_DEFAULT_OS_GDT_AS_HOST_GDT == FALSE
634
635 //
636 // Clear the VMCS State
637 //
638 if (!VmxClearVmcsState(VCpu))
639 {
640 LogError("Err, failed to clear vmcs");
641 return FALSE;
642 }
643
644 //
645 // Load VMCS (Set the Current VMCS)
646 //
647 if (!VmxLoadVmcs(VCpu))
648 {
649 LogError("Err, failed to load vmcs");
650 return FALSE;
651 }
652
653 LogDebugInfo("Setting up VMCS for current logical core");
654
655 VmxSetupVmcs(VCpu, GuestStack);
656
657 LogDebugInfo("Executing VMLAUNCH on logical core %d", CurrentCore);
658
659 //
660 // Setting the state to indicate current core is currently virtualized
661 //
662
663 VCpu->HasLaunched = TRUE;
664
665 __vmx_vmlaunch();
666
667 //
668 // ******** if Vmlaunch succeed will never be here ! ********
669 //
670
671 //
672 // If failed, then indicate that current core is not currently virtualized
673 //
674 VCpu->HasLaunched = FALSE;
675
676 //
677 // Read error code firstly
678 //
679 __vmx_vmread(VMCS_VM_INSTRUCTION_ERROR, &ErrorCode);
680
681 LogError("Err, unable to execute VMLAUNCH, status : 0x%llx", ErrorCode);
682
683 //
684 // Then Execute Vmxoff
685 //
686 __vmx_off();
687 LogError("Err, VMXOFF Executed Successfully but it was because of an error");
688
689 return FALSE;
690}
VOID IdtEmulationPrepareHostIdt(_Inout_ VIRTUAL_MACHINE_STATE *VCpu)
Prepare Host IDT.
Definition IdtEmulation.c:67
unsigned short AsmGetTr()
Get TR Register.
unsigned short AsmGetGdtLimit()
Get GDT Limit.
unsigned long long AsmGetGdtBase()
get GDT base
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 VmxClearVmcsState(VIRTUAL_MACHINE_STATE *VCpu)
Clearing Vmcs status using vmclear instruction.
Definition Vmx.c:766
_Use_decl_annotations_ BOOLEAN VmxLoadVmcs(VIRTUAL_MACHINE_STATE *VCpu)
Implementation of VMPTRLD instruction.
Definition Vmx.c:798
_Use_decl_annotations_ BOOLEAN VmxSetupVmcs(VIRTUAL_MACHINE_STATE *VCpu, PVOID GuestStack)
Create and Configure a Vmcs Layout.
Definition Vmx.c:820

◆ VmxVmptrst()

VOID VmxVmptrst ( )

Implementation of VMPTRST instruction.

Returns
VOID
749{
750 PHYSICAL_ADDRESS VmcsPhysicalAddr;
751 VmcsPhysicalAddr.QuadPart = 0;
752 __vmx_vmptrst((unsigned __int64 *)&VmcsPhysicalAddr);
753
754 LogDebugInfo("VMPTRST result : %llx", VmcsPhysicalAddr);
755}

◆ VmxVmread16()

UCHAR VmxVmread16 ( size_t Field,
UINT16 FieldValue )
externinline

VMX VMREAD instruction (16-bit)

Parameters
Field
FieldValue
Returns
UCHAR
56{
57 UINT64 TargetField = 0ull;
58
59 TargetField = FieldValue;
60
61 return __vmx_vmread((size_t)Field, (size_t *)TargetField);
62}

◆ VmxVmread16P()

UCHAR VmxVmread16P ( size_t Field,
UINT16 * FieldValue )
externinline

VMX VMREAD instruction (16-bit)

Parameters
Field
FieldValue
Returns
UCHAR
106{
107 UINT64 TargetField = 0ull;
108
109 TargetField = (UINT64)FieldValue;
110
111 return __vmx_vmread((size_t)Field, (size_t *)TargetField);
112}

◆ VmxVmread32()

UCHAR VmxVmread32 ( size_t Field,
UINT32 FieldValue )
externinline

VMX VMREAD instruction (32-bit)

Parameters
Field
FieldValue
Returns
UCHAR
38{
39 UINT64 TargetField = 0ull;
40
41 TargetField = FieldValue;
42
43 return __vmx_vmread((size_t)Field, (size_t *)TargetField);
44}

◆ VmxVmread32P()

UCHAR VmxVmread32P ( size_t Field,
UINT32 * FieldValue )
externinline

VMX VMREAD instruction (32-bit)

Parameters
Field
FieldValue
Returns
UCHAR
88{
89 UINT64 TargetField = 0ull;
90
91 TargetField = (UINT64)FieldValue;
92
93 return __vmx_vmread((size_t)Field, (size_t *)TargetField);
94}

◆ VmxVmread64()

UCHAR VmxVmread64 ( size_t Field,
UINT64 FieldValue )
externinline

VMX VMREAD instruction (64-bit)

Parameters
Field
FieldValue
Returns
UCHAR
24{
25 return __vmx_vmread((size_t)Field, (size_t *)FieldValue);
26}

◆ VmxVmread64P()

UCHAR VmxVmread64P ( size_t Field,
UINT64 * FieldValue )
externinline

VMX VMREAD instruction (64-bit)

Parameters
Field
FieldValue
Returns
UCHAR
74{
75 return __vmx_vmread((size_t)Field, (size_t *)FieldValue);
76}

◆ VmxVmresume()

VOID VmxVmresume ( )

Resume VM using VMRESUME instruction.

Returns
VOID
1021{
1022 UINT64 ErrorCode = 0;
1023
1024 __vmx_vmresume();
1025
1026 //
1027 // if VMRESUME succeed will never be here !
1028 //
1029
1030 __vmx_vmread(VMCS_VM_INSTRUCTION_ERROR, &ErrorCode);
1031 __vmx_off();
1032
1033 //
1034 // It's such a bad error because we don't where to go !
1035 // prefer to break
1036 //
1037 LogError("Err, in executing VMRESUME , status : 0x%llx", ErrorCode);
1038}

◆ VmxVmwrite16()

UCHAR VmxVmwrite16 ( size_t Field,
UINT16 FieldValue )
externinline

VMX VMWRITE instruction (16-bit)

Parameters
Field
FieldValue
Returns
UCHAR
154{
155 UINT64 TargetValue = NULL64_ZERO;
156 TargetValue = (UINT64)FieldValue;
157 return __vmx_vmwrite((size_t)Field, (size_t)TargetValue);
158}

◆ VmxVmwrite32()

UCHAR VmxVmwrite32 ( size_t Field,
UINT32 FieldValue )
externinline

VMX VMWRITE instruction (32-bit)

Parameters
Field
FieldValue
Returns
UCHAR
138{
139 UINT64 TargetValue = NULL64_ZERO;
140 TargetValue = (UINT64)FieldValue;
141 return __vmx_vmwrite((size_t)Field, (size_t)TargetValue);
142}

◆ VmxVmwrite64()

UCHAR VmxVmwrite64 ( size_t Field,
UINT64 FieldValue )
externinline

VMX VMWRITE instruction (64-bit)

Parameters
Field
FieldValue
Returns
UCHAR
124{
125 return __vmx_vmwrite((size_t)Field, (size_t)FieldValue);
126}

◆ VmxVmxoff()

VOID VmxVmxoff ( VIRTUAL_MACHINE_STATE * VCpu)

Prepare and execute Vmxoff instruction.

Parameters
VCpuThe virtual processor's state
Returns
VOID
1102{
1103 UINT64 GuestRSP = 0; // Save a pointer to guest rsp for times that we want to return to previous guest stateS
1104 UINT64 GuestRIP = 0; // Save a pointer to guest rip for times that we want to return to previous guest state
1105 UINT64 GuestCr3 = 0;
1106 UINT64 ExitInstructionLength = 0;
1107
1108 //
1109 // According to SimpleVisor :
1110 // Our callback routine may have interrupted an arbitrary user process,
1111 // and therefore not a thread running with a system-wide page directory.
1112 // Therefore if we return back to the original caller after turning off
1113 // VMX, it will keep our current "host" CR3 value which we set on entry
1114 // to the PML4 of the SYSTEM process. We want to return back with the
1115 // correct value of the "guest" CR3, so that the currently executing
1116 // process continues to run with its expected address space mappings.
1117 //
1118
1119 __vmx_vmread(VMCS_GUEST_CR3, &GuestCr3);
1120 __writecr3(GuestCr3);
1121
1122 //
1123 // Read guest rsp and rip
1124 //
1125 __vmx_vmread(VMCS_GUEST_RIP, &GuestRIP);
1126 __vmx_vmread(VMCS_GUEST_RSP, &GuestRSP);
1127
1128 //
1129 // Read instruction length
1130 //
1131 __vmx_vmread(VMCS_VMEXIT_INSTRUCTION_LENGTH, &ExitInstructionLength);
1132 GuestRIP += ExitInstructionLength;
1133
1134 //
1135 // Set the previous register states
1136 //
1137 VCpu->VmxoffState.GuestRip = GuestRIP;
1138 VCpu->VmxoffState.GuestRsp = GuestRSP;
1139
1140 //
1141 // Notify the Vmexit handler that VMX already turned off
1142 //
1144
1145 //
1146 // Restore the previous FS, GS , GDTR and IDTR register as patchguard might find the modified
1147 //
1149
1150 //
1151 // Before using vmxoff, you first need to use vmclear on any VMCSes that you want to be able to use again.
1152 // See sections 24.1 and 24.11 of the SDM.
1153 //
1154 VmxClearVmcsState(VCpu);
1155
1156 //
1157 // Execute Vmxoff
1158 //
1159 __vmx_off();
1160
1161 //
1162 // Indicate the current core is not currently virtualized
1163 //
1164 VCpu->HasLaunched = FALSE;
1165
1166 //
1167 // Now that VMX is OFF, we have to unset vmx-enable bit on cr4
1168 //
1169 __writecr4(__readcr4() & (~X86_CR4_VMXE));
1170}
VOID HvRestoreRegisters()
Reset GDTR/IDTR and other old when you do vmxoff as the patchguard will detect them left modified.
Definition Hv.c:463
#define X86_CR4_VMXE
Definition Common.h:83
BOOLEAN IsVmxoffExecuted
Definition State.h:152