Exemplo n.º 1
0
void
offline_instru_t::insert_save_pc(void *drcontext, instrlist_t *ilist, instr_t *where,
                                 reg_id_t reg_ptr, reg_id_t scratch, int adjust,
                                 uint64_t value)
{
    int disp = adjust;
#ifdef X64
    instrlist_insert_mov_immed_ptrsz(drcontext, (ptr_int_t) value,
                                     opnd_create_reg(scratch),
                                     ilist, where, NULL, NULL);
    MINSERT(ilist, where,
            XINST_CREATE_store(drcontext, OPND_CREATE_MEMPTR(reg_ptr, disp),
                               opnd_create_reg(scratch)));
#else
    instrlist_insert_mov_immed_ptrsz(drcontext, (int)value,
                                     opnd_create_reg(scratch),
                                     ilist, where, NULL, NULL);
    MINSERT(ilist, where,
            XINST_CREATE_store(drcontext, OPND_CREATE_MEMPTR(reg_ptr, disp),
                               opnd_create_reg(scratch)));
    instrlist_insert_mov_immed_ptrsz(drcontext, (int)(value >> 32),
                                     opnd_create_reg(scratch),
                                     ilist, where, NULL, NULL);
    MINSERT(ilist, where,
            XINST_CREATE_store(drcontext, OPND_CREATE_MEMPTR(reg_ptr, disp + 4),
                               opnd_create_reg(scratch)));
#endif
}
Exemplo n.º 2
0
static void
test_modrm16_helper(void *dc, reg_id_t base, reg_id_t scale, uint disp, uint len)
{
    instr_t *instr;
    /* Avoid REG_EAX b/c of the special 0xa0-0xa3 opcodes */
    instr = INSTR_CREATE_mov_ld(dc, opnd_create_reg(REG_EBX),
                                opnd_create_base_disp(base, scale,
                                                      (scale == REG_NULL ? 0 : 1),
                                                      /* we need OPSZ_4_short2 to match
                                                       * instr_same on decode! */
                                                      disp, OPSZ_4_short2));
    if (base == REG_NULL && scale == REG_NULL) {
        /* Don't need _ex unless abs addr, in which case should get 32-bit
         * disp!  Test both sides. */
        test_instr_encode(dc, instr, len + 1/*32-bit disp but no prefix*/);
        instr = INSTR_CREATE_mov_ld(dc, opnd_create_reg(REG_EBX),
                                    opnd_create_base_disp_ex(base, scale,
                                                             (scale == REG_NULL ? 0 : 1),
                                                             /* we need OPSZ_4_short2 to match
                                                              * instr_same on decode! */
                                                             disp, OPSZ_4_short2,
                                                             false, false, true));
        test_instr_encode(dc, instr, len);
    } else {
        test_instr_encode(dc, instr, len);
    }
}
Exemplo n.º 3
0
static void
insert_save_pc(void *drcontext, instrlist_t *ilist, instr_t *where, reg_id_t base,
               reg_id_t scratch, app_pc pc)
{
    instrlist_insert_mov_immed_ptrsz(drcontext, (ptr_int_t)pc, opnd_create_reg(scratch),
                                     ilist, where, NULL, NULL);
    MINSERT(ilist, where,
            XINST_CREATE_store(drcontext,
                               OPND_CREATE_MEMPTR(base, offsetof(mem_ref_t, addr)),
                               opnd_create_reg(scratch)));
}
Exemplo n.º 4
0
void
cfi_call_instrumentation_snapahot(void *dcontext, instrlist_t *ilist, instr_t *where, void *callee)
{
    uint dstack_offs = 0, pad = 0;

    unsigned int eflags_offs;

    CFI_ASSERT(dcontext != NULL, "cfi_call_instrumentation_snapahot: dcontext cannot be NULL");

    instr_t *next_snapshot = INSTR_CREATE_label(dcontext);
    PRE(ilist, where, INSTR_CREATE_pushf(dcontext));
    dstack_offs += XSP_SZ;
    eflags_offs = dstack_offs;

    PRE(ilist, where, INSTR_CREATE_push(dcontext, opnd_create_reg(DR_REG_RDI)));
    dstack_offs += XSP_SZ;

    PRE(ilist, where, INSTR_CREATE_mov_imm(dcontext, opnd_create_reg(DR_REG_RDI), OPND_CREATE_INT64(&flag_memory_snapshot)));
    PRE(ilist, where, INSTR_CREATE_mov_ld(dcontext, opnd_create_reg(DR_REG_RDI), opnd_create_base_disp(DR_REG_RDI, DR_REG_NULL, 0, 0, OPSZ_PTR)));
    PRE(ilist, where, INSTR_CREATE_cmp(dcontext, opnd_create_reg(DR_REG_RDI), OPND_CREATE_INT8(0x0)));
    PRE(ilist, where, INSTR_CREATE_jcc(dcontext, OP_je, opnd_create_instr(next_snapshot)));

    PRE(ilist, where, INSTR_CREATE_push(dcontext,
                          opnd_create_base_disp(DR_REG_RSP, DR_REG_NULL, 0,
                          dstack_offs - eflags_offs, OPSZ_STACK)));

    PRE(ilist, where, INSTR_CREATE_and(dcontext,
                         opnd_create_base_disp(DR_REG_RSP, DR_REG_NULL, 0, 0,
                                               OPSZ_STACK),
                         OPND_CREATE_INT32(~(EFLAGS_NON_SYSTEM | EFLAGS_IF))));

    PRE(ilist, where, INSTR_CREATE_popf(dcontext));

    instrlist_set_our_mangling(ilist, true);
    cfi_insert_meta_native_call_vargs(dcontext, ilist, where, true/*clean*/, callee);
    instrlist_set_our_mangling(ilist, false);

    cfi_insert_native_call(dcontext, ilist, where, callee /*, opnd_create_reg(DR_REG_RAX)*/);

    PRE(ilist, where, next_snapshot);
    PRE(ilist, where, INSTR_CREATE_pop(dcontext, opnd_create_reg(DR_REG_RDI)));
    PRE(ilist, where, INSTR_CREATE_popf(dcontext));



   /* dstack_offs = cfi_prepare_for_native_call(dcontext, ilist, where);

     instrlist_set_our_mangling(ilist, true);
     cfi_insert_meta_native_call_vargs(dcontext, ilist, where, true*//*clean*//*, callee);
     instrlist_set_our_mangling(ilist, false);

     cfi_cleanup_after_native_call(dcontext, ilist, where);*/
}
Exemplo n.º 5
0
static void
insert_save_size(void *drcontext, instrlist_t *ilist, instr_t *where, reg_id_t base,
                 reg_id_t scratch, ushort size)
{
    scratch = reg_resize_to_opsz(scratch, OPSZ_2);
    MINSERT(ilist, where,
            XINST_CREATE_load_int(drcontext, opnd_create_reg(scratch),
                                  OPND_CREATE_INT16(size)));
    MINSERT(ilist, where,
            XINST_CREATE_store_2bytes(drcontext,
                                      OPND_CREATE_MEM16(base, offsetof(mem_ref_t, size)),
                                      opnd_create_reg(scratch)));
}
Exemplo n.º 6
0
static dr_emit_flags_t
event_bb_insert(void *drcontext, void *tag, instrlist_t *bb, instr_t *inst,
                bool for_trace, bool translating, void *user_data)
{
    static int freq;
    reg_id_t reg1 = IF_X86_ELSE(DR_REG_XAX, DR_REG_R0);
    reg_id_t reg2 = IF_X86_ELSE(DR_REG_XCX, DR_REG_R1);

    CHECK(drmgr_is_first_instr(drcontext, instrlist_first_app(bb)), "first incorrect");
    CHECK(!drmgr_is_first_instr(drcontext, instrlist_last(bb)) ||
          instrlist_first_app(bb) == instrlist_last(bb), "first incorrect");
    CHECK(drmgr_is_last_instr(drcontext, instrlist_last(bb)), "last incorrect");
    CHECK(!drmgr_is_last_instr(drcontext, instrlist_first_app(bb)) ||
          instrlist_first_app(bb) == instrlist_last(bb), "last incorrect");

    /* hack to instrument every nth bb.  assumes DR serializes bb events. */
    freq++;
    if (freq % 100 == 0 && inst == (instr_t*)user_data/*first instr*/) {
        /* test read from cache */
        dr_save_reg(drcontext, bb, inst, reg1, SPILL_SLOT_1);
        drmgr_insert_read_tls_field(drcontext, tls_idx, bb, inst, reg1);
        dr_insert_clean_call(drcontext, bb, inst, (void *)check_tls_from_cache,
                             false, 1, opnd_create_reg(reg1));
        drmgr_insert_read_cls_field(drcontext, cls_idx, bb, inst, reg1);
        dr_insert_clean_call(drcontext, bb, inst, (void *)check_cls_from_cache,
                             false, 1, opnd_create_reg(reg1));
        dr_restore_reg(drcontext, bb, inst, reg1, SPILL_SLOT_1);
    }
    if (freq % 300 == 0 && inst == (instr_t*)user_data/*first instr*/) {
        instr_t *first, *second;
        /* test write from cache */
        dr_save_reg(drcontext, bb, inst, reg1, SPILL_SLOT_1);
        dr_save_reg(drcontext, bb, inst, reg2, SPILL_SLOT_2);
        instrlist_insert_mov_immed_ptrsz(drcontext,
                                         (ptr_int_t)MAGIC_NUMBER_FROM_CACHE,
                                         opnd_create_reg(reg1),
                                         bb, inst, &first, &second);
        instr_set_meta(first);
        if (second != NULL)
            instr_set_meta(second);
        drmgr_insert_write_tls_field(drcontext, tls_idx, bb, inst, reg1, reg2);
        dr_insert_clean_call(drcontext, bb, inst, (void *)check_tls_write_from_cache,
                             false, 0);
        drmgr_insert_write_cls_field(drcontext, cls_idx, bb, inst, reg1, reg2);
        dr_insert_clean_call(drcontext, bb, inst, (void *)check_cls_write_from_cache,
                             false, 0);
        dr_restore_reg(drcontext, bb, inst, reg2, SPILL_SLOT_2);
        dr_restore_reg(drcontext, bb, inst, reg1, SPILL_SLOT_1);
    }
    return DR_EMIT_DEFAULT;
}
Exemplo n.º 7
0
/* Insert arithmetic flags restore code with more control.
 * For x86:
 * - skip %eax restore if !restore_reg
 * - restore %eax from reg if reg is not DR_REG_NULL
 * - restore %eax from slot otherwise
 * For ARM:
 * - restores flags from reg
 * - restores reg to slot, unless !restore_reg.
 * Routine merge_prev_drx_aflags_switch looks for labels inserted by
 * drx_restore_arith_flags, so changes to this routine may affect
 * merge_prev_drx_aflags_switch.
 */
