Exemplo n.º 1
0
status_t
linux_symbol_to_address(
    vmi_instance_t vmi,
    const char *symbol,
    addr_t* UNUSED(__unused),
    addr_t* address)
{
    status_t ret = VMI_FAILURE;
    linux_instance_t linux_instance = vmi->os_data;

    if (linux_instance == NULL) {
        errprint("VMI_ERROR: OS instance not initialized\n");
        goto done;
    }

    if (!linux_instance->sysmap && !linux_instance->rekall_profile) {
        errprint("VMI_WARNING: No linux sysmap and Rekall profile configured\n");
        goto done;
    }

    if (linux_instance->sysmap)
        ret = linux_system_map_symbol_to_address(vmi, symbol, address);
    else
        ret = rekall_profile_symbol_to_rva(
                  linux_instance->rekall_profile,
                  symbol, NULL, address);

    if ( VMI_SUCCESS == ret )
        *address += linux_instance->kaslr_offset;

done:
    return ret;
}
Exemplo n.º 2
0
int xa_symbol_to_address (xa_instance_t *instance, char *sym, uint32_t *vaddr)
{
    if (XA_OS_LINUX == instance->os_type){
       return linux_system_map_symbol_to_address(instance, sym, vaddr);
    }
    else if (XA_OS_WINDOWS == instance->os_type){
        return windows_symbol_to_address(instance, sym, vaddr);
    }
    else{
        return XA_FAILURE;
    }
}
Exemplo n.º 3
0
int linux_init (xa_instance_t *instance)
{
    int ret = XA_SUCCESS;
    unsigned char *memory = NULL;
    uint32_t local_offset = 0;

    if (linux_system_map_symbol_to_address(
             instance, "swapper_pg_dir", &instance->kpgd) == XA_FAILURE){
        fprintf(stderr, "ERROR: failed to lookup 'swapper_pg_dir' address\n");
        ret = xa_report_error(instance, 0, XA_EMINOR);
        if (XA_FAILURE == ret) goto error_exit;
    }
    xa_dbprint("--got vaddr for swapper_pg_dir (0x%.8x).\n", instance->kpgd);

    if (!instance->hvm){
        instance->kpgd -= instance->page_offset;
        if (xa_read_long_phys(
                instance, instance->kpgd, &(instance->kpgd)) == XA_FAILURE){
            fprintf(stderr, "ERROR: failed to get physical addr for kpgd\n");
            ret = xa_report_error(instance, 0, XA_EMINOR);
            if (XA_FAILURE == ret) goto error_exit;
        }
    }
    xa_dbprint("**set instance->kpgd (0x%.8x).\n", instance->kpgd);
//    printf("kpgd search --> 0x%.8x\n", xa_find_kernel_pd(instance));

    memory = xa_access_kernel_sym(instance, "init_task", &local_offset, PROT_READ);
    if (NULL == memory){
        xa_dbprint("--address lookup failure, switching PAE mode\n");
        instance->pae = !instance->pae;
        xa_dbprint("**set instance->pae = %d\n", instance->pae);
        memory = xa_access_kernel_sym(instance, "init_task", &local_offset, PROT_READ);
        if (NULL == memory){
            fprintf(stderr, "ERROR: failed to get task list head 'init_task'\n");
            ret = xa_report_error(instance, 0, XA_EMINOR);
            //TODO should we switch PAE mode back?
            if (XA_FAILURE == ret) goto error_exit;
        }
    }
    instance->init_task =
        *((uint32_t*)(memory + local_offset +
        instance->os.linux_instance.tasks_offset));
    xa_dbprint("**set instance->init_task (0x%.8x).\n", instance->init_task);
    munmap(memory, instance->page_size);

error_exit:
    return ret;
}
Exemplo n.º 4
0
status_t linux_init (vmi_instance_t vmi)
{
    status_t ret = VMI_FAILURE;

    if (vmi->cr3){
        vmi->kpgd = vmi->cr3;
    }
    else if (VMI_SUCCESS == linux_system_map_symbol_to_address(vmi, "swapper_pg_dir", &vmi->kpgd)){
        dbprint("--got vaddr for swapper_pg_dir (0x%.16llx).\n", vmi->kpgd);
        if (driver_is_pv(vmi)){
            vmi->kpgd = vmi_translate_kv2p(vmi, vmi->kpgd);
            if (vmi_read_addr_pa(vmi, vmi->kpgd, &(vmi->kpgd)) == VMI_FAILURE){
                errprint("Failed to get physical addr for kpgd.\n");
                goto _exit;
            }
        }
        else{
            vmi->kpgd = vmi_translate_kv2p(vmi, vmi->kpgd);
        }
    }
    else{
        errprint("swapper_pg_dir not found and CR3 not set, exiting\n");
        goto _exit;
    }

    vmi->kpgd = vmi->cr3;
    dbprint("**set vmi->kpgd (0x%.16llx).\n", vmi->kpgd);

    addr_t address = vmi_translate_ksym2v(vmi, "init_task");
    address += vmi->os.linux_instance.tasks_offset;
    if (VMI_FAILURE == vmi_read_addr_va(vmi, address, 0, &(vmi->init_task))){
        errprint("Failed to get task list head 'init_task'.\n");
        goto _exit;
    }

    ret = VMI_SUCCESS;
_exit:
    return ret;
}
Exemplo n.º 5
0
Arquivo: core.c Projeto: kittel/libvmi
static status_t linux_filemode_init(vmi_instance_t vmi)
{
    status_t rc;
    addr_t swapper_pg_dir = 0, init_level4_pgt = 0;
    addr_t boundary = 0, phys_start = 0, virt_start = 0;

    switch (vmi->page_mode)
    {
    case VMI_PM_IA32E:
        linux_system_map_symbol_to_address(vmi, "phys_startup_64", NULL, &phys_start);
        linux_system_map_symbol_to_address(vmi, "startup_64", NULL, &virt_start);
        break;
    case VMI_PM_AARCH32:
    case VMI_PM_LEGACY:
    case VMI_PM_PAE:
        linux_system_map_symbol_to_address(vmi, "phys_startup_32", NULL, &phys_start);
        linux_system_map_symbol_to_address(vmi, "startup_32", NULL, &virt_start);
        break;
    case VMI_PM_UNKNOWN:
        linux_system_map_symbol_to_address(vmi, "phys_startup_64", NULL, &phys_start);
        linux_system_map_symbol_to_address(vmi, "startup_64", NULL, &virt_start);

        if (phys_start && virt_start) break;
        phys_start = virt_start = 0;

        linux_system_map_symbol_to_address(vmi, "phys_startup_32", NULL, &phys_start);
        linux_system_map_symbol_to_address(vmi, "startup_32", NULL, &virt_start);
        break;
    }

    if(phys_start && virt_start && phys_start < virt_start) {
        boundary = virt_start - phys_start;
        dbprint(VMI_DEBUG_MISC, "--got kernel boundary (0x%.16"PRIx64").\n", boundary);
    }

    rc = linux_system_map_symbol_to_address(vmi, "swapper_pg_dir", NULL, &swapper_pg_dir);

    if (VMI_SUCCESS == rc) {

        dbprint(VMI_DEBUG_MISC, "--got vaddr for swapper_pg_dir (0x%.16"PRIx64").\n",
                swapper_pg_dir);

        /* We don't know if VMI_PM_LEGACY, VMI_PM_PAE or VMI_PM_AARCH32 yet
         * so we do some heuristics below. */
        if (boundary)
        {
        rc = linux_filemode_32bit_init(vmi, swapper_pg_dir, boundary,
                                       phys_start, virt_start);
        if (VMI_SUCCESS == rc)
            return rc;
        }

        /*
         * So we have a swapper but don't know the physical page of it.
         * We will make some educated guesses now.
         */
        boundary = 0xC0000000;
        dbprint(VMI_DEBUG_MISC, "--trying boundary 0x%.16"PRIx64".\n",
                boundary);
        rc = linux_filemode_32bit_init(vmi, swapper_pg_dir, boundary,
                                       swapper_pg_dir-boundary, swapper_pg_dir);
        if (VMI_SUCCESS == rc)
        {
            return rc;
        }

        boundary = 0x80000000;
        dbprint(VMI_DEBUG_MISC, "--trying boundary 0x%.16"PRIx64".\n",
                boundary);
        rc = linux_filemode_32bit_init(vmi, swapper_pg_dir, boundary,
                                       swapper_pg_dir-boundary, swapper_pg_dir);
        if (VMI_SUCCESS == rc)
        {
        return rc;
        }

        boundary = 0x40000000;
        dbprint(VMI_DEBUG_MISC, "--trying boundary 0x%.16"PRIx64".\n",
            boundary);
        rc = linux_filemode_32bit_init(vmi, swapper_pg_dir, boundary,
                                       swapper_pg_dir-boundary, swapper_pg_dir);
        if (VMI_SUCCESS == rc)
        {
            return rc;
        }

        return VMI_FAILURE;
    }

    rc = linux_system_map_symbol_to_address(vmi, "init_level4_pgt", NULL, &init_level4_pgt);
    if (rc == VMI_SUCCESS) {

        dbprint(VMI_DEBUG_MISC, "--got vaddr for init_level4_pgt (0x%.16"PRIx64").\n",
                init_level4_pgt);

        if (boundary) {
            vmi->page_mode = VMI_PM_IA32E;
            if (VMI_SUCCESS == arch_init(vmi)) {
                if (phys_start == vmi_pagetable_lookup(vmi, init_level4_pgt - boundary, virt_start)) {
                    vmi->kpgd = init_level4_pgt - boundary;
                    return VMI_SUCCESS;
                }
            }
        }
    }

    return VMI_FAILURE;
}
Exemplo n.º 6
0
Arquivo: core.c Projeto: kittel/libvmi
status_t linux_init(vmi_instance_t vmi) {

    status_t rc;
    os_interface_t os_interface = NULL;

    if (vmi->config == NULL) {
        errprint("No config table found\n");
        return VMI_FAILURE;
    }

    if (vmi->os_data != NULL) {
        errprint("os data already initialized, reinitializing\n");
        free(vmi->os_data);
    }

    vmi->os_data = safe_malloc(sizeof(struct linux_instance));
    bzero(vmi->os_data, sizeof(struct linux_instance));
    linux_instance_t linux_instance = vmi->os_data;

    g_hash_table_foreach(vmi->config, (GHFunc)linux_read_config_ghashtable_entries, vmi);

#if defined(ARM)
    rc = driver_get_vcpureg(vmi, &vmi->kpgd, TTBR1, 0);
#elif defined(I386) || defined(X86_64)
    rc = driver_get_vcpureg(vmi, &vmi->kpgd, CR3, 0);
#endif

    /*
     * The driver failed to get us a pagetable.
     * As a fall-back, try to init using heuristics.
     * This path is taken in FILE mode as well.
     */
    if (VMI_FAILURE == rc)
        if (VMI_FAILURE == linux_filemode_init(vmi))
            goto _exit;

    dbprint(VMI_DEBUG_MISC, "**set vmi->kpgd (0x%.16"PRIx64").\n", vmi->kpgd);

    rc = linux_system_map_symbol_to_address(vmi, "init_task", NULL,
            &vmi->init_task);
    if (VMI_FAILURE == rc) {
        errprint("Could not get init_task from System.map\n");
        goto _exit;
    }

done:
    os_interface = safe_malloc(sizeof(struct os_interface));
    bzero(os_interface, sizeof(struct os_interface));
    os_interface->os_get_offset = linux_get_offset;
    os_interface->os_pid_to_pgd = linux_pid_to_pgd;
    os_interface->os_pgd_to_pid = linux_pgd_to_pid;
    os_interface->os_ksym2v = linux_system_map_symbol_to_address;
    os_interface->os_usym2rva = NULL;
    os_interface->os_v2sym = linux_system_map_address_to_symbol;
    os_interface->os_read_unicode_struct = NULL;
    os_interface->os_teardown = linux_teardown;

    vmi->os_interface = os_interface;

    return VMI_SUCCESS;

    _exit:
    free(vmi->os_data);
    vmi->os_data = NULL;
    return VMI_FAILURE;
}
Exemplo n.º 7
0
status_t linux_init(vmi_instance_t vmi) {
    status_t ret = VMI_FAILURE;
    os_interface_t os_interface = NULL;

    if (vmi->config == NULL) {
        errprint("No config table found\n");
        return VMI_FAILURE;
    }

    if (vmi->os_data != NULL) {
        errprint("os data already initialized, reinitializing\n");
        free(vmi->os_data);
    }

    vmi->os_data = safe_malloc(sizeof(struct linux_instance));
    bzero(vmi->os_data, sizeof(struct linux_instance));
    linux_instance_t linux_instance = vmi->os_data;

    g_hash_table_foreach(vmi->config, (GHFunc)linux_read_config_ghashtable_entries, vmi);

    addr_t boundary = 0, phys_start = 0, virt_start = 0;

    if(vmi->page_mode == VMI_PM_IA32E) {
        linux_system_map_symbol_to_address(vmi, "phys_startup_64", NULL, &phys_start);
        linux_system_map_symbol_to_address(vmi, "startup_64", NULL, &virt_start);
    } else if (vmi->page_mode == VMI_PM_LEGACY || vmi->page_mode == VMI_PM_PAE) {
        linux_system_map_symbol_to_address(vmi, "phys_startup_32", NULL, &phys_start);
        linux_system_map_symbol_to_address(vmi, "startup_32", NULL, &virt_start);
    } else if (vmi->page_mode == VMI_PM_UNKNOWN) {
        ret = linux_system_map_symbol_to_address(vmi, "phys_startup_64", NULL, &phys_start);
        if(VMI_SUCCESS == ret) {
            linux_system_map_symbol_to_address(vmi, "startup_64", NULL, &virt_start);
            vmi->page_mode = VMI_PM_IA32E;
        } else {
            linux_system_map_symbol_to_address(vmi, "phys_startup_32", NULL, &phys_start);
            linux_system_map_symbol_to_address(vmi, "startup_32", NULL, &virt_start);
            vmi->page_mode = VMI_PM_PAE; // it's just a guess
        }
    }

    if(phys_start && virt_start && phys_start < virt_start) {
        boundary = virt_start - phys_start;
    } else {
        // Just guess the boundary
        boundary = 0xc0000000UL;
    }

    linux_instance->kernel_boundary = boundary;
    dbprint(VMI_DEBUG_MISC, "--got kernel boundary (0x%.16"PRIx64").\n", boundary);

    if(VMI_FAILURE == driver_get_vcpureg(vmi, &vmi->kpgd, CR3, 0)) {

        if (VMI_SUCCESS == linux_system_map_symbol_to_address(vmi, "swapper_pg_dir", NULL, &vmi->kpgd)) {
            dbprint(VMI_DEBUG_MISC, "--got vaddr for swapper_pg_dir (0x%.16"PRIx64").\n",
                    vmi->kpgd);
            //We don't know if VMI_PM_LEGACY or VMI_PM_PAE yet
            //so we do some heuristics below
        } else if (VMI_SUCCESS == linux_system_map_symbol_to_address(vmi, "init_level4_pgt", NULL, &vmi->kpgd)) {
            dbprint(VMI_DEBUG_MISC, "--got vaddr for init_level4_pgt (0x%.16"PRIx64").\n",
                    vmi->kpgd);
            //Set page mode to VMI_PM_IA32E
            vmi->page_mode = VMI_PM_IA32E;
        } else {
            goto _exit;
        }

        vmi->kpgd -= boundary;
    }

    dbprint(VMI_DEBUG_MISC, "**set vmi->kpgd (0x%.16"PRIx64").\n", vmi->kpgd);

    // We check if the page mode is known
    // and if no arch interface has been setup yet we do it now
    if(VMI_PM_UNKNOWN == vmi->page_mode) {

        //Try to check 32-bit paging modes
        vmi->page_mode = VMI_PM_LEGACY;
        if(VMI_SUCCESS == arch_init(vmi)) {
            if(phys_start == vmi_pagetable_lookup(vmi, vmi->kpgd, virt_start)) {
                // PM found
                goto done;
            }
        }

        vmi->page_mode = VMI_PM_PAE;
        if(VMI_SUCCESS == arch_init(vmi)) {
            if(phys_start == vmi_pagetable_lookup(vmi, vmi->kpgd, virt_start)) {
                // PM found
                goto done;
            }
        }

        errprint("VMI_ERROR: Page mode is still unknown\n");
        goto _exit;
    }

    if(!vmi->arch_interface) {
        if(VMI_FAILURE == arch_init(vmi)) {
            goto _exit;
        }
    }

done:
    ret = linux_system_map_symbol_to_address(vmi, "init_task", NULL,
            &vmi->init_task);
    if (ret != VMI_SUCCESS) {
        errprint("Could not get init_task from System.map\n");
        goto _exit;
    }

    if(!vmi_pagetable_lookup(vmi, vmi->kpgd, vmi->init_task)) {
        errprint("Failed to translate init_task VA using the kpgd!\n");
        goto _exit;
    }

    os_interface = safe_malloc(sizeof(struct os_interface));
    bzero(os_interface, sizeof(struct os_interface));
    os_interface->os_get_offset = linux_get_offset;
    os_interface->os_pid_to_pgd = linux_pid_to_pgd;
    os_interface->os_pgd_to_pid = linux_pgd_to_pid;
    os_interface->os_ksym2v = linux_system_map_symbol_to_address;
    os_interface->os_usym2rva = NULL;
    os_interface->os_rva2sym = NULL;
    os_interface->os_read_unicode_struct = NULL;
    os_interface->os_teardown = linux_teardown;

    vmi->os_interface = os_interface;

    return VMI_SUCCESS;

    _exit:
    free(vmi->os_data);
    vmi->os_data = NULL;
    return VMI_FAILURE;
}
Exemplo n.º 8
0
status_t linux_init(vmi_instance_t vmi) {
    status_t ret = VMI_FAILURE;
    os_interface_t os_interface = NULL;

    if (vmi->config == NULL) {
        errprint("VMI_ERROR: No config table found\n");
        return VMI_FAILURE;
    }

    if (vmi->os_data != NULL) {
        errprint("VMI_ERROR: os data already initialized, reinitializing\n");
        free(vmi->os_data);
    }

    vmi->os_data = safe_malloc(sizeof(struct linux_instance));
    bzero(vmi->os_data, sizeof(struct linux_instance));

    g_hash_table_foreach(vmi->config, (GHFunc)linux_read_config_ghashtable_entries, vmi);

    if (VMI_SUCCESS
            == linux_system_map_symbol_to_address(vmi, "swapper_pg_dir", NULL,
                    &vmi->kpgd)) {
        dbprint("--got vaddr for swapper_pg_dir (0x%.16"PRIx64").\n",
                vmi->kpgd);
        if (driver_is_pv(vmi)) {
            vmi->kpgd = vmi_translate_kv2p(vmi, vmi->kpgd);
            if (vmi_read_addr_pa(vmi, vmi->kpgd, &(vmi->kpgd)) == VMI_FAILURE) {
                errprint(
                        "Failed to get physical addr for kpgd using swapper_pg_dir.\n");
            }
        }
    }

    if (!vmi->kpgd) {
        ret = driver_get_vcpureg(vmi, &vmi->kpgd, CR3, 0);
        if (ret != VMI_SUCCESS) {
            errprint(
                    "Driver does not support cr3 read and kpgd could not be set, exiting\n");
            goto _exit;
        }
    }

    dbprint("**set vmi->kpgd (0x%.16"PRIx64").\n", vmi->kpgd);

    ret = linux_system_map_symbol_to_address(vmi, "init_task", NULL,
            &vmi->init_task);
    if (ret != VMI_SUCCESS) {
        errprint("VMI_ERROR: Could not get init_task from System.map\n");
        return ret;
    }

    os_interface = safe_malloc(sizeof(struct os_interface));
    bzero(os_interface, sizeof(struct os_interface));
    os_interface->os_get_offset = linux_get_offset;
    os_interface->os_pid_to_pgd = linux_pid_to_pgd;
    os_interface->os_pgd_to_pid = linux_pgd_to_pid;
    os_interface->os_ksym2v = linux_system_map_symbol_to_address;
    os_interface->os_usym2rva = NULL;
    os_interface->os_rva2sym = NULL;
    os_interface->os_teardown = linux_teardown;

    vmi->os_interface = os_interface;

    _exit: return ret;
}