/** * Intialize the CPU struct and start VM by invoking VmxVirtualize() * requires: a valid <GuestRsp> */ NTSTATUS NTAPI HvmSubvertCpu ( PVOID GuestRsp ) { //Finish PCPU Cpu;//It will be used as the hypervisor struct. gvaddr_t HostKernelStackBase; NTSTATUS Status; gpaddr_t HostStackPA; ULONG i; Print(("HvmSubvertCpu(): Running on processor #%d\n", KeGetCurrentProcessorNumber())); // allocate memory for host stack, 16 * 4k HostKernelStackBase = MmAllocatePages(HOST_STACK_SIZE_IN_PAGES, &HostStackPA, TRUE); //HostKernelStackBase = MmAllocateContiguousPages(HOST_STACK_SIZE_IN_PAGES, &HostStackPA, TRUE); if (!HostKernelStackBase) { Print(("HvmSubvertCpu(): Failed to allocate %d pages for the host stack\n", HOST_STACK_SIZE_IN_PAGES)); return STATUS_INSUFFICIENT_RESOURCES; } // unchecked -8 or -4 ? Cpu = (PCPU) ((PCHAR) HostKernelStackBase + HOST_STACK_SIZE_IN_PAGES * PAGE_SIZE - 4 - sizeof (CPU)); Cpu->HostStack = HostKernelStackBase; // for interrupt handlers which will address CPU through the FS Cpu->SelfPointer = Cpu; Cpu->ProcessorNumber = KeGetCurrentProcessorNumber(); // Cpu->Nested = FALSE; // InitializeListHead (&Cpu->GeneralTrapsList); // InitializeListHead (&Cpu->MsrTrapsList); // InitializeListHead (&Cpu->IoTrapsList); for(i = 0; i < VMX_EXITS_NUM; i++) InitializeListHead (&Cpu->TrapsList[i]); Cpu->GdtArea = (PSEGMENT_DESCRIPTOR)MmAllocatePages (BYTES_TO_PAGES (BP_GDT_LIMIT), NULL, TRUE);//Currently we create our own GDT and IDT area if (!Cpu->GdtArea) { Print(("HvmSubvertCpu(): Failed to allocate memory for GDT\n")); return STATUS_INSUFFICIENT_RESOURCES; } Cpu->IdtArea = MmAllocatePages (BYTES_TO_PAGES (BP_IDT_LIMIT), NULL, TRUE); if (!Cpu->IdtArea) { Print(("HvmSubvertCpu(): Failed to allocate memory for IDT\n")); return STATUS_INSUFFICIENT_RESOURCES; } Status = Hvm->ArchRegisterTraps(Cpu, arch);//<----------------3.1 Finish if (!NT_SUCCESS (Status)) { Print(("HvmSubvertCpu(): Failed to register NewBluePill traps, status 0x%08hX\n", Status)); return STATUS_UNSUCCESSFUL; } Status = Hvm->ArchInitialize (Cpu, CmSlipIntoMatrix, GuestRsp);//<----------------3.2 Finish if (!NT_SUCCESS (Status)) { Print(("HvmSubvertCpu(): ArchInitialize() failed with status 0x%08hX\n", Status)); return Status; } InterlockedIncrement (&g_uSubvertedCPUs); // no API calls allowed below this point: we have overloaded GDTR and selectors // unchecked _HvmSetupGdt (Cpu);//<----------------3.3 Finish _HvmSetupIdt (Cpu);//<----------------3.4 Finish #if DEBUG_LEVEL > 1 Print(("HvmSubvertCpu(): RFLAGS = %#x\n", RegGetRflags ())); #endif Status = Hvm->ArchVirtualize(Cpu);//<----------------3.5 Finish // never reached InterlockedDecrement (&g_uSubvertedCPUs); return Status; }
NTSTATUS DriverEntry ( PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath ) { NTSTATUS Status; //CmDebugBreak(); // ULONG ulOldCR3; DbgInitComponent(); __asm { int 3 } // test for our pagetabel //__asm //{ // mov eax, cr3 // mov ulOldCR3, eax // mov eax, g_PageMapBasePhysicalAddress.LowPart // mov cr3, eax //} Status = HvMmInitManager(); if (!NT_SUCCESS (Status)) { Print(("HELLOWORLD: MadDog_MmInitManager() failed with status 0x%08hX\n", Status)); Finalize(); return Status; } if (!NT_SUCCESS (Status = MadDog_HypervisorInit())) { Print(("HELLOWORLD: MadDog_HypervisorInit() failed with status 0x%08hX\n", Status)); Finalize(); return Status; } Print(("HELLOWORLD: Successful in execute HvmInit()")); if (!NT_SUCCESS (Status = MadDog_InstallHypervisor(&md_Control,DriverObject))) //<------------------1 Finish { Print(("HELLOWORLD: InstallHypervisor() failed with status 0x%08hX\n", Status)); Finalize(); return Status; } // // // vt is on // // make all the kernel memory not writable // // MmProtectKernelMemory(); // DriverObject->DriverUnload = DriverUnload; // Print(("HELLOWORLD: Initialization finished\n")); #if DEBUG_LEVEL>1 Print(("HELLOWORLD: EFLAGS = %#x\n", RegGetRflags ())); #endif //// //// //__asm //// //{ //// // mov eax, ulOldCR3 //// // mov cr3, eax //// //} //// return STATUS_SUCCESS; }