0

I have a hypervisor that virtualizes the currently running system ( OS in my case is Windows). I tried to run a code below and it works perfectly. The function is executed in VMX Root mode when vm-exit occurs.

void Cr3Test()
{
    UINT64 GuestCr3;
    UINT64 HostCr3 = __readcr3();
    UINT64 GuestRIP;
    UINT64 PhysAddress;
    __vmx_vmread(VMCS::GUEST_CR3, &GuestCr3);
    __vmx_vmread(VMCS::GUEST_RIP, &GuestRIP);
    __writecr3(GuestCr3);
    PhysAddress = MmGetPhysicalAddress((PVOID)GuestRIP).QuadPart;
    __writecr3(HostCr3);
}

And I have one question about it: after Cr3 swapping we have an access to the code fetching, stack and RIP relative data without any trouble. How it works ? Why didn't the program change previous physical addresses mapping to the new process context ? In Windows the system address space is available to an arbitrary process with some conditions or what ?

id zero
  • 1
  • 1
  • 1

1 Answers1

0

Wow, I'm dumb. I should have done this before asking a question :D

1: kd> !vtop 12531e000 fffff8023c2e9008
Amd64VtoP: Virt fffff8023c2e9008, pagedir 000000012531e000
Amd64VtoP: PML4E 000000012531ef80
Amd64VtoP: PDPE 0000000004409040
Amd64VtoP: PDE 000000000440af08
Amd64VtoP: PTE 0000000189937748
Amd64VtoP: Mapped phys 00000001b215b008
Virtual address fffff8023c2e9008 translates to physical address 1b215b008.
1: kd> !vtop 1ad000 fffff8023c2e9008
Amd64VtoP: Virt fffff8023c2e9008, pagedir 00000000001ad000
Amd64VtoP: PML4E 00000000001adf80
Amd64VtoP: PDPE 0000000004409040
Amd64VtoP: PDE 000000000440af08
Amd64VtoP: PTE 0000000189937748
Amd64VtoP: Mapped phys 00000001b215b008
Virtual address fffff8023c2e9008 translates to physical address 1b215b008.

12531e000 - user space dir base, 1ad000 - system space dir base. The Windows kernel is mapped in each process address space with supervisor-only access bit. This is why.

id zero
  • 1
  • 1
  • 1