Ask Your Question
0

Convert guest virtual address to host physical address

asked 2018-08-02 04:14:49 -0500

updated 2018-08-03 04:56:44 -0500

genodeftest gravatar image

My environment:

Guest : ubuntu-16.04.3-server-amd64.iso (VM) Host . : ubuntu-16.04.3-server-amd64.iso (Nested VM)

I ran the following code in guest:

---[ mmu.c ]---
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <stdlib.h>
#include <fcntl.h>
#include <assert.h>
#include <inttypes.h>

#define PAGE_SHIFT  12
#define PAGE_SIZE   (1 << PAGE_SHIFT)
#define PFN_PRESENT (1ull << 63)
#define PFN_PFN     ((1ull << 55) - 1)

int fd;

uint32_t page_offset(uint32_t addr)
{
    return addr & ((1 << PAGE_SHIFT) - 1);
}

uint64_t gva_to_gfn(void *addr)
{
    uint64_t pme, gfn;
    size_t offset;
    offset = ((uintptr_t)addr >> 9) & ~7;
    lseek(fd, offset, SEEK_SET);
    read(fd, &pme, 8);
    if (!(pme & PFN_PRESENT))
        return -1;
    gfn = pme & PFN_PFN;
    return gfn;
}

uint64_t gva_to_gpa(void *addr)
{
    uint64_t gfn = gva_to_gfn(addr);
    assert(gfn != -1);
    return (gfn << PAGE_SHIFT) | page_offset((uint64_t)addr);
}

int main()
{
    uint8_t *ptr;
    uint64_t ptr_mem;

    fd = open("/proc/self/pagemap", O_RDONLY);
    if (fd < 0) {
        perror("open");
        exit(1);
    }

    ptr = malloc(256);
    strcpy(ptr, "Where am I?");
    printf("%s\n", ptr);
    ptr_mem = gva_to_gpa(ptr);
    printf("Your physical address is at 0x%"PRIx64"\n", ptr_mem);

    getchar();
    return 0;
}

output

Where am I? Your physical address is at 0x10

Is 0x10 valid guest physical address ? Else, what I have done wrong here. If it's right, Host physical adddress = Guest Physical address (gpa) + highmem_hva_base

Can anybody please help how to find highmem_hva_base ? What is my phys_mem_base in host?

edit retag flag offensive close merge delete

1 Answer

Sort by » oldest newest most voted
1

answered 2018-08-03 05:11:22 -0500

genodeftest gravatar image

I think you are missing the main point of virtualization: The guest physical address space is virtualized, i.e. any¹ address is possible.

¹: Usually there are some conventions by compiler or C/C++ standard library to not use specific parts of memory, e.g. 0x0 and a few subsequent addresses to detect null pointer access. Also, the address space is limited by data types for accessing it.

Another point: Any modern operating system uses memory virtualization for its processes. This means that any guest application will never be able to get any information on the physical addresses of the memory it accesses. This means that your approach must fail even if your application is being run in the host.

If you've not done so already you may want to read a few basics about MMUs, logical, physical and virtual address space and how they work.

Is 0x10 valid guest physical address ? Else, what I have done wrong here. If it's right, Host physical adddress = Guest Physical address (gpa) + highmemhvabase

It is not a physical address but a virtual address inside a guest "physical" address. I'd say if you were able to determine the host physical address from a guest process, both operating systems were broken severely rendering most security mechanisms useless.

To rephrase it: You should have at least two layers of memory address virtualization (one for the guest OS, one for the userspace process) which must prevent you from getting the real physical address in your guest process.

edit flag offensive delete link more

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

Stats

Asked: 2018-08-02 04:14:49 -0500

Seen: 97 times

Last updated: Aug 03 '18