Ejemplo 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;
}
Ejemplo n.º 2
0
///////////////////////////////////////////////////////////
// Easy write to virtual memory
static status_t vmi_write_X_va (vmi_instance_t vmi, addr_t vaddr, int pid, void *value, int size)
{
    size_t len_write = vmi_write_va(vmi, vaddr, pid, value, size);
    if (len_write == size){
        return VMI_SUCCESS;
    }
    else{
        return VMI_FAILURE;
    }
}
Ejemplo 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;
}
Ejemplo n.º 4
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;
}
Ejemplo n.º 5
0
void hijack_thread(struct injector *injector, vmi_instance_t vmi,
        unsigned int vcpu, vmi_pid_t pid) {

    printf("Ready to hijack thread of PID %u on vCPU %u!\n", pid, vcpu);

    addr_t cpa = sym2va(vmi, pid, "kernel32.dll", "CreateProcessA");

    printf("CPA @ 0x%lx\n", cpa);

    reg_t fsgs, rbp, rsp, rip, rcx, rdx, rax, r8, r9;
    addr_t stack_base, stack_limit;

    vmi_get_vcpureg(vmi, &rsp, RSP, vcpu);
    vmi_get_vcpureg(vmi, &rip, RIP, vcpu);
    vmi_get_vcpureg(vmi, &rax, RAX, vcpu);
    vmi_get_vcpureg(vmi, &rcx, RCX, vcpu);
    vmi_get_vcpureg(vmi, &rdx, RDX, vcpu);
    vmi_get_vcpureg(vmi, &r8, R8, vcpu);
    vmi_get_vcpureg(vmi, &r9, R9, vcpu);

    if (injector->pm == VMI_PM_LEGACY || injector->pm == VMI_PM_PAE) {
        vmi_get_vcpureg(vmi, &fsgs, FS_BASE, vcpu);
        vmi_get_vcpureg(vmi, &rbp, RBP, vcpu);
        printf("FS: 0x%lx RBP: 0x%lx", fsgs, rbp);
        vmi_read_addr_va(vmi, fsgs + 0x4, pid, &stack_base);
        vmi_read_addr_va(vmi, fsgs + 0x8, pid, &stack_limit);
    } else {
        vmi_get_vcpureg(vmi, &fsgs, GS_BASE, vcpu);
        printf("GS: 0x%lx ", fsgs);
        vmi_read_addr_va(vmi, fsgs + 0x8, pid, &stack_base);
        vmi_read_addr_va(vmi, fsgs + 0x10, pid, &stack_limit);
    }

    printf("RSP: 0x%lx. RIP: 0x%lx. RCX: 0x%lx\n", rsp, rip, rcx);
    printf("Stack base: 0x%lx. Limit: 0x%lx\n", stack_base, stack_limit);

    //Push input arguments on the stack
    //CreateProcess(NULL, TARGETPROC,
    //                 NULL, NULL, 0, CREATE_SUSPENDED, NULL, NULL, &si, pi))

    uint64_t nul64 = 0;
    uint32_t nul32 = 0;
    uint8_t nul8 = 0;
    size_t len = strlen(injector->target_proc);
    addr_t addr = rsp;
    injector->saved_rsp = rsp;
    injector->saved_rip = rip;
    injector->saved_rax = rax;
    injector->saved_rdx = rdx;
    injector->saved_rcx = rcx;
    injector->saved_r8 = r8;
    injector->saved_r9 = r9;

    if (injector->pm == VMI_PM_LEGACY || injector->pm == VMI_PM_PAE) {

        addr -= 0x4; // the stack has to be alligned to 0x4
                     // and we need a bit of extra buffer before the string for \0
        // we just going to null out that extra space fully
        vmi_write_32_va(vmi, addr, pid, &nul32);

        // this string has to be aligned as well!
        addr -= len + 0x4 - (len % 0x4);
        addr_t str_addr = addr;
        vmi_write_va(vmi, addr, pid, (void*) injector->target_proc, len);
        // add null termination
        vmi_write_8_va(vmi, addr + len, pid, &nul8);
        printf("%s @ 0x%lx.\n", injector->target_proc, str_addr);

        //struct startup_info_32 si = {.wShowWindow = SW_SHOWDEFAULT };
        struct startup_info_32 si;
        memset(&si, 0, sizeof(struct startup_info_32));
        struct process_information_32 pi;
        memset(&pi, 0, sizeof(struct process_information_32));

        addr -= sizeof(struct process_information_32);
        injector->process_info = addr;
        vmi_write_va(vmi, addr, pid, &pi,
                sizeof(struct process_information_32));
        printf("pip @ 0x%lx\n", addr);

        addr -= sizeof(struct startup_info_32);
        addr_t sip = addr;
        vmi_write_va(vmi, addr, pid, &si, sizeof(struct startup_info_32));
        printf("sip @ 0x%lx\n", addr);

        //p10
        addr -= 0x4;
        vmi_write_32_va(vmi, addr, pid, (uint32_t *) &injector->process_info);
        //p9
        addr -= 0x4;
        vmi_write_32_va(vmi, addr, pid, (uint32_t *) &sip);
        //p8
        addr -= 0x4;
        vmi_write_32_va(vmi, addr, pid, &nul32);
        //p7
        addr -= 0x4;
        vmi_write_32_va(vmi, addr, pid, &nul32);
        //p6
        addr -= 0x4;
        vmi_write_32_va(vmi, addr, pid, &nul32);
        //p5
        addr -= 0x4;
        vmi_write_32_va(vmi, addr, pid, &nul32);
        //p4
        addr -= 0x4;
        vmi_write_32_va(vmi, addr, pid, &nul32);
        //p3
        addr -= 0x4;
        vmi_write_32_va(vmi, addr, pid, &nul32);
        //p2
        addr -= 0x4;
        vmi_write_32_va(vmi, addr, pid, (uint32_t *) &str_addr);
        //p1
        addr -= 0x4;
        vmi_write_32_va(vmi, addr, pid, &nul32);

        // save the return address (RIP)
        addr -= 0x4;
        vmi_write_32_va(vmi, addr, pid, (uint32_t *) &rip);

    } else {

        addr -= 0x8; // the stack has to be alligned to 0x8
                     // and we need a bit of extra buffer before the string for \0

        // we just going to null out that extra space fully
        vmi_write_64_va(vmi, addr, pid, &nul64);

        // this string has to be aligned as well!
        addr -= len + 0x8 - (len % 0x8);
        addr_t str_addr = addr;
        vmi_write_va(vmi, addr, pid, (void*) injector->target_proc, len);
        // add null termination
        vmi_write_8_va(vmi, addr + len, pid, &nul8);
        printf("%s @ 0x%lx.\n", injector->target_proc, str_addr);

        struct startup_info_64 si;
        memset(&si, 0, sizeof(struct startup_info_64));
        struct process_information_64 pi;
        memset(&pi, 0, sizeof(struct process_information_64));

        addr -= sizeof(struct process_information_64);
        injector->process_info = addr;
        vmi_write_va(vmi, addr, pid, &pi,
                sizeof(struct process_information_64));
        printf("pip @ 0x%lx\n", addr);

        addr -= sizeof(struct startup_info_64);
        addr_t sip = addr;
        vmi_write_va(vmi, addr, pid, &si, sizeof(struct startup_info_64));
        printf("sip @ 0x%lx\n", addr);

        //http://www.codemachine.com/presentations/GES2010.TRoy.Slides.pdf
        //
        //First 4 parameters to functions are always passed in registers
        //P1=rcx, P2=rdx, P3=r8, P4=r9
        //5th parameter onwards (if any) passed via the stack

        //p10
        addr -= 0x8;
        vmi_write_64_va(vmi, addr, pid, &injector->process_info);
        //p9
        addr -= 0x8;
        vmi_write_64_va(vmi, addr, pid, &sip);
        //p8
        addr -= 0x8;
        vmi_write_64_va(vmi, addr, pid, &nul64);
        //p7
        addr -= 0x8;
        vmi_write_64_va(vmi, addr, pid, &nul64);
        //p6
        addr -= 0x8;
        vmi_write_64_va(vmi, addr, pid, &nul64);
        //p5
        addr -= 0x8;
        vmi_write_64_va(vmi, addr, pid, &nul64);

        // allocate 0x20 "homing space"
        addr -= 0x8;
        vmi_write_64_va(vmi, addr, pid, &nul64);
        addr -= 0x8;
        vmi_write_64_va(vmi, addr, pid, &nul64);
        addr -= 0x8;
        vmi_write_64_va(vmi, addr, pid, &nul64);
        addr -= 0x8;
        vmi_write_64_va(vmi, addr, pid, &nul64);

        //p1
        vmi_set_vcpureg(vmi, 0, RCX, vcpu);
        //p2
        vmi_set_vcpureg(vmi, str_addr, RDX, vcpu);
        //p3
        vmi_set_vcpureg(vmi, 0, R8, vcpu);
        //p4
        vmi_set_vcpureg(vmi, 0, R9, vcpu);

        // save the return address (RIP)
        addr -= 0x8;
        vmi_write_64_va(vmi, addr, pid, &rip);
    }

    printf("Return address @ 0x%lx -> 0x%lx. Setting RSP: 0x%lx.\n", addr, rip,
            addr);

    // Grow the stack and switch execution
    vmi_set_vcpureg(vmi, addr, RSP, vcpu);
    vmi_set_vcpureg(vmi, cpa, RIP, vcpu);

    printf("Done with hijack routine\n");
}
Ejemplo n.º 6
0
size_t vmi_write_ksym (vmi_instance_t vmi, char *sym, void *buf, size_t count)
{
    addr_t vaddr = vmi_translate_ksym2v(vmi, sym);
    return vmi_write_va(vmi, vaddr, 0, buf, count);
}