static int loads_init(Elf64_Phdr *phdr, u64 loads_offset)
{
	struct mem_chunk *chunk_array, *mem_chunk;
	int i;

	chunk_array = get_memory_layout();
	for (i = 0; i < MEMORY_CHUNKS; i++) {
		mem_chunk = &chunk_array[i];
		if (mem_chunk->size == 0)
			break;
		if (chunk_array[i].type != CHUNK_READ_WRITE &&
		    chunk_array[i].type != CHUNK_READ_ONLY)
			continue;
		else
			phdr->p_filesz = mem_chunk->size;
		phdr->p_type = PT_LOAD;
		phdr->p_offset = mem_chunk->addr;
		phdr->p_vaddr = mem_chunk->addr;
		phdr->p_paddr = mem_chunk->addr;
		phdr->p_memsz = mem_chunk->size;
		phdr->p_flags = PF_R | PF_W | PF_X;
		phdr->p_align = PAGE_SIZE;
		phdr++;
	}
	kfree(chunk_array);
	return i;
}
page_mode_t
vmi_get_page_mode(
    vmi_instance_t vmi)
{
    if(vmi->page_mode == VMI_PM_UNKNOWN) {
        page_mode_t ret=VMI_PM_UNKNOWN;
        get_memory_layout(vmi, &ret, NULL, NULL, NULL, NULL);
        return ret;
    } else {
        return vmi->page_mode;
    }
}
static int get_mem_chunk_cnt(void)
{
	struct mem_chunk *chunk_array, *mem_chunk;
	int i, cnt = 0;

	chunk_array = get_memory_layout();
	for (i = 0; i < MEMORY_CHUNKS; i++) {
		mem_chunk = &chunk_array[i];
		if (chunk_array[i].type != CHUNK_READ_WRITE &&
		    chunk_array[i].type != CHUNK_READ_ONLY)
			continue;
		if (mem_chunk->size == 0)
			continue;
		cnt++;
	}
	kfree(chunk_array);
	return cnt;
}
Beispiel #4
0
static status_t
vmi_init_private(
    vmi_instance_t *vmi,
    uint32_t flags,
    unsigned long id,
    char *name,
    vmi_config_t *config)
{
    uint32_t access_mode = flags & 0x0000FFFF;
    uint32_t init_mode = flags & 0x00FF0000;
    uint32_t config_mode = flags & 0xFF000000;
    status_t status = VMI_FAILURE;

    /* allocate memory for instance structure */
    *vmi = (vmi_instance_t) safe_malloc(sizeof(struct vmi_instance));
    memset(*vmi, 0, sizeof(struct vmi_instance));

    /* initialize instance struct to default values */
    dbprint("LibVMI Version 0.9_alpha\n");  //TODO change this with each release

    /* save the flags and init mode */
    (*vmi)->flags = flags;
    (*vmi)->init_mode = init_mode;
    (*vmi)->config = config;
    (*vmi)->config_mode = config_mode;

    /* setup the caches */
    pid_cache_init(*vmi);
    sym_cache_init(*vmi);
    rva_cache_init(*vmi);
    v2p_cache_init(*vmi);

    /* connecting to xen, kvm, file, etc */
    if (VMI_FAILURE == set_driver_type(*vmi, access_mode, id, name)) {
        goto error_exit;
    }

    /* resolve the id and name */
    if (VMI_FAILURE == set_id_and_name(*vmi, access_mode, id, name)) {
        goto error_exit;
    }

    /* driver-specific initilization */
    if (VMI_FAILURE == driver_init(*vmi)) {
        goto error_exit;
    }
    dbprint("--completed driver init.\n");

    /* we check VMI_INIT_COMPLETE first as
       VMI_INIT_PARTIAL is not exclusive */
    if (init_mode & VMI_INIT_COMPLETE) {

        /* init_complete requires configuration */
        if(VMI_CONFIG_NONE & (*vmi)->config_mode) {
            /* falling back to VMI_CONFIG_GLOBAL_FILE_ENTRY is unsafe here
                as the config pointer is probably NULL */
            goto error_exit;
        }
        /* read and parse the config file */
        else if ( (VMI_CONFIG_STRING & (*vmi)->config_mode || VMI_CONFIG_GLOBAL_FILE_ENTRY & (*vmi)->config_mode)
                 && VMI_FAILURE == read_config_file(*vmi)) {
            goto error_exit;
        }
        /* read and parse the ghashtable */
        else if (VMI_CONFIG_GHASHTABLE & (*vmi)->config_mode
                 && VMI_FAILURE == read_config_ghashtable(*vmi)) {
            dbprint("--failed to parse ghashtable\n");
            goto error_exit;
        }

        /* setup the correct page offset size for the target OS */
        if (VMI_FAILURE == init_page_offset(*vmi)) {
            goto error_exit;
        }

        /* get the memory size */
        if (driver_get_memsize(*vmi, &(*vmi)->size) == VMI_FAILURE) {
            errprint("Failed to get memory size.\n");
            goto error_exit;
        }
        dbprint("**set size = %"PRIu64" [0x%"PRIx64"]\n", (*vmi)->size,
                (*vmi)->size);

        /* determine the page sizes and layout for target OS */

        // Find the memory layout. If this fails, then proceed with the
        // OS-specific heuristic techniques.
        (*vmi)->pae = (*vmi)->pse = (*vmi)->lme = (*vmi)->cr3 = 0;
        (*vmi)->page_mode = VMI_PM_UNKNOWN;

        status = get_memory_layout(*vmi,
                                        &((*vmi)->page_mode),
                                        &((*vmi)->cr3),
                                        &((*vmi)->pae),
                                        &((*vmi)->pse),
                                        &((*vmi)->lme));

        if (VMI_FAILURE == status) {
            dbprint
                ("**Failed to get memory layout for VM. Trying heuristic method.\n");
            // fall-through
        }   // if

        // Heuristic method
        if (!(*vmi)->cr3) {
            (*vmi)->cr3 = find_cr3((*vmi));
            dbprint("**set cr3 = 0x%.16"PRIx64"\n", (*vmi)->cr3);
        }   // if

        /* setup OS specific stuff */
        if (VMI_OS_LINUX == (*vmi)->os_type) {
            status = linux_init(*vmi);
        }
        else if (VMI_OS_WINDOWS == (*vmi)->os_type) {
            status = windows_init(*vmi);
        }

        /* Enable event handlers only if we're in a consistent state */
        if((status == VMI_SUCCESS) && (init_mode & VMI_INIT_EVENTS)){
            events_init(*vmi);
        }

        return status;
    } else if (init_mode & VMI_INIT_PARTIAL) {
        init_page_offset(*vmi);
        driver_get_memsize(*vmi, &(*vmi)->size);

        /* Enable event handlers */
        if(init_mode & VMI_INIT_EVENTS){
            events_init(*vmi);
        }

        return VMI_SUCCESS;
    }

error_exit:
    return status;
}
bool DFInstanceLinux::find_running_copy(bool connect_anyway) {
    // find PID of DF
    TRACE << "attempting to find running copy of DF by executable name";
    QProcess *proc = new QProcess(this);
    QStringList args;
    args << "dwarfort.exe"; // 0.31.04 and earlier
    args << "Dwarf_Fortress"; // 0.31.05+
    proc->start("pidof", args);
    proc->waitForFinished(1000);
    if (proc->exitCode() == 0) { //found it
        QByteArray out = proc->readAllStandardOutput();
        QStringList str_pids = QString(out).split(" ");
        str_pids.sort();
        if(str_pids.count() > 1){
            m_pid = QInputDialog::getItem(0, tr("Warning"),tr("Multiple Dwarf Fortress processes found, please choose the process to use."),str_pids,str_pids.count()-1,false).toInt();
        }else{
            m_pid = str_pids.at(0).toInt();
        }

        m_memory_file.setFileName(QString("/proc/%1/mem").arg(m_pid));

        TRACE << "USING PID:" << m_pid;
    } else {
        QMessageBox::warning(0, tr("Warning"),
                             tr("Unable to locate a running copy of Dwarf "
                                "Fortress, are you sure it's running?"));
        LOGW << "can't find running copy";
        m_is_ok = false;
        return m_is_ok;
    }

    m_inject_addr = unsigned(-1);
    m_alloc_start = 0;
    m_alloc_end = 0;

    map_virtual_memory();

    //qDebug() << "LOWEST ADDR:" << hex << lowest_addr;


    //DUMP LIST OF MEMORY RANGES
    /*
    QPair<uint, uint> tmp_pair;
    foreach(tmp_pair, m_regions) {
        LOGD << "RANGE start:" << hex << tmp_pair.first << "end:" << tmp_pair.second;
    }*/

    VIRTADDR m_base_addr = read_addr(m_lowest_address + 0x18);
    LOGD << "base_addr:" << m_base_addr << "HEX" << hex << m_base_addr;
    m_is_ok = m_base_addr > 0;

    uint checksum = calculate_checksum();
    LOGD << "DF's checksum is" << hexify(checksum);
    if (m_is_ok) {
        m_layout = get_memory_layout(hexify(checksum).toLower(), !connect_anyway);
    }

    //Get dwarf fortress directory
    m_df_dir = QDir(QFileInfo(QString("/proc/%1/cwd").arg(m_pid)).symLinkTarget());
    LOGI << "Dwarf fortress path:" << m_df_dir.absolutePath();

    return m_is_ok || connect_anyway;
}