Esempio n. 1
0
char *
vmi_read_str_va(
    vmi_instance_t vmi,
    addr_t vaddr,
    vmi_pid_t pid)
{
    unsigned char *memory = NULL;
    char *rtnval = NULL;
    addr_t paddr = 0;
    addr_t pfn = 0;
    addr_t offset = 0;
    int len = 0;
    size_t read_len = 0;
    int read_more = 1;
 
    rtnval = NULL;

    while (read_more) {
        if (pid) {
            paddr = vmi_translate_uv2p(vmi, vaddr + len, pid);
        }
        else {
            paddr = vmi_translate_kv2p(vmi, vaddr + len);
        }

        if (!paddr) {
            return rtnval;
        }

        /* access the memory */
        pfn = paddr >> vmi->page_shift;
        offset = (vmi->page_size - 1) & paddr;
        memory = vmi_read_page(vmi, pfn);
        if (NULL == memory) {
            return rtnval;
        }

        /* Count new non-null characters */
        read_len = 0;
        while (offset + read_len < vmi->page_size) {
            if (memory[offset + read_len] == '\0') {
                read_more = 0;
                break;
            }

            read_len++;
        }

        /* Otherwise, realloc, tack on the '\0' in case of errors and
         * get ready to read the next page.
         */
        rtnval = realloc(rtnval, len + 1 + read_len);
        memcpy(&rtnval[len], &memory[offset], read_len);
        len += read_len;
        rtnval[len] = '\0';
    }

    return rtnval;
}
Esempio n. 2
0
// Reads memory at a guest's physical address
size_t
vmi_read_pa(
    vmi_instance_t vmi,
    addr_t paddr,
    void *buf,
    size_t count)
{
    //TODO not sure how to best handle this with respect to page size.  Is this hypervisor dependent?
    //  For example, the pfn for a given paddr should vary based on the size of the page where the
    //  paddr resides.  However, it is hard to know the page size from just the paddr.  For now, just
    //  assuming 4k pages and doing the read from there.

    unsigned char *memory = NULL;
    addr_t phys_address = 0;
    addr_t pfn = 0;
    addr_t offset = 0;
    size_t buf_offset = 0;

    while (count > 0) {
        size_t read_len = 0;

        /* access the memory */
        phys_address = paddr + buf_offset;
        pfn = phys_address >> vmi->page_shift;
        offset = (vmi->page_size - 1) & phys_address;
        memory = vmi_read_page(vmi, pfn);
        if (NULL == memory) {
            return buf_offset;
        }

        /* determine how much we can read */
        if ((offset + count) > vmi->page_size) {
            read_len = vmi->page_size - offset;
        }
        else {
            read_len = count;
        }

        /* do the read */
        memcpy(((char *) buf) + (addr_t) buf_offset,
               memory + (addr_t) offset, read_len);

        /* set variables for next loop */
        count -= read_len;
        buf_offset += read_len;
    }

    return buf_offset;
}
Esempio n. 3
0
///////////////////////////////////////////////////////////
// Classic read functions for access to memory
status_t
vmi_read(
    vmi_instance_t vmi,
    const access_context_t *ctx,
    size_t count,
    void *buf,
    size_t *bytes_read)
{
    status_t ret = VMI_FAILURE;
    unsigned char *memory = NULL;
    addr_t start_addr = 0;
    addr_t paddr = 0;
    addr_t pfn = 0;
    addr_t offset = 0;
    addr_t dtb = 0;
    size_t buf_offset = 0;

#ifdef ENABLE_SAFETY_CHECKS
    if (NULL == vmi) {
        dbprint(VMI_DEBUG_READ, "--%s: vmi passed as NULL, returning without read\n", __FUNCTION__);
        goto done;
    }

    if (NULL == ctx) {
        dbprint(VMI_DEBUG_READ, "--%s: ctx passed as NULL, returning without read\n", __FUNCTION__);
        goto done;
    }

    if (NULL == buf) {
        dbprint(VMI_DEBUG_READ, "--%s: buf passed as NULL, returning without read\n", __FUNCTION__);
        goto done;
    }
#endif

    switch (ctx->translate_mechanism) {
        case VMI_TM_NONE:
            start_addr = ctx->addr;
            break;
        case VMI_TM_KERNEL_SYMBOL:
#ifdef ENABLE_SAFETY_CHECKS
            if (!vmi->arch_interface || !vmi->os_interface || !vmi->kpgd)
                goto done;
#endif
            dtb = vmi->kpgd;
            if ( VMI_FAILURE == vmi_translate_ksym2v(vmi, ctx->ksym, &start_addr) )
                goto done;
            break;
        case VMI_TM_PROCESS_PID:
#ifdef ENABLE_SAFETY_CHECKS
            if (!vmi->arch_interface || !vmi->os_interface)
                goto done;
#endif

            if ( !ctx->pid )
                dtb = vmi->kpgd;
            else if (ctx->pid > 0) {
                if ( VMI_FAILURE == vmi_pid_to_dtb(vmi, ctx->pid, &dtb) )
                    goto done;
            }

            if (!dtb)
                goto done;

            start_addr = ctx->addr;
            break;
        case VMI_TM_PROCESS_DTB:
#ifdef ENABLE_SAFETY_CHECKS
            if (!vmi->arch_interface)
                goto done;
#endif

            dtb = ctx->dtb;
            start_addr = ctx->addr;
            break;
        default:
            errprint("%s error: translation mechanism is not defined.\n", __FUNCTION__);
            goto done;
    }


    while (count > 0) {
        size_t read_len = 0;

        if (dtb) {
            if (VMI_SUCCESS != vmi_pagetable_lookup_cache(vmi, dtb, start_addr + buf_offset, &paddr))
                goto done;
        } else {
            paddr = start_addr + buf_offset;
        }


        /* access the memory */
        pfn = paddr >> vmi->page_shift;
        offset = (vmi->page_size - 1) & paddr;
        memory = vmi_read_page(vmi, pfn);
        if (NULL == memory)
            goto done;

        /* determine how much we can read */
        if ((offset + count) > vmi->page_size) {
            read_len = vmi->page_size - offset;
        } else {
            read_len = count;
        }

        /* do the read */
        memcpy(((char *) buf) + (addr_t) buf_offset, memory + (addr_t) offset, read_len);

        /* set variables for next loop */
        count -= read_len;
        buf_offset += read_len;
    }

    ret = VMI_SUCCESS;

done:
    if ( bytes_read )
        *bytes_read = buf_offset;

    return ret;
}
Esempio n. 4
0
///////////////////////////////////////////////////////////
// Classic read functions for access to memory
size_t
vmi_read(
    vmi_instance_t vmi,
    access_context_t *ctx,
    void *buf,
    size_t count)
{
    unsigned char *memory = NULL;
    addr_t start_addr = 0;
    addr_t paddr = 0;
    addr_t pfn = 0;
    addr_t offset = 0;
    addr_t dtb = 0;
    size_t buf_offset = 0;

    if (NULL == ctx) {
        dbprint(VMI_DEBUG_READ, "--%s: ctx passed as NULL, returning without read\n", __FUNCTION__);
        return 0;
    }

    if (NULL == buf) {
        dbprint(VMI_DEBUG_READ, "--%s: buf passed as NULL, returning without read\n", __FUNCTION__);
        return 0;
    }

    switch (ctx->translate_mechanism) {
        case VMI_TM_NONE:
            start_addr = ctx->addr;
            break;
        case VMI_TM_KERNEL_SYMBOL:
            if (!vmi->arch_interface || !vmi->os_interface) {
              return 0;
            }
            dtb = vmi->kpgd;
            start_addr = vmi_translate_ksym2v(vmi, ctx->ksym);
            break;
        case VMI_TM_PROCESS_PID:
            if (!vmi->arch_interface || !vmi->os_interface) {
              return 0;
            }
            if(ctx->pid) {
                dtb = vmi_pid_to_dtb(vmi, ctx->pid);
            } else {
                dtb = vmi->kpgd;
            }
            start_addr = ctx->addr;
            break;
        case VMI_TM_PROCESS_DTB:
            if (!vmi->arch_interface) {
              return 0;
            }
            dtb = ctx->dtb;
            start_addr = ctx->addr;
            break;
        default:
            errprint("%s error: translation mechanism is not defined.\n", __FUNCTION__);
            return 0;
    }

    while (count > 0) {
        size_t read_len = 0;

        if(dtb) {
            paddr = vmi_pagetable_lookup(vmi, dtb, start_addr + buf_offset);
        } else {
            paddr = start_addr + buf_offset;
        }

        if (!paddr) {
            return buf_offset;
        }

        /* access the memory */
        pfn = paddr >> vmi->page_shift;
        offset = (vmi->page_size - 1) & paddr;
        memory = vmi_read_page(vmi, pfn);
        if (NULL == memory) {
            return buf_offset;
        }

        /* determine how much we can read */
        if ((offset + count) > vmi->page_size) {
            read_len = vmi->page_size - offset;
        } else {
            read_len = count;
        }

        /* do the read */
        memcpy(((char *) buf) + (addr_t) buf_offset, memory + (addr_t) offset, read_len);

        /* set variables for next loop */
        count -= read_len;
        buf_offset += read_len;
    }

    return buf_offset;
}
Esempio n. 5
0
size_t
vmi_read_va(
    vmi_instance_t vmi,
    addr_t vaddr,
    vmi_pid_t pid,
    void *buf,
    size_t count)
{
    unsigned char *memory = NULL;
    addr_t paddr = 0;
    addr_t pfn = 0;
    addr_t offset = 0;
    size_t buf_offset = 0;

    if (NULL == buf) {
        dbprint("--%s: buf passed as NULL, returning without read\n",
                __FUNCTION__);
        return 0;
    }

    while (count > 0) {
        size_t read_len = 0;

        if (pid) {
            paddr = vmi_translate_uv2p(vmi, vaddr + buf_offset, pid);
        }
        else {
            paddr = vmi_translate_kv2p(vmi, vaddr + buf_offset);
        }

        if (!paddr) {
            return buf_offset;
        }

        /* access the memory */
        pfn = paddr >> vmi->page_shift;
        offset = (vmi->page_size - 1) & paddr;
        memory = vmi_read_page(vmi, pfn);
        if (NULL == memory) {
            return buf_offset;
        }

        /* determine how much we can read */
        if ((offset + count) > vmi->page_size) {
            read_len = vmi->page_size - offset;
        }
        else {
            read_len = count;
        }

        /* do the read */
        memcpy(((char *) buf) + (addr_t) buf_offset,
               memory + (addr_t) offset, read_len);

        /* set variables for next loop */
        count -= read_len;
        buf_offset += read_len;
    }

    return buf_offset;
}