コード例 #1
0
uint64_t get_pdpte_ia32e (vmi_instance_t vmi, addr_t vaddr, uint64_t pml4e)
{
    uint64_t value = 0;
    addr_t pdpte_address = get_bits_51to12(pml4e) | get_pdpt_index_ia32e(vaddr);
    dbprint("--PTLookup: pdpte_address = 0x%.16"PRIx64"\n", pdpte_address);
    vmi_read_64_pa(vmi, pdpte_address, &value);
    return value;
}
コード例 #2
0
uint64_t get_pdpi (vmi_instance_t instance, uint32_t vaddr, uint32_t cr3)
{
    uint64_t value;
    uint32_t pdpi_entry = get_pdptb(cr3) + pdpi_index(vaddr);

    dbprint("--PTLookup: pdpi_entry = 0x%.8x\n", pdpi_entry);
    vmi_read_64_pa(instance, pdpi_entry, &value);
    return value;
}
コード例 #3
0
uint64_t get_pml4e (vmi_instance_t vmi, addr_t vaddr, reg_t cr3)
{
    uint64_t value = 0;
    addr_t pml4e_address = get_bits_51to12(cr3) | get_pml4_index(vaddr);

    dbprint("--PTLookup pml4e_address = 0x%.16"PRIx64"\n", pml4e_address);
    vmi_read_64_pa(vmi, pml4e_address, &value);
    return value;
}
コード例 #4
0
ファイル: intel.c プロジェクト: Zentific/libvmi
static inline
uint64_t get_pte_pae (vmi_instance_t instance,
    uint32_t vaddr,
    uint64_t pgd,
    addr_t *pte_entry)
{
    uint64_t value;
    *pte_entry = ptba_base_pae(pgd) + pte_index_pae(vaddr);
    dbprint(VMI_DEBUG_PTLOOKUP, "--PAE PTLookup: pte_entry = 0x%.8"PRIx64"\n", *pte_entry);
    if(VMI_FAILURE == vmi_read_64_pa(instance, *pte_entry, &value)) {
        value = 0;
    }
    return value;
}
コード例 #5
0
ファイル: amd64.c プロジェクト: WaitXie/libvmi
static inline
uint64_t get_pde_ia32e (vmi_instance_t vmi,
    addr_t vaddr,
    uint64_t pdpte,
    addr_t *pde_address)
{
    uint64_t value;
    *pde_address = get_bits_51to12(pdpte) | get_pd_index_ia32e(vaddr);
    dbprint(VMI_DEBUG_PTLOOKUP, "--PTLookup: pde_address = 0x%.16"PRIx64"\n", *pde_address);
    if(VMI_FAILURE == vmi_read_64_pa(vmi, *pde_address, &value)) {
        value = 0;
    }
    return value;
}
コード例 #6
0
ファイル: amd64.c プロジェクト: WaitXie/libvmi
static inline
uint64_t get_pml4e (vmi_instance_t vmi,
    addr_t vaddr,
    reg_t cr3,
    addr_t *pml4e_address)
{
    uint64_t value;
    *pml4e_address = get_bits_51to12(cr3) | get_pml4_index(vaddr);
    dbprint(VMI_DEBUG_PTLOOKUP, "--PTLookup pml4e_address = 0x%.16"PRIx64"\n", *pml4e_address);
    if(VMI_FAILURE == vmi_read_64_pa(vmi, *pml4e_address, &value)) {
        value = 0;
    }
    return value;
}
コード例 #7
0
ファイル: intel.c プロジェクト: Zentific/libvmi
static inline
uint64_t get_pdpi (vmi_instance_t instance,
    uint32_t vaddr,
    addr_t dtb,
    addr_t *pdpi_entry)
{
    uint64_t value;
    *pdpi_entry = get_pdptb(dtb) + pdpi_index(vaddr);
    dbprint(VMI_DEBUG_PTLOOKUP, "--PAE PTLookup: pdpi_entry = 0x%.16"PRIx64"\n", *pdpi_entry);
    if(VMI_FAILURE == vmi_read_64_pa(instance, *pdpi_entry, &value)) {
        value = 0;
    }

    return value;
}
コード例 #8
0
ファイル: amd64.c プロジェクト: chen0031/libvmi
static inline
status_t get_pml4e (vmi_instance_t vmi,
    addr_t vaddr,
    reg_t cr3,
    addr_t *pml4e_address,
    uint64_t *pml4e_value)
{
    *pml4e_value = 0;
    *pml4e_address = (cr3 & VMI_BIT_MASK(12,51)) | get_pml4_index(vaddr);
    if(VMI_FAILURE == vmi_read_64_pa(vmi, *pml4e_address, pml4e_value)) {
        dbprint(VMI_DEBUG_PTLOOKUP, "--PTLookup: error reading pml4e_address = 0x%.16"PRIx64"\n", *pml4e_address);
        return VMI_FAILURE;
    }
    dbprint(VMI_DEBUG_PTLOOKUP, "--PTLookup: pml4e_address = 0x%.16"PRIx64"\n", *pml4e_address);
    return VMI_SUCCESS;
}
コード例 #9
0
ファイル: intel.c プロジェクト: namidairo/libvmi
static inline
status_t get_pdpi (vmi_instance_t instance,
    uint32_t vaddr,
    addr_t dtb,
    addr_t *pdpi_entry,
    uint64_t *pdpi_value)
{
    *pdpi_entry = get_pdptb(dtb) + pdpi_index(vaddr);
    if(VMI_FAILURE == vmi_read_64_pa(instance, *pdpi_entry, pdpi_value)) {
        dbprint(VMI_DEBUG_PTLOOKUP, "--PAE PTLookup: failed to read pdpi_entry = 0x%.16"PRIx64"\n", *pdpi_entry);
        return VMI_FAILURE;
    }
    dbprint(VMI_DEBUG_PTLOOKUP, "--PAE PTLookup: pdpi_entry = 0x%.16"PRIx64", pdpi_value = 0x%.16"PRIx64"\n",
            *pdpi_entry, *pdpi_value);

    return VMI_SUCCESS;
}
コード例 #10
0
ファイル: intel.c プロジェクト: namidairo/libvmi
static inline
status_t get_pgd_pae (vmi_instance_t instance,
    uint32_t vaddr,
    uint64_t pdpe,
    addr_t *pgd_entry,
    addr_t *pgd_value)
{
    *pgd_value = 0;
    *pgd_entry = pdba_base_pae(pdpe) + pgd_index_pae(vaddr);
    if(VMI_FAILURE == vmi_read_64_pa(instance, *pgd_entry, pgd_value)) {
        dbprint(VMI_DEBUG_PTLOOKUP, "--PAE PTLookup: failed to read pgd_entry = 0x%.8"PRIx64"\n", *pgd_entry);
        return VMI_FAILURE;
    }
    dbprint(VMI_DEBUG_PTLOOKUP, "--PAE PTLookup: pgd_entry = 0x%.8"PRIx64", pgd_value = 0x%.8"PRIx64"\n",
            *pgd_entry, *pgd_value);
    return VMI_SUCCESS;
}
コード例 #11
0
ファイル: read.c プロジェクト: CrazyCoder4Carrot/libvmi
status_t
vmi_read_addr_pa(
    vmi_instance_t vmi,
    addr_t paddr,
    addr_t *value)
{
    if (vmi->page_mode == VMI_PM_IA32E) {
        return vmi_read_64_pa(vmi, paddr, value);
    }
    else {
        uint32_t tmp = 0;
        status_t ret = vmi_read_32_pa(vmi, paddr, &tmp);

        *value = (uint64_t) tmp;
        return ret;
    }
}
コード例 #12
0
ファイル: amd64.c プロジェクト: chen0031/libvmi
static inline
status_t get_pde_ia32e (vmi_instance_t vmi,
    addr_t vaddr,
    uint64_t pdpte,
    addr_t *pde_address,
    addr_t *pde_value)
{
    *pde_value = 0;
    *pde_address = (pdpte & VMI_BIT_MASK(12,51)) | get_pd_index_ia32e(vaddr);
    if(VMI_FAILURE == vmi_read_64_pa(vmi, *pde_address, pde_value)) {
        dbprint(VMI_DEBUG_PTLOOKUP, "--PTLookup: failed to read pde_address = 0x%.16"PRIx64"\n", *pde_address);
        return VMI_FAILURE;
    }
    dbprint(VMI_DEBUG_PTLOOKUP, "--PTLookup: pde_address = 0x%.16"PRIx64"pde_value= 0x%.16"PRIx64"\n",
            *pde_address, *pde_value);
    return VMI_SUCCESS;
}
コード例 #13
0
ファイル: core.c プロジェクト: dalevy/libvmi
/* Tries to find the kernel page directory by doing an exhaustive search
 * through the memory space for the System process.  The page directory
 * location is then pulled from this eprocess struct.
 */
