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);*/
}
Exemple #2
0
static void
instrument_mem(void *drcontext, instrlist_t *ilist, instr_t *where, 
               int pos, bool write)
{
    instr_t *instr;
    opnd_t   ref, opnd1, opnd2;
    reg_id_t reg1 = DR_REG_XAX; /* We can optimize it by picking dead reg */
    reg_id_t reg2 = DR_REG_XCX; /* reg2 must be ECX or RCX for jecxz */

    if (write)
       ref = instr_get_dst(where, pos);
    else
       ref = instr_get_src(where, pos);

    dr_save_reg(drcontext, ilist, where, reg1, SPILL_SLOT_2);
    dr_save_reg(drcontext, ilist, where, reg2, SPILL_SLOT_3);

	// reg2 = RBufIdx
    opnd1 = opnd_create_reg(reg2);
    opnd2 = OPND_CREATE_ABSMEM((byte *)&RBufIdx, OPSZ_4);
    instr = INSTR_CREATE_mov_ld(drcontext, opnd1, opnd2);
    instrlist_meta_preinsert(ilist, where, instr);
	// save flags since we are using inc, and
	dr_save_arith_flags_to_xax(drcontext, ilist, where);	

	// reg2 = reg2 & RBUF_SIZE 
    opnd1 = opnd_create_reg(reg2);
    opnd2 = OPND_CREATE_INT32(RBUF_SIZE);
    instr = INSTR_CREATE_and(drcontext, opnd1, opnd2);
    instrlist_meta_preinsert(ilist, where, instr);
	dr_restore_arith_flags_from_xax(drcontext, ilist, where);

	// reg1 = &RBuf
    opnd1 = opnd_create_reg(reg1);
    opnd2 = OPND_CREATE_INTPTR(RBuf);
    instr = INSTR_CREATE_mov_imm(drcontext, opnd1, opnd2);
    instrlist_meta_preinsert(ilist, where, instr);

	// reg1 = reg1 + reg2 * sizeof(uint)
	// 		= RBuf + RBufIdx * sizeof(uint)
	// 		= RBuf[RBufIdx]
    opnd1 = opnd_create_reg(reg1);
    opnd2 = opnd_create_base_disp(reg1, reg2, sizeof(uint), 0, OPSZ_lea);
    instr = INSTR_CREATE_lea(drcontext, opnd1, opnd2);
    instrlist_meta_preinsert(ilist, where, instr);

	// RBuf[RBufIdx].addr = addr;
    opnd1 = OPND_CREATE_MEMPTR(reg1, 0);
    drutil_insert_get_mem_addr(drcontext, ilist, where, ref, reg2, reg1);
    opnd2 = opnd_create_reg(reg2);
    instr = INSTR_CREATE_mov_st(drcontext, opnd1, opnd2);
    instrlist_meta_preinsert(ilist, where, instr);

	dr_save_arith_flags_to_xax(drcontext, ilist, where);	

	// reg2 = RBufIdx
    opnd1 = opnd_create_reg(reg2);
    opnd2 = OPND_CREATE_ABSMEM((byte *)&RBufIdx, OPSZ_4);
    instr = INSTR_CREATE_mov_ld(drcontext, opnd1, opnd2);
    instrlist_meta_preinsert(ilist, where, instr);

	// reg2 = reg2 + 1
    opnd1 = opnd_create_reg(reg2);
    instr = INSTR_CREATE_inc(drcontext, opnd1);
    instrlist_meta_preinsert(ilist, where, instr);

	// RBufIdx = reg2
    opnd1 = OPND_CREATE_ABSMEM((byte *)&RBufIdx, OPSZ_4);
    opnd2 = opnd_create_reg(reg2);
    instr = INSTR_CREATE_mov_st(drcontext, opnd1, opnd2);
    instrlist_meta_preinsert(ilist, where, instr);

	dr_restore_arith_flags_from_xax(drcontext, ilist, where);

    dr_restore_reg(drcontext, ilist, where, reg1, SPILL_SLOT_2);
    dr_restore_reg(drcontext, ilist, where, reg2, SPILL_SLOT_3);
}
unsigned int
cfi_prepare_for_native_call(void *drcontext, instrlist_t *ilist, instr_t *where)
{
	unsigned int eflags_offs, dstack_offs = 0;
    instr_t *in = (where == NULL) ? instrlist_last(ilist) : instr_get_prev(where);

    CFI_ASSERT(drcontext != NULL, "cfi_prepare_for_native_call: drcontext cannot be NULL");

    //PRE(ilist, where, INSTR_CREATE_push_imm(dcontext, OPND_CREATE_INT32(0)));
    //dstack_offs += XSP_SZ;

    PRE(ilist, where, INSTR_CREATE_pushf(drcontext));
    PRE(ilist, where, INSTR_CREATE_push(drcontext,
                          opnd_create_base_disp(REG_XSP, REG_NULL, 0, 0, OPSZ_STACK)));
    PRE(ilist, where, INSTR_CREATE_and(drcontext,
                         opnd_create_base_disp(REG_XSP, REG_NULL, 0, 0,
                                               OPSZ_STACK),
                         OPND_CREATE_INT32(~(EFLAGS_NON_SYSTEM | EFLAGS_IF))));

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

  /*  dstack_offs += XSP_SZ;
    eflags_offs = dstack_offs;

    PRE(ilist, where, INSTR_CREATE_lea(drcontext, opnd_create_reg(REG_XSP),
    		OPND_CREATE_MEM_lea(REG_XSP, REG_NULL, 0, - XMM_SLOTS_SIZE)));

    PRE(ilist, where, INSTR_CREATE_push(drcontext, opnd_create_reg(REG_R15)));
    PRE(ilist, where, INSTR_CREATE_push(drcontext, opnd_create_reg(REG_R14)));
    PRE(ilist, where, INSTR_CREATE_push(drcontext, opnd_create_reg(REG_R13)));
    PRE(ilist, where, INSTR_CREATE_push(drcontext, opnd_create_reg(REG_R12)));
    PRE(ilist, where, INSTR_CREATE_push(drcontext, opnd_create_reg(REG_R11)));
    PRE(ilist, where, INSTR_CREATE_push(drcontext, opnd_create_reg(REG_R10)));
    PRE(ilist, where, INSTR_CREATE_push(drcontext, opnd_create_reg(REG_R9)));
    PRE(ilist, where, INSTR_CREATE_push(drcontext, opnd_create_reg(REG_R8)));
    PRE(ilist, where, INSTR_CREATE_push(drcontext, opnd_create_reg(REG_RAX)));
    PRE(ilist, where, INSTR_CREATE_push(drcontext, opnd_create_reg(REG_RCX)));
    PRE(ilist, where, INSTR_CREATE_push(drcontext, opnd_create_reg(REG_RDX)));
    PRE(ilist, where, INSTR_CREATE_push(drcontext, opnd_create_reg(REG_RBX)));*/
    /* we do NOT match pusha xsp value *//*
    PRE(ilist, where, INSTR_CREATE_push(drcontext, opnd_create_reg(REG_RSP)));
    PRE(ilist, where, INSTR_CREATE_push(drcontext, opnd_create_reg(REG_RBP)));
    PRE(ilist, where, INSTR_CREATE_push(drcontext, opnd_create_reg(REG_RSI)));
    PRE(ilist, where, INSTR_CREATE_push(drcontext, opnd_create_reg(REG_RDI)));
    dstack_offs += 16*XSP_SZ + XMM_SLOTS_SIZE;

    PRE(ilist, where, INSTR_CREATE_push(drcontext,
                          opnd_create_base_disp(REG_XSP, REG_NULL, 0,
                          dstack_offs - eflags_offs, OPSZ_STACK)));

    PRE(ilist, where, INSTR_CREATE_and(drcontext,
                         opnd_create_base_disp(REG_XSP, REG_NULL, 0, 0,
                                               OPSZ_STACK),
                         OPND_CREATE_INT32(~(EFLAGS_NON_SYSTEM | EFLAGS_IF))));

    PRE(ilist, where, INSTR_CREATE_popf(drcontext));*/

    /* now go through and mark inserted instrs as meta */
    if (in == NULL)
        in = instrlist_first(ilist);
    else
        in = instr_get_next(in);

    while (in != where) {
        instr_set_ok_to_mangle(in, false);
        in = instr_get_next(in);
    }

    return dstack_offs;
}