admin 发表于 2025-2-22 23:11:14

x64VT虚拟化框架源码

#include "vtstart.h"
#include "asm64.h"
#include "vmxstruct.h"
#include "mem.h"


LONG                gvt_uSubvertedCPUs = 0;
static KMUTEX MY_HvmMutex;
BOOLEAN   g_vt_SubvertedCPU = FALSE;
_TEPTPPML4T EPT_Ptable;

/********************************************************************
检测当前的处理器是否支持Vt
********************************************************************/
BOOLEAN NTAPI VmxIsImplemented(
      )
{
      ULONG32 eax, ebx, ecx, edx;
      GetCpuIdInfo(0, &eax, &ebx, &ecx, &edx);
      if (eax < 1)
      {
                DbgPrint("vmx:VmxIsImplemented(): Extended CPUID functions not implemented\n");
                return FALSE;
      }
      if (!(ebx == 0x756e6547 && ecx == 0x6c65746e && edx == 0x49656e69))
      {
                DbgPrint("vmx:VmxIsImplemented(): Not an INTEL processor\n");
                return FALSE;
      }
      //intel cpu use fun_0x1 to test VMX.   
      GetCpuIdInfo(0x1, &eax, &ebx, &ecx, &edx);
      return (BOOLEAN)(CmIsBitSet(ecx, 5));
}



// 开启Intel VT内核调试
NTSTATUS NTAPI StartVirtualTechnology()
{
      CCHAR cProcessorNumber;
      NTSTATUS Status, CallbackStatus;

      if (g_vt_SubvertedCPU)
      {
                DbgPrint("vmx:已经开启过VT\n");
                return STATUS_UNSUCCESSFUL;
      }

      if (!VmxIsImplemented())
      {
                return STATUS_UNSUCCESSFUL;
      }

      DbgPrint("vmx:在每隔核心上开启VT HvmSwallowBluepill(): Going to subvert %d processor%s\n",
                KeNumberProcessors, KeNumberProcessors == 1 ? "" : "s");

      MmInitManager();
      MmInitEptPageTable();
      KeInitializeMutex(&MY_HvmMutex, 0);
      //
      // 获得互斥体MY_HvmMutex对象, 保证一时间只有一个HvmSwallowBluepill函数在执行
      //
      KeWaitForSingleObject(&MY_HvmMutex, Executive, KernelMode, FALSE, NULL);

      //
      // 遍历所有处理器
      //
      for (cProcessorNumber = 0; cProcessorNumber < KeNumberProcessors; cProcessorNumber++)
      {

                DbgPrint("vmx:HvmSwallowBluepill(): CPU数量 #%d\n", cProcessorNumber);

                //
                // 向每个处理器投递消息,要求执行CmSubvert
                // CmDeliverToProcessor通过KeSetSystemAffinityThread将代码运行在指定CPU上,并提升IRQL为DPC_LEVEL
                // CmSubvert的流程是保存所有寄存器(除了段寄存器)的内容到栈里后,调用HvmSubvertCpu
                //
                Status = CmDeliverToProcessor(cProcessorNumber, CmSubvert, NULL, &CallbackStatus);

                //
                // 验证是否投递成功
                //
                if (!NT_SUCCESS(Status))
                {
                        DbgPrint("vmx:StartVirtualTechnology() CmDeliverToProcessor failed with status 0x%08hX\n", Status);
                        KeReleaseMutex(&MY_HvmMutex, FALSE);

                        StopVirtualTechnology();

                        return Status;
                }

                //
                // 验证HvmSubvertCpu是否成功
                //
                if (!NT_SUCCESS(CallbackStatus))
                {
                        DbgPrint("vmx:StartVirtualTechnology() HvmSubvertCpu failed with status 0x%08hX\n", CallbackStatus);
                        KeReleaseMutex(&MY_HvmMutex, FALSE);

                        StopVirtualTechnology();

                        return CallbackStatus;
                }
      }

      KeReleaseMutex(&MY_HvmMutex, FALSE);

      //
      // 如果没有对每个核都侵染成功,则撤销更改
      //
      if (KeNumberProcessors != gvt_uSubvertedCPUs)
      {
                g_vt_SubvertedCPU = FALSE;
                DbgPrint("vmx:没有对每个核都侵染成功撤销更改 %d %d\n", KeNumberProcessors, gvt_uSubvertedCPUs);
                StopVirtualTechnology();
                return STATUS_UNSUCCESSFUL;
      }
      g_vt_SubvertedCPU = TRUE;

      return STATUS_SUCCESS;
}


NTSTATUS NTAPI CmDeliverToProcessor(
      CCHAR cProcessorNumber,
      PCALLBACK_PROC CallbackProc,
      PVOID CallbackParam,
      PNTSTATUS pCallbackStatus
      )
{
      NTSTATUS CallbackStatus;
      KIRQL OldIrql;

      if (!CallbackProc)
                return STATUS_INVALID_PARAMETER;

      if (pCallbackStatus)
                *pCallbackStatus = STATUS_UNSUCCESSFUL;

      KeSetSystemAffinityThread((KAFFINITY)(1 << cProcessorNumber));
      // 提升IRQL至DISPATCH_LEVEL
      OldIrql = KeRaiseIrqlToDpcLevel();

      // 调用回调函数
      CallbackStatus = CallbackProc(CallbackParam);

      KeLowerIrql(OldIrql);

      KeRevertToUserAffinityThread();
      // 保存callback的返回值
      // save the status of the callback which has run on the current core
      if (pCallbackStatus)
                *pCallbackStatus = CallbackStatus;

      return STATUS_SUCCESS;
}


/* 关闭VT内核调试 */
NTSTATUS NTAPI StopVirtualTechnology()
{
      CCHAR cProcessorNumber;
      NTSTATUS Status, CallbackStatus;

      if (g_vt_SubvertedCPU == FALSE)
      {
                return STATUS_UNSUCCESSFUL;
      }

      DbgPrint("vmx:HvmSpitOutBluepill(): Going to liberate %d processor%s\n",
                KeNumberProcessors, KeNumberProcessors == 1 ? "" : "s");

      //
      // 获得互斥体MY_HvmMutex对象, 保证一时间只有一个HvmSpitOutBluepill函数在执行
      //
      KeWaitForSingleObject(&MY_HvmMutex, Executive, KernelMode, FALSE, NULL);

      //
      // 遍历所有处理器
      //
      for (cProcessorNumber = 0; cProcessorNumber < KeNumberProcessors; cProcessorNumber++)
      {

                DbgPrint("vmx:HvmSpitOutBluepill(): Liberating processor #%d\n", cProcessorNumber);

                //
                // 向每个处理器投递消息,要求执行HvmLiberateCpu, 来通知CPU退出Guest模式
                //
                Status = CmDeliverToProcessor(cProcessorNumber, LiberateCpu, NULL, &CallbackStatus);

                //
                // 验证是否投递成功
                //
                if (!NT_SUCCESS(Status)) {
                        DbgPrint("vmx:HvmSpitOutBluepill(): CmDeliverToProcessor() failed with status 0x%08hX\n", Status);
                }

                //
                // 验证HvmLiberateCpu是否成功
                //
                if (!NT_SUCCESS(CallbackStatus)) {
                        DbgPrint("vmx:HvmSpitOutBluepill(): HvmLiberateCpu() failed with status 0x%08hX\n", CallbackStatus);
                }
      }

      DbgPrint("vmx:HvmSpitOutBluepill(): Finished at irql %d\n", KeGetCurrentIrql());

      KeReleaseMutex(&MY_HvmMutex, FALSE);
      MmShutdownManager();
      return STATUS_SUCCESS;
}

