/// <summary> /// Enable EPT for CPU /// </summary> /// <param name="PML4">PML4 pointer to use</param> VOID EptEnable( IN PEPT_PML4_ENTRY PML4 ) { VMX_CPU_BASED_CONTROLS primary = { 0 }; VMX_SECONDARY_CPU_BASED_CONTROLS secondary = { 0 }; EPT_TABLE_POINTER EPTP = { 0 }; __vmx_vmread( SECONDARY_VM_EXEC_CONTROL, (size_t*)&secondary.All ); __vmx_vmread( CPU_BASED_VM_EXEC_CONTROL, (size_t*)&primary.All ); // Set up the EPTP EPTP.Fields.PhysAddr = MmGetPhysicalAddress( PML4 ).QuadPart >> 12; EPTP.Fields.PageWalkLength = 3; __vmx_vmwrite( EPT_POINTER, EPTP.All ); __vmx_vmwrite( VIRTUAL_PROCESSOR_ID, VM_VPID ); primary.Fields.ActivateSecondaryControl = TRUE; secondary.Fields.EnableEPT = TRUE; if(g_Data->VPIDSpported) secondary.Fields.EnableVPID = TRUE; __vmx_vmwrite( SECONDARY_VM_EXEC_CONTROL, secondary.All ); __vmx_vmwrite( CPU_BASED_VM_EXEC_CONTROL, primary.All ); // Critical step EPT_CTX ctx = { 0 }; __invept( INV_ALL_CONTEXTS, &ctx ); //DPRINT( "HyperBone: CPU %d: %s: EPT enabled\n", CPU_NUM, __FUNCTION__ ); }
static inline void vcpu_launch(void) { size_t vmerr; uint8_t err = __vmx_vmread(VM_INSTRUCTION_ERROR, &vmerr); if (err) VCPU_DEBUG("VM_INSTRUCTION_ERROR: %zd\n", vmerr); err = __vmx_vmlaunch(); if (err) { __vmx_vmread(VM_INSTRUCTION_ERROR, &vmerr); VCPU_DEBUG("__vmx_vmlaunch(): failed %d %d\n", err, vmerr); } }
_Use_decl_annotations_ EXTERN_C static void VminitpLaunchVM() { size_t errorCode = 0; auto vmxStatus = static_cast<VMX_STATUS>(__vmx_vmread(VM_INSTRUCTION_ERROR, &errorCode)); if (vmxStatus != VMX_OK) { LOG_WARN("VM_INSTRUCTION_ERROR = %p %d", errorCode, vmxStatus); } DBG_BREAK(); vmxStatus = static_cast<VMX_STATUS>(__vmx_vmlaunch()); // Here is not be executed with successful vmlaunch. Instead, the context // jumps to an address specified by GUEST_RIP. if (vmxStatus == VMX_ERROR_WITH_STATUS) { vmxStatus = static_cast<VMX_STATUS>(__vmx_vmread(VM_INSTRUCTION_ERROR, &errorCode)); LOG_ERROR("VM_INSTRUCTION_ERROR = %p %d", errorCode, vmxStatus); } DBG_BREAK(); }
/// <summary> /// Disable EPT for CPU /// </summary> VOID EptDisable() { VMX_SECONDARY_CPU_BASED_CONTROLS secondary = { 0 }; __vmx_vmread( SECONDARY_VM_EXEC_CONTROL, (size_t*)&secondary.All ); secondary.Fields.EnableEPT = FALSE; secondary.Fields.EnableVPID = FALSE; __vmx_vmwrite( SECONDARY_VM_EXEC_CONTROL, secondary.All ); // Clear out the EPTP __vmx_vmwrite( EPT_POINTER, 0 ); }
ULONG_PTR FORCEINLINE ShvVmxRead ( _In_ ULONG VmcsFieldId ) { SIZE_T FieldData; // // Because VMXREAD returns an error code, and not the data, it is painful // to use in most circumstances. This simple function simplifies it use. // __vmx_vmread(VmcsFieldId, &FieldData); return FieldData; }