Debugging vmlaunch后调试VM

Debugging vmlaunch后调试VM,debugging,virtual-machine,windbg,hypervisor,Debugging,Virtual Machine,Windbg,Hypervisor,说明: 我正在关注虚拟机监控程序的开发。在完成系列之后,我无法运行我的代码。在\uuu vmx\u vmlaunch指令成功执行后,我正在测试虚拟机监控程序的虚拟机立即重新启动。我相信这是由于一些错误的设置。WinDbg中没有BSOD、崩溃或错误消息 我认为有两种方法可以解决这个问题。一种是以某种方式从WinDbg中提取更多信息。第二种方法需要有人发现我在vmcs初始化中做了什么愚蠢的事情或遗漏了什么 不幸的是,教程中的代码不完整。我花了一些时间来确保教程所涵盖的所有内容在我的代码中都是相同的。

说明
我正在关注虚拟机监控程序的开发。在完成系列之后,我无法运行我的代码。在
\uuu vmx\u vmlaunch
指令成功执行后,我正在测试虚拟机监控程序的虚拟机立即重新启动。我相信这是由于一些错误的设置。WinDbg中没有BSOD、崩溃或错误消息

我认为有两种方法可以解决这个问题。一种是以某种方式从WinDbg中提取更多信息。第二种方法需要有人发现我在vmcs初始化中做了什么愚蠢的事情或遗漏了什么

不幸的是,教程中的代码不完整。我花了一些时间来确保教程所涵盖的所有内容在我的代码中都是相同的。我将突出显示我添加的部分

我真的为这么多的代码感到抱歉。让我再次强调,我认为问题在于
主机
字段(因为来宾vm中的崩溃不应该导致主机崩溃)

