Implement RAnalCycleFrame Stuff, New optypes and esil-adc/sbc

This commit is contained in:
condret 2014-03-25 00:48:42 +01:00 committed by pancake
parent 598fe87f3c
commit d6dae07979
9 changed files with 320 additions and 43 deletions

View File

@ -21,7 +21,7 @@ STATIC_OBJS=$(addprefix $(LTOP)/anal/p/,$(STATIC_OBJ))
OBJLIBS=meta.o reflines.o ref.o op.o fcn.o bb.o var.o
OBJLIBS+=cond.o value.o cc.o diff.o types.o fcnstore.o
OBJLIBS+=hint.o vm.o anal.o data.o xrefs.o esil.o sign.o
OBJLIBS+=anal_ex.o switch.o state.o kvesil.o
OBJLIBS+=anal_ex.o switch.o state.o kvesil.o cycles.o
OBJS=${STATIC_OBJS} ${OBJLIBS} ${CPARSE_OBJS}

18
libr/anal/cycles.c Normal file
View File

@ -0,0 +1,18 @@
#include <r_anal.h>
#include <r_list.h>
#include <r_types.h>
R_API RAnalCycleFrame *r_anal_cycle_frame_new ()
{
RAnalCycleFrame *cf = R_NEW0 (RAnalCycleFrame);
cf->hooks = r_list_new ();
return cf;
}
R_API void r_anal_cycle_frame_free (RAnalCycleFrame *cf)
{
if (!cf) return;
r_list_free (cf->hooks);
free (cf);
}

View File

