Exemplo n.º 1
0
event_response_t after_extract_buf(vmi_instance_t vmi, vmi_event_t *event) {
	printf("Called after_extract_buf!\n");

	// read in all the bytes at buf
	uint8_t buffer[EXTRACT_SIZE];

	vmi_read_va(vmi, rng_buf, 0, buffer, EXTRACT_SIZE);
	printf("old buf: ");
	for (int i = 0; i < EXTRACT_SIZE; i++) {
		printf("%02x ",buffer[i]);
	}
	printf("\n");

	// modify rng buffer!
	vmi_write_va(vmi, rng_buf , 0, RNG_VALUE, EXTRACT_SIZE);

	// read in all the bytes at buf again (sanity check)
	vmi_read_va(vmi, rng_buf, 0, buffer, EXTRACT_SIZE);
	printf("new buf: ");
	for (int i = 0; i < EXTRACT_SIZE; i++) {
		printf("%02x ",buffer[i]);
	}
	printf("\n");

	return VMI_SUCCESS;
}
Exemplo n.º 2
0
addr_t
eprocess_list_search(
        vmi_instance_t vmi,
        addr_t list_head,
        int offset,
        size_t len,
        void *value)
{
    addr_t next_process = 0;
    addr_t tasks_offset = 0;
    addr_t rtnval = 0;
    void *buf = g_malloc0(len);

    if ( !buf )
        goto exit;

    if ( VMI_FAILURE == vmi_get_offset(vmi, "win_tasks", &tasks_offset) )
        goto exit;

    if ( VMI_FAILURE == vmi_read_addr_va(vmi, list_head + tasks_offset, 0, &next_process) )
        goto exit;

    if ( VMI_FAILURE == vmi_read_va(vmi, list_head + offset, 0, len, buf, NULL) )
        goto exit;

    if (memcmp(buf, value, len) == 0) {
        rtnval = list_head + tasks_offset;
        goto exit;
    }
    list_head = next_process;

    while(1) {
        addr_t tmp_next = 0;

        if ( VMI_FAILURE == vmi_read_addr_va(vmi, next_process, 0, &tmp_next) )
            goto exit;

        if (list_head == tmp_next) {
            break;
        }

        if ( VMI_FAILURE == vmi_read_va(vmi, next_process + offset - tasks_offset, 0, len, buf, NULL) )
            goto exit;

        if (memcmp(buf, value, len) == 0) {
            rtnval = next_process;
            goto exit;
        }
        next_process = tmp_next;
    }

exit:
    g_free(buf);
    return rtnval;
}
Exemplo n.º 3
0
event_response_t overwrite_buf(vmi_instance_t vmi, vmi_event_t *event) {
	printf("Called overwrite_buf!\n");
	// local vars
	addr_t val_addr = 0;
	uint8_t buf[EXTRACT_SIZE];

	// Print everything out
	//printf("VCPU: %d\n", event->vcpu_id);
	//printf("Pagetable id: %d\n", event->vmm_pagetable_id);
	//printf("Instruction pointer: 0x%x\n", event->interrupt_event.gla);
	//printf("Physical page of instruction: 0x%x\n", event->interrupt_event.gfn);
	//printf("Page offset: 0x%x\n", event->interrupt_event.offset);
	//printf("Interrupt type (1 is INT3): %d\n", event->interrupt_event.intr);

	//////////////////////////
	// Access random number // 
	//////////////////////////
	
	// Print amd64 function args --> see below link for reference
	// https://blogs.oracle.com/eschrock/entry/debugging_://blogs.oracle.com/eschrock/entry/debugging_on_amd64_part_twoon_amd64_part_two
	
	printf("Reading RDI register (*r):      0x%llx\n", event->regs.x86->rdi);
	printf("Reading RSI register (*tmp):    0x%llx\n", event->regs.x86->rsi);
	printf("Reading RSP+0x16:               0x%llx  (should be the same as RSI)\n", event->regs.x86->rsp+0x16);

	// val_addr is our RSP+0x16
	val_addr = event->regs.x86->rsp + 0x16;

	// what's currently at RSP+0x16?
	vmi_read_va(vmi, val_addr, 0, buf, EXTRACT_SIZE);
	printf("old buf: ");
	for (int i = 0; i < EXTRACT_SIZE; i++) {
		printf("%02x ",buf[i]);
	}
	printf("\n");

	// modify rng buffer! (should be at RSP+0x16, from static code analysis)
	vmi_write_va(vmi, val_addr, 0, RNG_VALUE , EXTRACT_SIZE);

	// what's at RSP+0x16 now?
	vmi_read_va(vmi, val_addr, 0, buf, EXTRACT_SIZE);
	printf("new buf: ");
	for (int i = 0; i < EXTRACT_SIZE; i++) {
		printf("%02x ",buf[i]);
	}
	printf("\n");

	return VMI_SUCCESS;
}
Exemplo n.º 4
0
END_TEST