static void
drx_restore_arith_flags(void *drcontext, instrlist_t *ilist, instr_t *where,
                        bool restore_reg, bool restore_oflag,
                        dr_spill_slot_t slot, reg_id_t reg)
{
    instr_t *instr;
    ilist_insert_note_label(drcontext, ilist, where,
                            NOTE_VAL(DRX_NOTE_AFLAGS_RESTORE_BEGIN));
#ifdef X86
    if (restore_oflag) {
        /* add 0x7f, %al */
        instr = INSTR_CREATE_add(drcontext, opnd_create_reg(DR_REG_AL),
                                 OPND_CREATE_INT8(0x7f));
        MINSERT(ilist, where, instr);
    }
    /* sahf */
    instr = INSTR_CREATE_sahf(drcontext);
    instr_set_note(instr, NOTE_VAL(DRX_NOTE_AFLAGS_RESTORE_SAHF));
    MINSERT(ilist, where, instr);
    /* restore eax if necessary */
    if (restore_reg) {
        if (reg != DR_REG_NULL) {
            ASSERT(reg >= DR_REG_START_GPR && reg <= DR_REG_STOP_GPR &&
                   reg != DR_REG_XAX, "wrong dead reg");
            MINSERT(ilist, where,
                    INSTR_CREATE_mov_st(drcontext,
                                        opnd_create_reg(DR_REG_XAX),
                                        opnd_create_reg(reg)));
        } else {
            ASSERT(slot >= SPILL_SLOT_1 && slot <= SPILL_SLOT_MAX,
                   "wrong spill slot");
            dr_restore_reg(drcontext, ilist, where, DR_REG_XAX, slot);
        }
    }
#elif defined(ARM)
    ASSERT(reg >= DR_REG_START_GPR && reg <= DR_REG_STOP_GPR, "reg must be a GPR");
    instr = INSTR_CREATE_mrs(drcontext, opnd_create_reg(reg),
                             opnd_create_reg(DR_REG_CPSR));
    instr_set_note(instr, NOTE_VAL(DRX_NOTE_AFLAGS_RESTORE_SAHF));
    MINSERT(ilist, where, instr);
    if (restore_reg) {
        ASSERT(slot >= SPILL_SLOT_1 && slot <= SPILL_SLOT_MAX,
               "wrong spill slot");
        dr_restore_reg(drcontext, ilist, where, reg, slot);
    }
#endif
    ilist_insert_note_label(drcontext, ilist, where,
                            NOTE_VAL(DRX_NOTE_AFLAGS_RESTORE_END));
}
Exemplo n.º 8
0
dr_emit_flags_t
memdump_bb_instrumentation(void *drcontext, void *tag, instrlist_t *bb,
instr_t *instr, bool for_trace, bool translating,
void *user_data)
{

	reg_id_t reg1 = DR_REG_XAX;
	reg_id_t reg2 = DR_REG_XBX;
	int i = 0;

	if(filter_bb_level_from_list(app_pc_head, instr)){

		dr_save_reg(drcontext, bb, instr, reg1, SPILL_SLOT_1);
		dr_save_reg(drcontext, bb, instr, reg2, SPILL_SLOT_2);
		
		dr_mutex_lock(mutex);
		DEBUG_PRINT("instrumenting %x pc\n", instr_get_app_pc(instr));

		instr_clones[instr_clone_amount] = instr_clone(drcontext, instr);

		for (i = 0; i < instr_num_srcs(instr); i++){
			if (opnd_is_memory_reference(instr_get_src(instr, i))) {
				drutil_insert_get_mem_addr(drcontext, bb, instr, instr_get_src(instr,i), reg1, reg2);
				dr_insert_clean_call(drcontext, bb, instr, clean_call_mem_information, false, 3, 
					OPND_CREATE_INTPTR(instr_clones[instr_clone_amount]), opnd_create_reg(reg1), OPND_CREATE_INTPTR(false));
			}
		}
		for (i = 0; i < instr_num_dsts(instr); i++){
			if (opnd_is_memory_reference(instr_get_dst(instr, i))) {
				drutil_insert_get_mem_addr(drcontext, bb, instr, instr_get_dst(instr, i), reg1, reg2);
				dr_insert_clean_call(drcontext, bb, instr, clean_call_mem_information, false, 3, 
					OPND_CREATE_INTPTR(instr_clones[instr_clone_amount]), opnd_create_reg(reg1), OPND_CREATE_INTPTR(true));
			}
		}
		

		instr_clone_amount++;

		dr_mutex_unlock(mutex);

		dr_restore_reg(drcontext, bb, instr, reg1, SPILL_SLOT_1);
		dr_restore_reg(drcontext, bb, instr, reg2, SPILL_SLOT_2);


	}

	return DR_EMIT_DEFAULT;
}
Exemplo n.º 9
0
static void
test_instr_as_immed(void)
{
    void *drcontext = dr_get_current_drcontext();
    instrlist_t *ilist = instrlist_create(drcontext);
    byte *pc;
    instr_t *ins0, *ins1, *ins2;
    opnd_t opnd;
    byte *highmem = PREFERRED_ADDR;
    pc = dr_raw_mem_alloc(PAGE_SIZE, DR_MEMPROT_READ|DR_MEMPROT_WRITE|
                               DR_MEMPROT_EXEC, highmem);
    ASSERT(pc == highmem);

    /* Test push_imm of instr */
    ins0 = INSTR_CREATE_nop(drcontext);
    instrlist_append(ilist, ins0);
    instrlist_insert_push_instr_addr(drcontext, ins0, highmem,
                                     ilist, NULL, &ins1, &ins2);
    ASSERT(ins2 != NULL);
    instrlist_append(ilist, INSTR_CREATE_pop
                     (drcontext, opnd_create_reg(DR_REG_RAX)));
    instrlist_append(ilist, INSTR_CREATE_ret(drcontext));
    pc = instrlist_encode(drcontext, ilist, highmem, true);
    instrlist_clear(drcontext, ilist);
    ASSERT(pc < highmem + PAGE_SIZE);
    pc = ((byte* (*)(void))highmem)();
    ASSERT(pc == highmem);

    /* Test mov_imm of instr */
    ins0 = INSTR_CREATE_nop(drcontext);
    instrlist_append(ilist, ins0);
    /* Beyond TOS, but a convenient mem dest */
    opnd = opnd_create_base_disp(DR_REG_RSP, DR_REG_NULL, 0, -8, OPSZ_8);
    instrlist_insert_mov_instr_addr(drcontext, ins0, highmem, opnd,
                                    ilist, NULL, &ins1, &ins2);
    ASSERT(ins2 != NULL);
    instrlist_append(ilist, INSTR_CREATE_mov_ld
                     (drcontext, opnd_create_reg(DR_REG_RAX), opnd));
    instrlist_append(ilist, INSTR_CREATE_ret(drcontext));
    pc = instrlist_encode(drcontext, ilist, highmem, true);
    instrlist_clear(drcontext, ilist);
    ASSERT(pc < highmem + PAGE_SIZE);
    pc = ((byte* (*)(void))highmem)();
    ASSERT(pc == highmem);

    instrlist_clear_and_destroy(drcontext, ilist);
    dr_raw_mem_free(highmem, PAGE_SIZE);
}
Exemplo n.º 10
0
static void
test_x86_mode(void *dc)
{
    byte *pc, *end;
    instr_t *instr;

    /* create instr that looks different in x86 vs x64 */
    instr = INSTR_CREATE_add(dc, opnd_create_reg(REG_RAX), OPND_CREATE_INT32(42));
    end = instr_encode(dc, instr, buf);
    ASSERT(end - buf < BUFFER_SIZE_ELEMENTS(buf));

    /* read back in */
    set_x86_mode(dc, false/*64-bit*/);
    instr_reset(dc, instr);
    pc = decode(dc, buf, instr);
    ASSERT(pc != NULL);
    ASSERT(instr_get_opcode(instr) == OP_add);

    /* now interpret as 32-bit where rex will be an inc */
    set_x86_mode(dc, true/*32-bit*/);
    instr_reset(dc, instr);
    pc = decode(dc, buf, instr);
    ASSERT(pc != NULL);
    ASSERT(instr_get_opcode(instr) == OP_dec);

    instr_free(dc, instr);
    set_x86_mode(dc, false/*64-bit*/);
}
Exemplo n.º 11
0
static
dr_emit_flags_t bb_event(void* drcontext, void *tag, instrlist_t* bb,
                         bool for_trace, bool translating)
{
    instr_t *instr;
    instr_t *next_instr;
    reg_t in_eax = -1;

    for (instr = instrlist_first(bb); instr != NULL; instr = next_instr) {
        next_instr = instr_get_next(instr);
        if (instr_get_opcode(instr) == OP_mov_imm &&
            opnd_get_reg(instr_get_dst(instr, 0)) == REG_EAX)
            in_eax = opnd_get_immed_int(instr_get_src(instr, 0));
        if (instr_is_syscall(instr) &&
            in_eax == SYS_getpid) {
            instr_t *myval = INSTR_CREATE_mov_imm
                (drcontext, opnd_create_reg(REG_EAX), OPND_CREATE_INT32(-7));
            instr_set_translation(myval, instr_get_app_pc(instr));
            instrlist_preinsert(bb, instr, myval);
            instrlist_remove(bb, instr);
            instr_destroy(drcontext, instr);
        }
    }
    return DR_EMIT_DEFAULT;
}
Exemplo n.º 12
0
/*
 * Function that tests a single operand of an instruction to see if
 * it's a memory reference, and if so, adds a call to log_mem.
 */