//===========================================================================
//      这就是解放CPU了.会在每个Processor上面都执行一遍
//===========================================================================
NTSTATUS NTAPI LiberateCpu(PVOID Param)
{
      NTSTATUS Status;
      ULONG64 Efer;

      //
      // 中断级判断, 必须处在 DPC 级别上
      //
      if (KeGetCurrentIrql() != DISPATCH_LEVEL)
      {
                return STATUS_UNSUCCESSFUL;
      }

      //
      // 这个寄存器标示了是否开启了HVM.
      //
      Efer = MsrRead(MSR_EFER);

      DbgPrint("vmx:Ddvp-> Reading MSR_EFER on entry: 0x%X\n", Efer);
      if (g_vt_SubvertedCPU == FALSE)
      {
                DbgPrint("vmx:开启失败关闭CR4\n");
                VmxDisable();
                return STATUS_SUCCESS;
      }
      //
      // 这个函数向 Hypervisor 发出申请卸载的NBP_HYPERCALL_UNLOAD消息
      //
      if (!NT_SUCCESS(Status = MakeHyperExitCall()))
      {
                DbgPrint("vmx:Ddvp-> MakeHyperExitCall() failed on processor #%d, status 0x%08hX\n",
                        KeGetCurrentProcessorNumber(), Status);

                return Status;
      }

      Efer = MsrRead(MSR_EFER);

      DbgPrint("vmx:Ddvp-> Reading MSR_EFER on exit: 0x%X\n", Efer);

      return STATUS_SUCCESS;
}

NTSTATUS Virtualize(PCPU pCpu)
{
      /*    ULONG64 rsp;*/
      ULONG32 i;
      g_vt_SubvertedCPU = TRUE;
      i = KeGetCurrentProcessorNumber();
      DbgPrint("vmx:CPU: 0x%p \n", pCpu);
      //DbgPrint(("rsp: 0x%llx \n", _Rsp()));
      __vmx_vmlaunch();
      //VmxLaunch();
      /* never returns if successful */
      DbgPrint("vmx:rflags after _VmLaunch: 0x%x\n", RegGetRflags());
      if (_VmFailInvalid())
      {
                g_vt_SubvertedCPU = FALSE;
                DbgPrint("vmx:no current VMCS\n");
                return STATUS_UNSUCCESSFUL;
      }

      if (_VmFailValid())
      {
                g_vt_SubvertedCPU = FALSE;
                DbgPrint("vmx:vmlaunch failed\n");
                DbgPrint("vmx:_ReadVMCS: 0x%llx\n", ReadVMCS(VM_INSTRUCTION_ERROR));
                return STATUS_UNSUCCESSFUL;
      }
      g_vt_SubvertedCPU = FALSE;
      return STATUS_UNSUCCESSFUL;
}

NTSTATUS HvmSubvertCpu(PVOID GuestRsp)
{
      NTSTATUS Status;
      PVOID HostKernelStackBase;
      PCPU pCpu;

      Status = CheckIfVMXIsEnabled();
      if (!NT_SUCCESS(Status))
                return STATUS_UNSUCCESSFUL;

      //HostKernelStackBase = ExAllocatePoolWithTag(NonPagedPool, 16 * 0x1000, 0x42424242);
      HostKernelStackBase = MmAllocatePages(16, NULL);
      RtlZeroMemory(HostKernelStackBase, 16 * 0x1000);
      if (!HostKernelStackBase)
      {
                DbgPrint("vmx:can't allocate host kernel stack\n");
                return STATUS_INSUFFICIENT_RESOURCES;
      }

      pCpu = (PCPU)((PCHAR)HostKernelStackBase + 16 * 0x1000 - 8 - sizeof(CPU));
      pCpu->pHostRsp = HostKernelStackBase;
      pCpu->Self = pCpu;
      pCpu->State = STATE_RUNNING;
      pCpu->Mailbox = IPI_RUNNING;

      Status = SetupVMX(pCpu);

      // 当前处理器数量
      pCpu->CpuIndex = KeGetCurrentProcessorNumber();
      DbgPrint("vmx:Ddvp-> Vmx Cpu Address :%p HostKernelStackBase %p !\n", pCpu, HostKernelStackBase);
      if (Status == STATUS_UNSUCCESSFUL)
      {
                return STATUS_UNSUCCESSFUL;
      }
      //_HvmSetupGdt (pCpu);   // 配置Guest Gdt
      //_HvmSetupIdt(pCpu);   // 配置Guest Idt
      Status = SetupVMCS(pCpu, GuestRsp);
      //CmSetHookIdtEntry(0x3, (PVOID)InGeneralProtection);
      //_HvmSetupIdt(pCpu);   // 配置Guest Idt
      if (Status == STATUS_UNSUCCESSFUL)
      {
                return STATUS_UNSUCCESSFUL;
      }

      InterlockedIncrement(&gvt_uSubvertedCPUs);

      Status = Virtualize(pCpu);

      if (Status == STATUS_UNSUCCESSFUL)
      {
                DbgPrint("vmx:开启虚拟化这个函数返回执行失败 !\n");
                InterlockedDecrement(&gvt_uSubvertedCPUs);
                g_vt_SubvertedCPU = FALSE;
                return STATUS_UNSUCCESSFUL;
      }

      return STATUS_SUCCESS;
}


NTSTATUS CheckIfVMXIsEnabled()
{
      ULONG64 cr4;
      IA32_FEATURE_CONTROL_MSR msr;
      CR0_REG cr0;
      // 设置cr4位,为启用VM模式做准备

      

      /* vmx desactived by bios ? */
      /*msr = MsrRead(MSR_IA32_FEATURE_CONTROL);
      if (!(msr & 4))
      {
                DbgPrint("vmx is disabled in bios: MSR_IA32_FEATURE_CONTROL is 0x%llx\n", msr);
                return STATUS_UNSUCCESSFUL;
      }*/
      //bochs的bug,要改IA32_FEATURE_CONTROL的Lock为1
      //#if bochsdebug
      //MsrWrite(MSR_IA32_FEATURE_CONTROL, 5);
      //#endif
      
      TO_ULL(msr) = __readmsr(MSR_IA32_FEATURE_CONTROL);

      if (msr.Lock == 1)
      {
                // If the MSR is locked, it can't be modified
                // If 'EnableVmxon' is unset, virtualization is not possible
                if (msr.EnableVmxon == 0)
                {
                        DbgPrint("vmx:VMX is disabled in bios: MSR_IA32_FEATURE_CONTROL is 0x%llx\n", msr);
                        return STATUS_NOT_SUPPORTED;
                }
      }
      else
      {
                // Force the lock to be on and enable VMXON
                msr.Lock = 1;
                msr.VmxonInSmx = 1;
                msr.EnableVmxon = 1;

                __writemsr(MSR_IA32_FEATURE_CONTROL, TO_ULL(msr));
      }

      
      TO_ULL(cr0) = __readcr0();

      if (cr0.PE == 0 || cr0.PG == 0)
      {
                DbgPrint("vmx:Error: Protected mode or paging is not set in CR0\n");
                return STATUS_NOT_SUPPORTED;
      }
      else
      {
                // Required by first processors that supported VMX
                cr0.NE = 1;
      }

      __writecr0(TO_ULL(cr0));

      set_in_cr4(X86_CR4_VMXE);
      cr4 = RegGetCr4();

      if (!(cr4 & X86_CR4_VMXE))
      {
                DbgPrint("vmx:error: VMXON not supported\n");
                return STATUS_UNSUCCESSFUL;
      }

      return STATUS_SUCCESS;
}