#if ENABLE_KVM == 1
/* test vmi_get_dgvma */
// we use vmi_read_va() to verify vmi_get_dgvma()
START_TEST (test_vmi_get_dgvma)
{
    vmi_instance_t vmi = NULL;
    vmi_init(&vmi, VMI_AUTO | VMI_INIT_COMPLETE, get_testvm());
    vmi_shm_snapshot_create(vmi);

    addr_t va = 0x0;
    size_t count = 4096;
    unsigned long max_size = 0xffff;
    void *buf_readva = malloc(count);
    void *buf_dgvma = NULL;
    for (; va + count <= max_size; va += count) {
        size_t read_va = vmi_read_va(vmi, va, 0, buf_readva, count);
        size_t read_dgvma = vmi_get_dgvma(vmi, va, 0, &buf_dgvma, count);
        fail_unless(read_va == read_dgvma, "vmi_get_dgvma(0x%"PRIx64
            ") read size %d dosn't conform to %d of vmi_read_va()",
            va, read_dgvma, read_va);

        int cmp = memcmp(buf_readva, buf_dgvma, read_va);
        fail_unless(0 == cmp, "vmi_get_dgvma(0x%"PRIx64
            ") contents dosn't conform to vmi_read_va()", va);
    }
    free(buf_readva);

    vmi_shm_snapshot_destroy(vmi);
    vmi_destroy(vmi);
}
Exemplo n.º 5
0
addr_t
eprocess_list_search(
        vmi_instance_t vmi,
        int offset,
        size_t len,
        void *value)
{
    addr_t next_process, list_head;
    int tasks_offset;
    void *buf = malloc(len);
    addr_t rtnval = 0;

    tasks_offset = vmi_get_offset(vmi, "win_tasks");

    vmi_read_addr_ksym(vmi, "PsInitialSystemProcess", &list_head);
    vmi_read_addr_va(vmi, list_head + tasks_offset, 0, &next_process);
    vmi_read_va(vmi, list_head + offset, 0, buf, len);
    if (memcmp(buf, value, len) == 0) {
        rtnval = list_head + tasks_offset;
        goto exit;
    }
    list_head = next_process;

    while(1) {
        addr_t tmp_next = 0;
        vmi_read_addr_va(vmi, next_process, 0, &tmp_next);
        if (list_head == tmp_next) {
            break;
        }
        vmi_read_va(vmi, next_process + offset - tasks_offset, 0, buf, len);
        if (memcmp(buf, value, len) == 0) {
            rtnval = next_process;
            goto exit;
        }
        next_process = tmp_next;
    }

exit:
    free(buf);
    return rtnval;
}   
Exemplo n.º 6
0
event_response_t bnrand_callback(vmi_instance_t vmi, vmi_event_t *event) {

	uint64_t nbytes;
	addr_t buf_addr;
	uint8_t* buffer;
	vmi_pid_t pid = vmi_dtb_to_pid(vmi, event->regs.x86->cr3);
	printf("Called bnrand_callback from pid %d!\n");

	// look at args
	printf("Reading RDI register (*buf):    0x%llx\n", event->regs.x86->rdi);
	printf("Reading RSI register (bytes):    0x%llx\n", event->regs.x86->rsi);
	printf("Reading RDX register (*rnd):    0x%llx\n", event->regs.x86->rdx);

	// read in all the bytes at buf
	nbytes = event->regs.x86->rsi;
	buf_addr = event->regs.x86->rdi;
	buffer = malloc(nbytes); // allocate buffer

	vmi_read_va(vmi, buf_addr, pid, buffer, nbytes);
	printf("old buf: ");
	for (unsigned int i = 0; i < nbytes; i++) {
		printf("%02x ",buffer[i]);
	}
	printf("\n");

	// modify rng buffer!
	vmi_write_va(vmi, buf_addr, pid, RNG_VALUE, nbytes);

	// read in all the bytes at buf again (sanity check)
	vmi_read_va(vmi, buf_addr, pid, buffer, nbytes);
	printf("new buf: ");
	for (unsigned int i = 0; i < nbytes; i++) {
		printf("%02x ",buffer[i]);
	}
	printf("\n");

	return VMI_SUCCESS;
}
Exemplo n.º 7
0
size_t
vmi_read_ksym(
    vmi_instance_t vmi,
    char *sym,
    void *buf,
    size_t count)
{
    addr_t vaddr = vmi_translate_ksym2v(vmi, sym);

    if (0 == vaddr) {
        dbprint("--%s: vmi_translate_ksym2v failed for '%s'\n",
                __FUNCTION__, sym);
        return 0;
    }
    return vmi_read_va(vmi, vaddr, 0, buf, count);
}
Exemplo n.º 8
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);
        }