static status_t
get_kpgd_method2(
    vmi_instance_t vmi)
{
    addr_t sysproc = 0;
    windows_instance_t windows = NULL;

    if (vmi->os_data == NULL) {
        errprint("VMI_ERROR: No OS data initialized\n");
        return VMI_FAILURE;
    }

    windows = vmi->os_data;
    sysproc = windows->sysproc;

    /* get address for System process */
    if (!sysproc) {
        if ((sysproc = windows_find_eprocess(vmi, "System")) == 0) {
            dbprint(VMI_DEBUG_MISC, "--failed to find System process.\n");
            goto error_exit;
        }
        printf("LibVMI Suggestion: set win_sysproc=0x%"PRIx64" in libvmi.conf for faster startup.\n",
             sysproc);
    }
    dbprint(VMI_DEBUG_MISC, "--got PA to PsInitialSystemProcess (0x%.16"PRIx64").\n",
            sysproc);

    /* Get address for page directory (from system process).
       We are reading 64-bit value here deliberately as we might not know the page mode yet */
    if (VMI_FAILURE ==
        vmi_read_64_pa(vmi,
                         sysproc +
                         windows->pdbase_offset,
                         &vmi->kpgd)) {
        dbprint(VMI_DEBUG_MISC, "--failed to resolve PD for System process\n");
        goto error_exit;
    }

    if (!vmi->kpgd) {
        dbprint(VMI_DEBUG_MISC, "--kpgd was zero\n");
        goto error_exit;
    }

    if (VMI_FAILURE ==
        vmi_read_64_pa(vmi,
                     sysproc + windows->tasks_offset,
                     &vmi->init_task)) {
        dbprint(VMI_DEBUG_MISC, "--failed to resolve address of System process\n");
        goto error_exit;
    }

    vmi->init_task -= windows->tasks_offset;

    /* If the page mode is already known to be 32-bit we just mask the value here.
       If don't know the page mode yet it will be determined using heuristics in find_page_mode later. */
    switch(vmi->page_mode) {
        case VMI_PM_LEGACY:
        case VMI_PM_PAE: {
            uint32_t mask = ~0;
            vmi->kpgd &= mask;
            vmi->init_task &= mask;
            break;
        }
        default: break;
    }

    dbprint(VMI_DEBUG_MISC, "**set kpgd (0x%.16"PRIx64").\n", vmi->kpgd);
    dbprint(VMI_DEBUG_MISC, "**set init_task (0x%.16"PRIx64").\n", vmi->init_task);

    return VMI_SUCCESS;

error_exit:
    return VMI_FAILURE;
}
コード例 #14
0
ファイル: kdbg.c プロジェクト: bentau/libvmi
status_t
find_kdbg_address_fast(
    vmi_instance_t vmi,
    addr_t *kdbg_pa,
    addr_t *kernel_pa,
    addr_t *kernel_va)
{

    dbprint(VMI_DEBUG_MISC, "**Trying find_kdbg_address_fast\n");

    status_t ret = VMI_FAILURE;
    reg_t cr3;
    if (VMI_FAILURE == driver_get_vcpureg(vmi, &cr3, CR3, 0)) {
        return ret;
    }

    addr_t memsize = vmi_get_max_physical_address(vmi);
    GSList *va_pages = vmi_get_va_pages(vmi, (addr_t)cr3);
    void *bm = 0;   // boyer-moore internal state
    unsigned char haystack[VMI_PS_4KB];
    int find_ofs = 0;

    if (VMI_PM_IA32E == vmi->page_mode) {
        bm = boyer_moore_init((unsigned char *)"\x00\xf8\xff\xffKDBG", 8);
        find_ofs = 0xc;
    } else {
        bm = boyer_moore_init((unsigned char *)"\x00\x00\x00\x00\x00\x00\x00\x00KDBG",
                              12);
        find_ofs = 0x8;
    }   // if-else

    GSList *va_pages_loop = va_pages;
    while (va_pages_loop) {

        page_info_t *vap = (page_info_t *)va_pages_loop->data;

        // We might get pages that are greater than 4Kb
        // so we are just going to split them to 4Kb pages
        while (vap && vap->size >= VMI_PS_4KB) {
            vap->size -= VMI_PS_4KB;
            addr_t page_paddr = vap->paddr+vap->size;

            if (page_paddr + VMI_PS_4KB - 1 > memsize) {
                continue;
            }

            if ( VMI_FAILURE == vmi_read_pa(vmi, page_paddr, VMI_PS_4KB, haystack, NULL) )
                continue;

            int match_offset = boyer_moore2(bm, haystack, VMI_PS_4KB);

            if (-1 != match_offset) {

                addr_t tmp_kva = 0, tmp_kpa = 0;
                addr_t tmp_kdbg = page_paddr + (unsigned int) match_offset - find_ofs;

                if (VMI_FAILURE == vmi_read_64_pa(vmi, tmp_kdbg + sizeof(DBGKD_DEBUG_DATA_HEADER64), &tmp_kva)) {
                    continue;
                }

                if ( VMI_FAILURE == vmi_pagetable_lookup(vmi, cr3, tmp_kva, &tmp_kpa) )
                    continue;

                *kdbg_pa = tmp_kdbg;
                *kernel_va = tmp_kva;
                *kernel_pa = tmp_kpa;

                ret = VMI_SUCCESS;

                goto done;
            }
        }
        g_free(vap);
        va_pages_loop = va_pages_loop->next;
    }

done:
    // free the rest of the list
    while (va_pages_loop) {
        g_free(va_pages_loop->data);
        va_pages_loop = va_pages_loop->next;
    }
    g_slist_free(va_pages);

    if (VMI_SUCCESS == ret)
        dbprint(VMI_DEBUG_MISC, "--Found KdDebuggerDataBlock at PA %.16"PRIx64"\n", *kdbg_pa);
    boyer_moore_fini(bm);
    return ret;
}
コード例 #15
0
ファイル: amd64.c プロジェクト: WaitXie/libvmi
GSList* get_va_pages_ia32e(vmi_instance_t vmi, addr_t dtb) {

    GSList *ret = NULL;
    uint8_t entry_size = 0x8;

    #define PDES_AND_PTES_PER_PAGE 0x200 // 0x1000/0x8

    uint64_t pml4e;
    for(pml4e=0;pml4e<PDES_AND_PTES_PER_PAGE;pml4e++) {

        addr_t vaddr = pml4e << 39;
        addr_t pml4e_a = 0;
        uint64_t pml4e_value = get_pml4e(vmi, vaddr, dtb, &pml4e_a);

        if(!ENTRY_PRESENT(vmi->os_type, pml4e_value)) {
            continue;
        }

        uint64_t pdpte;
        for(pdpte=0;pdpte<PDES_AND_PTES_PER_PAGE;pdpte++) {

            vaddr = (pml4e << 39) | (pdpte << 30);

            addr_t pdpte_a = 0;
            uint64_t pdpte_value = get_pdpte_ia32e(vmi, vaddr, pml4e_value, &pdpte_a);
            if(!ENTRY_PRESENT(vmi->os_type, pdpte_value)) {
                continue;
            }

            if(PAGE_SIZE_FLAG(pdpte_value)) {
                page_info_t *p = g_malloc0(sizeof(page_info_t));
                p->vaddr = vaddr;
                p->paddr = get_gigpage_ia32e(vaddr, pdpte_value);
                p->size = VMI_PS_1GB;
                p->l4_a = pml4e_a;
                p->l4_v = pml4e_value;
                p->l3_a = pdpte_a;
                p->l3_v = pdpte_value;
                ret = g_slist_append(ret, p);
                continue;
            }

            uint64_t pgd_curr = pdba_base_ia32e(pdpte_value);
            uint64_t j;
            for(j=0;j<PTRS_PER_PAE_PGD;j++,pgd_curr+=entry_size) {

                uint64_t soffset = vaddr + (j * PTRS_PER_PAE_PGD * PTRS_PER_PAE_PTE * entry_size);

                uint64_t entry;
                if(VMI_FAILURE == vmi_read_64_pa(vmi, pgd_curr, &entry)) {
                    continue;
                }

                if(ENTRY_PRESENT(vmi->os_type, entry)) {

                    if(PAGE_SIZE_FLAG(entry)) {
                        page_info_t *p = g_malloc0(sizeof(page_info_t));
                        p->vaddr = soffset;
                        p->paddr = get_2megpage_ia32e(vaddr, entry);
                        p->size = VMI_PS_2MB;
                        p->l4_a = pml4e_a;
                        p->l4_v = pml4e_value;
                        p->l3_a = pdpte_a;
                        p->l3_v = pdpte_value;
                        p->l2_a = pgd_curr;
                        p->l2_v = entry;
                        ret = g_slist_append(ret, p);
                        continue;
                    }

                    uint64_t pte_curr = pte_pfn_ia32e(entry);
                    uint64_t k;
                    for(k=0;k<PTRS_PER_PAE_PTE;k++,pte_curr+=entry_size) {
                        uint64_t pte_entry;
                        if(VMI_FAILURE == vmi_read_64_pa(vmi, pte_curr, &pte_entry)) {
                            continue;
                        }

                        if(ENTRY_PRESENT(vmi->os_type, pte_entry)) {
                            page_info_t *p = g_malloc0(sizeof(page_info_t));
                            p->vaddr = soffset + k * VMI_PS_4KB;
                            p->paddr = get_paddr_ia32e(vaddr, pte_entry);
                            p->size = VMI_PS_4KB;
                            p->l4_a = pml4e_a;
                            p->l4_v = pml4e_value;
                            p->l3_a = pdpte_a;
                            p->l3_v = pdpte_value;
                            p->l2_a = pgd_curr;
                            p->l2_v = entry;
                            p->l1_a = pte_curr;
                            p->l1_v = pte_entry;
                            ret = g_slist_append(ret, p);
                            continue;
                        }
                    }
                }
            }
        }
    }

    return ret;
}