emu *emu_new() { struct emu_t *e = R_NEW0(emu); e->reg = r_reg_new(); e->io = r_io_new(); e->bin = r_bin_new(); e->lib = r_lib_new("ramulate_plugin"); e->plugins = r_list_new(); e->a = r_asm_new(); e->op = R_NEW0(RAsmOp); e->anal = r_anal_new(); e->anop = r_anal_op_new(); e->next_vs_id = 0; e->screen = NULL; r_lib_add_handler(e->lib, RAMULATE_EMU_PLUGIN, "emulation plugin handler", &emu_plugin_cb, &emu_plugin_cb_end, e); return e; }
R_API int r_anal_bb(RAnal *anal, RAnalBlock *bb, ut64 addr, ut8 *buf, ut64 len, int head) { RAnalOp *op = NULL; int oplen, idx = 0; if (bb->addr == -1) { bb->addr = addr; } len -= 16; // XXX: hack to avoid segfault by x86im while (idx < len) { // TODO: too slow object construction if (!(op = r_anal_op_new ())) { eprintf ("Error: new (op)\n"); return R_ANAL_RET_ERROR; } if ((oplen = r_anal_op (anal, op, addr + idx, buf + idx, len - idx)) == 0) { r_anal_op_free (op); op = NULL; if (idx == 0) { VERBOSE_ANAL eprintf ("Unknown opcode at 0x%08"PFMT64x"\n", addr+idx); return R_ANAL_RET_END; } break; } if (oplen < 1) { return R_ANAL_RET_END; } r_anal_bb_set_offset (bb, bb->ninstr, addr + idx - bb->addr); idx += oplen; bb->size += oplen; bb->ninstr++; #if R_ANAL_BB_HAS_OPS r_list_append (bb->ops, op); #endif if (head) { bb->type = R_ANAL_BB_TYPE_HEAD; } switch (op->type) { case R_ANAL_OP_TYPE_CMP: r_anal_cond_free (bb->cond); bb->cond = r_anal_cond_new_from_op (op); break; case R_ANAL_OP_TYPE_CJMP: if (bb->cond) { // TODO: get values from anal backend bb->cond->type = R_ANAL_COND_EQ; } else VERBOSE_ANAL eprintf ("Unknown conditional for block 0x%"PFMT64x"\n", bb->addr); bb->conditional = 1; bb->fail = op->fail; bb->jump = op->jump; bb->type |= R_ANAL_BB_TYPE_BODY; goto beach; case R_ANAL_OP_TYPE_JMP: bb->jump = op->jump; bb->type |= R_ANAL_BB_TYPE_BODY; goto beach; case R_ANAL_OP_TYPE_UJMP: bb->type |= R_ANAL_BB_TYPE_FOOT; goto beach; case R_ANAL_OP_TYPE_RET: bb->type |= R_ANAL_BB_TYPE_LAST; goto beach; case R_ANAL_OP_TYPE_LEA: { RAnalValue *src = op->src[0]; if (src && src->reg && anal->reg) { const char *pc = anal->reg->name[R_REG_NAME_PC]; RAnalValue *dst = op->dst; if (dst && dst->reg && !strcmp (src->reg->name, pc)) { int memref = anal->bits/8; ut8 b[8]; ut64 ptr = idx+addr+src->delta; anal->iob.read_at (anal->iob.io, ptr, b, memref); r_anal_ref_add (anal, ptr, addr+idx-op->size, 'd'); } } } } r_anal_op_free (op); } return bb->size; beach: r_anal_op_free (op); return R_ANAL_RET_END; }
int main(int argc, char **argv) { RLib *lib; RAnal *anal = r_anal_new (); RAnalOp *op = r_anal_op_new (); ut8 *ptr, *buf = NULL, *data = NULL; ut64 offset = 0x8048000LL; char *arch = NULL; int bin = false, len = 0, bits = 32; int c, idx, ret, tlen, word; lib = r_lib_new ("radare_plugin"); r_lib_add_handler (lib, R_LIB_TYPE_ANAL, "analysis plugins", &__lib_anal_cb, &__lib_anal_dt, anal); r_lib_opendir (lib, r_sys_getenv ("LIBR_PLUGINS")); while ((c = getopt (argc, argv, "a:b:Bhl:Lo:")) != -1) { switch (c) { case 'a': arch = optarg; break; case 'b': bits = r_num_math (NULL, optarg); break; case 'B': bin = true; break; case 'h': return usage (); case 'l': len = r_num_math (NULL, optarg); break; case 'L': return r_anal_list (anal); case 'o': offset = r_num_math (NULL, optarg); break; } } if (!argv[optind] || (bin && !len)) return usage (); /* Set default options */ if (arch) { if (!r_anal_use (anal, arch)) { eprintf ("Invalid plugin\n"); return 1; } } else r_anal_use (anal, "x86"); if (!r_anal_set_bits (anal, bits)) r_anal_set_bits (anal, 32); /* Get input & convert to bin if necessary */ if (argv[optind][0] == '-') { idx = 0; while (true) { if (!(buf = realloc (buf, idx+1024))) return 1; fgets ((char*)buf+idx, 1024, stdin); if ((!bin && feof (stdin)) ||(len && idx >= len)) break; idx += 1023; } } else { if (!(buf = (ut8 *)strdup (argv[optind]))) return 1; } if (bin) { data = (ut8*)buf; } else { ptr = buf, word = tlen = 0; while (ptr[0]) { int p = *ptr; if (p!= ' ' && p!= '\n' && p!= '\r') if (0==(++word%2)) tlen++; ptr += 1; } data = malloc (tlen+1); if (!data) { r_anal_free (anal); r_anal_op_free (op); return 1; } r_hex_str2bin ((char *)buf, data); if (!len || len > tlen) len = tlen; free (buf); } /* Analyze */ for (idx=ret=0; idx<len; idx+=ret) { if (!(ret = analyze (anal, op, offset+idx, data+idx, len-idx))) { eprintf ("Ooops\n"); free (data); r_anal_free (anal); r_anal_op_free (op); return 1; } } free (data); r_anal_free (anal); r_anal_op_free (op); return 0; }