NTSTATUS SetupVMX(PCPU pCpu)
{
      //      PHYSICAL_ADDRESS pa;
      ULONG64 msr;
      PVMX_BASIC_MSR pvmx;
      //      ULONG32 i;
      //      PVOID va;
      ULONG size;
      NTSTATUS Status = STATUS_SUCCESS;

      pCpu->CpuIndex = KeGetCurrentProcessorNumber();

      msr = MsrRead(MSR_IA32_VMX_BASIC);
      pvmx = (PVMX_BASIC_MSR)&msr;
      // Vmx结构体大小.
      size = pvmx->szVmxOnRegion;

      DbgPrint("vmx:VMXON region size: %p %p\n", size, msr);
      DbgPrint("vmx:VMX revision ID: %p pCpu->CpuIndex %p\n", pvmx->RevId, pCpu->CpuIndex);
      //

      //
      // Allocate memory for VMON, 然后执行vmxon指令
      //
      pCpu->pVMONVirtualAddress = MmAllocatePages(1, &pCpu->pVMONPyhicalAddress);
      if (pCpu->pVMONVirtualAddress == 0)
      {
                DbgPrint(("vmx:Ddvp-> VMXON 内存分配失败 !\n"));
                Status = STATUS_INSUFFICIENT_RESOURCES;
                goto __Exit;
      }

      DbgPrint("vmx:Ddvp-> VMON 虚拟地址%p !\n", pCpu->pVMONVirtualAddress);
      DbgPrint("vmx:Ddvp-> VMXON 内存物理地址:%p!\n", pCpu->pVMONPyhicalAddress);
      // vmxon版本号.
      //
      *(ULONG32 *)pCpu->pVMONVirtualAddress = pvmx->RevId;

      VmxTurnOn(pCpu->pVMONPyhicalAddress);

      if (_VmFailInvalid())
      {
                DbgPrint("vmx:_VmxOn failed\n");
                Status = STATUS_INSUFFICIENT_RESOURCES;
      }

      pCpu->pVMCSVirtualAddress = MmAllocatePages(1, &pCpu->pVMCSPyhicalAddress);
      if (pCpu->pVMCSVirtualAddress == 0)
      {
                DbgPrint("vmx:Ddvp-> 分配 VMCS结构内存失败!\n");
                Status = STATUS_INSUFFICIENT_RESOURCES;
                goto __Exit;
      }
      *(ULONG32 *)pCpu->pVMCSVirtualAddress = pvmx->RevId;
      DbgPrint("vmx:Ddvp-> VMCS 虚拟地址%p !\n", pCpu->pVMCSVirtualAddress);
      DbgPrint("vmx:Ddvp-> VMCS 内存物理地址:%p !\n", pCpu->pVMCSPyhicalAddress);

      // 这边是MSR位图.
      //
      pCpu->pMSRBitmapVirtualAddress = MmAllocatePages(4, &pCpu->pMSRBitmapPyhicalAddress);

      if (pCpu->pMSRBitmapVirtualAddress == NULL)
      {
                DbgPrint(("vmx:Ddvp-> 分配 MSR Bitmap 结构内存失败!\n"));
                Status = STATUS_INSUFFICIENT_RESOURCES;
                goto __Exit;
      }
      DbgPrint("vmx:Ddvp-> MSR 虚拟地址%p !\n", pCpu->pMSRBitmapVirtualAddress);

      DbgPrint("vmx:Ddvp-> MSR Bitmap 内存物理地址高位:%p, 低位:%p !\n",
                pCpu->pMSRBitmapPyhicalAddress.HighPart, pCpu->pMSRBitmapPyhicalAddress.LowPart);

      //
      // 这边是 IOBitmapA
      //
      pCpu->pIOBitmapVirtualAddressA = MmAllocatePages(1, &pCpu->pIOBitmapPyhicalAddressA);
      if (pCpu->pIOBitmapVirtualAddressA == NULL)
      {
                DbgPrint(("vmx:Ddvp-> 分配 IOBitmapA 结构内存失败!\n"));
                Status = STATUS_INSUFFICIENT_RESOURCES;
                goto __Exit;
      }
      DbgPrint("vmx:Ddvp-> IOBitmapA 虚拟地址%p !\n", pCpu->pIOBitmapVirtualAddressA);
      DbgPrint("vmx:Ddvp-> IOBitmapA 内存物理地址高位:%p, 低位:%p !\n",
                pCpu->pIOBitmapPyhicalAddressA.HighPart, pCpu->pIOBitmapPyhicalAddressA.LowPart);
      //
      // 这边是 IOBitmapB
      //
      pCpu->pIOBitmapVirtualAddressB = MmAllocatePages(1, &pCpu->pIOBitmapPyhicalAddressB);
      if (pCpu->pIOBitmapVirtualAddressB == NULL)
      {
                DbgPrint(("vmx:Ddvp-> 分配 IOBitmapB 结构内存失败!\n"));
                Status = STATUS_INSUFFICIENT_RESOURCES;
                goto __Exit;
      }
      DbgPrint("vmx:Ddvp-> IOBitmaB 虚拟地址:%p !\n", pCpu->pIOBitmapVirtualAddressB);
      DbgPrint("vmx:Ddvp-> IOBitmapB 内存物理地址高位:%p, 低位:%p !\n",
                pCpu->pIOBitmapPyhicalAddressB.HighPart, pCpu->pIOBitmapPyhicalAddressB.LowPart);

      pCpu->GdtArea = MmAllocatePages(BYTES_TO_PAGES(BP_GDT_LIMIT), NULL);

      if (!pCpu->GdtArea) {
                DbgPrint("vmx:HvmSubvertCpu(): Failed to allocate memory for GDT\n");
                Status = STATUS_INSUFFICIENT_RESOURCES;
                goto __Exit;
      }
      DbgPrint("vmx:Ddvp-> pCpu->GdtArea内存地址%p !\n", pCpu->GdtArea);
      pCpu->IdtArea = MmAllocatePages(BYTES_TO_PAGES(BP_IDT_LIMIT), NULL);
      if (!pCpu->IdtArea)
      {
                DbgPrint("vmx:HvmSubvertCpu(): Failed to allocate memory for IDT\n");
                Status = STATUS_INSUFFICIENT_RESOURCES;
                goto __Exit;
      }
      DbgPrint("vmx:Ddvp-> pCpu->IdtArea内存地址%p !\n", pCpu->IdtArea);
      // 填写版本号
      

__Exit:

      if (!NT_SUCCESS(Status))
      {
                DbgPrint("vmx:Ddvp-> 失败 释放内存!\n");

                if (pCpu->pVMONVirtualAddress)
                {
                        MmFreeNonCachedMemory(pCpu->pVMONVirtualAddress, 0x1000);
                        pCpu->pVMONVirtualAddress = NULL;

                }

                if (pCpu->pVMCSVirtualAddress)
                {
                        MmFreeNonCachedMemory(pCpu->pVMCSVirtualAddress, 0x1000);
                        pCpu->pVMCSVirtualAddress = NULL;
                }

                if (pCpu->pIOBitmapVirtualAddressA)
                {
                        MmFreeNonCachedMemory(pCpu->pIOBitmapVirtualAddressA, 0x1000);
                        pCpu->pIOBitmapVirtualAddressA = NULL;
                }

                if (pCpu->pIOBitmapVirtualAddressB)
                {
                        MmFreeNonCachedMemory(pCpu->pIOBitmapVirtualAddressB, 0x1000);
                        pCpu->pIOBitmapVirtualAddressB = NULL;
                }

                if (pCpu->pMSRBitmapVirtualAddress)
                {
                        MmFreeNonCachedMemory(pCpu->pMSRBitmapVirtualAddress, 0x1000);
                        pCpu->pMSRBitmapVirtualAddress = NULL;
                }
                if (pCpu->IdtArea)
                {
                        MmFreeNonCachedMemory(pCpu->IdtArea, BYTES_TO_PAGES(BP_IDT_LIMIT));
                        pCpu->IdtArea = NULL;
                }
                if (pCpu->GdtArea)
                {
                        MmFreeNonCachedMemory(pCpu->GdtArea, BYTES_TO_PAGES(BP_GDT_LIMIT));
                        pCpu->GdtArea = NULL;
                }

      }
      return Status;
}