static void try_mem_opnd(
    void *drcontext, instrlist_t *bb, instr_t *instr, char **loc,
    opnd_t opnd, bool write)
{
    if (!opnd_is_memory_reference(opnd))
        return;

    instr_format_location(instr, loc);

    reg_id_t r0, r1;
    drreg_status_t st;
    st = drreg_reserve_register(drcontext, bb, instr, NULL, &r0);
    DR_ASSERT(st == DRREG_SUCCESS);
    st = drreg_reserve_register(drcontext, bb, instr, NULL, &r1);
    DR_ASSERT(st == DRREG_SUCCESS);

    bool ok = drutil_insert_get_mem_addr(drcontext, bb, instr, opnd, r0, r1);
    DR_ASSERT(ok);

    uint size = drutil_opnd_mem_size_in_bytes(opnd, instr);

    dr_insert_clean_call(
        drcontext, bb, instr, (void *)log_mem, false,
        4, opnd_create_reg(r0), OPND_CREATE_INT32(size),
        OPND_CREATE_INT32(write), OPND_CREATE_INTPTR(*loc));

    st = drreg_unreserve_register(drcontext, bb, instr, r1);
    DR_ASSERT(st == DRREG_SUCCESS);
    st = drreg_unreserve_register(drcontext, bb, instr, r0);
    DR_ASSERT(st == DRREG_SUCCESS);
}
Exemplo n.º 13
0
static void
test_disp_control_helper(void *dc, int disp,
                         bool encode_zero_disp, bool force_full_disp, bool disp16,
                         uint len_expect)
{
    byte *pc;
    uint len;
    instr_t *instr = INSTR_CREATE_mov_ld
        (dc, opnd_create_reg(REG_ECX),
         opnd_create_base_disp_ex(disp16 ? IF_X64_ELSE(REG_EBX, REG_BX) :
                                  REG_XBX, REG_NULL, 0,
                                  disp, OPSZ_4,
                                  encode_zero_disp, force_full_disp, disp16));
    pc = instr_encode(dc, instr, buf);
    len = (int) (pc - (byte *)buf);
#if VERBOSE
    pc = disassemble_with_info(dc, buf, STDOUT, true, true);
#endif
    ASSERT(len == len_expect);
    instr_reset(dc, instr);
    decode(dc, buf, instr);
    ASSERT(instr_num_srcs(instr) == 1 &&
           opnd_is_base_disp(instr_get_src(instr, 0)) &&
           BOOLS_MATCH(encode_zero_disp, 
                       opnd_is_disp_encode_zero(instr_get_src(instr, 0))) &&
           BOOLS_MATCH(force_full_disp,
                       opnd_is_disp_force_full(instr_get_src(instr, 0))) &&
           BOOLS_MATCH(disp16,
                       opnd_is_disp_short_addr(instr_get_src(instr, 0))));
    instr_destroy(dc, instr);
}
Exemplo n.º 14
0
/* code cache to hold the call to "clean_call" and return to DR code cache */
static void
code_cache_init(void)
{
    void         *drcontext;
    instrlist_t  *ilist;
    instr_t      *where;
    byte         *end;

    drcontext  = dr_get_current_drcontext();
    code_cache = dr_nonheap_alloc(PAGE_SIZE,
                                  DR_MEMPROT_READ  |
                                  DR_MEMPROT_WRITE |
                                  DR_MEMPROT_EXEC);
    ilist = instrlist_create(drcontext);
    /* The lean procecure simply performs a clean call, and then jump back */
    /* jump back to the DR's code cache */
    where = INSTR_CREATE_jmp_ind(drcontext, opnd_create_reg(DR_REG_XCX));
    instrlist_meta_append(ilist, where);
    /* clean call */
    dr_insert_clean_call(drcontext, ilist, where, (void *)clean_call_ins_trace, false, 0);
    /* Encodes the instructions into memory and then cleans up. */
    end = instrlist_encode(drcontext, ilist, code_cache, false);
    DR_ASSERT((end - code_cache) < PAGE_SIZE);
    instrlist_clear_and_destroy(drcontext, ilist);
    /* set the memory as just +rx now */
    dr_memory_protect(code_cache, PAGE_SIZE, DR_MEMPROT_READ | DR_MEMPROT_EXEC);
}
Exemplo n.º 15
0
static void
test_x64_abs_addr(void *dc)
{
    /* 48 a1 ef be ad de ef be ad de    mov    0xdeadbeefdeadbeef -> %rax 
     * 48 a3 ef be ad de ef be ad de    mov    %rax -> 0xdeadbeefdeadbeef 
     */
    instr_t *instr;
    opnd_t abs_addr = opnd_create_abs_addr((void*)0xdeadbeefdeadbeef, OPSZ_8);

    /* movabs load */
    instr = INSTR_CREATE_mov_ld(dc, opnd_create_reg(DR_REG_RAX), abs_addr);
    test_instr_encode(dc, instr, 10);  /* REX + op + 8 */

    /* movabs store */
    instr = INSTR_CREATE_mov_st(dc, abs_addr, opnd_create_reg(DR_REG_RAX));
    test_instr_encode(dc, instr, 10);  /* REX + op + 8 */
}
Exemplo n.º 16
0
static void
test_x64_inc(void *dc)
{
    /* i#842: inc/dec should not be encoded as 40-4f in x64 */
    instr_t *instr;

    instr = INSTR_CREATE_inc(dc, opnd_create_reg(REG_EAX));
    test_instr_encode(dc, instr, 2);
}
Exemplo n.º 17
0
static print_base_disp_for_lea(file_t file, opnd_t opnd){

	/* [base + index * scale + disp] */
	dr_fprintf(file, " base - %d %s\n", opnd_get_base(opnd), get_register_name(opnd_get_base(opnd)));
	dr_fprintf(file, " index - %d %s\n", opnd_get_index(opnd), get_register_name(opnd_get_index(opnd)));
	dr_fprintf(file, "reg - %d\n", opnd_is_reg(opnd_create_reg(opnd_get_index(opnd))));
	dr_fprintf(file, " scale - %d\n", opnd_get_scale(opnd));
	dr_fprintf(file, " disp - %d\n", opnd_get_disp(opnd));

}
Exemplo n.º 18
0
static void
insert_update_buf_ptr(void *drcontext, instrlist_t *ilist, instr_t *where,
                      reg_id_t reg_ptr, int adjust)
{
    MINSERT(
        ilist, where,
        XINST_CREATE_add(drcontext, opnd_create_reg(reg_ptr), OPND_CREATE_INT16(adjust)));
    dr_insert_write_raw_tls(drcontext, ilist, where, tls_seg,
                            tls_offs + MEMTRACE_TLS_OFFS_BUF_PTR, reg_ptr);
}
Exemplo n.º 19
0
/* Insert arithmetic flags saving code with more control.
 * For x86:
 * - skip %eax save if !save_reg
 * - save %eax to reg if reg is not DR_REG_NULL,
 * - save %eax to slot otherwise
 * For ARM:
 * - saves flags to reg
 * - saves reg first to slot, unless !save_reg.
 */