Exemplo n.º 9
0
///////////////////////////////////////////////////////////
// Easy access to virtual memory
static status_t
vmi_read_X_va(
    vmi_instance_t vmi,
    addr_t vaddr,
    vmi_pid_t pid,
    void *value,
    int size)
{
    size_t len_read = vmi_read_va(vmi, vaddr, pid, value, size);

    if (len_read == size) {
        return VMI_SUCCESS;
    }
    else {
        return VMI_FAILURE;
    }
}
Exemplo n.º 10
0
event_response_t urandom_read_end(vmi_instance_t vmi, vmi_event_t *event) {
	printf("Called urandom_read_end!\n");

	// read in all the bytes at buf
	uint8_t buffer[nbytes];
	vmi_read_va(vmi, rng_buf, 0, buffer, nbytes);
	printf("buf: ");
	for (int i = 0; i < nbytes; i++) {
		printf("%02x ",buffer[i]);
	}
	printf("\n");
	
	// clear global vars
	rng_buf = 0;
	nbytes = 0;

	return VMI_SUCCESS;
}
Exemplo n.º 11
0
event_response_t check_buf(vmi_instance_t vmi, vmi_event_t *event) {
	printf("Called check_buf!\n");

	// sanity check
	if (rng_buf == 0 || nbytes == 0) {
		printf("We don't have a buf or nbytes! AHHHHHH! 0x%llx   %u\n", rng_buf, nbytes);
	}

	// read in all the bytes at buf
	uint8_t buffer[nbytes];
	vmi_read_va(vmi, rng_buf, 0, buffer, nbytes);
	printf("buf: ");
	for (int i = 0; i < nbytes; i++) {
		printf("%02x ",buffer[i]);
	}
	printf("\n");

	return VMI_SUCCESS;
}
Exemplo n.º 12
0
int
main(
    int argc,
    char **argv)
{
    if ( argc != 3 )
        return 1;

    vmi_instance_t vmi;
    unsigned char *memory = malloc(PAGE_SIZE);

    /* this is the VM or file that we are looking at */
    char *name = argv[1];

    /* this is the address to map */
    char *addr_str = argv[2];
    addr_t addr = (addr_t) strtoul(addr_str, NULL, 16);

    /* initialize the libvmi library */
    if (VMI_FAILURE ==
        vmi_init_complete(&vmi, name, VMI_INIT_DOMAINNAME, NULL,
                          VMI_CONFIG_GLOBAL_FILE_ENTRY, NULL, NULL))
    {
        printf("Failed to init LibVMI library.\n");
        goto error_exit;
    }

    /* get the symbol's memory page */
    if (VMI_FAILURE == vmi_read_va(vmi, addr, 0, PAGE_SIZE, memory, NULL)) {
        printf("failed to map memory.\n");
        goto error_exit;
    }
    vmi_print_hex(memory, PAGE_SIZE);

error_exit:
    if (memory)
        free(memory);

    /* cleanup any memory associated with the libvmi instance */
    vmi_destroy(vmi);

    return 0;
}
Exemplo n.º 13
0
// Helpful resource for describing the Kernel's representation of virtual memory
// http://www.seas.ucla.edu/~uentao/spring15/CS33_1A_Week10.1.pdf
// More helpful stuff
// http://lxr.free-electrons.com/source/include/linux/sched.h#L1378
// http://lxr.free-electrons.com/source/include/linux/mm_types.h#L390
// keep following mm_types -> fs -> path -> dcache
addr_t walk_vmmap_for_lib(vmi_instance_t vmi, addr_t proc, char* libname) {
	// returns base address of first mmap'd occurrence of library
	// local vars
	addr_t mm;
	addr_t mmap;
	addr_t vm_area_st_itr;
	addr_t file;
	addr_t path;
	addr_t dentry;
	addr_t iname;
	addr_t vm_start;
	char filename[32];

	// walk the structs TODO: check each of these dereferences for errors and fail nicely
	// task_struct->mm->mmap->vm_next->vm_next->vm_next->...->vm_file->path
	vmi_read_64_va(vmi, proc + mm_offset, 0, &mm); // read address of mm
	//printf("mm is at 0x%llx\n",mm);
	vmi_read_64_va(vmi, mm + mmap_offset, 0, &mmap); // read address of first mmap in list
	//printf("mmap is at 0x%llx\n",mmap);
	vm_area_st_itr = mmap; // 
	while (vm_area_st_itr != 0) { // iterate over vm_area_structs
		vmi_read_64_va(vmi, vm_area_st_itr + vm_area_file_offset, 0, &file); // get this struct's file pointer
		//printf("file is at 0x%llx\n",file);
		path = file + file_path_offset; // not a pointer, so no need to dereference
		//printf("path is at 0x%llx\n",path);
		vmi_read_64_va(vmi, path + dentry_offset, 0, &dentry); // get dentry
		//printf("dentry is at 0x%llx\n",dentry);
		iname = dentry + iname_offset; // pointer to filename that was loaded into memory here
		//printf("iname is at 0x%llx\n",iname);
		vmi_read_va(vmi, iname, 0, filename, sizeof(filename));
		//printf("filename is %s\n",filename);
		if (strncmp(filename, libname, sizeof(libname)) == 0) { // if we've found the lib
			vmi_read_64_va(vmi, vm_area_st_itr + vm_area_start_offset, 0, &vm_start); // grab address of start of memory-mapped region
			//printf("base address of memory is 0x%llx\n", vm_start);
			return vm_start;
		}

		// go to next
		vmi_read_64_va(vmi, vm_area_st_itr + vm_area_next_offset, 0, &vm_area_st_itr);
	} 
	return 0; // Failure
}
Exemplo n.º 14
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);
    }
