VT学习问题,__vmx_vmlaunch 错误

代码链接
https://wwqf.lanzoue.com/iTBFY14okted

问题描述:
运行后VMLAUNCH错误 : 8

VOID SetupVMCS()
{
    unsigned __int64 ret = 0;
    //KdBreakPoint();
    // 客户机 guest

    // 宿主机 root
    __vmx_vmwrite(HOST_CR0, ret = __readcr0());                                         KdPrintEx((77, 0, "cr0 = [%p]\r\n", ret));
    __vmx_vmwrite(HOST_CR3, ret = __readcr3());                                         KdPrintEx((77, 0, "cr3 = [%p]\r\n", ret));
    __vmx_vmwrite(HOST_CR4, ret = __readcr4());                                         KdPrintEx((77, 0, "cr4 = [%p]\r\n", ret));

    __vmx_vmwrite(HOST_ES_SELECTOR, ret = (Asm_GetEs() & 0xFFFFFFFFFFFFFFF8));          KdPrintEx((77, 0, "es = [%p]\r\n", ret));
    __vmx_vmwrite(HOST_CS_SELECTOR, ret = (Asm_GetCs() & 0xFFFFFFFFFFFFFFF8));          KdPrintEx((77, 0, "cs = [%p]\r\n", ret));
    __vmx_vmwrite(HOST_DS_SELECTOR, ret = (Asm_GetDs() & 0xFFFFFFFFFFFFFFF8));          KdPrintEx((77, 0, "ds = [%p]\r\n", ret));
    __vmx_vmwrite(HOST_FS_SELECTOR, ret = (Asm_GetFs() & 0xFFFFFFFFFFFFFFF8));          KdPrintEx((77, 0, "fs = [%p]\r\n", ret));
    __vmx_vmwrite(HOST_GS_SELECTOR, ret = (Asm_GetGs() & 0xFFFFFFFFFFFFFFF8));          KdPrintEx((77, 0, "gs = [%p]\r\n", ret));
    __vmx_vmwrite(HOST_SS_SELECTOR, ret = (Asm_GetSs() & 0xFFFFFFFFFFFFFFF8));          KdPrintEx((77, 0, "ss = [%p]\r\n", ret));
    __vmx_vmwrite(HOST_TR_SELECTOR, ret = (Asm_GetTr() & 0xFFFFFFFFFFFFFFF8));          KdPrintEx((77, 0, "tr = [%p]\r\n", ret));

    __vmx_vmwrite(HOST_TR_BASE, (ret = GetSegmentBase((ULONG)Asm_GetTr())));            KdPrintEx((77, 0, "trBase = [%p]\r\n", ret));
    __vmx_vmwrite(HOST_FS_BASE, (ret = GetSegmentBase((ULONG)Asm_GetFs())));            KdPrintEx((77, 0, "fsBase = [%p]\r\n", ret));
    __vmx_vmwrite(HOST_GS_BASE, (ret = GetSegmentBase((ULONG)Asm_GetGs())));            KdPrintEx((77, 0, "gsBase = [%p]\r\n", ret));

    __vmx_vmwrite(HOST_GDTR_BASE, (ret = ASM_GETGDTR()));                               KdPrintEx((77, 0, "gdtr = [%p]\r\n", ret));
    __vmx_vmwrite(HOST_IDTR_BASE, (ret = ASM_GETIDTR()));                               KdPrintEx((77, 0, "idtr = [%p]\r\n", ret));

    //__vmx_vmwrite(HOST_IA32_SYSENTER_CS, 0x10);                                         //KdPrintEx((77,0,"MSR_IA32_SYSENTER_CS = [%p]\r\n",ret));
    //__vmx_vmwrite(HOST_IA32_SYSENTER_ESP,((size_t)virtualAddress_STACK + 0x1000));      //KdPrintEx((77,0,"MSR_IA32_SYSENTER_ESP = [%p]\r\n",ret));
    //__vmx_vmwrite(HOST_IA32_SYSENTER_EIP,(ret = __readmsr(MSR_IA32_LSTAR)));            KdPrintEx((77,0,"MSR_IA32_SYSENTER_EIP = [%p]\r\n",ret));

    __vmx_vmwrite(HOST_IA32_SYSENTER_CS, __readmsr(MSR_IA32_SYSENTER_CS) & 0xFFFFFFFF);
    __vmx_vmwrite(HOST_IA32_SYSENTER_ESP, __readmsr(MSR_IA32_SYSENTER_ESP) & 0xFFFFFFFF);
    __vmx_vmwrite(HOST_IA32_SYSENTER_EIP, __readmsr(MSR_IA32_SYSENTER_EIP) & 0xFFFFFFFF);

    __vmx_vmwrite(HOST_RSP, (size_t)virtualAddress_STACK);
    __vmx_vmwrite(HOST_RIP, (size_t)_exitHandle);

    // 虚拟机控制
    // 1;虚拟机执行
    __vmx_vmwrite(PIN_BASED_VM_EXEC_CONTROL, AdjustControls(0, MSR_IA32_VMX_PINBASED_CTLS));
    __vmx_vmwrite(CPU_BASED_VM_EXEC_CONTROL, AdjustControls(0, MSR_IA32_VMX_PROCBASED_CTLS));
    // 2;虚拟机进入
    __vmx_vmwrite(VM_ENTRY_CONTROLS, AdjustControls(0, MSR_IA32_VMX_ENTRY_CTLS));
    // 3;虚拟机退出
    __vmx_vmwrite(VM_EXIT_CONTROLS, AdjustControls(0, MSR_IA32_VMX_EXIT_CTLS));
}