NTSTATUS SetupVMCS(PCPU pCpu, PVOID GuestRsp)
{
      ULONG32 Interceptions, ExceptionBitmap, Cr0, Cr4;
      PVOID GdtBase;
      SEGMENT_SELECTOR SegmentSelector;
      ULONG32 i;
      PHYSICAL_ADDRESS pa;
      ULONG64 ExceptionBit;
      PTEPTPPML4T pPML4T;
      //i = KeGetCurrentProcessorNumber();
      //DbgPrint(("pCpu %p GuestRsp=%p\n", pCpu,GuestRsp));

      pa = pCpu->pVMCSPyhicalAddress;
      VmxClear(pa);
      _VmxPtrLd(pa);

      DbgPrint("vmx:RegGetCr0() %p\n", RegGetCr0());
      Cr0 = (ULONG32)RegGetCr0();
      CmSetBit32(&Cr0, 0);      // PE
      CmSetBit32(&Cr0, 5);      // NE
      CmSetBit32(&Cr0, 31);      // PG
      DbgPrint("vmx:CR0         %p\n", Cr0);
      
      WriteVMCS(GUEST_CR0, Cr0);
      WriteVMCS(GUEST_CR3, RegGetCr3());
      //; DbgPrint((" RegGetCr3() %p\n", RegGetCr3()));
      //; DbgPrint((" RegGetCr4() %p\n", RegGetCr4()));
      Cr4 = RegGetCr4();
      CmSetBit32(&Cr4, 13);// 一定要设置VMXE
      WriteVMCS(GUEST_CR4, Cr4);
      WriteVMCS(GUEST_DR7, 0x400);
      WriteVMCS(GUEST_RSP, (ULONG64)GuestRsp);
      WriteVMCS(GUEST_RIP, (ULONG64)_GuestEntryPoint);
      WriteVMCS(GUEST_RFLAGS, RegGetRflags());

      /*DbgPrint("RegGetRflags %p\n", RegGetRflags());
      DbgPrint("DR7 %p\n", ReadVMCS(GUEST_DR7));
      DbgPrint("GUEST_RSP %p\n", ReadVMCS(GUEST_RSP));
      DbgPrint("GUEST_RIP %p\n", ReadVMCS(GUEST_RIP));
      DbgPrint("GUEST_RFLAGS %p\n", ReadVMCS(GUEST_RFLAGS));*/

      GdtBase = (PVOID)GetGdtBase();
      //DbgPrint(("GdtBase %p\n", GdtBase));

      FillGuestSelectorData(GdtBase, ES, RegGetEs());
      FillGuestSelectorData(GdtBase, CS, RegGetCs());
      FillGuestSelectorData(GdtBase, SS, RegGetSs());
      FillGuestSelectorData(GdtBase, DS, RegGetDs());
      FillGuestSelectorData(GdtBase, FS, RegGetFs());
      FillGuestSelectorData(GdtBase, GS, RegGetGs());
      FillGuestSelectorData(GdtBase, LDTR, GetLdtr());
      FillGuestSelectorData(GdtBase, TR, GetTrSelector());
      /*DbgPrint("ES %x CS %x SS %x DS %x FS %x GS %x LDTR %x TR %x \n", ES ,CS,SS,DS,FS,GS,LDTR,TR);
      DbgPrint("RegGetEs() %p\n", RegGetEs());
      DbgPrint("RegGetCs() %p\n", RegGetCs());
      DbgPrint("RegGetSs() %p\n", RegGetSs());
      DbgPrint("RegGetDs() %p\n", RegGetDs());
      DbgPrint("RegGetFs() %p\n", RegGetFs());
      DbgPrint("RegGetGs() %p\n", RegGetGs());
      DbgPrint("GetLdtr() %p\n", GetLdtr());
      DbgPrint("GetTrSelector() %p\n", GetTrSelector());*/

      // 填写Guest段描述符基址
      WriteVMCS(GUEST_ES_BASE, 0);
      WriteVMCS(GUEST_CS_BASE, 0);
      WriteVMCS(GUEST_SS_BASE, 0);
      WriteVMCS(GUEST_DS_BASE, 0);
      WriteVMCS(GUEST_FS_BASE, MsrRead(MSR_FS_BASE));
      WriteVMCS(GUEST_GS_BASE, MsrRead(MSR_GS_BASE));
      // 填写Guest GDTR/IDTR基址
      WriteVMCS(GUEST_GDTR_BASE, GetGdtBase());
      WriteVMCS(GUEST_IDTR_BASE, GetIdtBase());
      // 填写Guest段描述符限长
      WriteVMCS(GUEST_GDTR_LIMIT, GetGdtLimit());
      WriteVMCS(GUEST_IDTR_LIMIT, GetIdtLimit());
      /*DbgPrint("GetIdtBase() %p\n", GetIdtBase());
      DbgPrint("GetGdtLimit() %p\n", GetGdtLimit());
      DbgPrint("GetIdtLimit() %p\n", GetIdtLimit());
      DbgPrint("MsrRead(MSR_FS_BASE) %p MsrRead(MSR_GS_BASE) %p\n", MsrRead(MSR_FS_BASE), MsrRead(MSR_GS_BASE));*/

      // 填写Guest MSR IA32_DEBUGCTL 寄存器值
      WriteVMCS(GUEST_IA32_DEBUGCTL, MsrRead(MSR_IA32_DEBUGCTL) & 0xffffffff);
      WriteVMCS(GUEST_IA32_DEBUGCTL_HIGH, MsrRead(MSR_IA32_DEBUGCTL) >> 32);

      //DbgPrint("MsrRead(GUEST_IA32_DEBUGCTL) %pMsrRead(GUEST_IA32_DEBUGCTL_HIGH) %p\n", MsrRead(MSR_IA32_DEBUGCTL), MsrRead(MSR_IA32_DEBUGCTL));
      // 填写Guest MSR IA32_SYSENTER_CS
      WriteVMCS(GUEST_SYSENTER_CS, MsrRead(MSR_IA32_SYSENTER_CS));
      // 填写Guest MSR IA32_SYSENTER_ESP
      WriteVMCS(GUEST_SYSENTER_ESP, MsrRead(MSR_IA32_SYSENTER_ESP));
      // 填写Guest MSR IA32_SYSENTER_EIP
      WriteVMCS(GUEST_SYSENTER_EIP, MsrRead(MSR_IA32_SYSENTER_EIP));
      /*DbgPrint("MsrRead(MSR_IA32_SYSENTER_CS) %p MsrRead(MSR_IA32_SYSENTER_ESP) %p MsrRead(MSR_IA32_SYSENTER_ESP) % p", MsrRead(MSR_IA32_SYSENTER_CS),MsrRead(MSR_IA32_SYSENTER_ESP), MsrRead(MSR_IA32_SYSENTER_ESP));

      DbgPrint(" ReadVMCS(GUEST_SYSENTER_CS) %pReadVMCS(GUEST_IA32_DEBUGCTL_HIGH) %p\n", ReadVMCS(GUEST_SYSENTER_CS), ReadVMCS(GUEST_SYSENTER_ESP));*/
      // 填写 GUEST IA32_EFER
      WriteVMCS(GUEST_IA32_EFER, MsrRead(MSR_EFER));
      //DbgPrint(" ReadVMCS(GUEST_IA32_EFER) %pReadVMCS(GUEST_SYSENTER_EIP) %p\n", ReadVMCS(GUEST_IA32_EFER), ReadVMCS(GUEST_SYSENTER_EIP));
      /* guest non register state */
      // Guest中断能力状态
      WriteVMCS(GUEST_INTERRUPTIBILITY_INFO, 0);
      // Guest活动性状态
      WriteVMCS(GUEST_ACTIVITY_STATE, 0);
      // VMCS连接指针(保留)
      WriteVMCS(VMCS_LINK_POINTER, 0xffffffff);
      WriteVMCS(VMCS_LINK_POINTER_HIGH, 0xffffffff);

      /* host state area */
      // 控制寄存器 CR0, CR3, CR4
      WriteVMCS(HOST_CR0, RegGetCr0());
      WriteVMCS(HOST_CR3, RegGetCr3());
      WriteVMCS(HOST_CR4, RegGetCr4());
      // 设置Host ESP, EIP
      WriteVMCS(HOST_RSP, (ULONG64)pCpu);
      WriteVMCS(HOST_RIP, (ULONG64)_ExitHandler);
      // 填写Host CS, SS, DS, ES, FS, GS和TR寄存器
      WriteVMCS(HOST_ES_SELECTOR, KGDT64_R0_DATA);
      WriteVMCS(HOST_CS_SELECTOR, KGDT64_R0_CODE);
      WriteVMCS(HOST_SS_SELECTOR, KGDT64_R0_DATA);
      WriteVMCS(HOST_DS_SELECTOR, KGDT64_R0_DATA);
      WriteVMCS(HOST_FS_SELECTOR, (RegGetFs() & 0xf8));
      WriteVMCS(HOST_GS_SELECTOR, (RegGetGs() & 0xf8));
      WriteVMCS(HOST_TR_SELECTOR, (GetTrSelector() & 0xf8));

      WriteVMCS(HOST_FS_BASE, MsrRead(MSR_FS_BASE));
      WriteVMCS(HOST_GS_BASE, MsrRead(MSR_GS_BASE));
      //DbgPrint(("MsrRead(MSR_GS_BASE) %p MsrRead(MSR_FS_BASE) %p\n", MsrRead(MSR_GS_BASE), MsrRead(MSR_FS_BASE)));
      InitializeSegmentSelector(&SegmentSelector, GetTrSelector(), (PVOID)
                GetGdtBase());

      WriteVMCS(HOST_TR_BASE, SegmentSelector.base);

      WriteVMCS(HOST_GDTR_BASE, (ULONG64)GetGdtBase());
      WriteVMCS(HOST_IDTR_BASE, (ULONG64)GetIdtBase());
      DbgPrint("vmx:GetGdtBase() %pGetIdtBase() %p\n", GetGdtBase(), GetIdtBase());
      WriteVMCS(HOST_IA32_SYSENTER_ESP, MsrRead(MSR_IA32_SYSENTER_ESP));
      WriteVMCS(HOST_IA32_SYSENTER_EIP, MsrRead(MSR_IA32_SYSENTER_EIP));
      WriteVMCS(HOST_IA32_SYSENTER_CS, MsrRead(MSR_IA32_SYSENTER_CS));
      // 填写 Host IA32_EFER
      WriteVMCS(HOST_IA32_EFER, MsrRead(MSR_EFER));

      /* VM Execution Control Fields */
      WriteVMCS(PIN_BASED_VM_EXEC_CONTROL, VmxAdjustControls(0,
                MSR_IA32_VMX_PINBASED_CTLS));


      Interceptions = VmxAdjustControls(0, MSR_IA32_VMX_PROCBASED_CTLS);
      //DbgPrint("Interceptions    %p\n", Interceptions);
      Interceptions |= CPU_BASED_ACTIVATE_MSR_BITMAP;
      //Interceptions |= CPU_BASED_INVLPG_EXITING;
      //Interceptions|=CPU_BASED_MTF_TRAP_EXITING;//启用MTF调试功能
      Interceptions |= CPU_BASED_ACTIVATE_SECONDARY_CONTROLS;//启用SECONDARY_VM_EXEC_CONTROL字段
      //Interceptions |=CPU_BASED_MOV_DR_EXITING;//DR寄存器访问
      Interceptions &= ~CPU_BASED_CR3_LOAD_EXITING;//关闭拦截CR3寄存器
      Interceptions &= ~CPU_BASED_CR3_STORE_EXITING;//关闭拦截CR3寄存器
      //Interceptions &= ~CPU_BASED_ACTIVATE_MSR_BITMAP;
      WriteVMCS(CPU_BASED_VM_EXEC_CONTROL, Interceptions);
      //DbgPrint("Interceptions%p\n", Interceptions);

      ExceptionBitmap = 0;
      ExceptionBitmap |= SECONDARY_EXEC_ENABLE_EPT;//启用EPT
      ExceptionBitmap |= SECONDARY_EXEC_ENABLE_VPID;//启用虚拟VPID
      WriteVMCS(SECONDARY_VM_EXEC_CONTROL, ExceptionBitmap);

      ExceptionBitmap = 0;
      ExceptionBitmap |= 1 << DEBUG_EXCEPTION;
      ExceptionBitmap |= 1 << BREAKPOINT_EXCEPTION;
      ExceptionBitmap |= 1 << PAGE_FAULT_EXCEPTION;
      WriteVMCS(EXCEPTION_BITMAP, ExceptionBitmap);
      // 配置页故障
      WriteVMCS(PAGE_FAULT_ERROR_CODE_MASK, 0);
      WriteVMCS(PAGE_FAULT_ERROR_CODE_MATCH, 0);
      // 填写 3.4 I/O bitmap IO位图, 这里可以拦截了60号端口.. 也就是键盘输入
      WriteVMCS(IO_BITMAP_A, pCpu->pIOBitmapPyhicalAddressA.LowPart);
      WriteVMCS(IO_BITMAP_A_HIGH, pCpu->pIOBitmapPyhicalAddressA.HighPart);
      WriteVMCS(IO_BITMAP_B, pCpu->pIOBitmapPyhicalAddressB.LowPart);
      WriteVMCS(IO_BITMAP_B_HIGH, pCpu->pIOBitmapPyhicalAddressB.HighPart);
      // 填写 3.5 时间戳计数器偏移(Time-Stamp Counter Offset )
      WriteVMCS(TSC_OFFSET, 0);
      WriteVMCS(TSC_OFFSET_HIGH, 0);

      // 填写 3.7 CR3访问控制.
      WriteVMCS(CR3_TARGET_COUNT, 0);
      WriteVMCS(CR3_TARGET_VALUE0, 0);      //no use
      WriteVMCS(CR3_TARGET_VALUE1, 0);      //no use                        
      WriteVMCS(CR3_TARGET_VALUE2, 0);      //no use
      WriteVMCS(CR3_TARGET_VALUE3, 0);      //no use
      // 填写3.9 MSR 位图地址(MSR Bitmap Address)
      // 这里我只需要截获 MSR_IA32_SYSENTER_EIP MSR寄存器的读写
      // 对于其他优化现在还没有.. 先不管
      //
      WriteVMCS(MSR_BITMAP, pCpu->pMSRBitmapPyhicalAddress.LowPart);
      WriteVMCS(MSR_BITMAP_HIGH, pCpu->pMSRBitmapPyhicalAddress.HighPart);

      WriteVMCS(VM_ENTRY_CONTROLS, VmxAdjustControls(VM_ENTRY_IA32E_MODE | VM_ENTRY_LOAD_IA32_EFER, MSR_IA32_VMX_ENTRY_CTLS));
      DbgPrint("vmx:VM_ENTRY行为控制域 %p\n", ReadVMCS(VM_ENTRY_CONTROLS));
      WriteVMCS(VM_ENTRY_MSR_LOAD_COUNT, 0);
      WriteVMCS(VM_ENTRY_INTR_INFO_FIELD, 0);

      /* VM Exit Control */
      WriteVMCS(VM_EXIT_CONTROLS, VmxAdjustControls(VM_EXIT_IA32E_MODE |
                VM_EXIT_ACK_INTR_ON_EXIT, MSR_IA32_VMX_EXIT_CTLS));
      WriteVMCS(VM_EXIT_MSR_STORE_COUNT, 0);
      WriteVMCS(VM_EXIT_MSR_LOAD_COUNT, 0);
      //WriteVMCS(VM_EXIT_CONTROLS,
      //VmxAdjustControls(VM_EXIT_SAVE_DEBUG_CONTROLS | VM_EXIT_IA32E_MODE | VM_EXIT_ACK_INTR_ON_EXIT | VM_EXIT_SAVE_IA32_EFER | VM_EXIT_LOAD_IA32_EFER, MSR_IA32_VMX_EXIT_CTLS));

      //DbgPrint(("VMExit行为控制域 %p%p\n", ReadVMCS(VM_EXIT_CONTROLS), VmxAdjustControls(VM_EXIT_SAVE_DEBUG_CONTROLS | VM_EXIT_IA32E_MODE | VM_EXIT_ACK_INTR_ON_EXIT | VM_EXIT_SAVE_IA32_EFER | VM_EXIT_LOAD_IA32_EFER, MSR_IA32_VMX_EXIT_CTLS)));

      //WriteVMCS(CR0_GUEST_HOST_MASK, X86_CR0_PG);
      //WriteVMCS(CR0_READ_SHADOW, (_Cr0() & X86_CR0_PG) | X86_CR0_PG);

      //WriteVMCS(CR4_GUEST_HOST_MASK, X86_CR4_VMXE);
      //WriteVMCS(CR4_READ_SHADOW, 0);

      
      //3.11 EPT指针(Extended Page Table Pointer), 没有用
      //检测并开启UG
      // 读取cpu的MSR_IA32_VMX_PROCBASED_CTLS2(0x48B), 以检测cpu是否支持UC。
      DbgPrint("vmx:检测是否支持EPT %p%p\n", MsrRead(MSR_IA32_VMX_PROCBASED_CTLS2), VmxAdjustControls(0, MSR_IA32_VMX_PROCBASED_CTLS2));
      /*DbgPrint (("检测是否支持EPT %p%p\n",MsrRead(MSR_IA32_VMX_PROCBASED_CTLS), VmxAdjustControls (0, MSR_IA32_VMX_PROCBASED_CTLS)));
      DbgPrint (("检测是否支持EPT %p%p\n",MsrRead(MSR_IA32_VMX_EPT_VPID_CAP), VmxAdjustControls (0, MSR_IA32_VMX_PROCBASED_CTLS)));*/
      //在VMCS的SECONDARY_VM_EXEC_CONTROL(0x401E) 字段,对应的ENABLE_UC(0x80)标识位置1。

      ExceptionBit = 0;
      pPML4T = (PTEPTPPML4T)&ExceptionBit;
      pPML4T->MEMORYTYPE = 6;//(内存类型)UD = 0,WB = 6
      pPML4T->WalkLength = 3;//EPT页表结构的层级,这个值+1才是真正的层级(3)就代表有4层
      pPML4T->reserved = 0;
      pPML4T->D = 1;//代表EPT页表里access 与 dirty 标志位有效
      pPML4T->PML4T = EPT_Ptable.PML4EPHY.QuadPart >> 12;//让开前面的12-1位域写入
      //pPML4T->reserved2=0;
      WriteVMCS(EPT_POINTER, ExceptionBit);

      WriteVMCS(VIRTUAL_PROCESSOR_ID, 1);

      return STATUS_SUCCESS;
}


