diff --git a/hyperdbg/hyperhv/code/interface/Export.c b/hyperdbg/hyperhv/code/interface/Export.c index eb9a4071..f2d89b43 100644 --- a/hyperdbg/hyperhv/code/interface/Export.c +++ b/hyperdbg/hyperhv/code/interface/Export.c @@ -412,6 +412,17 @@ VmFuncGetDebugctlVmcallOnTargetCore() return CrossVmcallGetDebugctlVmcallOnTargetCore(); } +/** + * @brief Check if CPU support save and load debug controls on exit and load entries + * + * @return BOOLEAN + */ +BOOLEAN +VmFuncCheckCpuSupportForSaveAndLoadDebugControls() +{ + return HvCheckCpuSupportForSaveAndLoadDebugControls(); +} + /** * @brief Set the guest state of IA32_DEBUGCTL * @param Value diff --git a/hyperdbg/hyperhv/code/vmm/vmx/Hv.c b/hyperdbg/hyperhv/code/vmm/vmx/Hv.c index c7c9035a..1cd2299e 100644 --- a/hyperdbg/hyperhv/code/vmm/vmx/Hv.c +++ b/hyperdbg/hyperhv/code/vmm/vmx/Hv.c @@ -1540,6 +1540,54 @@ HvSetDebugctl(UINT64 Value) VmxVmwrite64(VMCS_GUEST_DEBUGCTL_HIGH, Value >> 32); } +/** + * @brief Check if CPU support save and load debug controls on exit and load entries + * + * @return BOOLEAN + */ +BOOLEAN +HvCheckCpuSupportForSaveAndLoadDebugControls() +{ + IA32_VMX_BASIC_REGISTER VmxBasicMsr = {0}; + + // + // Reading IA32_VMX_BASIC_MSR + // + VmxBasicMsr.AsUInt = __readmsr(IA32_VMX_BASIC); + + // + // Read 1-settings of save debug controls (exit controls) + // + UINT32 ExitCtls = HvAdjustControls( + IA32_VMX_EXIT_CTLS_SAVE_DEBUG_CONTROLS_FLAG, + VmxBasicMsr.VmxControls ? IA32_VMX_TRUE_EXIT_CTLS : IA32_VMX_EXIT_CTLS); + + // + // Read 1-settings of load debug controls (entry controls) + // + UINT32 EntryCtls = HvAdjustControls( + IA32_VMX_ENTRY_CTLS_LOAD_DEBUG_CONTROLS_FLAG, + VmxBasicMsr.VmxControls ? IA32_VMX_TRUE_ENTRY_CTLS : IA32_VMX_ENTRY_CTLS); + + // + // Check if entry and exit controls are supported on this system + // + if (ExitCtls != NULL_ZERO && EntryCtls != NULL_ZERO) + { + // + // Supported + // + return TRUE; + } + else + { + // + // Not supported + // + return FALSE; + } +} + /** * @brief Set the guest state of DR7 * @param Value The new value for DR7 diff --git a/hyperdbg/hyperhv/code/vmm/vmx/Vmx.c b/hyperdbg/hyperhv/code/vmm/vmx/Vmx.c index ae6b4a5c..6053f9d0 100644 --- a/hyperdbg/hyperhv/code/vmm/vmx/Vmx.c +++ b/hyperdbg/hyperhv/code/vmm/vmx/Vmx.c @@ -908,15 +908,13 @@ VmxSetupVmcs(VIRTUAL_MACHINE_STATE * VCpu, PVOID GuestStack) VmxVmwrite64(VMCS_CTRL_PRIMARY_VMEXIT_CONTROLS, HvAdjustControls( IA32_VMX_EXIT_CTLS_HOST_ADDRESS_SPACE_SIZE_FLAG | - IA32_VMX_EXIT_CTLS_LOAD_IA32_CET_STATE_FLAG | - IA32_VMX_EXIT_CTLS_SAVE_DEBUG_CONTROLS_FLAG, + IA32_VMX_EXIT_CTLS_LOAD_IA32_CET_STATE_FLAG, VmxBasicMsr.VmxControls ? IA32_VMX_TRUE_EXIT_CTLS : IA32_VMX_EXIT_CTLS)); VmxVmwrite64(VMCS_CTRL_VMENTRY_CONTROLS, HvAdjustControls( IA32_VMX_ENTRY_CTLS_IA32E_MODE_GUEST_FLAG | - IA32_VMX_ENTRY_CTLS_LOAD_CET_STATE_FLAG | - IA32_VMX_ENTRY_CTLS_LOAD_DEBUG_CONTROLS_FLAG, + IA32_VMX_ENTRY_CTLS_LOAD_CET_STATE_FLAG, VmxBasicMsr.VmxControls ? IA32_VMX_TRUE_ENTRY_CTLS : IA32_VMX_ENTRY_CTLS)); VmxVmwrite64(VMCS_CTRL_CR0_GUEST_HOST_MASK, 0); diff --git a/hyperdbg/hyperhv/header/vmm/vmx/Hv.h b/hyperdbg/hyperhv/header/vmm/vmx/Hv.h index 49a28e0e..60a7664a 100644 --- a/hyperdbg/hyperhv/header/vmm/vmx/Hv.h +++ b/hyperdbg/hyperhv/header/vmm/vmx/Hv.h @@ -476,6 +476,14 @@ HvGetAndStoreDebugctl(UINT64 * StoreDebugctl); VOID HvSetDebugctl(UINT64 Value); +/** + * @brief Check if CPU support save and load debug controls on exit and load entries + * + * @return BOOLEAN + */ +BOOLEAN +HvCheckCpuSupportForSaveAndLoadDebugControls(); + /** * @brief Set the guest state of DR7 * @param Value The new value for DR7 diff --git a/hyperdbg/hyperkd/code/driver/Loader.c b/hyperdbg/hyperkd/code/driver/Loader.c index c3678e07..9470d8d0 100644 --- a/hyperdbg/hyperkd/code/driver/Loader.c +++ b/hyperdbg/hyperkd/code/driver/Loader.c @@ -36,10 +36,11 @@ LoaderInitHyperTrace() // // Fill the callbacks for using hyperhv in hypertrace // - HyperTraceCallbacks.VmFuncGetDebugctl = VmFuncGetDebugctl; - HyperTraceCallbacks.VmFuncGetDebugctlVmcallOnTargetCore = VmFuncGetDebugctlVmcallOnTargetCore; - HyperTraceCallbacks.VmFuncSetDebugctl = VmFuncSetDebugctl; - HyperTraceCallbacks.VmFuncSetDebugctlVmcallOnTargetCore = VmFuncSetDebugctlVmcallOnTargetCore; + HyperTraceCallbacks.VmFuncGetDebugctl = VmFuncGetDebugctl; + HyperTraceCallbacks.VmFuncGetDebugctlVmcallOnTargetCore = VmFuncGetDebugctlVmcallOnTargetCore; + HyperTraceCallbacks.VmFuncSetDebugctl = VmFuncSetDebugctl; + HyperTraceCallbacks.VmFuncSetDebugctlVmcallOnTargetCore = VmFuncSetDebugctlVmcallOnTargetCore; + HyperTraceCallbacks.VmFuncCheckCpuSupportForSaveAndLoadDebugControls = VmFuncCheckCpuSupportForSaveAndLoadDebugControls; // // Memory callbacks diff --git a/hyperdbg/hypertrace/code/Tracing.c b/hyperdbg/hypertrace/code/Tracing.c index 4121c4f4..08c68cad 100644 --- a/hyperdbg/hypertrace/code/Tracing.c +++ b/hyperdbg/hypertrace/code/Tracing.c @@ -202,12 +202,24 @@ HyperTraceEnableLbrTracing(HYPERTRACE_OPERATION_PACKETS * HyperTraceOperationReq return FALSE; } + // + // Check LBR support on CPU + // if (!LbrCheck()) { HyperTraceOperationRequest->KernelStatus = DEBUGGER_ERROR_LBR_NOT_SUPPORTED; return FALSE; } + // + // Check VMCS support for LBR + // + if (!g_Callbacks.VmFuncCheckCpuSupportForSaveAndLoadDebugControls()) + { + HyperTraceOperationRequest->KernelStatus = DEBUGGER_ERROR_DEBUGCTL_NOT_SUPPORTED_ON_VMCS; + return FALSE; + } + // // Enabling LBR // diff --git a/hyperdbg/include/SDK/headers/ErrorCodes.h b/hyperdbg/include/SDK/headers/ErrorCodes.h index 9990fbc9..d2fc07ae 100644 --- a/hyperdbg/include/SDK/headers/ErrorCodes.h +++ b/hyperdbg/include/SDK/headers/ErrorCodes.h @@ -611,6 +611,12 @@ */ #define DEBUGGER_ERROR_LBR_NOT_SUPPORTED 0xc000005e +/** + * @brief error, Dubugctl not supported on VMCS + * + */ +#define DEBUGGER_ERROR_DEBUGCTL_NOT_SUPPORTED_ON_VMCS 0xc000005f + // // WHEN YOU ADD ANYTHING TO THIS LIST OF ERRORS, THEN // MAKE SURE TO ADD AN ERROR MESSAGE TO ShowErrorMessage(UINT32 Error) diff --git a/hyperdbg/include/SDK/imports/kernel/HyperDbgVmmImports.h b/hyperdbg/include/SDK/imports/kernel/HyperDbgVmmImports.h index 3da4bfbc..116b2ec0 100644 --- a/hyperdbg/include/SDK/imports/kernel/HyperDbgVmmImports.h +++ b/hyperdbg/include/SDK/imports/kernel/HyperDbgVmmImports.h @@ -229,6 +229,9 @@ VmFuncVmxGetCurrentExecutionMode(); IMPORT_EXPORT_VMM BOOLEAN VmFuncQueryModeExecTrap(); +IMPORT_EXPORT_VMM BOOLEAN +VmFuncCheckCpuSupportForSaveAndLoadDebugControls(); + IMPORT_EXPORT_VMM INT32 VmFuncVmxCompatibleStrcmp(const CHAR * Address1, const CHAR * Address2); diff --git a/hyperdbg/include/SDK/modules/HyperTrace.h b/hyperdbg/include/SDK/modules/HyperTrace.h index f65782f3..2b145e90 100644 --- a/hyperdbg/include/SDK/modules/HyperTrace.h +++ b/hyperdbg/include/SDK/modules/HyperTrace.h @@ -70,6 +70,12 @@ typedef VOID (*VM_FUNC_SET_DEBUGCTL)(UINT64 Value); */ typedef VOID (*VM_FUNC_SET_DEBUGCTL_VMCALL_ON_TARGET_CORE)(UINT64 Value); +/** + * @brief A function that checks whether IA32_DEBUGCTL can be used in load and save of exit and entry controls + * + */ +typedef BOOLEAN (*VM_FUNC_CHECK_CPU_SUPPORT_FOR_SAVE_AND_LOAD_DEBUG_CONTROLS)(); + /** * @brief A function that checks the validity and safety of the target address * @@ -115,10 +121,11 @@ typedef struct _HYPERTRACE_CALLBACKS // // *** Hypervisor (Hyperhv) callbacks *** // - VM_FUNC_GET_DEBUGCTL VmFuncGetDebugctl; - VM_FUNC_GET_DEBUGCTL_VMCALL_ON_TARGET_CORE VmFuncGetDebugctlVmcallOnTargetCore; - VM_FUNC_SET_DEBUGCTL VmFuncSetDebugctl; - VM_FUNC_SET_DEBUGCTL_VMCALL_ON_TARGET_CORE VmFuncSetDebugctlVmcallOnTargetCore; + VM_FUNC_GET_DEBUGCTL VmFuncGetDebugctl; + VM_FUNC_GET_DEBUGCTL_VMCALL_ON_TARGET_CORE VmFuncGetDebugctlVmcallOnTargetCore; + VM_FUNC_SET_DEBUGCTL VmFuncSetDebugctl; + VM_FUNC_SET_DEBUGCTL_VMCALL_ON_TARGET_CORE VmFuncSetDebugctlVmcallOnTargetCore; + VM_FUNC_CHECK_CPU_SUPPORT_FOR_SAVE_AND_LOAD_DEBUG_CONTROLS VmFuncCheckCpuSupportForSaveAndLoadDebugControls; // // *** HYPERTRACE callbacks *** diff --git a/hyperdbg/libhyperdbg/code/debugger/core/debugger.cpp b/hyperdbg/libhyperdbg/code/debugger/core/debugger.cpp index 37979cd5..0fea3872 100644 --- a/hyperdbg/libhyperdbg/code/debugger/core/debugger.cpp +++ b/hyperdbg/libhyperdbg/code/debugger/core/debugger.cpp @@ -594,6 +594,11 @@ ShowErrorMessage(UINT32 Error) Error); break; + case DEBUGGER_ERROR_DEBUGCTL_NOT_SUPPORTED_ON_VMCS: + ShowMessages("err, Debugctl is not supported on VMCS (%x)\n", + Error); + break; + default: ShowMessages("err, error not found (%x)\n", Error);