最近学习硬件虚拟化方面的AMD-V部分的, 在执行VMRUN指令的时候, CPU跳到Guest eip的第一条指令的时候机器蓝屏蓝屏代码是0x7F, 后来查了下是#GP异常, 我那框架是参考 nbp-0.32-public 那个代码的,Vmcb 设置应该是没错不然会发生VMEXIT_INVALID错误, 这个问题困扰了我快2个星期了
,希望知道的指点下,谢谢了。 下面是我的一些初始化代码:
void InitVmcb(PCPU Cpu, PVOID GuestRip, PVOID GuestRsp)
{
PVMCB Vmcb;
ULONG uCs;
ULONG GdtBase, IdtBase;
MSR msr;
GdtBase = GetGdtBase();
IdtBase = GetIdtBase();
KdPrint(("GdtBase : %08x Limit : %08x\n", GdtBase, GetGdtLimit()));
KdPrint(("IdtBase : %08x Limit : %08x\n", IdtBase, GetIdtLimit()));
Vmcb = Cpu->Vmcb;
Vmcb->gdtr.base = GdtBase;
Vmcb->gdtr.limit = GetGdtLimit();
Vmcb->idtr.base = IdtBase;
Vmcb->idtr.limit = GetIdtLimit();
__asm int 3
InitializeSegmentSelector(&Vmcb->cs, RegGetCs(), GdtBase);
InitializeSegmentSelector(&Vmcb->ds, RegGetDs(), GdtBase);
InitializeSegmentSelector(&Vmcb->es, RegGetEs(), GdtBase);
InitializeSegmentSelector(&Vmcb->fs, RegGetFs(), GdtBase);
InitializeSegmentSelector(&Vmcb->ss, RegGetSs(), GdtBase);
InitializeSegmentSelector(&Vmcb->tr, RegGetTr(), GdtBase);
*((PUCHAR)Vmcb + 0x403) |= 4;
*((PUCHAR)Vmcb + 0x413) |= 4;
*((PUCHAR)Vmcb + 0x423) |= 4;
*((PUCHAR)Vmcb + 0x433) |= 4;
*((PUCHAR)Vmcb + 0x443) |= 4;
*((PUCHAR)Vmcb + 0x403) |= 8;
*((PUCHAR)Vmcb + 0x413) |= 8;
*((PUCHAR)Vmcb + 0x423) |= 8;
*((PUCHAR)Vmcb + 0x433) |= 8;
*((PUCHAR)Vmcb + 0x443) |= 8;
Vmcb->rflags = RegGetRflags();
Vmcb->cr0 = RegGetCr0();
Cpu->HostCr0 = (ULONG)Vmcb->cr0;
Vmcb->cr2 = RegGetCr2();
Vmcb->cr3 = RegGetCr3();
Vmcb->cr4 = RegGetCr4();
Vmcb->rax = 0;
Vmcb->rip = (ULONG64)GuestRip;
Vmcb->rsp = (ULONG64)GuestRsp;
Vmcb->dr6 = RegGetDr6();
Vmcb->dr7 = RegGetDr7();
ReadMsr(MSR_IA32_EFER, &msr);
Vmcb->efer = msr.value;
ReadMsr(MSR_IA32_SYSENTER_CS, &msr);
Vmcb->sysenter_cs = msr.value;
ReadMsr(MSR_IA32_SYSENTER_ESP, &msr);
Vmcb->sysenter_esp = msr.value;
ReadMsr(MSR_IA32_SYSENTER_EIP, &msr);
Vmcb->sysenter_eip = msr.value;
Vmcb->guest_asid = 1;
Vmcb->h_cr3 = 0;
Vmcb->cr_intercepts = 0;
Vmcb->exception_intercepts = 0;
Vmcb->general1_intercepts = 0;
Vmcb->general2_intercepts = (1 << 0);// VMRUN
Vmcb->tsc_offset = 0;
Vmcb->msrpm_base_pa = 0;
}
void __declspec(naked) VmSvmRun(ULONG Vmcb_Low_PhysicalAddress, ULONG HostStackBottom)
{
__asm
{
mov ax, ds
and ax, 0x0FFFC
mov ds, ax
mov ax, es
and ax, 0x0FFFC
mov es, ax
mov eax, [esp + 04h]
int 3
mov esp, [esp + 08h]
//vmsave
__emit 0x0F
__emit 0x01
__emit 0xDB
l_loop:
//vmload
__emit 0x0F
__emit 0x01
__emit 0xDA
//vmrun
__emit 0x0F
__emit 0x01
__emit 0xD8
int 3
//vmsave
__emit 0x0F
__emit 0x01
__emit 0xDB
cli
pushad
pushf
mov eax, esp
push eax
popfd
popad
sti
jmp l_loop
}
}
void Virtualization(PCPU Cpu)
{
KdPrint(("Cpu->VmcbPA.LowPart = %08X Cpu->Vmcb = %08X\n", Cpu->VmcbPA.LowPart, Cpu->Vmcb));
VmSvmRun((ULONG)Cpu->VmcbPA.LowPart, Cpu->HostStack);
}
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课