NTSTATUS ResumeGuest()
{
      DbgPrint("vmx:Resuming guest ok...\n");
      return STATUS_SUCCESS;
}


NTSTATUS NTAPI VmxShutdown(
      PCPU Cpu,
      PGUEST_REGS GuestRegs
      )
{
      ULONG uTrampolineSize = 0;
      ULONG64 NewRsp;
      ULONG64 cr4;
      UCHAR Trampoline;

      DbgPrint("vmx:VmxShutdown(): CPU#%d\n", gvt_uSubvertedCPUs);
      InterlockedDecrement(&gvt_uSubvertedCPUs);

      // The code should be updated to build an approproate trampoline to exit to any guest mode.

      VmxGenerateTrampolineToGuest(Cpu, GuestRegs, Trampoline);


      DbgPrint("vmx:VmxShutdown(): Trampoline generate %d\n", gvt_uSubvertedCPUs);



      VmxDisable();




      ((VOID(*)()) & Trampoline) ();

      DbgPrint("vmx:never returns********************* CPU#%d\n", gvt_uSubvertedCPUs);
      return STATUS_SUCCESS;
}

NTSTATUS NTAPI VmxDisable(
      )
{
      ULONG64 cr4;
      VmxTurnOff();
      cr4 = RegGetCr4();
      clear_in_cr4(X86_CR4_VMXE);
      //clear_in_cr4(X86_CR4_SMEP);
      cr4 = RegGetCr4();
      DbgPrint("vmx:VmxDisable(): CR4 after VmxDisable: 0x%llx\n", cr4);
      return STATUS_SUCCESS;
}

