This is the Initialization of Drakvuf object and setup of LibVMI, it follows this steps:

  1. JSON PROFILES PARSING
  2. xen_init_interface()
  3. drakvuf_event_fd_add()
  4. get_dom_info()
  5. drakvuf_pause()
  6. init_vmi()
  7. drakvuf_init_os()
    1. drakvuf_lock_and_get_vmi()
    2. _drakvuf_init_os()
      1. vmi_init_paging()
      2. vmi_get_address_width()
      3. vmi_init_os()
        1. linux_init() ← Finds the KASLR Offset
      4. set_os_linux() 2. find_kernbase() ← Finds Kernel Base Address (_text)
    3. drakvuf_release_vmi()
bool drakvuf_init(drakvuf_t* drakvuf, const char* domain, const char* json_kernel_path, const char* json_wow_path, bool _verbose, bool libvmi_conf, addr_t kpgd, bool fast_singlestep, uint64_t limited_traps_ttl, bool get_userid)
{
 
    if ( !domain )
        return 0;
 
#ifdef DRAKVUF_DEBUG
    verbose = _verbose;
#endif
 
    *drakvuf = (drakvuf_t)g_try_malloc0(sizeof(struct drakvuf));
 
    (*drakvuf)->get_userid = get_userid;
    (*drakvuf)->limited_traps_ttl = limited_traps_ttl;
    (*drakvuf)->context_switch_ixen_init_vmintercept_processes = NULL;
    (*drakvuf)->enable_cr3_based_interception = false;
    (*drakvuf)->libvmi_conf = libvmi_conf;
    (*drakvuf)->kpgd = kpgd;
 
    if ( json_kernel_path )
        (*drakvuf)->json_kernel_path = g_strdup(json_kernel_path);
 
    if ( json_wow_path )
    {
        (*drakvuf)->json_wow = json_object_from_file(json_wow_path);
        (*drakvuf)->json_wow_path = g_strdup(json_wow_path);
    }
    else
        PRINT_DEBUG("drakvuf_init: Rekall WoW64 profile not used\n");
 
    g_rec_mutex_init(&(*drakvuf)->vmi_lock);
 
    if ( !xen_init_interface(&(*drakvuf)->xen) )
        goto err;
 
    /* register the main VMI event callback */
    drakvuf_event_fd_add(*drakvuf, (*drakvuf)->xen->evtchn_fd, drakvuf_vmi_event_callback, drakvuf);
    PRINT_DEBUG("drakvuf_init: adding event_fd done\n");
 
    get_dom_info((*drakvuf)->xen, domain, &(*drakvuf)->domID, &(*drakvuf)->dom_name);
    domid_t test = ~0;
    if ( (*drakvuf)->domID == test )
        goto err;
 
    drakvuf_pause(*drakvuf);
 
    if (!init_vmi(*drakvuf, fast_singlestep))
        goto err;
 
    drakvuf_init_os(*drakvuf);
 
    if ( (*drakvuf)->pm == VMI_PM_UNKNOWN )
    {
        fprintf(stderr, "Failed to determine paging mode\n");
        goto err;
    }
 
    PRINT_DEBUG("libdrakvuf initialized\n");
 
    return 1;
 
err:
    drakvuf_close(*drakvuf, 1);
    *drakvuf = NULL;
 
    PRINT_DEBUG("libdrakvuf initialization failed\n");
 
    return 0;
}

drakvuf_init_os

bool drakvuf_init_os(drakvuf_t drakvuf)
{
    drakvuf_lock_and_get_vmi(drakvuf);
    bool ret = _drakvuf_init_os(drakvuf);
    drakvuf_release_vmi(drakvuf);
    return ret;
}
static bool _drakvuf_init_os(drakvuf_t drakvuf)
{
    /*
     * We want to make sure paging is initialized with the actual state. LibVMI
     * only auto-detects paging during vmi_init_os the first time its called.
     * In case the OS not yet booted then paging mode might change, so we force a
     * refresh here.
     */
    if ( VMI_PM_UNKNOWN == (drakvuf->pm = vmi_init_paging(drakvuf->vmi, 0)) )
        return false;
 
    drakvuf->address_width = vmi_get_address_width(drakvuf->vmi);
 
    if (drakvuf->libvmi_conf)
        drakvuf->os = vmi_init_os(drakvuf->vmi, VMI_CONFIG_GLOBAL_FILE_ENTRY, NULL, NULL);
    else if ( drakvuf->json_kernel_path )
    {
        GHashTable* config = g_hash_table_new(g_str_hash, g_str_equal);
        g_hash_table_insert(config, "volatility_ist", drakvuf->json_kernel_path);
        if (drakvuf->kpgd)
            g_hash_table_insert(config, "kpgd", &drakvuf->kpgd);
        drakvuf->os = vmi_init_os(drakvuf->vmi, VMI_CONFIG_GHASHTABLE, config, NULL);
        g_hash_table_destroy(config);
    }
 
    switch (drakvuf->os)
    {
        case VMI_OS_WINDOWS:
            if ( !set_os_windows(drakvuf) )
                drakvuf->os = VMI_OS_UNKNOWN;
            else
                drakvuf->pm = vmi_init_paging(drakvuf->vmi, VMI_PM_INITFLAG_TRANSITION_PAGES);
            break;
        case VMI_OS_LINUX:
            if ( !set_os_linux(drakvuf) )
                drakvuf->os = VMI_OS_UNKNOWN;
            break;
        case VMI_OS_UNKNOWN: /* fall-through */
        case VMI_OS_FREEBSD: /* fall-through */
        default:
            break;
    }
 
    return drakvuf->os != VMI_OS_UNKNOWN;
}
 

🌱 Back to Garden