int init_vmcs(结构vcpu_t*vcpu)
{
日志项(“初始化vmcs()\n”);
//确定特定于实现的确切大小。
//我们希望它是4KB,但不能保证。
联合uu vmx_basic_msr_t vmx_basic_msr={0};
vmx_basic_msr.control=u readmsr(IA32_vmx_basic);
if(vmx_基本_msr.bits.vmxon_区域_大小!=sizeof(struct_uvmcs_t)){
日志错误(“非标准vmcs区域大小:%llx。尚未实施支持。\n”,
vmx_基本_msr.bits.vmxon_区域(单位大小);
日志退出(“初始化vmcs()\n”);
返回-1;
}
物理地址物理地址最大值;
物理_max.QuadPart=MAXULONG64;
vcpu->vmcs=mmaallocateContinguousMemory(sizeof(struct\u vmcs\u t),physical\u max);
如果(!vcpu->vmcs){
日志错误(“分配vcpu->vmcs失败(MmAllocateContiguousMemory失败)。\n”);
日志退出(“初始化vmcs()\n”);
返回-1;
}
RtlSecureZeroMemory(vcpu->vmcs,sizeof(struct_uVMCS_t));
vcpu->vmcs_physical=MmGetPhysicalAddress(vcpu->vmcs);
//通过读取来发现处理器使用的VMCS修订标识符
//VMX功能MSR IA32_VMX_基本。
vcpu->vmcs->header.bits.revision_identifier=(unsigned int)vmx_basic_msr.bits.vmcs_revision_identifier;
vcpu->vmcs->header.bits.shadow_vmcs_指示器=0;
//在加载VMC之前,我们调用vmclear来刷新处理器可能缓存的数据。
如果(_-vmx_-vmclear(&vcpu->vmcs_-physical)| _-vmx_-vmptrld(&vcpu->vmcs_-physical)){
日志错误(“刷新数据或加载VMC失败。(\uuuVMx\uVMClear或\uuVMx\uVMPtrld失败)。\n”);
日志退出(“初始化vmcs()\n”);
返回-1;
}
//初始化VMCS来宾状态区域。
if(_-vmx_-vmwrite(GUEST_-CR0,_-readcr0())||
__vmx_vmwrite(GUEST_CR3,__readcr3())||
__vmx_vmwrite(GUEST_CR4,__readcr4())||
__vmx_vmwrite(来宾_DR7,u readdr(7))||
__vmx_vmwrite(来宾_RSP,vcpu->来宾_RSP)||
__vmx_vmwrite(来宾_RIP,vcpu->来宾_RIP)||
__vmx_vmwrite(GUEST_RFLAGS,__readeflags())||
__vmx_vmwrite(来宾_调试_控件,u readmsr(IA32_调试CTL))||
__vmx_vmwrite(来宾系统输入ESP,读取MSR(IA32系统输入ESP))||
__vmx_vmwrite(来宾系统输入EIP,uu读取MSR(IA32_系统输入EIP))||
__vmx_vmwrite(来宾系统输入系统、读取系统(IA32系统输入系统))||
__vmx_vmwrite(来宾_VMCS_链接_指针,~0ULL)||
__vmx_vmwrite(来宾_FS_库、读MSR(IA32_FS_库))||
__vmx_vmwrite(来宾_GS_BASE,u readmsr(IA32_GS_BASE))
) {
日志错误(“未能设置来宾状态。(u-vmx_-vmwrite失败)。\n”);
日志退出(“初始化vmcs()\n”);
返回-1;
}
if(_-vmx_-vmwrite(CR0_-READ_-SHADOW,_-readcr0())||
__vmx_vmwrite(CR4_READ_SHADOW,_readcr4())
) {
日志错误(“设置cr0\U读\U卷影或cr4\U读\U卷影失败。(uu-vmx\u-vmwrite失败)。\n”);
日志退出(“初始化vmcs()\n”);
返回-1;
}
联合uu vmx_条目u控件u t条目u控件={0};
entry_controls.bits.ia32e_mode_guest=1;
vmx_调整_条目_控件(&条目_控件);
__vmx_vmwrite(VM_ENTRY_控件,ENTRY_控件.control);
联合(union)vmx(u exit)控制(u t exit)控制={0};
exit_controls.bits.host_address_space_size=1;
vmx_调整_退出_控件(&退出_控件);
__vmx_vmwrite(VM_EXIT_控件,EXIT_控件.control);
union uu vmx_pinbased_control_msr_t pinbased_controls={0};
vmx_调整_基于pinu的_控件(&基于pinu的_控件);
__vmx_vmwrite(基于PIN_的VM_执行_控件,基于PIN的_控件.控件);
基于union u u vmx u primary u处理器的u control u t primary u controls={0};
主\u controls.bits.use\u msr\u位图=1;
主\u控件.bits.active\u次要\u控件=1;
vmx_调整_主处理器基于_的_控件(&主_控件);
__vmx_vmwrite(基于主处理器的_VM_执行_控件,主_控件.control);
基于union u u vmx u secondary u处理器的u控制u t secondary u控制={0};
辅助_controls.bits.enable_rdtscp=1;
辅助_controls.bits.enable_xsave_xrstor=1;
辅助_controls.bits.enable_invpcid=1;
vmx_调整_辅助_处理器基于_的_控件(&辅助_控件);
__vmx_vmwrite(基于辅助处理器的_VM_执行_控件,辅助_控件.control);
__vmx_vmwrite(来宾_CS_选择器,u_read_CS());
__vmx_vmwrite(GUEST_SS_选择器,u_read_SS());
__vmx_vmwrite(GUEST_DS_选择器,u_read_DS());
__vmx_vmwrite(来宾选择器,u read_ES());
__vmx_vmwrite(GUEST_FS_选择器,u_read_FS());
__vmx_vmwrite(来宾选择器,u read_GS());
__vmx_vmwrite(来宾选择器,u read_LDTR());
__vmx_vmwrite(来宾选择器,u read_TR());
__vmx_vmwrite(来宾访问限制,u段限制(u read_CS());
__vmx_vmwrite(GUEST_SS_LIMIT,u segmentlimit(u read_SS());
__vmx_vmwrite(GUEST_DS_LIMIT,u segmentlimit(u read_DS());
__vmx_vmwrite(来宾权限,
vmm_entrypoint proc
    int 3 ; addded by me
vmm_entrypoint endp


guest_entry_stub proc
    mov rax, 1337h
    hlt
guest_entry_stub endp