VOID VmxGenerateTrampolineToGuest(
      PCPU Cpu,
      PGUEST_REGS GuestRegs,
      PUCHAR Trampoline
      )
{
      ULONG uTrampolineSize = 0;
      ULONG64 NewRsp;

      //      if (!Cpu || !GuestRegs)
      //      return;

      // assume Trampoline buffer is big enough
      WriteVMCS(GUEST_RFLAGS, ReadVMCS(GUEST_RFLAGS) & ~0x100);   // disable TF

      CmGenerateMovReg(&Trampoline, &uTrampolineSize, REG_RCX, GuestRegs->rcx);
      CmGenerateMovReg(&Trampoline, &uTrampolineSize, REG_RDX, GuestRegs->rdx);

      CmGenerateMovReg(&Trampoline, &uTrampolineSize, REG_RBX, GuestRegs->rbx);
      CmGenerateMovReg(&Trampoline, &uTrampolineSize, REG_RBP, GuestRegs->rbp);
      CmGenerateMovReg(&Trampoline, &uTrampolineSize, REG_RSI, GuestRegs->rsi);
      CmGenerateMovReg(&Trampoline, &uTrampolineSize, REG_RDI, GuestRegs->rdi);

#ifndef _X86_
      CmGenerateMovReg(&Trampoline, &uTrampolineSize, REG_R8, GuestRegs->r8);
      CmGenerateMovReg(&Trampoline, &uTrampolineSize, REG_R9, GuestRegs->r9);
      CmGenerateMovReg(&Trampoline, &uTrampolineSize, REG_R10, GuestRegs->r10);
      CmGenerateMovReg(&Trampoline, &uTrampolineSize, REG_R11, GuestRegs->r11);
      CmGenerateMovReg(&Trampoline, &uTrampolineSize, REG_R12, GuestRegs->r12);
      CmGenerateMovReg(&Trampoline, &uTrampolineSize, REG_R13, GuestRegs->r13);
      CmGenerateMovReg(&Trampoline, &uTrampolineSize, REG_R14, GuestRegs->r14);
      CmGenerateMovReg(&Trampoline, &uTrampolineSize, REG_R15, GuestRegs->r15);
#endif

      CmGenerateMovReg(&Trampoline, &uTrampolineSize, REG_CR0, ReadVMCS(GUEST_CR0));
      CmGenerateMovReg(&Trampoline, &uTrampolineSize, REG_CR3, ReadVMCS(GUEST_CR3));
      CmGenerateMovReg(&Trampoline, &uTrampolineSize, REG_CR4, ReadVMCS(GUEST_CR4));

      NewRsp = ReadVMCS(GUEST_RSP);

      CmGenerateMovReg(&Trampoline, &uTrampolineSize, REG_RSP, NewRsp);

      // construct stack frame for IRETQ:
      //       rip
      //    cs
      //    rflags
      //    rsp
      //    ss

      // construct stack frame for IRETD:
      //       rip
      //     cs
      //     rflags

#ifndef _X86_
      CmGenerateMovReg(&Trampoline, &uTrampolineSize, REG_RAX, ReadVMCS(GUEST_SS_SELECTOR));
      CmGeneratePushReg(&Trampoline, &uTrampolineSize, REG_RAX);
      CmGenerateMovReg(&Trampoline, &uTrampolineSize, REG_RAX, NewRsp);
      CmGeneratePushReg(&Trampoline, &uTrampolineSize, REG_RAX);
#endif
      CmGenerateMovReg(&Trampoline, &uTrampolineSize, REG_RAX, ReadVMCS(GUEST_RFLAGS));
      CmGeneratePushReg(&Trampoline, &uTrampolineSize, REG_RAX);
      CmGenerateMovReg(&Trampoline, &uTrampolineSize, REG_RAX, ReadVMCS(GUEST_CS_SELECTOR));
      CmGeneratePushReg(&Trampoline, &uTrampolineSize, REG_RAX);

      CmGenerateMovReg(&Trampoline, &uTrampolineSize, REG_RAX,
                ReadVMCS(GUEST_RIP) + ReadVMCS(VM_EXIT_INSTRUCTION_LEN));

      CmGeneratePushReg(&Trampoline, &uTrampolineSize, REG_RAX);

      CmGenerateMovReg(&Trampoline, &uTrampolineSize, REG_RAX, GuestRegs->rax);

#ifdef _X86_
      CmGenerateIretd(&Trampoline, &uTrampolineSize);
#else
      CmGenerateIretq(&Trampoline, &uTrampolineSize);
#endif

      // restore old GDTR
      CmReloadGdtr((PVOID)ReadVMCS(GUEST_GDTR_BASE), (ULONG)ReadVMCS(GUEST_GDTR_LIMIT));

      MsrWrite(MSR_GS_BASE, ReadVMCS(GUEST_GS_BASE));
      MsrWrite(MSR_FS_BASE, ReadVMCS(GUEST_FS_BASE));

      // FIXME???
      // restore ds, es
      //      CmSetDS((USHORT)ReadVMCS(GUEST_DS_SELECTOR));
      //   CmSetES((USHORT)ReadVMCS(GUEST_ES_SELECTOR));

      // cs and ss must be the same with the guest OS in this implementation
      DbgPrint("vmx:restore old IDTR\n");
      // restore old IDTR
      CmReloadIdtr((PVOID)ReadVMCS(GUEST_IDTR_BASE), (ULONG)ReadVMCS(GUEST_IDTR_LIMIT));

      return;
}