@ -146,9 +146,11 @@ R_API char *r_anal_optype_to_string(int t) {
case R_ANAL_OP_TYPE_JMP : return "jmp";
case R_ANAL_OP_TYPE_UJMP : return "ujmp";
case R_ANAL_OP_TYPE_CJMP : return "cjmp";
case R_ANAL_OP_TYPE_UCJMP : return "ucjmp";
case R_ANAL_OP_TYPE_CALL : return "call";
case R_ANAL_OP_TYPE_UCALL : return "ucall";
case R_ANAL_OP_TYPE_CCALL : return "ccall";
case R_ANAL_OP_TYPE_UCCALL: return "uccall";
case R_ANAL_OP_TYPE_REP : return "rep";
case R_ANAL_OP_TYPE_RET : return "ret";
case R_ANAL_OP_TYPE_CRET : return "cret";
@ -162,6 +164,7 @@ R_API char *r_anal_optype_to_string(int t) {
case R_ANAL_OP_TYPE_PUSH : return "push";
case R_ANAL_OP_TYPE_POP : return "pop";
case R_ANAL_OP_TYPE_CMP : return "cmp";
case R_ANAL_OP_TYPE_ACMP : return "acmp";
case R_ANAL_OP_TYPE_ADD : return "add";
case R_ANAL_OP_TYPE_SUB : return "sub";
case R_ANAL_OP_TYPE_MUL : return "mul";
@ -176,10 +179,10 @@ R_API char *r_anal_optype_to_string(int t) {
case R_ANAL_OP_TYPE_LOAD : return "load";
case R_ANAL_OP_TYPE_LEA : return "lea";
case R_ANAL_OP_TYPE_LEAVE : return "leave";
case R_ANAL_OP_TYPE_ROR : return "ror";
case R_ANAL_OP_TYPE_ROL : return "rol";
case R_ANAL_OP_TYPE_XCHG : return "xchg";
case R_ANAL_OP_TYPE_MOD : return "mod";
case R_ANAL_OP_TYPE_ROR : return "ror";
case R_ANAL_OP_TYPE_ROL : return "rol";
case R_ANAL_OP_TYPE_XCHG : return "xchg";
case R_ANAL_OP_TYPE_MOD : return "mod";
case R_ANAL_OP_TYPE_SWITCH : return "switch";
}
return "undefined";

View File

@ -19,7 +19,8 @@ static const char *regs_x[] = { "b", "c", "d", "e", "h", "l", "hl", "a"};
static const char *regs_16[] = { "bc", "de", "hl", "sp"};
static const char *regs_16_alt[] = { "bc", "de", "hl", "af" };
static ut8 gb_op_calljump(RAnal *a, RAnalOp *op, const ut8 *data, ut64 addr){
static ut8 gb_op_calljump(RAnal *a, RAnalOp *op, const ut8 *data, ut64 addr)
{
if (GB_IS_RAM_DST (data[1],data[2])) {
op->jump = GB_SOFTCAST (data[1], data[2]);
r_meta_set_string (a, R_META_TYPE_COMMENT, addr, "--> unpredictable");
@ -189,6 +190,7 @@ static void gb_anal_mov_imm (RReg *reg, RAnalOp *op, const ut8 *data)
r_strbuf_setf (&op->esil, "%s=0x%02x", regs_8[data[0] & 7], op->src[0]->imm);
}
op->src[0]->absolute = R_TRUE;
op->val = op->src[0]->imm;
}
static inline void gb_anal_mov_sp_hl (RReg *reg, RAnalOp *op)
@ -359,13 +361,25 @@ static void gb_anal_xoaasc (RReg *reg, RAnalOp *op, const ut8 *data)
break;
case R_ANAL_OP_TYPE_ADD:
if (op->src[0]->memref)
r_strbuf_setf (&op->esil, "a=a+1[%s],N=0,Z=a==0", regs_x[data[0] & 7]);
else r_strbuf_setf (&op->esil, "a=a+%s,N=0,Z=a==0", regs_x[data[0] & 7]);
r_strbuf_setf (&op->esil, "a=a+1[%s]", regs_x[data[0] & 7]);
else r_strbuf_setf (&op->esil, "a=a+%s", regs_x[data[0] & 7]);
if (data[0] > 0x87) { //adc
op->src[1] = r_anal_value_new ();
op->src[1]->reg = r_reg_get (reg, "C", R_REG_TYPE_GPR);
r_strbuf_append (&op->esil, "+C");
}
r_strbuf_append (&op->esil, ",N=0,Z=a==0");
break;
case R_ANAL_OP_TYPE_SUB:
if (op->src[0]->memref)
r_strbuf_setf (&op->esil, "a=a-1[%s],N=1,Z=a==0", regs_x[data[0] & 7]);
else r_strbuf_setf (&op->esil, "a=a-%s,N=1,Z=a==0", regs_x[data[0] & 7]);
r_strbuf_setf (&op->esil, "a=a-1[%s]", regs_x[data[0] & 7]);
else r_strbuf_setf (&op->esil, "a=a-%s", regs_x[data[0] & 7]);
if (data[0] > 0x97) { //sbc
op->src[1] = r_anal_value_new ();
op->src[1]->reg = r_reg_get (reg, "C", R_REG_TYPE_GPR);
r_strbuf_append (&op->esil, "-C");
}
r_strbuf_append (&op->esil, ",N=1,Z=a==0");
break;
case R_ANAL_OP_TYPE_CMP:
if (op->src[0]->memref)
@ -393,10 +407,22 @@ static void gb_anal_xoaasc_imm (RReg *reg, RAnalOp *op, const ut8 *data) //xor ,
r_strbuf_setf (&op->esil, "a=a&0x%02x,N=0,H=1,C=0,Z=a==0", data[1]);
break;
case R_ANAL_OP_TYPE_ADD:
r_strbuf_setf (&op->esil, "a=a+0x%02x,N=0,Z=a==0", data[1]);
r_strbuf_setf (&op->esil, "a=a+0x%02x", data[1]);
if (data[0] == 0xce) { //adc
op->src[1] = r_anal_value_new ();
op->src[1]->reg = r_reg_get (reg, "C", R_REG_TYPE_GPR);
r_strbuf_append (&op->esil, "+C");
}
r_strbuf_append (&op->esil, ",N=0,Z=a==0");
break;
case R_ANAL_OP_TYPE_SUB:
r_strbuf_setf (&op->esil, "a=a-0x%02x,N=1,Z=a==0", data[1]);
r_strbuf_setf (&op->esil, "a=a-0x%02x", data[1]);
if (data[0] == 0xde) { //sbc
op->src[1] = r_anal_value_new ();
op->src[1]->reg = r_reg_get (reg, "C", R_REG_TYPE_GPR);
r_strbuf_append (&op->esil, "-C");
}
r_strbuf_append (&op->esil, ",N=0,Z=a==0");
break;
case R_ANAL_OP_TYPE_CMP:
r_strbuf_setf (&op->esil, "Z=a==0x%02x,N=1", data[1]);
@ -433,6 +459,12 @@ static inline void gb_anal_load (RReg *reg, RAnalOp *op, const ut8 *data)
break;
case 0xfa:
op->src[0]->base = GB_SOFTCAST (data[1], data[2]);
if (op->src[0]->base < 0x4000)
op->ptr = op->src[0]->base;
else {
if (op->addr > 0x3fff && op->src[0]->base < 0x8000)
op->ptr = op->src[0]->base + (op->addr & 0xffffffffffff0000);
}
r_strbuf_setf (&op->esil, "a=1[0x%04x]", op->src[0]->base);
break;
default:
@ -941,6 +973,8 @@ static int gb_anop(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *data, int len
op->eob = 1;
op->cycles = 16;
gb_anal_esil_ret (op);
op->stackop = R_ANAL_STACK_INC;
op->stackptr = -2;
op->type = R_ANAL_OP_TYPE_RET;
break;
case 0x0b:
@ -993,8 +1027,8 @@ static int gb_anop(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *data, int len
gb_anal_esil_jmp (op);
} else {
op->type = R_ANAL_OP_TYPE_UJMP;
op->eob = 1;
}
op->eob = 1;
op->cycles = 16;
op->fail = addr+ilen;
break;
@ -1003,6 +1037,7 @@ static int gb_anop(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *data, int len
op->fail = addr + ilen;
gb_anal_esil_jmp (op);
op->cycles = 12;
op->eob = 1;
op->type = R_ANAL_OP_TYPE_JMP;
break;
case 0x20:
@ -1015,6 +1050,7 @@ static int gb_anop(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *data, int len
gb_anal_esil_cjmp (op, data[0]);
op->cycles = 12;
op->failcycles = 8;
op->eob = 1;
op->type = R_ANAL_OP_TYPE_CJMP;
break;
case 0xc2:
@ -1024,9 +1060,9 @@ static int gb_anop(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *data, int len
if( gb_op_calljump (anal, op, data, addr)) {
op->type = R_ANAL_OP_TYPE_CJMP;
} else {
op->type = R_ANAL_OP_TYPE_UJMP;
op->eob = 1;
op->type = R_ANAL_OP_TYPE_UCJMP;
}
op->eob = 1;
gb_anal_esil_cjmp (op, data[0]);
op->cycles = 16;
op->failcycles = 12;
@ -1034,12 +1070,13 @@ static int gb_anop(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *data, int len
break;
case 0xe9:
op->cycles = 4;
op->eob = 1;
op->type = R_ANAL_OP_TYPE_UJMP;
gb_anal_jmp_hl (anal->reg, op);
break;
case 0x76:
op->type = R_ANAL_OP_TYPE_CJMP;
op->eob = 1; //halt migth wait for interrupts
op->eob = 1; //halt migth wait for interrupts
op->fail = addr + ilen;
if(len > 1)
op->jump = addr + gbOpLength (gb_op[data[1]].type) + ilen;
@ -1060,7 +1097,7 @@ static int gb_anop(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *data, int len
gb_anal_cond (anal->reg, op, data[0]);
if( gb_op_calljump (anal, op, data, addr))
op->type = R_ANAL_OP_TYPE_CCALL;
else op->type = R_ANAL_OP_TYPE_UCALL;
else op->type = R_ANAL_OP_TYPE_UCCALL;
op->fail = addr + ilen;
op->eob = 1;
gb_anal_esil_ccall (op, data[0]);
@ -1200,7 +1237,7 @@ static int gb_anop(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *data, int len
if ((data[1]&7) == 6)
op->cycles = 12;
else op->cycles = 8;
op->type = R_ANAL_OP_TYPE_CMP;
op->type = R_ANAL_OP_TYPE_ACMP;
gb_anal_and_bit (anal->reg, op, data[1]);
break; //bit
case 16:
@ -1234,6 +1271,11 @@ static int gb_anop(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *data, int len
}
r_strbuf_append (&op->esil, ",N=0,H=0");
}
if (op->type == R_ANAL_OP_TYPE_CALL)
{
op->stackop = R_ANAL_STACK_INC;
op->stackptr = 2;
}
return op->size;
}

View File

@ -993,12 +993,13 @@ R_API int r_core_anal_search(RCore *core, ut64 from, ut64 to, ut64 ref) {
if (!r_anal_op (core->anal, &op, at+i, buf+i, core->blocksize-i))
continue;
if (op.type == R_ANAL_OP_TYPE_JMP || op.type == R_ANAL_OP_TYPE_CJMP ||
op.type == R_ANAL_OP_TYPE_CALL) {
op.type == R_ANAL_OP_TYPE_CALL || op.type == R_ANAL_OP_TYPE_CCALL) {
if (op.jump != -1 &&
r_core_anal_followptr (core, at+i, op.jump, ref, R_TRUE, 0)) {
count ++;
}
} else if (op.type == R_ANAL_OP_TYPE_UJMP || op.type == R_ANAL_OP_TYPE_UCALL) {
} else if (op.type == R_ANAL_OP_TYPE_UJMP || op.type == R_ANAL_OP_TYPE_UCALL ||
op.type == R_ANAL_OP_TYPE_UCJMP || op.type == R_ANAL_OP_TYPE_UCCALL) {
if (op.ptr != -1 &&
r_core_anal_followptr (core, at+i, op.ptr, ref, R_TRUE, 1)) {
count ++;
@ -1243,3 +1244,165 @@ TODO: sdbize
R_API void r_core_anal_stats_free (RCoreAnalStats *s) {
free (s);
}
R_API RList* r_core_anal_cycles (RCore *core, int ccl)
{
ut64 addr = core->offset;
RAnalOp *op = NULL;
RAnalCycleFrame *prev = NULL, *cf = r_anal_cycle_frame_new ();
RAnalCycleHook *ch;
RList *hooks = r_list_new ();
while (cf && !core->cons->breaked) {
if ((ccl > 0) && (op = r_core_anal_op (core, addr)) && (op->cycles)) {
r_cons_clear_line (1);
eprintf ("%i -- ", ccl);
addr += op->size;
switch (op->type) {
case R_ANAL_OP_TYPE_JMP:
addr = op->jump;
ccl -= op->cycles;
eprintf ("0x%08"PFMT64x" > 0x%08"PFMT64x"\r", op->addr, addr);
break;
case R_ANAL_OP_TYPE_UJMP:
case R_ANAL_OP_TYPE_UCALL:
ch = R_NEW0 (RAnalCycleHook);
ch->addr = op->addr;
eprintf ("0x%08"PFMT64x" > ?\r", op->addr);
ch->cycles = ccl;
r_list_append (hooks, ch);
ch = NULL;
while (!ch && cf) {
ch = r_list_pop (cf->hooks);
if (ch) {
addr = ch->addr;
ccl = ch->cycles;
free (ch);
} else {
r_anal_cycle_frame_free (cf);
cf = prev;
if (cf)
prev = cf->prev;
}
}
break;
case R_ANAL_OP_TYPE_CJMP:
ch = R_NEW0 (RAnalCycleHook);
ch->addr = addr;
ch->cycles = ccl - op->failcycles;
r_list_push (cf->hooks, ch);
ch = NULL;
addr = op->jump;
eprintf ("0x%08"PFMT64x" > 0x%08"PFMT64x"\r", op->addr, addr);
break;
case R_ANAL_OP_TYPE_UCJMP:
case R_ANAL_OP_TYPE_UCCALL:
ch = R_NEW0 (RAnalCycleHook);
ch->addr = op->addr;
ch->cycles = ccl;
r_list_append (hooks, ch);
ch = NULL;
ccl -= op->failcycles;
eprintf ("0x%08"PFMT64x" > ?\r");
break;
case R_ANAL_OP_TYPE_CCALL:
ch = R_NEW0 (RAnalCycleHook);
ch->addr = addr;
ch->cycles = ccl - op->failcycles;
r_list_push (cf->hooks, ch);
ch = NULL;
case R_ANAL_OP_TYPE_CALL:
if (op->addr != op->jump) { //no selfies
cf->naddr = addr;
prev = cf;
cf = r_anal_cycle_frame_new ();
cf->prev = prev;
}
ccl -= op->cycles;
addr = op->jump;
eprintf ("0x%08"PFMT64x" > 0x%08"PFMT64x"\r", op->addr, addr);
break;
case R_ANAL_OP_TYPE_RET:
ch = R_NEW0 (RAnalCycleHook);
if (prev) {
ch->addr = prev->naddr;
ccl -= op->cycles;
ch->cycles = ccl;
r_list_push (prev->hooks, ch);
eprintf ("0x%08"PFMT64x" < 0x%08"PFMT64x"\r", prev->naddr, op->addr);
} else {
ch->addr = op->addr;
ch->cycles = ccl;
r_list_append (hooks, ch);
eprintf ("? < 0x%08"PFMT64x"\r", op->addr);
}
ch = NULL;
while (!ch && cf) {
ch = r_list_pop (cf->hooks);
if (ch) {
addr = ch->addr;
ccl = ch->cycles;
free (ch);
} else {
r_anal_cycle_frame_free (cf);
cf = prev;
if (cf)
prev = cf->prev;
}
}
break;
case R_ANAL_OP_TYPE_CRET:
ch = R_NEW0 (RAnalCycleHook);
if (prev) {
ch->addr = prev->naddr;
ch->cycles = ccl - op->cycles;
r_list_push (prev->hooks, ch);
eprintf ("0x%08"PFMT64x" < 0x%08"PFMT64x"\r", prev->naddr, op->addr);
} else {
ch->addr = op->addr;
ch->cycles = ccl - op->cycles;
r_list_append (hooks, ch);
eprintf ("? < 0x%08"PFMT64x"\r", op->addr);
}
ccl -= op->failcycles;
break;
default:
ccl -= op->cycles;
eprintf ("0x%08"PFMT64x"\r", op->addr);
break;
}
r_anal_op_free (op);
} else {
ch = R_NEW0 (RAnalCycleHook);
ch->addr = addr;
ch->cycles = ccl;
r_list_append (hooks, ch);
ch = NULL;
while (!ch && cf) {
ch = r_list_pop (cf->hooks);
if (ch) {
addr = ch->addr;
ccl = ch->cycles;
free (ch);
} else {
r_anal_cycle_frame_free (cf);
cf = prev;
if (cf)
prev = cf->prev;
}
}
}
}
if (core->cons->breaked) {
while (cf) {
ch = r_list_pop (cf->hooks);
while (ch) {
free (ch);
ch = r_list_pop (cf->hooks);
}
prev = cf->prev;
r_anal_cycle_frame_free (cf);
cf = prev;
}
}
return hooks;
};

View File

@ -950,6 +950,35 @@ static int cmd_anal(void *data, const char *input) {
eprintf ("Interrupted\n");
r_cons_break_end();
break;
case 'c':
{
int ccl = r_num_math (core->num, &input[2]); //get cycles to look for
int cr = r_config_get_i (core->config, "asm.cmtright"); //make stuff look nice
int fun = r_config_get_i (core->config, "asm.functions");
int li = r_config_get_i (core->config, "asm.lines");
int xr = r_config_get_i (core->config, "asm.xrefs");
r_config_set_i (core->config, "asm.cmtright", R_TRUE);
r_config_set_i (core->config, "asm.functions", R_FALSE);
r_config_set_i (core->config, "asm.lines", R_FALSE);
r_config_set_i (core->config, "asm.xrefs", R_FALSE);
RList *hooks ;
RListIter *iter;
RAnalCycleHook *hook;
r_cons_break (NULL, NULL);
hooks = r_core_anal_cycles (core, ccl); //analyse
r_cons_break_end ();
r_cons_clear_line (1);
r_list_foreach (hooks, iter, hook) {
r_cons_printf ("After %4i cycles:\t%s", (ccl - hook->cycles), r_core_disassemble_instr (core, hook->addr, 1));
r_cons_flush ();
}
r_list_free (hooks);
r_config_set_i (core->config, "asm.cmtright", cr); //reset settings
r_config_set_i (core->config, "asm.functions", fun);
r_config_set_i (core->config, "asm.lines", li);
r_config_set_i (core->config, "asm.xrefs", xr);
}
break;
case 'p':
if (input[1]=='?') {
// TODO: accept parameters for ranges

View File

@ -206,12 +206,15 @@ static void handle_add_show_color ( RCore *core, RDisasmState *ds) {
r_cons_strcat (ds->color_jmp);
break;
case R_ANAL_OP_TYPE_CJMP:
case R_ANAL_OP_TYPE_UCJMP:
r_cons_strcat (ds->color_cjmp);
break;
case R_ANAL_OP_TYPE_CMP:
case R_ANAL_OP_TYPE_ACMP:
r_cons_strcat (ds->color_cmp);
break;
case R_ANAL_OP_TYPE_UCALL:
case R_ANAL_OP_TYPE_UCCALL:
case R_ANAL_OP_TYPE_CALL:
case R_ANAL_OP_TYPE_CCALL:
r_cons_strcat (ds->color_call);

View File

@ -392,9 +392,11 @@ typedef enum {
R_ANAL_OP_TYPE_JMP = 1, /* mandatory jump */
R_ANAL_OP_TYPE_UJMP = 2, /* unknown jump (register or so) */
R_ANAL_OP_TYPE_CJMP = R_ANAL_OP_TYPE_COND | R_ANAL_OP_TYPE_JMP, /* conditional jump */
R_ANAL_OP_TYPE_UCJMP = R_ANAL_OP_TYPE_COND | R_ANAL_OP_TYPE_UJMP, /* conditional unknown jump */
R_ANAL_OP_TYPE_CALL = 3, /* call to subroutine (branch+link) */
R_ANAL_OP_TYPE_UCALL = 4, /* unknown call (register or so) */
R_ANAL_OP_TYPE_CCALL = R_ANAL_OP_TYPE_COND | R_ANAL_OP_TYPE_CALL, /* conditional call to subroutine */
R_ANAL_OP_TYPE_UCCALL= R_ANAL_OP_TYPE_COND | R_ANAL_OP_TYPE_UCALL, /* conditional unknown call */
R_ANAL_OP_TYPE_RET = 5, /* returns from subroutine */
R_ANAL_OP_TYPE_CRET = R_ANAL_OP_TYPE_COND | R_ANAL_OP_TYPE_RET, /* conditional return from subroutine */
R_ANAL_OP_TYPE_ILL = 6, /* illegal instruction // trap */
@ -406,29 +408,30 @@ typedef enum {
R_ANAL_OP_TYPE_UPUSH = 12, /* unknown push of data into stack */
R_ANAL_OP_TYPE_PUSH = 13, /* push value into stack */
R_ANAL_OP_TYPE_POP = 14, /* pop value from stack to register */
R_ANAL_OP_TYPE_CMP = 15, /* copmpare something */
R_ANAL_OP_TYPE_ADD = 16,
R_ANAL_OP_TYPE_SUB = 17,
R_ANAL_OP_TYPE_IO = 18,
R_ANAL_OP_TYPE_MUL = 19,
R_ANAL_OP_TYPE_DIV = 20,
R_ANAL_OP_TYPE_SHR = 21,
R_ANAL_OP_TYPE_SHL = 22,
R_ANAL_OP_TYPE_SAL = 23,
R_ANAL_OP_TYPE_SAR = 24,
R_ANAL_OP_TYPE_OR = 25,
R_ANAL_OP_TYPE_AND = 26,
R_ANAL_OP_TYPE_XOR = 27,
R_ANAL_OP_TYPE_NOT = 28,
R_ANAL_OP_TYPE_STORE = 29, /* store from register to memory */
R_ANAL_OP_TYPE_LOAD = 30, /* load from memory to register */
R_ANAL_OP_TYPE_LEA = 31,
R_ANAL_OP_TYPE_LEAVE = 32,
R_ANAL_OP_TYPE_ROR = 33,
R_ANAL_OP_TYPE_ROL = 34,
R_ANAL_OP_TYPE_XCHG = 35,
R_ANAL_OP_TYPE_MOD = 36,
R_ANAL_OP_TYPE_SWITCH = 37,
R_ANAL_OP_TYPE_CMP = 15, /* compare something */
R_ANAL_OP_TYPE_ACMP = 16, /* compare via and */
R_ANAL_OP_TYPE_ADD = 17,
R_ANAL_OP_TYPE_SUB = 18,
R_ANAL_OP_TYPE_IO = 19,
R_ANAL_OP_TYPE_MUL = 20,
R_ANAL_OP_TYPE_DIV = 21,
R_ANAL_OP_TYPE_SHR = 22,
R_ANAL_OP_TYPE_SHL = 23,
R_ANAL_OP_TYPE_SAL = 24,
R_ANAL_OP_TYPE_SAR = 25,
R_ANAL_OP_TYPE_OR = 26,
R_ANAL_OP_TYPE_AND = 27,
R_ANAL_OP_TYPE_XOR = 28,
R_ANAL_OP_TYPE_NOT = 29,
R_ANAL_OP_TYPE_STORE = 30, /* store from register to memory */
R_ANAL_OP_TYPE_LOAD = 31, /* load from memory to register */
R_ANAL_OP_TYPE_LEA = 32,
R_ANAL_OP_TYPE_LEAVE = 33,
R_ANAL_OP_TYPE_ROR = 34,
R_ANAL_OP_TYPE_ROL = 35,
R_ANAL_OP_TYPE_XCHG = 36,
R_ANAL_OP_TYPE_MOD = 37,
R_ANAL_OP_TYPE_SWITCH = 38,
} _RAnalOp;
/* TODO: what to do with signed/unsigned conditionals? */
@ -739,6 +742,17 @@ typedef struct r_anal_state_type_t {
void *user_state;
} RAnalState;
typedef struct r_anal_cycle_frame_t {
ut64 naddr; //next addr
RList *hooks;
struct r_anal_cycle_frame_t *prev;
} RAnalCycleFrame;
typedef struct r_anal_cycle_hook_t { //rename ?
ut64 addr;
int cycles;
} RAnalCycleHook;
typedef int (*RAnalCmdExt)(/* Rcore */RAnal *anal, const char* input);
typedef int (*RAnalAnalyzeFunctions)(RAnal *a, ut64 at, ut64 from, int reftype, int depth);
typedef int (*RAnalExCallback)(RAnal *a, struct r_anal_state_type_t *state, ut64 addr);
@ -1089,6 +1103,10 @@ R_API RAnalSwitchOp * r_anal_switch_op_new(ut64 addr, ut64 min_val, ut64 max_val
R_API void r_anal_switch_op_free(RAnalSwitchOp * swop);
R_API RAnalCaseOp* r_anal_switch_op_add_case(RAnalSwitchOp * swop, ut64 addr, ut64 jump, ut64 value);
/* cycles.c */
R_API RAnalCycleFrame* r_anal_cycle_frame_new ();
R_API void r_anal_cycle_frame_free (RAnalCycleFrame *cf);
/*
* RAnalState maintains state during analysis.
* there are standard values current_fcn, current_op, current_bb, addr,

View File

@ -265,6 +265,7 @@ R_API int r_core_anal_graph_fcn(RCore *core, char *input, int opts);
R_API RList* r_core_anal_graph_to(RCore *core, ut64 addr, int n);
R_API int r_core_anal_ref_list(RCore *core, int rad);
R_API int r_core_anal_all(RCore *core);
R_API RList* r_core_anal_cycles (RCore *core, int ccl);
/* asm.c */
typedef struct r_core_asm_hit {