Esempio n. 1
0
// search for the given module+symbol in the given module list
static status_t
modlist_sym2va(drakvuf_t drakvuf, addr_t list_head, access_context_t *ctx,
               const char *mod_name, const char *symbol, addr_t *va) {

    vmi_instance_t vmi = drakvuf->vmi;
    addr_t next_module = list_head;
    /* walk the module list */
    while (1) {

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

        ctx->addr = next_module;
        if(VMI_FAILURE==vmi_read_addr(vmi, ctx, &tmp_next))
            break;

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

        ctx->addr = next_module + drakvuf->offsets[LDR_DATA_TABLE_ENTRY_BASEDLLNAME];
        unicode_string_t *us = vmi_read_unicode_str(vmi, ctx);
        unicode_string_t out = { .contents = NULL };

        if (us && VMI_SUCCESS == vmi_convert_str_encoding(us, &out, "UTF-8")) {

            PRINT_DEBUG("Found module %s\n", out.contents);

            if (!strcasecmp((char*) out.contents, mod_name)) {

                addr_t dllbase;

                ctx->addr = next_module + drakvuf->offsets[LDR_DATA_TABLE_ENTRY_DLLBASE];
                vmi_read_addr(vmi, ctx, &dllbase);

                ctx->addr = dllbase;
                *va = vmi_translate_sym2v(vmi, ctx, (char *) symbol);

                PRINT_DEBUG("\t%s @ 0x%lx\n", symbol, *va);

                free(out.contents);
                vmi_free_unicode_str(us);
                return VMI_SUCCESS;
            }

            free(out.contents);
        }

        if (us)
            vmi_free_unicode_str(us);

        next_module = tmp_next;
    }

    return VMI_FAILURE;
}
Esempio n. 2
0
// search for the given module+symbol in the given module list
static status_t
modlist_va2sym(drakvuf_t drakvuf, addr_t list_head, addr_t va,
               access_context_t *ctx, char **out_mod, char **out_sym) {

    vmi_instance_t vmi = drakvuf->vmi;
    addr_t next_module = list_head;

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

        /* follow the next pointer */
        addr_t tmp_next = 0;
        ctx->addr = next_module;
        if(VMI_FAILURE == vmi_read_addr(vmi, ctx, &tmp_next))
            break;

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

        ctx->addr = next_module + drakvuf->offsets[LDR_DATA_TABLE_ENTRY_BASEDLLNAME];
        unicode_string_t *us = vmi_read_unicode_str(vmi, ctx);
        unicode_string_t out = { .contents = NULL };

        if (us && VMI_SUCCESS == vmi_convert_str_encoding(us, &out, "UTF-8")) {
            addr_t dllbase;
            ctx->addr = next_module + drakvuf->offsets[LDR_DATA_TABLE_ENTRY_DLLBASE];
            if(VMI_FAILURE == vmi_read_addr(vmi, ctx, &dllbase)) {
                free(us);
                break;
            }

            ctx->addr = dllbase;
            const char *sym = vmi_translate_v2sym(vmi, ctx, va);

            if (sym) {
                *out_mod = g_strdup((char*)out.contents);
                *out_sym = (char*) sym;
                free(out.contents);
                vmi_free_unicode_str(us);
                return VMI_SUCCESS;
            } else {
                free(out.contents);
            }
        }

        if (us)
            vmi_free_unicode_str(us);

        next_module = tmp_next;
    }

    return VMI_FAILURE;
}
Esempio n. 3
0
bool drakvuf_get_module_base_addr( drakvuf_t drakvuf, addr_t module_list_head, const char *module_name, addr_t *base_addr_out )
{
    addr_t base_addr ;
    size_t name_len = strlen( module_name );
    vmi_instance_t vmi = drakvuf->vmi;
    addr_t next_module = module_list_head;

    while( 1 )
    {
        addr_t tmp_next = 0;

        if ( vmi_read_addr_va( vmi, next_module, 4, &tmp_next ) != VMI_SUCCESS )
            break;

        if ( module_list_head == tmp_next )
            break;

        base_addr = 0 ;

        if ( vmi_read_addr_va( vmi, next_module + offsets[LDR_DATA_TABLE_ENTRY_DLLBASE], 4, &base_addr ) != VMI_SUCCESS )
            break;

        if ( ! base_addr )
            break;

        unicode_string_t *us = vmi_read_unicode_str_va( vmi, next_module + offsets[LDR_DATA_TABLE_ENTRY_BASEDLLNAME], 4 );

        if ( us )
        {
            unicode_string_t out = { 0 };
            if ( vmi_convert_str_encoding( us, &out, "UTF-8" ) == VMI_SUCCESS  )
            {
                if ( ! strncasecmp( (char *)out.contents, module_name, name_len ) )
                {
                    free( out.contents );
                    vmi_free_unicode_str( us );
                    *base_addr_out = base_addr ;
                    return true ;
                }

                free( out.contents );
            }
            vmi_free_unicode_str( us );
        }

        next_module = tmp_next ;
    }

    return false ;
}
Esempio n. 4
0
static event_response_t file_name_cb(drakvuf_t drakvuf, drakvuf_trap_info_t *info) {
    vmi_instance_t vmi = drakvuf_lock_and_get_vmi(drakvuf);
    struct file_watch *watch = (struct file_watch*)info->trap->data;
    filetracer *f = watch->f;

    if (info->trap_pa == watch->file_name_buffer)
    {
        addr_t file_name = 0;
        uint16_t length = 0;
        vmi_read_addr_pa(vmi, watch->file_name_buffer, &file_name);
        vmi_read_16_pa(vmi, watch->file_name_length, &length);

        //printf("File name @ 0x%lx. Length: %u\n", file_name, length);

        if (file_name && length > 0 && length < VMI_PS_4KB) {
            char *procname = drakvuf_get_current_process_name(drakvuf, info->vcpu, info->regs);
            unicode_string_t str = { .contents = NULL };
            str.length = length;
            str.encoding = "UTF-16";
            str.contents = (unsigned char *)g_malloc0(length);
            vmi_read_va(vmi, file_name, 0, str.contents, length);
            unicode_string_t str2 = { .contents = NULL };
            status_t rc = vmi_convert_str_encoding(&str, &str2, "UTF-8");

            if (VMI_SUCCESS == rc) {

                switch(f->format) {
                case OUTPUT_CSV:
                    printf("filetracer,%" PRIu32 ",0x%" PRIx64 ",%s,%s\n",
                           info->vcpu, info->regs->cr3, procname, str2.contents);
                    break;
                default:
                case OUTPUT_DEFAULT:
                    printf("[FILETRACER] VCPU:%" PRIu32 " CR3:0x%" PRIx64 ",%s %s\n",
                           info->vcpu, info->regs->cr3, procname, str2.contents);
                    break;
                };

                g_free(str2.contents);
            }

            free(str.contents);
            free(procname);
            //printf("Requesting to free writetrap @ %p\n", info->trap);
            info->trap->data=f;
            drakvuf_remove_trap(drakvuf, info->trap, free_writetrap);
        }
Esempio n. 5
0
void carve_file_from_memory(drakvuf_t *drakvuf, addr_t ph_base,
        addr_t block_size) {

    addr_t aligned_file_size = struct_sizes[FILE_OBJECT];
    if(PM2BIT(drakvuf->pm) == BIT32) {
        // 8-byte alignment on 32-bit mode
        if(struct_sizes[FILE_OBJECT] % 8) {
            aligned_file_size += 8 - (struct_sizes[FILE_OBJECT] % 8);
        }
    } else {
        // 16-byte alignment on 64-bit mode
        if(struct_sizes[FILE_OBJECT] % 16) {
            aligned_file_size += 16 - (struct_sizes[FILE_OBJECT] % 16);
        }
    }

    addr_t file_base = ph_base + block_size - aligned_file_size;
    addr_t file_name = file_base + offsets[FILE_OBJECT_FILENAME];

    addr_t file_name_str = 0;
    uint16_t length = 0;

    vmi_read_addr_pa(drakvuf->vmi, file_name + offsets[UNICODE_STRING_BUFFER], &file_name_str);
    vmi_read_16_pa(drakvuf->vmi, file_name + offsets[UNICODE_STRING_LENGTH], &length);

    if (file_name_str && length) {
        unicode_string_t str = { .contents = NULL };
        str.length = length;
        str.encoding = "UTF-16";
        str.contents = malloc(length);
        vmi_read_va(drakvuf->vmi, file_name, 0, str.contents, length);
        unicode_string_t str2 = { .contents = NULL };
        status_t rc = vmi_convert_str_encoding(&str, &str2, "UTF-8");

        if (VMI_SUCCESS == rc) {
            PRINT_DEBUG("\tFile closing: %s.\n", str2.contents);
            volatility_extract_file(drakvuf, file_base);
            g_free(str2.contents);
        }

        free(str.contents);
    }
Esempio n. 6
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;
}