| 
                         接下来是一些坑爹的代码: 
- /* 
 -   Vmx初始化 
 - */ 
 - NTSTATUS NTAPI VmxInitialize ( 
 -    PCPU Cpu, 
 -    PVOID GuestEip, 
 -    PVOID GuestEsp 
 - ) 
 - { 
 -    PHYSICAL_ADDRESS AlignedVmcsPA; 
 -    ULONG VaDelta; 
 -    NTSTATUS Status; 
 -  
 -  
 -    // 为 VMXON region 申请内存空间 
 -    Cpu->Vmx.OriginaVmxonR = MmAllocateContiguousPages( 
 -        VMX_VMXONR_SIZE_IN_PAGES,  
 -        &Cpu->Vmx.OriginalVmxonRPA); 
 -    if (!Cpu->Vmx.OriginaVmxonR)  
 -    { 
 -  DbgPrint("VmxInitialize(): Failed to allocate memory for original VMCSn"); 
 -        return STATUS_INSUFFICIENT_RESOURCES; 
 -    } 
 -  
 -    DbgPrint("VmxInitialize(): OriginaVmxonR VA: 0x%xn", Cpu->Vmx.OriginaVmxonR); 
 -    DbgPrint("VmxInitialize(): OriginaVmxonR PA: 0x%llxn", Cpu->Vmx.OriginalVmxonRPA.QuadPart); 
 -  
 -    // 为 VMCS 申请内存空间  
 -    Cpu->Vmx.OriginalVmcs = MmAllocateContiguousPages( 
 -        VMX_VMCS_SIZE_IN_PAGES,  
 -        &Cpu->Vmx.OriginalVmcsPA); 
 -    if (!Cpu->Vmx.OriginalVmcs)  
 -    { 
 -  DbgPrint("VmxInitialize(): Failed to allocate memory for original VMCSn"); 
 -        return STATUS_INSUFFICIENT_RESOURCES; 
 -    } 
 -  
 -    DbgPrint("VmxInitialize(): Vmcs VA: 0x%xn", Cpu->Vmx.OriginalVmcs); 
 -    DbgPrint("VmxInitialize(): Vmcs PA: 0x%llxn", Cpu->Vmx.OriginalVmcsPA.QuadPart); 
 -  
 -    // 开启vmx 
 -    if (!NT_SUCCESS (VmxEnable (Cpu->Vmx.OriginaVmxonR))) 
 -    { 
 -        DbgPrint("VmxInitialize(): Failed to enable Vmxn"); 
 -        return STATUS_UNSUCCESSFUL; 
 -    } 
 -  
 -    *((ULONG64 *)(Cpu->Vmx.OriginalVmcs)) =  
 -        (MsrRead (MSR_IA32_VMX_BASIC) & 0xffffffff); //set up vmcs_revision_id       
 -  
 -    // 填充VMCS结构 
 - Status = VmxSetupVMCS (Cpu, GuestEip, GuestEsp); 
 -    if (!NT_SUCCESS (Status))  
 -    { 
 -        DbgPrint("VmxSetupVMCS() failed with status 0x%08hXn", Status); 
 -        VmxDisable(); 
 -        return Status; 
 -    } 
 -  
 -    DbgPrint("VmxInitialize(): Vmx enabledn"); 
 -  
 -   // 保存EFER 
 -    Cpu->Vmx.GuestEFER = MsrRead (MSR_EFER); 
 -    DbgPrint("Guest MSR_EFER Read 0x%llx n", Cpu->Vmx.GuestEFER); 
 -  
 -   // 保存控制寄存器 
 -    Cpu->Vmx.GuestCR0 = RegGetCr0 (); 
 -    Cpu->Vmx.GuestCR3 = RegGetCr3 (); 
 -    Cpu->Vmx.GuestCR4 = RegGetCr4 (); 
 -  
 -    CmCli (); 
 -    return STATUS_SUCCESS; 
 - } 
 -  
 -  
 -  
 - /* 
 -   开启vmx 
 - */ 
 - NTSTATUS NTAPI VmxEnable ( 
 -    PVOID VmxonVA 
 - ) 
 - { 
 -    ULONG cr4; 
 -    ULONG64 vmxmsr; 
 -    ULONG flags; 
 -    PHYSICAL_ADDRESS VmxonPA; 
 -  
 - // 设置cr4位,为启用VM模式做准备 
 -    set_in_cr4 (X86_CR4_VMXE); 
 -    cr4 = get_cr4 (); 
 -    DbgPrint("VmxEnable(): CR4 after VmxEnable: 0x%llxn", cr4); 
 -    if (!(cr4 & X86_CR4_VMXE)) 
 -        return STATUS_NOT_SUPPORTED; 
 -  
 - // 检测是否支持vmx 
 -    vmxmsr = MsrRead (MSR_IA32_FEATURE_CONTROL); 
 -    if (!(vmxmsr & 4))  
 -    { 
 -        DbgPrint("VmxEnable(): VMX is not supported: IA32_FEATURE_CONTROL is 0x%llxn", vmxmsr); 
 -        return STATUS_NOT_SUPPORTED; 
 -    } 
 -  
 - //bochs的bug,要改IA32_FEATURE_CONTROL的Lock为1 
 - #if bochsdebug 
 - MsrWrite(MSR_IA32_FEATURE_CONTROL,5); 
 -    #endif 
 -  
 -    vmxmsr = MsrRead (MSR_IA32_VMX_BASIC); 
 -    *((ULONG64 *) VmxonVA) = (vmxmsr & 0xffffffff);       //set up vmcs_revision_id 
 -    VmxonPA = MmGetPhysicalAddress (VmxonVA); 
 -  
 -    DbgPrint("VmxEnable(): VmxonPA:  0x%llxn", VmxonPA.QuadPart); 
 -  
 - //开启VMX 
 - VmxTurnOn(VmxonPA); 
 -    flags = RegGetEflags (); 
 -    DbgPrint("VmxEnable(): vmcs_revision_id: 0x%x  Eflags: 0x%x n", vmxmsr, flags); 
 -  
 -    return STATUS_SUCCESS; 
 - } 
 -  
 -  
 -  
 - /* 
 -   进入虚拟机 
 - */ 
 - NTSTATUS NTAPI VmxVirtualize ( 
 -  PCPU Cpu 
 - ) 
 - { 
 -  
 -    ULONG esp; 
 -    if (!Cpu) 
 -        return STATUS_INVALID_PARAMETER; 
 -  
 - *((PULONG) (g_HostStackBaseAddress + 0x0C00)) = (ULONG) Cpu; 
 -            
 -    VmxLaunch (); 
 -  
 -    // never returns 
 -  
 -    return STATUS_UNSUCCESSFUL; 
 - } 
 
  
三、蛋疼的拦截处理 
sysenter的处理方法: 
由于硬件虚拟化(HVM)无法直接拦截sysenter指令,所以只能使用其他方法来获得控制权。 
这里有三种方法: 
1、在kifastcallentery的头部写入cpuid,int3等利用中断或特权指令进入vm。 
2、使用调试寄存器在kifastcallentery下硬件执行中断,利用中断进入vm 
3、进入VMM后直接修改guest的sysenter_eip地址,通过控制msr的读写来欺骗其他访问msr的程序。 
为了不被内存检测和充分利用调试寄存器,Avalon中我选用了方案3来控制进程执行sysenter后的运行流向。                         (编辑:滁州站长网) 
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! 
                     |