NTSTATUS NTAPI CmGenerateIretq(
      PUCHAR pCode,
      PULONG pGeneratedCodeLength
      )
{
      if (!pCode || !pGeneratedCodeLength)
                return STATUS_INVALID_PARAMETER;

      pCode = 0x48;
      pCode = 0xcf;
      *pGeneratedCodeLength += 2;
      //DbgPrint(("CmGenerateIretq\n"));
      return STATUS_SUCCESS;
}


NTSTATUS NTAPI CmGenerateMovReg(
      PUCHAR pCode,
      PULONG pGeneratedCodeLength,
      ULONG Register,
      ULONG64 Value
      )
{
      ULONG uCodeLength;

      if (!pCode || !pGeneratedCodeLength)
                return STATUS_INVALID_PARAMETER;

      switch (Register & ~REG_MASK) {
      case REG_GP:
                pCode = 0x48;
                pCode = 0xb8 | (UCHAR)(Register & REG_MASK);
                memcpy(&pCode, &Value, 8);
                uCodeLength = 10;
                break;

      case REG_GP_ADDITIONAL:
                pCode = 0x49;
                pCode = 0xb8 | (UCHAR)(Register & REG_MASK);
                memcpy(&pCode, &Value, 8);
                uCodeLength = 10;
                break;

      case REG_CONTROL:
                uCodeLength = *pGeneratedCodeLength;
                CmGenerateMovReg(pCode, pGeneratedCodeLength, REG_RAX, Value);
                // calc the size of the "mov rax, value"
                uCodeLength = *pGeneratedCodeLength - uCodeLength;
                pCode += uCodeLength;

                uCodeLength = 0;

                if (Register == (REG_CR8)) {
                        // build 0x44 0x0f 0x22 0xc0
                        pCode = 0x44;
                        uCodeLength = 1;
                        pCode++;
                        Register = 0;
                }
                // mov crX, rax

                pCode = 0x0f;
                pCode = 0x22;
                pCode = 0xc0 | (UCHAR)((Register & REG_MASK) << 3);

                // *pGeneratedCodeLength has already been adjusted to the length of the "mov rax"
                uCodeLength += 3;
      }

      if (pGeneratedCodeLength)
                *pGeneratedCodeLength += uCodeLength;
      //DbgPrint((" CmGenerateMovReg\n"));
      return STATUS_SUCCESS;
}