Exemplo n.º 15
0
status_t
peparse_get_image_virt(
    vmi_instance_t vmi,
    addr_t base_vaddr,
    vmi_pid_t pid,
    size_t len,
    const uint8_t * const image)
{

    uint32_t nbytes = vmi_read_va(vmi, base_vaddr, pid, (void *)image, len);

    if(nbytes != len) {
        dbprint(VMI_DEBUG_MISC, "--PEPARSE: failed to read PE header\n");
        return VMI_FAILURE;
    }

    if(VMI_SUCCESS != peparse_validate_pe_image(image, len)) {
        dbprint(VMI_DEBUG_MISC, "--PEPARSE: failed to validate PE header(s)\n");
        return VMI_FAILURE;
    }

    return VMI_SUCCESS;
}
Exemplo n.º 16
0
static unicode_string_t *
vmi_read_win_unicode_struct_va(
    vmi_instance_t vmi,
    addr_t vaddr,
    vmi_pid_t pid)
{
    unicode_string_t *us = 0;   // return val
    size_t struct_size = 0;
    size_t read = 0;
    addr_t buffer_va = 0;
    uint16_t buffer_len = 0;

    if (VMI_PM_IA32E == vmi_get_page_mode(vmi)) {   // 64 bit guest
        win64_unicode_string_t us64 = { 0 };
        struct_size = sizeof(us64);
        // read the UNICODE_STRING struct
        read = vmi_read_va(vmi, vaddr, pid, &us64, struct_size);
        if (read != struct_size) {
            dbprint
                ("--%s: failed to read UNICODE_STRING at VA 0x%.16"PRIx64" for pid %d\n",
                 __FUNCTION__, vaddr, pid);
            goto out_error;
        }   // if
        buffer_va = us64.pBuffer;
        buffer_len = us64.length;
    }
    else {
        win32_unicode_string_t us32 = { 0 };
        struct_size = sizeof(us32);
        // read the UNICODE_STRING struct
        read = vmi_read_va(vmi, vaddr, pid, &us32, struct_size);
        if (read != struct_size) {
            dbprint
                ("--%s: failed to read UNICODE_STRING at VA 0x%.16"PRIx64" for pid %d\n",
                 __FUNCTION__, vaddr, pid);
            goto out_error;
        }   // if
        buffer_va = us32.pBuffer;
        buffer_len = us32.length;
    }   // if-else

    // allocate the return value
    us = safe_malloc(sizeof(unicode_string_t));

    us->length = buffer_len;
    us->contents = safe_malloc(sizeof(uint8_t) * (buffer_len + 2));

    read = vmi_read_va(vmi, buffer_va, pid, us->contents, us->length);
    if (read != us->length) {
        dbprint
            ("--%s: failed to read buffer at VA 0x%.16"PRIx64" for pid %d\n",
             __FUNCTION__, buffer_va, pid);
        goto out_error;
    }   // if

    // end with NULL (needed?)
    us->contents[buffer_len] = 0;
    us->contents[buffer_len + 1] = 0;

    us->encoding = "UTF-16";

    return us;

out_error:
    if (us) {
        if (us->contents) {
            free(us->contents);
        }
        free(us);
    }
    return 0;
}
Exemplo n.º 17
0
void injector_int3_cb(vmi_instance_t vmi, vmi_event_t *event) {

    struct injector *injector = event->data;
    addr_t pa = (event->interrupt_event.gfn << 12)
            + event->interrupt_event.offset;

    reg_t cr3;
    vmi_get_vcpureg(vmi, &cr3, CR3, event->vcpu_id);
    vmi_pid_t pid = vmi_dtb_to_pid(vmi, cr3);

    printf("INT3 @ 0x%lx. PID %u\n", pa, pid);

    if (pa == injector->userspace_return) {

        event->interrupt_event.reinject = 0;

        if (pid != injector->target_pid) {
            printf("Userspace return trap hit by another PID, not the target (%u)\n",
                    injector->target_pid);
            vmi_write_8_pa(vmi, pa, &injector->userspace_return_backup);
            vmi_step_event(vmi, event, event->vcpu_id, 1, reset_return_trap);
            return;
        }

        injector->target_pid = pid;
        injector->target_rip = pa;
        injector->backup = injector->userspace_return_backup;
        injector->userspace_return = 0;

        hijack_thread(injector, vmi, event->vcpu_id, pid);

/*
                injector->ss_enabled = 1;
                memset(&injector->ss_event, 0, sizeof(vmi_event_t));
                injector->ss_event.type = VMI_EVENT_SINGLESTEP;
                injector->ss_event.callback = ss_callback;
                injector->ss_event.data = injector;
                SET_VCPU_SINGLESTEP(injector->ss_event.ss_event,
                        event->vcpu_id);
                vmi_register_event(vmi, &injector->ss_event);
*/


        vmi_clear_event(vmi, &injector->cr3_event);
        injector->mm_count++;
        return;
    }

    if (pa == injector->target_rip) {

        event->interrupt_event.reinject = 0;

        if (pid != injector->target_pid) {
            printf("Return trap hit by another PID, not the target (%u)\n",
                    injector->target_pid);
            vmi_write_8_pa(vmi, pa, &injector->backup);
            vmi_step_event(vmi, event, event->vcpu_id, 1, reset_return_trap);
            return;
        }

        reg_t rax;
        vmi_get_vcpureg(vmi, &rax, RAX, event->vcpu_id);
        vmi_pid_t pid = vmi_dtb_to_pid(vmi, cr3);

        printf("RAX: 0x%lx\n", rax);

        printf("Restoring RSP to 0x%lx\n", injector->saved_rsp);
        printf("Restoring RAX to 0x%lx\n", injector->saved_rax);
        printf("Restoring RCX to 0x%lx\n", injector->saved_rcx);
        printf("Restoring RDX to 0x%lx\n", injector->saved_rdx);
        printf("Restoring R8 to 0x%lx\n", injector->saved_r8);
        printf("Restoring R9 to 0x%lx\n", injector->saved_r9);

        vmi_set_vcpureg(vmi, injector->saved_rsp, RSP, event->vcpu_id);
        vmi_set_vcpureg(vmi, injector->saved_rax, RAX, event->vcpu_id);
        vmi_set_vcpureg(vmi, injector->saved_rcx, RCX, event->vcpu_id);
        vmi_set_vcpureg(vmi, injector->saved_rdx, RDX, event->vcpu_id);
        vmi_set_vcpureg(vmi, injector->saved_r8, R8, event->vcpu_id);
        vmi_set_vcpureg(vmi, injector->saved_r9, R9, event->vcpu_id);

        if (rax) {
            printf("-- CreateProcessA SUCCESS --\n");

            if (PM2BIT(injector->pm) == BIT32) {
                struct process_information_32 pip;
                vmi_read_va(vmi, injector->process_info, pid, &pip,
                        sizeof(struct process_information_32));
                printf("\tProcess handle: 0x%x. Thread handle: 0x%x\n",
                        pip.hProcess, pip.hThread);
                printf("\tPID: %u. TID: %u\n", pip.dwProcessId, pip.dwThreadId);

                injector->pid = pip.dwProcessId;
                injector->tid = pip.dwThreadId;
                injector->hProc = pip.hProcess;
                injector->hThr = pip.hThread;

            } else {
                struct process_information_64 pip;
                vmi_read_va(vmi, injector->process_info, pid, &pip,
                        sizeof(struct process_information_64));
                printf("\tProcess handle: 0x%lx. Thread handle: 0x%lx\n",
                        pip.hProcess, pip.hThread);
                printf("\tPID: %u. TID: %u\n", pip.dwProcessId, pip.dwThreadId);

                injector->pid = pip.dwProcessId;
                injector->tid = pip.dwThreadId;
                injector->hProc = pip.hProcess;
                injector->hThr = pip.hThread;

            }

            if (injector->pid && injector->tid) {
                injector->ret = rax;

                injector->cr3_event.callback = waitfor_cr3_callback;
                injector->cr3_event.reg_event.equal = vmi_pid_to_dtb(vmi,
                        injector->pid);
                injector->cr3_event.data = injector;
                vmi_register_event(vmi, &injector->cr3_event);
                printf("\tInjected process CR3: 0x%lx\n",
                        injector->cr3_event.reg_event.equal);
            }
        } else {
            injector->clone->interrupted = 1;
        }

        vmi_write_8_pa(vmi, pa, &injector->backup);
        vmi_clear_event(vmi, event);

    } else {
        event->interrupt_event.reinject = 1;
    }
}
Exemplo n.º 18
0
status_t
peparse_get_export_table(
    vmi_instance_t vmi,
    addr_t base_vaddr,
    vmi_pid_t pid,
    struct export_table *et,
    addr_t *export_table_rva,
    size_t *export_table_size)
{
    // Note: this function assumes a "normal" PE where all the headers are in
    // the first page of the PE and the field DosHeader.OffsetToPE points to
    // an address in the first page.

    addr_t export_header_rva = 0;
    addr_t export_header_va = 0;
    size_t export_header_size = 0;
    size_t nbytes = 0;

#define MAX_HEADER_BYTES 1024   // keep under 1 page
    uint8_t image[MAX_HEADER_BYTES];

    if(VMI_FAILURE == peparse_get_image_virt(vmi, base_vaddr, pid, MAX_HEADER_BYTES, image)) {
        return VMI_FAILURE;
    }

    void *optional_header = NULL;
    uint16_t magic = 0;

    peparse_assign_headers(image, NULL, NULL, &magic, &optional_header, NULL, NULL);
    export_header_rva = peparse_get_idd_rva(IMAGE_DIRECTORY_ENTRY_EXPORT, &magic, optional_header, NULL, NULL);
    export_header_size = peparse_get_idd_size(IMAGE_DIRECTORY_ENTRY_EXPORT, &magic, optional_header, NULL, NULL);

    if(export_table_rva) {
        *export_table_rva=export_header_rva;
    }

    if(export_table_size) {
        *export_table_size=export_header_size;
    }

    /* Find & read the export header; assume a different page than the headers */
    export_header_va = base_vaddr + export_header_rva;

    dbprint
        (VMI_DEBUG_MISC, "--PEParse: found export table at [VA] 0x%.16"PRIx64" = 0x%.16"PRIx64" + 0x%"PRIx64"\n",
         export_header_va, ((windows_instance_t)vmi->os_data)->ntoskrnl_va,
         export_header_rva);

    nbytes = vmi_read_va(vmi, export_header_va, pid, et, sizeof(*et));
    if (nbytes != sizeof(struct export_table)) {
        dbprint(VMI_DEBUG_MISC, "--PEParse: failed to map export header\n");
        return VMI_FAILURE;
    }

    /* sanity check */
    if (et->export_flags || !et->name) {
        dbprint(VMI_DEBUG_MISC, "--PEParse: bad export directory table\n");
        return VMI_FAILURE;
    }

    return VMI_SUCCESS;
}