static void
drx_save_arith_flags(void *drcontext, instrlist_t *ilist, instr_t *where,
                     bool save_reg, bool save_oflag,
                     dr_spill_slot_t slot, reg_id_t reg)
{
#ifdef X86
    instr_t *instr;
    /* save %eax if necessary */
    if (save_reg) {
        if (reg != DR_REG_NULL) {
            ASSERT(reg >= DR_REG_START_GPR && reg <= DR_REG_STOP_GPR &&
                   reg != DR_REG_XAX, "wrong dead reg");
            MINSERT(ilist, where,
                    INSTR_CREATE_mov_st(drcontext,
                                        opnd_create_reg(reg),
                                        opnd_create_reg(DR_REG_XAX)));
        } else {
            ASSERT(slot >= SPILL_SLOT_1 && slot <= SPILL_SLOT_MAX,
                   "wrong spill slot");
            dr_save_reg(drcontext, ilist, where, DR_REG_XAX, slot);
        }
    }
    /* lahf */
    instr = INSTR_CREATE_lahf(drcontext);
    MINSERT(ilist, where, instr);
    if (save_oflag) {
        /* seto %al */
        instr = INSTR_CREATE_setcc(drcontext, OP_seto, opnd_create_reg(DR_REG_AL));
        MINSERT(ilist, where, instr);
    }
#elif defined(ARM)
    ASSERT(reg >= DR_REG_START_GPR && reg <= DR_REG_STOP_GPR, "reg must be a GPR");
    if (save_reg) {
        ASSERT(slot >= SPILL_SLOT_1 && slot <= SPILL_SLOT_MAX,
               "wrong spill slot");
        dr_save_reg(drcontext, ilist, where, reg, slot);
    }
    MINSERT(ilist, where, INSTR_CREATE_msr
            (drcontext, opnd_create_reg(DR_REG_CPSR), OPND_CREATE_INT_MSR_NZCVQG(),
             opnd_create_reg(reg)));
#endif
}
Exemplo n.º 20
0
static dr_emit_flags_t
event_bb(void *dc, void *tag, instrlist_t *bb, bool for_trace, bool translating)
{
    instr_t *where = instrlist_first(bb);
    instr_t *ret_label = INSTR_CREATE_label(dc);
    dr_save_reg(dc, bb, where, DR_REG_XAX, SPILL_SLOT_1);
    PRE(bb, where, INSTR_CREATE_mov_imm(dc, opnd_create_reg(DR_REG_XAX),
                                        opnd_create_instr(ret_label)));
    PRE(bb, where, INSTR_CREATE_jmp(dc, opnd_create_pc(slowpath)));
    PRE(bb, where, ret_label);
    dr_restore_reg(dc, bb, where, DR_REG_XAX, SPILL_SLOT_1);
    return DR_EMIT_DEFAULT;
}
Exemplo n.º 21
0
static dr_emit_flags_t
event_bb_insert(void *drcontext, void *tag, instrlist_t *bb, instr_t *inst,
                bool for_trace, bool translating, void *user_data)
{
    /* hack to instrument every nth bb.  assumes DR serializes bb events. */
    static int freq;
    freq++;
    if (freq % 100 == 0 && inst == (instr_t*)user_data/*first instr*/) {
        /* test read from cache */
        dr_save_reg(drcontext, bb, inst, DR_REG_XAX, SPILL_SLOT_1);
        drmgr_insert_read_tls_field(drcontext, tls_idx, bb, inst, DR_REG_XAX);
        dr_insert_clean_call(drcontext, bb, inst, (void *)check_tls_from_cache,
                             false, 1, opnd_create_reg(DR_REG_XAX));
        drmgr_insert_read_cls_field(drcontext, cls_idx, bb, inst, DR_REG_XAX);
        dr_insert_clean_call(drcontext, bb, inst, (void *)check_cls_from_cache,
                             false, 1, opnd_create_reg(DR_REG_XAX));
        dr_restore_reg(drcontext, bb, inst, DR_REG_XAX, SPILL_SLOT_1);
    }
    if (freq % 300 == 0 && inst == (instr_t*)user_data/*first instr*/) {
        /* test write from cache */
        dr_save_reg(drcontext, bb, inst, DR_REG_XAX, SPILL_SLOT_1);
        dr_save_reg(drcontext, bb, inst, DR_REG_XCX, SPILL_SLOT_2);
        instrlist_meta_preinsert(bb, inst, INSTR_CREATE_mov_imm
                                 (drcontext, opnd_create_reg(DR_REG_EAX),
                                  OPND_CREATE_INT32(MAGIC_NUMBER_FROM_CACHE)));
        drmgr_insert_write_tls_field(drcontext, tls_idx, bb, inst, DR_REG_XAX,
                                     DR_REG_XCX);
        dr_insert_clean_call(drcontext, bb, inst, (void *)check_tls_write_from_cache,
                             false, 0);
        drmgr_insert_write_cls_field(drcontext, cls_idx, bb, inst, DR_REG_XAX,
                                     DR_REG_XCX);
        dr_insert_clean_call(drcontext, bb, inst, (void *)check_cls_write_from_cache,
                             false, 0);
        dr_restore_reg(drcontext, bb, inst, DR_REG_XCX, SPILL_SLOT_2);
        dr_restore_reg(drcontext, bb, inst, DR_REG_XAX, SPILL_SLOT_1);
    }
    return DR_EMIT_DEFAULT;
}
Exemplo n.º 22
0
/* save aflags from eax */
void
umbra_save_eax_aflags(void         *drcontext,
                      umbra_info_t *info,
                      instrlist_t  *ilist,
                      instr_t      *where)
{
    instr_t *instr;

    instr = INSTR_CREATE_mov_st(drcontext,
                                OPND_CREATE_ABSMEM(&info->aflags,
                                        OPSZ_4),
                                opnd_create_reg(DR_REG_EAX));
    instrlist_meta_preinsert(ilist, where, instr);
}
Exemplo n.º 23
0
static void
insert_save_addr(void *drcontext, instrlist_t *ilist, instr_t *where, opnd_t ref,
                 reg_id_t reg_ptr, reg_id_t reg_addr)
{
    bool ok;
    /* we use reg_ptr as scratch to get addr */
    ok = drutil_insert_get_mem_addr(drcontext, ilist, where, ref, reg_addr, reg_ptr);
    DR_ASSERT(ok);
    insert_load_buf_ptr(drcontext, ilist, where, reg_ptr);
    MINSERT(ilist, where,
            XINST_CREATE_store(drcontext,
                               OPND_CREATE_MEMPTR(reg_ptr, offsetof(mem_ref_t, addr)),
                               opnd_create_reg(reg_addr)));
}
Exemplo n.º 24
0
DR_EXPORT void
dr_init(client_id_t id)
{
    /* Generate the "slowpath" which just returns to eax. */
    void *dc = dr_get_current_drcontext();
    instrlist_t *ilist = instrlist_create(dc);
    PRE(ilist, NULL, INSTR_CREATE_jmp_ind(dc, opnd_create_reg(DR_REG_XAX)));
    slowpath = dr_nonheap_alloc(SLOWPATH_SIZE, (DR_MEMPROT_READ|
                                                DR_MEMPROT_WRITE|
                                                DR_MEMPROT_EXEC));
    instrlist_encode(dc, ilist, slowpath, false /*no relative jumps*/);
    instrlist_clear_and_destroy(dc, ilist);

    dr_register_bb_event(event_bb);
    dr_register_exit_event(event_exit);
}
Exemplo n.º 25
0
DR_EXPORT
bool
drmgr_insert_read_tls_field(void *drcontext, int idx,
                            instrlist_t *ilist, instr_t *where, reg_id_t reg)
{
    tls_array_t *tls = (tls_array_t *) dr_get_tls_field(drcontext);
    if (idx < 0 || idx > MAX_NUM_TLS || !tls_taken[idx] || tls == NULL)
        return false;
    if (!reg_is_gpr(reg) || !reg_is_pointer_sized(reg))
        return false;
    dr_insert_read_tls_field(drcontext, ilist, where, reg);
    instrlist_meta_preinsert(ilist, where, INSTR_CREATE_mov_ld
                             (drcontext, opnd_create_reg(reg),
                              OPND_CREATE_MEMPTR(reg, offsetof(tls_array_t, tls) +
                                                 idx*sizeof(void*))));
    return true;
}
Exemplo n.º 26
0
/* save reg before where in ilist */
void
umbra_save_reg(void         *drcontext,
               umbra_info_t *info,
               instrlist_t  *ilist,
               instr_t      *where,
               reg_id_t      reg)
{
    int slot;
    instr_t *instr;

    DR_ASSERT(reg >= REG_SPILL_START && reg <= REG_SPILL_STOP);
    slot  = reg - REG_SPILL_START;
    instr = INSTR_CREATE_mov_st(drcontext,
                                OPND_CREATE_ABSMEM(&info->spill_regs[slot],
                                        OPSZ_PTR),
                                opnd_create_reg(reg));
    instrlist_meta_preinsert(ilist, where, instr);
}
Exemplo n.º 27
0
/* PR 332254: test xchg vs nop */
static void
test_nop_xchg(void *dc)
{
    /*   0x0000000000671460  87 c0                xchg   %eax %eax -> %eax %eax
     *   0x0000000000671460  48 87 c0             xchg   %rax %rax -> %rax %rax
     *   0x0000000000671460  41 87 c0             xchg   %r8d %eax -> %r8d %eax
     *   0x0000000000671460  46 90                nop
     *   0x0000000000671460  4e 90                nop
     *   0x0000000000671460  41 90                xchg   %r8d %eax -> %r8d %eax
     */
    instr_t *instr;
    instr = INSTR_CREATE_xchg(dc, opnd_create_reg(REG_EAX), opnd_create_reg(REG_EAX));
    test_instr_encode(dc, instr, 2);
#ifdef X64
    /* we don't do the optimal "48 90" instead of "48 87 c0" */
    instr = INSTR_CREATE_xchg(dc, opnd_create_reg(REG_RAX), opnd_create_reg(REG_RAX));
    test_instr_encode(dc, instr, 3);
    /* we don't do the optimal "41 90" instead of "41 87 c0" */
    instr = INSTR_CREATE_xchg(dc, opnd_create_reg(REG_R8D), opnd_create_reg(REG_EAX));
    test_instr_encode(dc, instr, 3);
    /* ensure we treat as nop and NOT xchg if doesn't have rex.b */
    buf[0] = 0x46;
    buf[1] = 0x90;
    instr = instr_create(dc);
# if VERBOSE
    disassemble_with_info(dc, buf, STDOUT, true, true);
# endif
    decode(dc, buf, instr);
    ASSERT(instr_get_opcode(instr) == OP_nop);
    instr_destroy(dc, instr);
    buf[0] = 0x4e;
    buf[1] = 0x90;
    instr = instr_create(dc);
# if VERBOSE
    disassemble_with_info(dc, buf, STDOUT, true, true);
# endif
    decode(dc, buf, instr);
    ASSERT(instr_get_opcode(instr) == OP_nop);
    instr_destroy(dc, instr);
    buf[0] = 0x41;
    buf[1] = 0x90;
    instr = instr_create(dc);
# if VERBOSE
    disassemble_with_info(dc, buf, STDOUT, true, true);
# endif
    decode(dc, buf, instr);
    ASSERT(instr_get_opcode(instr) == OP_xchg);
    instr_destroy(dc, instr);
#endif
}
Exemplo n.º 28
0
static bool
reg_update_is_limited(instr_t *instr, reg_id_t reg)
{
    int opcode;
    int offset;

    opcode = instr_get_opcode(instr);
    if (opcode == OP_inc || opcode == OP_dec)
        return true;
    if (opcode == OP_and) 
        /* for 0xffffffd0 & reg => reg */
        return true;

    if ((opcode == OP_add || opcode == OP_sub || 
         opcode == OP_adc || opcode == OP_sbb) &&
        opnd_is_immed_int(instr_get_src(instr, 0))) {
        offset = opnd_get_immed_int(instr_get_src(instr, 0));
        if (offset > PAGE_SIZE || offset < -PAGE_SIZE)
            return false;
        return true;
    }
    if (reg != DR_REG_XSP)
        return false;

    if (opcode >= OP_push && opcode <= OP_popa) {
        if (opcode == OP_pop && opnd_same(instr_get_dst(instr, 0),
                                          opnd_create_reg(DR_REG_XSP)))
            return false;
        return true;
    }
    if (opcode >= OP_call && opcode <= OP_call_far_ind)
        return true;
    if (opcode == OP_ret || opcode == OP_ret_far ||
        opcode == OP_enter || opcode == OP_leave ||
        opcode == OP_pushf || opcode == OP_popf)
        return true;
    return false;
}
Exemplo n.º 29
0
void
offline_instru_t::insert_save_addr(void *drcontext, instrlist_t *ilist, instr_t *where,
                                   reg_id_t reg_ptr, reg_id_t reg_addr, int adjust,
                                   opnd_t ref)
{
    bool ok;
    int disp = adjust;
    if (opnd_uses_reg(ref, reg_ptr))
        drreg_get_app_value(drcontext, ilist, where, reg_ptr, reg_ptr);
    if (opnd_uses_reg(ref, reg_addr))
        drreg_get_app_value(drcontext, ilist, where, reg_addr, reg_addr);
    // We use reg_ptr as scratch to get the address.
    ok = drutil_insert_get_mem_addr(drcontext, ilist, where, ref, reg_addr, reg_ptr);
    DR_ASSERT(ok);
    // drutil_insert_get_mem_addr may clobber reg_ptr, so we need to re-load reg_ptr.
    // XXX i#2001: determine whether we have to and avoid it when we don't.
    insert_load_buf_ptr(drcontext, ilist, where, reg_ptr);
    MINSERT(ilist, where,
            XINST_CREATE_store(drcontext,
                               OPND_CREATE_MEMPTR(reg_ptr, disp),
                               opnd_create_reg(reg_addr)));
    // We allow either 0 or all 1's as the type so no need to write anything else.
}
Exemplo n.º 30
0
/* prints the trace and empties the instruction buffer */
static void ins_trace(void *drcontext)
{
    per_thread_t *data;
    int num_refs;
	instr_trace_t *instr_trace;
	instr_t * instr;
	int i;
	int j;
#ifdef READABLE_TRACE
	char disassembly[SHORT_STRING_LENGTH];
#else
	output_t * output;
#endif

    data      = drmgr_get_tls_field(drcontext, tls_index);
    instr_trace   = (instr_trace_t *)data->buf_base;
    num_refs  = (int)((instr_trace_t *)data->buf_ptr - instr_trace);

	uint mem_type;
	uint64 mem_addr;

	opnd_t opnd;

	
#ifdef READABLE_TRACE
	//TODO
    for (i = 0; i < num_refs; i++) {

		instr = instr_trace->static_info_instr;
		instr_disassemble_to_buffer(drcontext,instr,disassembly,SHORT_STRING_LENGTH);

		dr_fprintf(data->outfile,"%u",instr_get_opcode(instr));

		dr_fprintf(data->outfile,",%u",calculate_operands(instr,DST_TYPE));
		for(j=0; j<instr_num_dsts(instr); j++){
			get_address(instr_trace, j, DST_TYPE, &mem_type, &mem_addr);
			output_populator_printer(drcontext,instr_get_dst(instr,j),instr,mem_addr,mem_type,NULL);
		}

		dr_fprintf(data->outfile,",%u",calculate_operands(instr,SRC_TYPE));
		for(j=0; j<instr_num_srcs(instr); j++){
			get_address(instr_trace, j, SRC_TYPE, &mem_type, &mem_addr);
			opnd = instr_get_src(instr, j);
			if (instr_get_opcode(instr) == OP_lea && opnd_is_base_disp(opnd)){
				/* four operands here for [base + index * scale + disp] */
				output_populator_printer(drcontext, opnd_create_reg(opnd_get_base(opnd)), instr, mem_addr, mem_type, NULL);
				output_populator_printer(drcontext, opnd_create_reg(opnd_get_index(opnd)), instr, mem_addr, mem_type, NULL);
				output_populator_printer(drcontext, opnd_create_immed_int(opnd_get_scale(opnd),OPSZ_PTR), instr, mem_addr, mem_type, NULL);
				output_populator_printer(drcontext, opnd_create_immed_int(opnd_get_disp(opnd), OPSZ_PTR), instr, mem_addr, mem_type, NULL);
			}
			else{
				output_populator_printer(drcontext, opnd, instr, mem_addr, mem_type, NULL);
			}
		}
		dr_fprintf(data->outfile,",%u,%u\n",instr_trace->eflags,instr_trace->pc);
        ++instr_trace;
    }
#else

	/* we need to fill up the output array here */

	for(i = 0; i< num_refs; i++){
		instr = instr_trace->static_info_instr;
		output = &data->output_array[i];
		
		//opcode 
		output->opcode = instr_get_opcode(instr);
		output->num_dsts = 0;
		output->num_srcs = 0;

		for(j=0; j<instr_num_dsts(instr); j++){

			output_populator_printer(drcontext,instr_get_dst(instr,j),instr,get_address(instr_trace,j,DST_TYPE),&output->dsts[output->num_dsts]);
			output->num_dsts++;
		}

		for(j=0; j<instr_num_srcs(instr); j++){
			output_populator_printer(drcontext,instr_get_src(instr,j),instr,get_address(instr_trace,j,SRC_TYPE),&output->srcs[output->num_srcs]);
			output->num_srcs++;
		}
		
		output->eflags = instr_trace->eflags;

		++instr_trace;

	}

	dr_write_file(data->outfile,data->output_array,num_refs * sizeof(output_t));
#endif

	
    memset(data->buf_base, 0, INSTR_BUF_SIZE);
    data->num_refs += num_refs;
    data->buf_ptr   = data->buf_base;
	
}