Exemple #1
0
addr_t drakvuf_get_current_thread(drakvuf_t drakvuf, uint64_t vcpu_id, x86_registers_t *regs){
    vmi_instance_t vmi = drakvuf->vmi;
    addr_t thread;
    addr_t prcb;
    reg_t fsgs;

    /*
     * fs_base/gs_base in the info->regs structure are not actually filled in
     * by Xen for vm_events, so we need to manually ask for these each time
     */
    if(vmi_get_page_mode(vmi) == VMI_PM_IA32E)  {
        if (!regs->gs_base)
            vmi_get_vcpureg(vmi, &fsgs, GS_BASE, vcpu_id);
        else
            fsgs = regs->gs_base;

        prcb=offsets[KPCR_PRCB];
    } else {
        if (!regs->fs_base)
            vmi_get_vcpureg(vmi, &fsgs, FS_BASE, vcpu_id);
        else
            fsgs = regs->fs_base;

        prcb=offsets[KPCR_PRCBDATA];
    }

    if (VMI_SUCCESS != vmi_read_addr_va(vmi, fsgs + prcb + offsets[KPRCB_CURRENTTHREAD], 0, &thread)){
        return 0;
    }

    return thread;
}
Exemple #2
0
void ss_callback(vmi_instance_t vmi, vmi_event_t *event) {
    reg_t rip, cr3;
    vmi_get_vcpureg(vmi, &rip, RIP, event->vcpu_id);
    vmi_get_vcpureg(vmi, &cr3, CR3, event->vcpu_id);
    page_mode_t pm = vmi_get_page_mode(vmi);
    vmi_pid_t pid = vmi_dtb_to_pid(vmi, cr3);
    printf("----- Singlestep: CR3 0x%lx PID %u executing RIP 0x%lx\n", cr3, pid,
            rip);

    if ((PM2BIT(pm) == BIT32 && rip < KERNEL32)
            || (PM2BIT(pm) == BIT64 && rip < KERNEL64)) {
        printf("Good RIP: 0x%lx\n", rip);
        struct injector *injector = event->data;
        injector->ss_enabled = 0;

        injector->target_pid = pid;
        injector->target_rip = vmi_pagetable_lookup(vmi, cr3, rip);

        hijack_thread(injector, vmi, event->vcpu_id, pid);

        vmi_clear_event(vmi, event);
        vmi_clear_event(vmi, &injector->cr3_event);
        injector->mm_count++;

        uint8_t trap = 0xCC;
        vmi_read_8_pa(vmi, injector->target_rip, &injector->backup);
        vmi_write_8_pa(vmi, injector->target_rip, &trap);
    }
}
Exemple #3
0
addr_t drakvuf_get_kernel_base(drakvuf_t drakvuf) {
    reg_t fsgs;

    if(vmi_get_page_mode(drakvuf->vmi) == VMI_PM_IA32E)  {
        vmi_get_vcpureg(drakvuf->vmi, &fsgs, GS_BASE, 0);
    } else {
        vmi_get_vcpureg(drakvuf->vmi, &fsgs, FS_BASE, 0);
    }

    return fsgs - drakvuf->offsets[KIINITIALPCR];
}
Exemple #4
0
unicode_string_t *
windows_read_unicode_struct(
    vmi_instance_t vmi,
    const access_context_t *ctx)
{
    access_context_t _ctx = *ctx;
    unicode_string_t *us = 0;   // return val
    size_t struct_size = 0;
    size_t read = 0;
    addr_t buffer_va = 0;
    uint16_t buffer_len = 0;

    if (VMI_PM_IA32E == vmi_get_page_mode(vmi)) {   // 64 bit guest
        win64_unicode_string_t us64 = { 0 };
        struct_size = sizeof(us64);
        // read the UNICODE_STRING struct
        read = vmi_read(vmi, ctx, &us64, struct_size);
        if (read != struct_size) {
            dbprint(VMI_DEBUG_READ, "--%s: failed to read UNICODE_STRING\n",__FUNCTION__);
            goto out_error;
        }   // if
        buffer_va = us64.pBuffer;
        buffer_len = us64.length;
    }
    else {
        win32_unicode_string_t us32 = { 0 };
        struct_size = sizeof(us32);
        // read the UNICODE_STRING struct
        read = vmi_read(vmi, ctx, &us32, struct_size);
        if (read != struct_size) {
            dbprint(VMI_DEBUG_READ, "--%s: failed to read UNICODE_STRING\n",__FUNCTION__);
            goto out_error;
        }   // if
        buffer_va = us32.pBuffer;
        buffer_len = us32.length;
    }   // if-else

    // allocate the return value
    us = safe_malloc(sizeof(unicode_string_t));

    us->length = buffer_len;
    us->contents = safe_malloc(sizeof(uint8_t) * (buffer_len + 2));

    _ctx.addr = buffer_va;
    read = vmi_read(vmi, &_ctx, us->contents, us->length);
    if (read != us->length) {
        dbprint
            (VMI_DEBUG_READ, "--%s: failed to read UNICODE_STRING buffer\n",__FUNCTION__);
        goto out_error;
    }   // if

    // end with NULL (needed?)
    us->contents[buffer_len] = 0;
    us->contents[buffer_len + 1] = 0;

    us->encoding = "UTF-16";

    return us;

out_error:
    if (us) {
        if (us->contents) {
            free(us->contents);
        }
        free(us);
    }
    return 0;
}
int
main(
    int argc,
    char **argv)
{
    vmi_instance_t vmi;
    uint32_t offset;
    addr_t next_module, list_head;

    /* this is the VM or file that we are looking at */
    char *name = argv[1];

    /* initialize the libvmi library */
    if (vmi_init(&vmi, VMI_AUTO | VMI_INIT_COMPLETE, name) ==
        VMI_FAILURE) {
        printf("Failed to init LibVMI library.\n");
        return 1;
    }

    /* pause the vm for consistent memory access */
    vmi_pause_vm(vmi);

    /* get the head of the module list */
    if (VMI_OS_LINUX == vmi_get_ostype(vmi)) {
        vmi_read_addr_ksym(vmi, "modules", &next_module);
    }
    else if (VMI_OS_WINDOWS == vmi_get_ostype(vmi)) {
        vmi_read_addr_ksym(vmi, "PsLoadedModuleList", &next_module);
    }
    list_head = next_module;

    /* walk the module list */
    while (1) {

        /* follow the next pointer */
        addr_t tmp_next = 0;

        vmi_read_addr_va(vmi, next_module, 0, &tmp_next);

        /* if we are back at the list head, we are done */
        if (list_head == tmp_next) {
            break;
        }

        /* print out the module name */

        /* Note: the module struct that we are looking at has a string
         * directly following the next / prev pointers.  This is why you
         * can just add the length of 2 address fields to get the name.
         * See include/linux/module.h for mode details */
        if (VMI_OS_LINUX == vmi_get_ostype(vmi)) {
            char *modname = NULL;

            if (VMI_PM_IA32E == vmi_get_page_mode(vmi)) {   // 64-bit paging
                modname = vmi_read_str_va(vmi, next_module + 16, 0);
            }
            else {
                modname = vmi_read_str_va(vmi, next_module + 8, 0);
            }
            printf("%s\n", modname);
            free(modname);
        }
        else if (VMI_OS_WINDOWS == vmi_get_ostype(vmi)) {
            /*TODO don't use a hard-coded offsets here */
            /* this offset works with WinXP SP2 */
            unicode_string_t *us =
                vmi_read_unicode_str_va(vmi, next_module + 0x2c, 0);
            unicode_string_t out = { 0 };
            //         both of these work
            if (us &&
                VMI_SUCCESS == vmi_convert_str_encoding(us, &out,
                                                        "UTF-8")) {
                printf("%s\n", out.contents);
                //            if (us && 
                //                VMI_SUCCESS == vmi_convert_string_encoding (us, &out, "WCHAR_T")) {
                //                printf ("%ls\n", out.contents);
                free(out.contents);
            }   // if
            if (us)
                vmi_free_unicode_str(us);
        }
        next_module = tmp_next;
    }

error_exit:
    /* resume the vm */
    vmi_resume_vm(vmi);

    /* cleanup any memory associated with the libvmi instance */
    vmi_destroy(vmi);

    return 0;
}
Exemple #6
0
static unicode_string_t *
vmi_read_win_unicode_struct_va(
    vmi_instance_t vmi,
    addr_t vaddr,
    vmi_pid_t pid)
{
    unicode_string_t *us = 0;   // return val
    size_t struct_size = 0;
    size_t read = 0;
    addr_t buffer_va = 0;
    uint16_t buffer_len = 0;

    if (VMI_PM_IA32E == vmi_get_page_mode(vmi)) {   // 64 bit guest
        win64_unicode_string_t us64 = { 0 };
        struct_size = sizeof(us64);
        // read the UNICODE_STRING struct
        read = vmi_read_va(vmi, vaddr, pid, &us64, struct_size);
        if (read != struct_size) {
            dbprint
                ("--%s: failed to read UNICODE_STRING at VA 0x%.16"PRIx64" for pid %d\n",
                 __FUNCTION__, vaddr, pid);
            goto out_error;
        }   // if
        buffer_va = us64.pBuffer;
        buffer_len = us64.length;
    }
    else {
        win32_unicode_string_t us32 = { 0 };
        struct_size = sizeof(us32);
        // read the UNICODE_STRING struct
        read = vmi_read_va(vmi, vaddr, pid, &us32, struct_size);
        if (read != struct_size) {
            dbprint
                ("--%s: failed to read UNICODE_STRING at VA 0x%.16"PRIx64" for pid %d\n",
                 __FUNCTION__, vaddr, pid);
            goto out_error;
        }   // if
        buffer_va = us32.pBuffer;
        buffer_len = us32.length;
    }   // if-else

    // allocate the return value
    us = safe_malloc(sizeof(unicode_string_t));

    us->length = buffer_len;
    us->contents = safe_malloc(sizeof(uint8_t) * (buffer_len + 2));

    read = vmi_read_va(vmi, buffer_va, pid, us->contents, us->length);
    if (read != us->length) {
        dbprint
            ("--%s: failed to read buffer at VA 0x%.16"PRIx64" for pid %d\n",
             __FUNCTION__, buffer_va, pid);
        goto out_error;
    }   // if

    // end with NULL (needed?)
    us->contents[buffer_len] = 0;
    us->contents[buffer_len + 1] = 0;

    us->encoding = "UTF-16";

    return us;

out_error:
    if (us) {
        if (us->contents) {
            free(us->contents);
        }
        free(us);
    }
    return 0;
}