mirror of
https://github.com/radareorg/radare2.git
synced 2024-11-27 23:20:40 +00:00
Implement RAnalCycleFrame Stuff, New optypes and esil-adc/sbc
This commit is contained in:
parent
598fe87f3c
commit
d6dae07979
@ -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
18
libr/anal/cycles.c
Normal 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);
|
||||
}
|
@ -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";
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
167
libr/core/anal.c
167
libr/core/anal.c
@ -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;
|
||||
};
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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 {
|
||||
|
Loading…
Reference in New Issue
Block a user