↑ 这是对虚拟机宿主机字段设置的相关代码,

img

上图是文档中关于字段设置描述的内容

img

上图是运行后的输出内容

如果正常的话应该是没有错误的,会进入到给定的_exitHandle处理函数中。
希望能帮忙看下,谢谢

环境:
Win10 - 64 (1903)

【以下回答由 GPT 生成】

回答: 根据你提供的代码,你遇到了一个以__vmx_vmlaunch错误的问题。这个错误可能是由于一些虚拟化配置的问题导致的。以下是一些可能的解决方案:

  1. 确保你的处理器支持VT技术。使用以下代码来验证:
BOOL IsVTSupported()
{
    int cpu_info[4] = {0};
    __cpuid(cpu_info, 1);

    if (cpu_info[2] & (1 << 5)) {
        return TRUE;
    } else {
        return FALSE;
    }
}

如果IsVTSupported()函数返回FALSE,那么你的处理器可能不支持VT技术。此时,你需要使用支持虚拟化的处理器。

  1. 确保你的操作系统和BIOS已启用虚拟化。进入BIOS设置,并查找虚拟化(Virtualization)选项。确保它已启用。如果操作系统已经安装,你需要在安装时启用虚拟化。

  2. 检查你的代码是否正确设置了VMCS(虚拟机控制结构)。__vmx_vmwrite()函数用于将一个值写入对应的VMCS字段,你需要确保写入的字段值正确。

  3. 确保在执行__vmx_vmlaunch之前已经正确初始化了VMCS。你可以使用以下代码来初始化VMCS:

VOID InitVMCS()
{
    // 根据需要设置VMCS字段的值
    __vmx_vmwrite(GUEST_CR0, __readcr0());
    __vmx_vmwrite(GUEST_CR3, __readcr3());
    __vmx_vmwrite(GUEST_CR4, __readcr4());
    // 设置其他VMCS字段...

    // 将VMCS指针加载到VMCS区域
    unsigned __int64 vmcs_physical_address = 0; // 设置一个空的地址
    __vmx_vmptrld(&vmcs_physical_address);
}

然后,在执行__vmx_vmlaunch之前调用InitVMCS()函数来初始化VMCS。

请注意,虚拟化是一项复杂的技术,错误可能有很多种原因。以上提供的解决方案只是针对一些常见问题的建议。如果问题仍然存在,请进一步调查和分析错误消息以获得更多信息,并参考虚拟化相关的文档和资源。


如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^