This is the Initialization of Drakvuf object and setup of LibVMI, it follows this steps:
- JSON PROFILES PARSING
- xen_init_interface()
- drakvuf_event_fd_add()
- get_dom_info()
- drakvuf_pause()
- init_vmi()
- drakvuf_init_os()
- drakvuf_lock_and_get_vmi()
- _drakvuf_init_os()
- vmi_init_paging()
- vmi_get_address_width()
- vmi_init_os()
- linux_init() ← Finds the KASLR Offset
- set_os_linux() 2. find_kernbase() ← Finds Kernel Base Address (_text)
- 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;
}