NTSTATUS NTAPI CmGeneratePushReg(
      PUCHAR pCode,
      PULONG pGeneratedCodeLength,
      ULONG Register
      )
{
      if (!pCode || !pGeneratedCodeLength)
                return STATUS_INVALID_PARAMETER;

      if ((Register & ~REG_MASK) != REG_GP)
                return STATUS_NOT_SUPPORTED;

      pCode = 0x50 | (UCHAR)(Register & REG_MASK);
      *pGeneratedCodeLength += 1;
      //DbgPrint((" CmGeneratePushReg\n"));
      return STATUS_SUCCESS;
}


NTSTATUS NTAPI MmInitEptPageTable()
{
      PHYSICAL_ADDRESS FirstPtePA, FirstPdePA, FirstPdptePA, l1, l2, l3;
      PULONG64 FirstPteVA, FirstPdeVA, FirstPdpteVA, FirstPml4eVA;
      PULONG64 FirstPdeVa_Legacy;
      ULONG64 i, j;
      l1.QuadPart = 0;
      l2.QuadPart = -1;
      l3.QuadPart = 0x200000;


      //FirstPteVA = (PULONG64)MmAllocateContiguousMemorySpecifyCache(64 * PAGE_SIZE, l1, l2, l3, MmCached);// MmAllocateContiguousPagesSpecifyCache(512, &FirstPtePA, MmCached);
      //if (!FirstPteVA)
      //      return NULL;
      //RtlZeroMemory(FirstPteVA, 64 * PAGE_SIZE);
      //FirstPtePA = MmGetPhysicalAddress(FirstPteVA);
      //KdPrint(("FirstPteVA 0x%p FirstPtePA 0x%llX\n", FirstPteVA, FirstPtePA.QuadPart));
      //for (i = 0; i < 512; i++)
      //{
      //      for (j = 0; j < 512; j++) {
      //                *FirstPteVA = ((i *0x200000) + j * 0x1000) | EPT_READ | EPT_WRIT | EPT_EXECUTE;
      //                FirstPteVA++;
      //      }
      //}

      DbgPrint("vmx:FirstPteVA 0x%p FirstPtePA 0x%llX\n", FirstPteVA, FirstPtePA.QuadPart);
      //64*512 Pde
      //FirstPdeVA = (PULONG64)MmAllocateContiguousMemorySpecifyCache(64 * PAGE_SIZE, l1, l2, l3, MmCached);
      FirstPdeVA = AllocateContiguousMemory(64 * PAGE_SIZE);
      if (!FirstPdeVA)
                return STATUS_INSUFFICIENT_RESOURCES;

      RtlZeroMemory(FirstPdeVA, 64 * PAGE_SIZE);

      FirstPdePA = MmGetPhysicalAddress(FirstPdeVA);
      EPT_Ptable.PDE = (ULONG64)FirstPdeVA;
      EPT_Ptable.PDEPHY = FirstPdePA;

      DbgPrint("vmx:MmInitIdentityPageTable: FirstPdeVA 0x%p FirstPdePA 0x%llX\n", FirstPdeVA, FirstPdePA.QuadPart);
      for (i = 0; i < 64; i++) {
                for (j = 0; j < 512; j++) {
                        *FirstPdeVA = ((i * 0x40000000) + j * 0x200000) | EPT_READ | EPT_WRIT | EPT_EXECUTE | P_LARGE;
                        FirstPdeVA++;
                }
      }
      DbgPrint("vmx:MmInitIdentityPageTable: FirstPdeVA 0x%p FirstPdePA 0x%llX\n", FirstPdeVA, FirstPdePA.QuadPart);
      //////////////////////////////////////////



      //64 Pdpte
      //FirstPdpteVA = (PULONG64)MmAllocateContiguousMemorySpecifyCache(PAGE_SIZE, l1, l2, l3, MmCached);
      FirstPdpteVA = AllocateContiguousMemory(PAGE_SIZE);
      if (!FirstPdpteVA)
                return STATUS_INSUFFICIENT_RESOURCES;

      RtlZeroMemory(FirstPdpteVA, PAGE_SIZE);

      FirstPdptePA = MmGetPhysicalAddress(FirstPdpteVA);
      EPT_Ptable.PDPTE = (ULONG64)FirstPdpteVA;
      EPT_Ptable.PDPTEPHY = FirstPdptePA;


      DbgPrint("vmx:MmInitIdentityPageTable: FirstPdpteVA 0x%p FirstPdptePA 0x%llX\n", FirstPdpteVA, FirstPdptePA.QuadPart);
      for (i = 0; i < 64; i++)
      {
                {
                        *FirstPdpteVA = (i * 0x1000 + FirstPdePA.QuadPart) | EPT_READ | EPT_WRIT | EPT_EXECUTE;
                        FirstPdpteVA++;
                }
      }

      //Pml4e
      //FirstPml4eVA = (PULONG64)MmAllocateContiguousMemorySpecifyCache(PAGE_SIZE, l1, l2, l3, MmCached);
      FirstPml4eVA = AllocateContiguousMemory(PAGE_SIZE);
      if (!FirstPml4eVA)
                return STATUS_INSUFFICIENT_RESOURCES;

      RtlZeroMemory(FirstPml4eVA, PAGE_SIZE);
      EPT_Ptable.PML4E = (ULONG64)FirstPml4eVA;
      EPT_Ptable.PML4EPHY = MmGetPhysicalAddress(FirstPml4eVA);

      DbgPrint("vmx:MmInitIdentityPageTable: FirstPml4eVA 0x%p EPT_Ptable.PML4EPHY0x%llX\n", FirstPml4eVA,
                EPT_Ptable.PML4EPHY.QuadPart);
      *FirstPml4eVA = (FirstPdptePA.QuadPart) | EPT_READ | EPT_WRIT | EPT_EXECUTE;

      //do_guest_physical_address_mapping(0x7409AF88,0x7409AF88);
      return STATUS_SUCCESS;
}


**** Hidden Message *****


1297762112 发表于 2025-2-25 14:41:53

6666666666666666666666

大雪山123 发表于 2025-2-25 14:44:23

学习了学习了

断点 发表于 2025-2-25 15:28:53

学习了!

tw1314521 发表于 2025-2-25 15:33:06

66666666666666666666666666666

jiweihong 发表于 2025-3-11 10:42:20

看看全不全吧。。哎

anuwatxx 发表于 2025-3-24 09:14:51

6666666666666666666666

anuwatxx 发表于 2025-3-24 09:15:22

文件已被分享者删除

DOTM 发表于 前天 21:02

6666666666666666666666
页: [1]
查看完整版本: x64VT虚拟化框架源码