Esempio n. 1
0
void check_opnd(opnd_t opnd, void *pc, int read, void *drcontext,
		dr_mcontext_t *mctx, void *prev_pc)
{
  if (opnd_is_memory_reference(opnd) && opnd_is_base_disp(opnd))
    add_hit(pc, opnd_size_in_bytes(opnd_get_size(opnd)),
	    opnd_get_disp(opnd) + (void *)reg_get_value(opnd_get_base(opnd),
						       mctx),
	    read, drcontext, prev_pc);
  else if (opnd_is_memory_reference(opnd) && opnd_get_addr(opnd))
    add_hit(pc, opnd_size_in_bytes(opnd_get_size(opnd)), opnd_get_addr(opnd),
	    read, drcontext, prev_pc);
  // for now no other kind of memory reference was noticed to access heap data
  else if (opnd_is_memory_reference(opnd))
    dr_printf("need to implem other memory ref\n");
}
Esempio n. 2
0
static void
test_instr_opnds(void *dc)
{
    /* Verbose disasm looks like this:
     * 32-bit:
     *   0x080f1ae0  ff 25 e7 1a 0f 08    jmp    0x080f1ae7
     *   0x080f1ae6  b8 ef be ad de       mov    $0xdeadbeef -> %eax
     *   0x080f1ae0  a0 e6 1a 0f 08       mov    0x080f1ae6 -> %al
     *   0x080f1ae5  b8 ef be ad de       mov    $0xdeadbeef -> %eax
     * 64-bit:
     *   0x00000000006b8de0  ff 25 02 00 00 00    jmp    <rel> 0x00000000006b8de8
     *   0x00000000006b8de6  48 b8 ef be ad de 00 mov    $0x00000000deadbeef -> %rax
     *                       00 00 00
     *   0x00000000006b8de0  8a 05 02 00 00 00    mov    <rel> 0x00000000006b8de8 -> %al
     *   0x00000000006b8de6  48 b8 ef be ad de 00 mov    $0x00000000deadbeef -> %rax
     *                       00 00 00
     */
    instrlist_t *ilist;
    instr_t *tgt, *instr;
    byte *pc;
    short disp;

    ilist = instrlist_create(dc);

    /* test mem instr as ind jmp target */
    tgt = INSTR_CREATE_mov_imm(dc, opnd_create_reg(DR_REG_XAX),
                               opnd_create_immed_int(0xdeadbeef, OPSZ_PTR));
    /* skip rex+opcode */
    disp = IF_X64_ELSE(2,1);
    instrlist_append(ilist, INSTR_CREATE_jmp_ind
                     (dc, opnd_create_mem_instr(tgt, disp, OPSZ_PTR)));
    instrlist_append(ilist, tgt);
    pc = instrlist_encode(dc, ilist, buf, true/*instr targets*/);
    ASSERT(pc != NULL);
    instrlist_clear(dc, ilist);
#if VERBOSE
    pc = disassemble_with_info(dc, buf, STDOUT, true, true);
    pc = disassemble_with_info(dc, pc, STDOUT, true, true);
#endif
    pc = buf;
    instr = instr_create(dc);
    pc = decode(dc, pc, instr);
    ASSERT(pc != NULL);
    ASSERT(instr_get_opcode(instr) == OP_jmp_ind);
#ifdef X64
    ASSERT(opnd_is_rel_addr(instr_get_src(instr, 0)));
    ASSERT(opnd_get_addr(instr_get_src(instr, 0)) == pc + disp);
#else
    ASSERT(opnd_is_base_disp(instr_get_src(instr, 0)));
    ASSERT(opnd_get_base(instr_get_src(instr, 0)) == REG_NULL);
    ASSERT(opnd_get_index(instr_get_src(instr, 0)) == REG_NULL);
    ASSERT(opnd_get_disp(instr_get_src(instr, 0)) == (ptr_int_t)pc + disp);
#endif

    /* test mem instr as TYPE_O */
    tgt = INSTR_CREATE_mov_imm(dc, opnd_create_reg(DR_REG_XAX),
                               opnd_create_immed_int(0xdeadbeef, OPSZ_PTR));
    /* skip rex+opcode */
    disp = IF_X64_ELSE(2,1);
    instrlist_append(ilist, INSTR_CREATE_mov_ld
                     (dc, opnd_create_reg(DR_REG_AL),
                      opnd_create_mem_instr(tgt, disp, OPSZ_1)));
    instrlist_append(ilist, tgt);
    pc = instrlist_encode(dc, ilist, buf, true/*instr targets*/);
    ASSERT(pc != NULL);
    instrlist_clear(dc, ilist);
#if VERBOSE
    pc = disassemble_with_info(dc, buf, STDOUT, true, true);
    pc = disassemble_with_info(dc, pc, STDOUT, true, true);
#endif
    pc = buf;
    instr_reset(dc, instr);
    pc = decode(dc, pc, instr);
    ASSERT(pc != NULL);
    ASSERT(instr_get_opcode(instr) == OP_mov_ld);
#ifdef X64
    ASSERT(opnd_is_rel_addr(instr_get_src(instr, 0)));
    ASSERT(opnd_get_addr(instr_get_src(instr, 0)) == pc + disp);
#else
    ASSERT(opnd_is_base_disp(instr_get_src(instr, 0)));
    ASSERT(opnd_get_base(instr_get_src(instr, 0)) == REG_NULL);
    ASSERT(opnd_get_index(instr_get_src(instr, 0)) == REG_NULL);
    ASSERT(opnd_get_disp(instr_get_src(instr, 0)) == (ptr_int_t)pc + disp);
#endif

    instr_free(dc, instr);
    instrlist_destroy(dc, ilist);
}
Esempio n. 3
0
static instr_t *
analyze_client_code(void *drcontext, 
                    instrlist_t *ilist,
                    instr_t *where,
                    ref_info_t *ref_info)
{
    instr_t *next, *lea, *and, *cmp, *jcc, *sub;
    opnd_t   ref, opnd;
    ref_cache_t *cache;
    reg_id_t reg;
    int      pos, i;

    next = instr_get_next(where);
    if (next == NULL)
        return NULL;
    
    if (instr_get_opcode(where) != OP_lea)
        return next;

    /* lea [ref] => r1 */
    ref = instr_get_src(where, 0);
    if (!opnd_is_base_disp(ref) || opnd_get_index(ref) != DR_REG_NULL)
        return next;

    lea = where;
    and = next;
    cmp = instr_get_next(and);
    jcc = instr_get_next(cmp);

    if (instr_get_app_pc(and) == NULL   &&
        instr_get_opcode(and) == OP_and &&
        instr_get_app_pc(cmp) == NULL   &&
        instr_get_opcode(cmp) == OP_cmp &&
        instr_get_app_pc(jcc) == NULL   &&
        instr_get_opcode(jcc) == OP_jz) {
        /* find pattern of 
         *   lea [ref] => reg
         *   and 0xffffffff00000000 reg
         *   cmp cache->tag  reg
         *   jz
         */
        opnd  = instr_get_src(cmp, 1);
        cache = opnd_get_addr(opnd) - offsetof(ref_cache_t, tag);
        for (i = 0; i < 10; ) {
            lea = instr_get_next(lea);
            if (!instr_is_label(lea))
                i++;
        }
        DR_ASSERT(instr_get_opcode(lea) == OP_lea);
    } else if (instr_get_app_pc(next) == NULL &&
               instr_get_opcode(next) == OP_sub) {
        opnd  = instr_get_src(next, 0);
        cache = opnd_get_addr(opnd) - offsetof(ref_cache_t, offset);
    } else {
        return next;
    }

    reg = opnd_get_base(ref);
    UMBRA_REG_TO_POS(reg, pos);
    if (ref_info[pos].cache == NULL) {
        ref_info[pos].cache = cache;
    } else {
        sub = instr_get_next(lea);
        DR_ASSERT(instr_get_opcode(sub) == OP_sub);
        while (lea != where) {
            next = instr_get_next(where);
            instrlist_remove(ilist, where);
            instr_destroy(drcontext, where);
            where = next;
        }
        opnd = OPND_CREATE_ABSMEM((void *)(reg_t)ref_info[pos].cache + 
                                  offsetof(ref_cache_t, offset),
                                  OPSZ_PTR);
        instr_set_src(sub, 0, opnd);
        if (proc_info.client.app_unit_bits  > 0 && 
            proc_info.client.shd_unit_bits != 0)
            next = instr_get_next(sub); /* reg & mask => reg */
        if (proc_info.client.orig_addr) {
            next = instr_get_next(next); /* mov reg => r2 */
            next = instr_get_next(next); /* r2 & bit_mask => r2 */
        }
    }

    next = instr_get_next(lea);
    return instr_get_next(next);
}