學習BluePill源碼筆記-3

二、Hvm過程

2.1 newbp.c (116)

  if (!NT_SUCCESS (Status = HvmInit ())) {
    _KdPrint (("NEWBLUEPILL: HvmInit() failed with status 0x%08hX\n", Status));

在吞下“藍色藥丸”之前,還要先初始化一下。HvmInit()函數主要的作用是

1、確定系統構架是否支持HEV 並確定支持哪種HEV技術~VT/SVM SVM暫時忽略吧~畢竟AMD的不多呀

PHVM_DEPENDENT Hvm; (common.h)


PHVM_DEPENDENT的定義

typedef struct
{
  UCHAR Architecture;

  ARCH_IS_HVM_IMPLEMENTED ArchIsHvmImplemented;

  ARCH_INITIALIZE ArchInitialize;
  ARCH_VIRTUALIZE ArchVirtualize;
  ARCH_SHUTDOWN ArchShutdown;

  ARCH_IS_NESTED_EVENT ArchIsNestedEvent;
  ARCH_DISPATCH_NESTED_EVENT ArchDispatchNestedEvent;
  ARCH_DISPATCH_EVENT ArchDispatchEvent;
  ARCH_ADJUST_RIP ArchAdjustRip;
  ARCH_REGISTER_TRAPS ArchRegisterTraps;
  ARCH_IS_TRAP_VALID ArchIsTrapValid;
} HVM_DEPENDENT,
 *PHVM_DEPENDENT;

我去...高端霸氣上了個檔次啊...

HvmInit函數體

NTSTATUS NTAPI HvmInit (
)
{
  BOOLEAN ArchIsOK = FALSE;

  Hvm = &Svm;

  if (Hvm->ArchIsHvmImplemented ()) {
    ArchIsOK = TRUE;
  } else {
    Hvm = &Vmx;
    if (Hvm->ArchIsHvmImplemented ()) {
      ArchIsOK = TRUE;
    }
  }

  if (ArchIsOK == FALSE) {
    _KdPrint (("HvmInit(): %s is not supported\n",
               Hvm->Architecture == ARCH_SVM ? "SVM" : Hvm->Architecture == ARCH_VMX ? "VMX" : "???"));
    return STATUS_NOT_SUPPORTED;
  } else {
    _KdPrint (("HvmInit(): Running on %s\n",
               Hvm->Architecture == ARCH_SVM ? "SVM" : Hvm->Architecture == ARCH_VMX ? "VMX" : "???"));
  }

  KeInitializeMutex (&g_HvmMutex, 0);

  return STATUS_SUCCESS;
}
Hvm調用了ArchIsHvmImplemented()函數(也可以說方法吧)。ArchIsHvmImplemented是何物?在common.h中查到了定義:

typedef BOOLEAN (
  NTAPI * ARCH_IS_HVM_IMPLEMENTED
) (
);
嗯?函數體在哪裏呢。。。

誒。。。函數體在哪呢。。。我去找函數體了。。

這貨似乎蠻像的

static BOOLEAN NTAPI VmxIsImplemented (
)
{
  ULONG32 eax, ebx, ecx, edx;
  GetCpuIdInfo (0, &eax, &ebx, &ecx, &edx);
  if (eax < 1) {
    _KdPrint (("VmxIsImplemented(): Extended CPUID functions not implemented\n"));
    return FALSE;
  }
  if (!(ebx == 0x756e6547 && ecx == 0x6c65746e && edx == 0x49656e69)) {
    _KdPrint (("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));
}

咦。。。這貨原來是這麼定義的...

在vmx.c中

HVM_DEPENDENT Vmx = {
  ARCH_VMX,
  VmxIsImplemented,
  VmxInitialize,
  VmxVirtualize,
  VmxShutdown,
  VmxIsNestedEvent,
  VmxDispatchNestedEvent,
  VmxDispatchEvent,
  VmxAdjustRip,
  VmxRegisterTraps,
  VmxIsTrapVaild
};

哇哦~原來如此~這明顯是爲了區分Intel和AMD嘛~~


HvmInit ()函數通過cpuid判斷當前cpu是否支持vt後,DriverEntry繼續調用HvmSwallowBluepill ()函數。至此,DriverEntry已無其他內容。HvmSwallowBluepill ()函數名稱取得倒是好形象啊~~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章