* Rename r_anal_aop_* to r_anal_op_*
--HG-- rename : libr/anal/aop.c => libr/anal/op.c
This commit is contained in:
parent
af604bed6b
commit
332524e120
|
@ -62,27 +62,27 @@ static char *optype2str(int type) {
|
|||
|
||||
}
|
||||
|
||||
static int analyze(RAnal *anal, RAnalOp *aop, ut64 offset, ut8* buf, int len) {
|
||||
static int analyze(RAnal *anal, RAnalOp *op, ut64 offset, ut8* buf, int len) {
|
||||
char *bytes, *optype = NULL, *stackop = NULL;
|
||||
int ret;
|
||||
|
||||
ret = r_anal_aop (anal, aop, offset, buf, len);
|
||||
ret = r_anal_op (anal, op, offset, buf, len);
|
||||
if (ret) {
|
||||
stackop = stackop2str (aop->stackop);
|
||||
optype = optype2str (aop->type);
|
||||
stackop = stackop2str (op->stackop);
|
||||
optype = optype2str (op->type);
|
||||
bytes = r_hex_bin2strdup (buf, ret);
|
||||
printf ("bytes: %s\n", bytes);
|
||||
printf ("type: %s\n", optype);
|
||||
if (aop->jump != -1LL)
|
||||
printf ("jump: 0x%08"PFMT64x"\n", aop->jump);
|
||||
if (aop->fail != -1LL)
|
||||
printf ("fail: 0x%08"PFMT64x"\n", aop->fail);
|
||||
if (aop->ref != -1LL)
|
||||
printf ("ref: 0x%08"PFMT64x"\n", aop->ref);
|
||||
if (aop->value != -1LL)
|
||||
printf ("value: 0x%08"PFMT64x"\n", aop->value);
|
||||
if (op->jump != -1LL)
|
||||
printf ("jump: 0x%08"PFMT64x"\n", op->jump);
|
||||
if (op->fail != -1LL)
|
||||
printf ("fail: 0x%08"PFMT64x"\n", op->fail);
|
||||
if (op->ref != -1LL)
|
||||
printf ("ref: 0x%08"PFMT64x"\n", op->ref);
|
||||
if (op->value != -1LL)
|
||||
printf ("value: 0x%08"PFMT64x"\n", op->value);
|
||||
printf ("stackop: %s\n", stackop);
|
||||
printf ("stackptr: %"PFMT64d"\n", aop->stackptr);
|
||||
printf ("stackptr: %"PFMT64d"\n", op->stackptr);
|
||||
printf ("--\n");
|
||||
free (optype);
|
||||
free (stackop);
|
||||
|
@ -107,7 +107,7 @@ static int usage() {
|
|||
int main(int argc, char **argv) {
|
||||
RLib *lib;
|
||||
RAnal *anal = r_anal_new ();
|
||||
RAnalOp *aop = r_anal_aop_new ();
|
||||
RAnalOp *op = r_anal_op_new ();
|
||||
ut8 *ptr, *buf = NULL, *data = NULL;
|
||||
ut64 offset = 0x8048000LL;
|
||||
char *arch = NULL;
|
||||
|
@ -184,16 +184,16 @@ int main(int argc, char **argv) {
|
|||
}
|
||||
/* Analyze */
|
||||
for (idx=ret=0; idx<len; idx+=ret) {
|
||||
if (!(ret = analyze (anal, aop, offset+idx, data+idx, len-idx))) {
|
||||
if (!(ret = analyze (anal, op, offset+idx, data+idx, len-idx))) {
|
||||
eprintf ("Ooops\n");
|
||||
free (data);
|
||||
r_anal_free (anal);
|
||||
r_anal_aop_free (aop);
|
||||
r_anal_op_free (op);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
free (data);
|
||||
r_anal_free (anal);
|
||||
r_anal_aop_free (aop);
|
||||
r_anal_op_free (op);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ foo: pre libr_anal.${EXT_SO} libr_anal.${EXT_AR} plugins
|
|||
|
||||
include ${STATIC_ANAL_PLUGINS}
|
||||
STATIC_OBJS=$(subst ../ar,p/../ar,$(subst anal_,p/anal_,$(STATIC_OBJ)))
|
||||
OBJLIBS=meta.o reflines.o ref.o aop.o fcn.o bb.o var.o anal.o cond.o value.o cc.o diff.o type.o
|
||||
OBJLIBS=meta.o reflines.o ref.o op.o fcn.o bb.o var.o anal.o cond.o value.o cc.o diff.o type.o
|
||||
OBJ=${STATIC_OBJS} ${OBJLIBS}
|
||||
|
||||
pre:
|
||||
|
|
|
@ -118,36 +118,36 @@ R_API int r_anal_set_big_endian(RAnal *anal, int bigend) {
|
|||
}
|
||||
|
||||
R_API char *r_anal_strmask (RAnal *anal, const char *data) {
|
||||
RAnalOp *aop;
|
||||
RAnalOp *op;
|
||||
ut8 *buf;
|
||||
char *ret = NULL;
|
||||
int oplen, len, idx = 0;
|
||||
|
||||
ret = strdup (data);
|
||||
buf = malloc (strlen (data));
|
||||
aop = r_anal_aop_new ();
|
||||
if (aop == NULL || ret == NULL || buf == NULL) {
|
||||
free (aop);
|
||||
op = r_anal_op_new ();
|
||||
if (op == NULL || ret == NULL || buf == NULL) {
|
||||
free (op);
|
||||
free (buf);
|
||||
free (ret);
|
||||
return NULL;
|
||||
}
|
||||
len = r_hex_str2bin (data, buf);
|
||||
while (idx < len) {
|
||||
if ((oplen = r_anal_aop (anal, aop, 0, buf+idx, len-idx)) == 0)
|
||||
if ((oplen = r_anal_op (anal, op, 0, buf+idx, len-idx)) == 0)
|
||||
break;
|
||||
switch (aop->type) {
|
||||
switch (op->type) {
|
||||
case R_ANAL_OP_TYPE_CALL:
|
||||
case R_ANAL_OP_TYPE_UCALL:
|
||||
case R_ANAL_OP_TYPE_CJMP:
|
||||
case R_ANAL_OP_TYPE_JMP:
|
||||
case R_ANAL_OP_TYPE_UJMP:
|
||||
if (aop->nopcode != 0)
|
||||
memset (ret+(idx+aop->nopcode)*2, '.', (oplen-aop->nopcode)*2);
|
||||
if (op->nopcode != 0)
|
||||
memset (ret+(idx+op->nopcode)*2, '.', (oplen-op->nopcode)*2);
|
||||
}
|
||||
idx += oplen;
|
||||
}
|
||||
free (aop);
|
||||
free (op);
|
||||
free (buf);
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ R_API RAnalBlock *r_anal_bb_new() {
|
|||
bb->jump = -1;
|
||||
bb->fail = -1;
|
||||
bb->type = R_ANAL_BB_TYPE_NULL;
|
||||
bb->aops = r_anal_aop_list_new();
|
||||
bb->ops = r_anal_op_list_new();
|
||||
bb->cond = NULL;
|
||||
bb->fingerprint = NULL;
|
||||
bb->diff = r_anal_diff_new ();
|
||||
|
@ -31,8 +31,8 @@ R_API void r_anal_bb_free(void *_bb) {
|
|||
RAnalBlock *bb = _bb;
|
||||
free (bb->cond);
|
||||
free (bb->fingerprint);
|
||||
if (bb->aops)
|
||||
r_list_free (bb->aops);
|
||||
if (bb->ops)
|
||||
r_list_free (bb->ops);
|
||||
if (bb->diff)
|
||||
r_anal_diff_free (bb->diff);
|
||||
free (bb);
|
||||
|
@ -40,18 +40,18 @@ R_API void r_anal_bb_free(void *_bb) {
|
|||
}
|
||||
|
||||
R_API int r_anal_bb(RAnal *anal, RAnalBlock *bb, ut64 addr, ut8 *buf, ut64 len, int head) {
|
||||
RAnalOp *aop = NULL;
|
||||
RAnalOp *op = NULL;
|
||||
int oplen, idx = 0;
|
||||
|
||||
if (bb->addr == -1)
|
||||
bb->addr = addr;
|
||||
while (idx < len) {
|
||||
if (!(aop = r_anal_aop_new ())) {
|
||||
eprintf ("Error: new (aop)\n");
|
||||
if (!(op = r_anal_op_new ())) {
|
||||
eprintf ("Error: new (op)\n");
|
||||
return R_ANAL_RET_ERROR;
|
||||
}
|
||||
if ((oplen = r_anal_aop (anal, aop, addr+idx, buf+idx, len-idx)) == 0) {
|
||||
r_anal_aop_free (aop);
|
||||
if ((oplen = r_anal_op (anal, op, addr+idx, buf+idx, len-idx)) == 0) {
|
||||
r_anal_op_free (op);
|
||||
if (idx == 0) {
|
||||
VERBOSE_ANAL eprintf ("Unknown opcode at 0x%08"PFMT64x"\n", addr+idx);
|
||||
return R_ANAL_RET_END;
|
||||
|
@ -61,12 +61,12 @@ R_API int r_anal_bb(RAnal *anal, RAnalBlock *bb, ut64 addr, ut8 *buf, ut64 len,
|
|||
idx += oplen;
|
||||
bb->size += oplen;
|
||||
bb->ninstr++;
|
||||
r_list_append (bb->aops, aop);
|
||||
r_list_append (bb->ops, op);
|
||||
if (head)
|
||||
bb->type = R_ANAL_BB_TYPE_HEAD;
|
||||
switch (aop->type) {
|
||||
switch (op->type) {
|
||||
case R_ANAL_OP_TYPE_CMP:
|
||||
bb->cond = r_anal_cond_new_from_aop (aop);
|
||||
bb->cond = r_anal_cond_new_from_op (op);
|
||||
break;
|
||||
case R_ANAL_OP_TYPE_CJMP:
|
||||
if (bb->cond) {
|
||||
|
@ -74,12 +74,12 @@ R_API int r_anal_bb(RAnal *anal, RAnalBlock *bb, ut64 addr, ut8 *buf, ut64 len,
|
|||
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 = aop->fail;
|
||||
bb->jump = aop->jump;
|
||||
bb->fail = op->fail;
|
||||
bb->jump = op->jump;
|
||||
bb->type |= R_ANAL_BB_TYPE_BODY;
|
||||
return R_ANAL_RET_END;
|
||||
case R_ANAL_OP_TYPE_JMP:
|
||||
bb->jump = aop->jump;
|
||||
bb->jump = op->jump;
|
||||
bb->type |= R_ANAL_BB_TYPE_BODY;
|
||||
return R_ANAL_RET_END;
|
||||
case R_ANAL_OP_TYPE_UJMP:
|
||||
|
|
|
@ -82,7 +82,7 @@ R_API char *r_anal_cond_to_string(RAnalCond *cond) {
|
|||
return out;
|
||||
}
|
||||
|
||||
R_API RAnalCond *r_anal_cond_new_from_aop(RAnalOp *op) {
|
||||
R_API RAnalCond *r_anal_cond_new_from_op(RAnalOp *op) {
|
||||
RAnalCond *cond;
|
||||
if (!(cond = r_anal_cond_new()))
|
||||
return NULL;
|
||||
|
|
|
@ -43,7 +43,7 @@ R_API void r_anal_fcn_free(void *_fcn) {
|
|||
}
|
||||
|
||||
R_API int r_anal_fcn(RAnal *anal, RAnalFcn *fcn, ut64 addr, ut8 *buf, ut64 len, int reftype) {
|
||||
RAnalOp aop;
|
||||
RAnalOp op;
|
||||
RAnalRef *ref;
|
||||
char *varname;
|
||||
int oplen, idx = 0;
|
||||
|
@ -52,7 +52,7 @@ R_API int r_anal_fcn(RAnal *anal, RAnalFcn *fcn, ut64 addr, ut8 *buf, ut64 len,
|
|||
fcn->type = (reftype==R_ANAL_REF_TYPE_CODE)?
|
||||
R_ANAL_FCN_TYPE_LOC: R_ANAL_FCN_TYPE_FCN;
|
||||
while (idx < len) {
|
||||
if ((oplen = r_anal_aop (anal, &aop, addr+idx, buf+idx, len-idx)) == 0) {
|
||||
if ((oplen = r_anal_op (anal, &op, addr+idx, buf+idx, len-idx)) == 0) {
|
||||
if (idx == 0) {
|
||||
VERBOSE eprintf ("Unknown opcode at 0x%08"PFMT64x"\n", addr+idx);
|
||||
return R_ANAL_RET_END;
|
||||
|
@ -62,36 +62,36 @@ R_API int r_anal_fcn(RAnal *anal, RAnalFcn *fcn, ut64 addr, ut8 *buf, ut64 len,
|
|||
idx += oplen;
|
||||
fcn->size += oplen;
|
||||
/* TODO: Parse fastargs (R_ANAL_VAR_ARGREG) */
|
||||
switch (aop.stackop) {
|
||||
switch (op.stackop) {
|
||||
case R_ANAL_STACK_INCSTACK:
|
||||
fcn->stack += aop.value;
|
||||
fcn->stack += op.value;
|
||||
break;
|
||||
case R_ANAL_STACK_SET:
|
||||
if (aop.ref > 0) {
|
||||
varname = r_str_dup_printf ("arg_%x", aop.ref);
|
||||
r_anal_var_add (anal, fcn, aop.addr, aop.ref,
|
||||
if (op.ref > 0) {
|
||||
varname = r_str_dup_printf ("arg_%x", op.ref);
|
||||
r_anal_var_add (anal, fcn, op.addr, op.ref,
|
||||
R_ANAL_VAR_TYPE_ARG|R_ANAL_VAR_DIR_IN, NULL, varname, 1);
|
||||
} else {
|
||||
varname = r_str_dup_printf ("local_%x", -aop.ref);
|
||||
r_anal_var_add (anal, fcn, aop.addr, -aop.ref,
|
||||
varname = r_str_dup_printf ("local_%x", -op.ref);
|
||||
r_anal_var_add (anal, fcn, op.addr, -op.ref,
|
||||
R_ANAL_VAR_TYPE_LOCAL|R_ANAL_VAR_DIR_NONE, NULL, varname, 1);
|
||||
}
|
||||
free (varname);
|
||||
break;
|
||||
case R_ANAL_STACK_GET:
|
||||
if (aop.ref > 0) {
|
||||
varname = r_str_dup_printf ("arg_%x", aop.ref);
|
||||
r_anal_var_add (anal, fcn, aop.addr, aop.ref,
|
||||
if (op.ref > 0) {
|
||||
varname = r_str_dup_printf ("arg_%x", op.ref);
|
||||
r_anal_var_add (anal, fcn, op.addr, op.ref,
|
||||
R_ANAL_VAR_TYPE_ARG|R_ANAL_VAR_DIR_IN, NULL, varname, 0);
|
||||
} else {
|
||||
varname = r_str_dup_printf ("local_%x", -aop.ref);
|
||||
r_anal_var_add (anal, fcn, aop.addr, -aop.ref,
|
||||
varname = r_str_dup_printf ("local_%x", -op.ref);
|
||||
r_anal_var_add (anal, fcn, op.addr, -op.ref,
|
||||
R_ANAL_VAR_TYPE_LOCAL|R_ANAL_VAR_DIR_NONE, NULL, varname, 0);
|
||||
}
|
||||
free (varname);
|
||||
break;
|
||||
}
|
||||
switch (aop.type) {
|
||||
switch (op.type) {
|
||||
case R_ANAL_OP_TYPE_JMP:
|
||||
case R_ANAL_OP_TYPE_CJMP:
|
||||
case R_ANAL_OP_TYPE_CALL:
|
||||
|
@ -101,10 +101,10 @@ R_API int r_anal_fcn(RAnal *anal, RAnalFcn *fcn, ut64 addr, ut8 *buf, ut64 len,
|
|||
return R_ANAL_RET_ERROR;
|
||||
}
|
||||
ref = R_NEW (RAnalRef);
|
||||
ref->type = aop.type == R_ANAL_OP_TYPE_CALL?
|
||||
ref->type = op.type == R_ANAL_OP_TYPE_CALL?
|
||||
R_ANAL_REF_TYPE_CALL : R_ANAL_REF_TYPE_CODE;
|
||||
ref->at = aop.addr;
|
||||
ref->addr = aop.jump;
|
||||
ref->at = op.addr;
|
||||
ref->addr = op.jump;
|
||||
r_list_append (fcn->refs, ref);
|
||||
break;
|
||||
case R_ANAL_OP_TYPE_RET:
|
||||
|
@ -207,7 +207,7 @@ R_API int r_anal_fcn_add_bb(RAnalFcn *fcn, ut64 addr, ut64 size, ut64 jump, ut64
|
|||
|
||||
R_API int r_anal_fcn_split_bb(RAnalFcn *fcn, RAnalBlock *bb, ut64 addr) {
|
||||
RAnalBlock *bbi;
|
||||
RAnalOp *aopi;
|
||||
RAnalOp *opi;
|
||||
RListIter *iter;
|
||||
|
||||
r_list_foreach (fcn->bbs, iter, bbi)
|
||||
|
@ -231,13 +231,13 @@ R_API int r_anal_fcn_split_bb(RAnalFcn *fcn, RAnalBlock *bb, ut64 addr) {
|
|||
bb->type = bbi->type;
|
||||
bbi->type = R_ANAL_BB_TYPE_BODY;
|
||||
}
|
||||
iter = r_list_iterator (bbi->aops);
|
||||
iter = r_list_iterator (bbi->ops);
|
||||
while (r_list_iter_next (iter)) {
|
||||
aopi = r_list_iter_get (iter);
|
||||
if (aopi->addr >= addr) {
|
||||
r_list_split (bbi->aops, aopi);
|
||||
opi = r_list_iter_get (iter);
|
||||
if (opi->addr >= addr) {
|
||||
r_list_split (bbi->ops, opi);
|
||||
bbi->ninstr--;
|
||||
r_list_append (bb->aops, aopi);
|
||||
r_list_append (bb->ops, opi);
|
||||
bb->ninstr++;
|
||||
}
|
||||
}
|
||||
|
@ -248,7 +248,7 @@ R_API int r_anal_fcn_split_bb(RAnalFcn *fcn, RAnalBlock *bb, ut64 addr) {
|
|||
|
||||
R_API int r_anal_fcn_overlap_bb(RAnalFcn *fcn, RAnalBlock *bb) {
|
||||
RAnalBlock *bbi;
|
||||
RAnalOp *aopi;
|
||||
RAnalOp *opi;
|
||||
RListIter *iter;
|
||||
|
||||
r_list_foreach (fcn->bbs, iter, bbi)
|
||||
|
@ -261,9 +261,9 @@ R_API int r_anal_fcn_overlap_bb(RAnalFcn *fcn, RAnalBlock *bb) {
|
|||
bb->type = R_ANAL_BB_TYPE_HEAD;
|
||||
bbi->type = bbi->type^R_ANAL_BB_TYPE_HEAD;
|
||||
} else bb->type = R_ANAL_BB_TYPE_BODY;
|
||||
r_list_foreach (bb->aops, iter, aopi)
|
||||
if (aopi->addr >= bbi->addr)
|
||||
r_list_unlink (bb->aops, aopi);
|
||||
r_list_foreach (bb->ops, iter, opi)
|
||||
if (opi->addr >= bbi->addr)
|
||||
r_list_unlink (bb->ops, opi);
|
||||
r_list_append (fcn->bbs, bb);
|
||||
return R_ANAL_RET_END;
|
||||
}
|
||||
|
|
|
@ -5,47 +5,47 @@
|
|||
#include <r_util.h>
|
||||
#include <r_list.h>
|
||||
|
||||
R_API RAnalOp *r_anal_aop_new() {
|
||||
RAnalOp *aop = R_NEW (RAnalOp);
|
||||
if (aop) {
|
||||
memset (aop, 0, sizeof (RAnalOp));
|
||||
aop->mnemonic = NULL;
|
||||
aop->addr = -1;
|
||||
aop->jump = -1;
|
||||
aop->fail = -1;
|
||||
aop->ref = -1;
|
||||
aop->value = -1;
|
||||
R_API RAnalOp *r_anal_op_new() {
|
||||
RAnalOp *op = R_NEW (RAnalOp);
|
||||
if (op) {
|
||||
memset (op, 0, sizeof (RAnalOp));
|
||||
op->mnemonic = NULL;
|
||||
op->addr = -1;
|
||||
op->jump = -1;
|
||||
op->fail = -1;
|
||||
op->ref = -1;
|
||||
op->value = -1;
|
||||
}
|
||||
return aop;
|
||||
return op;
|
||||
}
|
||||
|
||||
R_API RList *r_anal_aop_list_new() {
|
||||
R_API RList *r_anal_op_list_new() {
|
||||
RList *list = r_list_new ();
|
||||
list->free = &r_anal_aop_free;
|
||||
list->free = &r_anal_op_free;
|
||||
return list;
|
||||
}
|
||||
|
||||
R_API void r_anal_aop_free(void *_aop) {
|
||||
if (_aop) {
|
||||
RAnalOp *aop = _aop;
|
||||
r_anal_value_free (aop->src[0]);
|
||||
r_anal_value_free (aop->src[1]);
|
||||
r_anal_value_free (aop->src[2]);
|
||||
r_anal_value_free (aop->dst);
|
||||
free (aop->mnemonic);
|
||||
free (aop);
|
||||
R_API void r_anal_op_free(void *_op) {
|
||||
if (_op) {
|
||||
RAnalOp *op = _op;
|
||||
r_anal_value_free (op->src[0]);
|
||||
r_anal_value_free (op->src[1]);
|
||||
r_anal_value_free (op->src[2]);
|
||||
r_anal_value_free (op->dst);
|
||||
free (op->mnemonic);
|
||||
free (op);
|
||||
}
|
||||
}
|
||||
|
||||
R_API int r_anal_aop(RAnal *anal, RAnalOp *aop, ut64 addr, const ut8 *data, int len) {
|
||||
if (anal && aop && anal->cur && anal->cur->aop)
|
||||
return anal->cur->aop (anal, aop, addr, data, len);
|
||||
R_API int r_anal_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *data, int len) {
|
||||
if (anal && op && anal->cur && anal->cur->op)
|
||||
return anal->cur->op (anal, op, addr, data, len);
|
||||
return R_FALSE;
|
||||
}
|
||||
|
||||
// TODO: return RAnalException *
|
||||
R_API int r_anal_aop_execute (RAnal *anal, RAnalOp *aop) {
|
||||
switch (aop->type) {
|
||||
R_API int r_anal_op_execute (RAnal *anal, RAnalOp *op) {
|
||||
switch (op->type) {
|
||||
case R_ANAL_OP_TYPE_ADD:
|
||||
// dst = src[0] + src[1] + src[2]
|
||||
break;
|
||||
|
@ -63,7 +63,7 @@ R_API int r_anal_aop_execute (RAnal *anal, RAnalOp *aop) {
|
|||
return R_TRUE;
|
||||
}
|
||||
|
||||
R_API char *r_anal_aop_to_string(RAnal *anal, RAnalOp *op) {
|
||||
R_API char *r_anal_op_to_string(RAnal *anal, RAnalOp *op) {
|
||||
int retsz = 128;
|
||||
char *cstr, *ret = malloc (128);
|
||||
char *r0 = r_anal_value_to_string (op->dst);
|
|
@ -43,199 +43,199 @@ static unsigned int disarm_branch_offset (unsigned int pc, unsigned int insoff)
|
|||
#define API static
|
||||
#include "../../asm/arch/arm/armthumb.c"
|
||||
|
||||
static int aop_thumb(RAnal *anal, RAnalOp *aop, ut64 addr, const ut8 *data, int len) {
|
||||
static int op_thumb(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *data, int len) {
|
||||
int op_code;
|
||||
ut16 *_ins = (ut16*)data;
|
||||
ut16 ins = *_ins;
|
||||
aop->length = armthumb_length (ins);
|
||||
op->length = armthumb_length (ins);
|
||||
// TODO: handle 32bit instructions (branches are not correctly decoded //
|
||||
|
||||
/* CMP */
|
||||
if (((ins & _(B1110,0,0,0)) == _(B0010,0,0,0) )
|
||||
&& (1 == (ins & _(1,B1000,0,0)) >> 11)) { // dp3
|
||||
aop->type = R_ANAL_OP_TYPE_CMP;
|
||||
return aop->length;
|
||||
op->type = R_ANAL_OP_TYPE_CMP;
|
||||
return op->length;
|
||||
}
|
||||
if ( (ins & _(B1111,B1100,0,0)) == _(B0100,0,0,0) ) {
|
||||
op_code = (ins & _(0,B0011,B1100,0)) >> 6;
|
||||
if (op_code == 8 || op_code == 10) { // dp5
|
||||
aop->type = R_ANAL_OP_TYPE_CMP;
|
||||
return aop->length;
|
||||
op->type = R_ANAL_OP_TYPE_CMP;
|
||||
return op->length;
|
||||
}
|
||||
}
|
||||
if ( (ins & _(B1111,B1100,0,0)) == _(B0100,B0100,0,0) ) {
|
||||
op_code = (ins & _(0,B0011,0,0)) >> 8; // dp8
|
||||
if (op_code== 1) {
|
||||
aop->type = R_ANAL_OP_TYPE_CMP;
|
||||
return aop->length;
|
||||
op->type = R_ANAL_OP_TYPE_CMP;
|
||||
return op->length;
|
||||
}
|
||||
}
|
||||
|
||||
if (ins == 0xbf) {
|
||||
// TODO: add support for more NOP instructions
|
||||
aop->type = R_ANAL_OP_TYPE_NOP;
|
||||
op->type = R_ANAL_OP_TYPE_NOP;
|
||||
} else if (((op_code = ((ins & _(B1111,B1000,0,0)) >> 11)) >= 12 && op_code <= 17 )) {
|
||||
if (op_code%2)
|
||||
aop->type = R_ANAL_OP_TYPE_LOAD;
|
||||
else aop->type = R_ANAL_OP_TYPE_STORE;
|
||||
op->type = R_ANAL_OP_TYPE_LOAD;
|
||||
else op->type = R_ANAL_OP_TYPE_STORE;
|
||||
} else if ( (ins & _(B1111,0,0,0)) == _(B0101,0,0,0) ) {
|
||||
op_code = (ins & _(0,B1110,0,0)) >> 9;
|
||||
if (op_code%2)
|
||||
aop->type = R_ANAL_OP_TYPE_LOAD;
|
||||
else aop->type = R_ANAL_OP_TYPE_STORE;
|
||||
op->type = R_ANAL_OP_TYPE_LOAD;
|
||||
else op->type = R_ANAL_OP_TYPE_STORE;
|
||||
} else if ( (ins & _(B1111,0,0,0)) == _(B1101,0,0,0) ) {
|
||||
// BNE..
|
||||
int delta = (ins & _(0,0,B1111,B1111));
|
||||
aop->type = R_ANAL_OP_TYPE_CJMP;
|
||||
aop->jump = addr+4+(delta<<1);
|
||||
aop->fail = addr+4;
|
||||
op->type = R_ANAL_OP_TYPE_CJMP;
|
||||
op->jump = addr+4+(delta<<1);
|
||||
op->fail = addr+4;
|
||||
} else if ( (ins & _(B1110,B1000,0,0)) == _(B1110,0,0,0) ) {
|
||||
// B
|
||||
int delta = (ins & _(0,0,B1111,B1111));
|
||||
aop->type = R_ANAL_OP_TYPE_JMP;
|
||||
aop->jump = addr+4+(delta<<1);
|
||||
aop->fail = addr+4;
|
||||
op->type = R_ANAL_OP_TYPE_JMP;
|
||||
op->jump = addr+4+(delta<<1);
|
||||
op->fail = addr+4;
|
||||
} else if ( (ins & _(B1111,B1111,0,0)) == _(B0100,B0111,0,0) ) {
|
||||
// BLX
|
||||
aop->type = R_ANAL_OP_TYPE_UJMP;
|
||||
aop->jump = addr+4+(ut32)((ins & _(0,0,B0111,B1000)) >> 3);
|
||||
aop->fail = addr+4;
|
||||
op->type = R_ANAL_OP_TYPE_UJMP;
|
||||
op->jump = addr+4+(ut32)((ins & _(0,0,B0111,B1000)) >> 3);
|
||||
op->fail = addr+4;
|
||||
} else if ( (ins & _(B1111,B1111,0,0)) == _(B1011,B1110,0,0) ) {
|
||||
aop->type = R_ANAL_OP_TYPE_TRAP;
|
||||
aop->value = (ut64)(ins>>8);
|
||||
op->type = R_ANAL_OP_TYPE_TRAP;
|
||||
op->value = (ut64)(ins>>8);
|
||||
} else if ( (ins & _(B1111,B1111,0,0)) == _(B1101,B1111,0,0)) {
|
||||
aop->type = R_ANAL_OP_TYPE_SWI;
|
||||
aop->value = (ut64)(ins>>8);
|
||||
op->type = R_ANAL_OP_TYPE_SWI;
|
||||
op->value = (ut64)(ins>>8);
|
||||
}
|
||||
return aop->length;
|
||||
return op->length;
|
||||
}
|
||||
|
||||
static int aop(RAnal *anal, RAnalOp *aop, ut64 addr, const ut8 *data, int len) {
|
||||
static int arm_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *data, int len) {
|
||||
ut32 branch_dst_addr, i = 0;
|
||||
ut32* code = (ut32 *)data;
|
||||
const ut8 *b = (ut8 *)data;
|
||||
|
||||
if (data == NULL)
|
||||
return 0;
|
||||
memset (aop, '\0', sizeof (RAnalOp));
|
||||
aop->addr = addr;
|
||||
aop->type = R_ANAL_OP_TYPE_UNK;
|
||||
aop->jump = aop->fail = -1;
|
||||
aop->ref = aop->value = -1;
|
||||
memset (op, '\0', sizeof (RAnalOp));
|
||||
op->addr = addr;
|
||||
op->type = R_ANAL_OP_TYPE_UNK;
|
||||
op->jump = op->fail = -1;
|
||||
op->ref = op->value = -1;
|
||||
if (anal->bits==16)
|
||||
return aop_thumb(anal, aop, addr, data, len);
|
||||
aop->length = 4;
|
||||
return op_thumb(anal, op, addr, data, len);
|
||||
op->length = 4;
|
||||
#if 0
|
||||
fprintf(stderr, "CODE %02x %02x %02x %02x\n",
|
||||
codeA[0], codeA[1], codeA[2], codeA[3]);
|
||||
#endif
|
||||
// 0x000037b8 00:0000 0 800000ef svc 0x00000080
|
||||
if (b[3]==0xef) {
|
||||
aop->type = R_ANAL_OP_TYPE_SWI;
|
||||
aop->value = (b[0] | (b[1]<<8) | (b[2]<<2));
|
||||
op->type = R_ANAL_OP_TYPE_SWI;
|
||||
op->value = (b[0] | (b[1]<<8) | (b[2]<<2));
|
||||
} else
|
||||
if (b[3]==0xe5) {
|
||||
if (b[2]==0x9f) {
|
||||
/* STORE */
|
||||
aop->type = R_ANAL_OP_TYPE_STORE;
|
||||
aop->stackop = R_ANAL_STACK_SET;
|
||||
op->type = R_ANAL_OP_TYPE_STORE;
|
||||
op->stackop = R_ANAL_STACK_SET;
|
||||
|
||||
//printf ("FUCKING PT Rpc AT 0x%08llx + %d\n", addr, b[0]);
|
||||
//aop->ref = 4+addr+b[0]+(b[1]&4<<8);
|
||||
aop->ref = 8+addr+b[0]+((b[1]&0xf)<<8);
|
||||
aop->refptr = R_TRUE;
|
||||
//op->ref = 4+addr+b[0]+(b[1]&4<<8);
|
||||
op->ref = 8+addr+b[0]+((b[1]&0xf)<<8);
|
||||
op->refptr = R_TRUE;
|
||||
} else
|
||||
if ((b[1]&0xf0) == 0xf0) {
|
||||
//ldr pc, [pc, #1] ;
|
||||
aop->type = R_ANAL_OP_TYPE_UJMP;
|
||||
aop->type = R_ANAL_OP_TYPE_RET; // FAKE FOR FUN
|
||||
//aop->stackop = R_ANAL_STACK_SET;
|
||||
aop->jump = 1234;
|
||||
//aop->ref = 4+addr+b[0]; // sure? :)
|
||||
//aop->refptr = R_TRUE;
|
||||
op->type = R_ANAL_OP_TYPE_UJMP;
|
||||
op->type = R_ANAL_OP_TYPE_RET; // FAKE FOR FUN
|
||||
//op->stackop = R_ANAL_STACK_SET;
|
||||
op->jump = 1234;
|
||||
//op->ref = 4+addr+b[0]; // sure? :)
|
||||
//op->refptr = R_TRUE;
|
||||
}
|
||||
} else
|
||||
//eprintf("0x%08x\n", code[i] & ARM_DTX_LOAD);
|
||||
// 0x0001B4D8, 1eff2fe1 bx lr
|
||||
if (b[3]==0xe2 && b[2]==0x8d && b[1]==0xd0) {
|
||||
// ADD SP, SP, ...
|
||||
aop->type = R_ANAL_OP_TYPE_ADD;
|
||||
aop->stackop = R_ANAL_STACK_INCSTACK;
|
||||
aop->value = -b[0];
|
||||
op->type = R_ANAL_OP_TYPE_ADD;
|
||||
op->stackop = R_ANAL_STACK_INCSTACK;
|
||||
op->value = -b[0];
|
||||
} else
|
||||
if (b[3]==0xe2 && b[2]==0x4d && b[1]==0xd0) {
|
||||
// SUB SP, SP, ..
|
||||
aop->type = R_ANAL_OP_TYPE_SUB;
|
||||
aop->stackop = R_ANAL_STACK_INCSTACK;
|
||||
aop->value = b[0];
|
||||
op->type = R_ANAL_OP_TYPE_SUB;
|
||||
op->stackop = R_ANAL_STACK_INCSTACK;
|
||||
op->value = b[0];
|
||||
} else
|
||||
if (b[3]==0xe2 && b[2]==0x4c && b[1]==0xb0) {
|
||||
// SUB SP, FP, ..
|
||||
aop->type = R_ANAL_OP_TYPE_SUB;
|
||||
aop->stackop = R_ANAL_STACK_INCSTACK;
|
||||
aop->value = -b[0];
|
||||
op->type = R_ANAL_OP_TYPE_SUB;
|
||||
op->stackop = R_ANAL_STACK_INCSTACK;
|
||||
op->value = -b[0];
|
||||
} else
|
||||
if (b[3]==0xe2 && b[2]==0x4b && b[1]==0xd0) {
|
||||
// SUB SP, IP, ..
|
||||
aop->type = R_ANAL_OP_TYPE_SUB;
|
||||
aop->stackop = R_ANAL_STACK_INCSTACK;
|
||||
aop->value = -b[0];
|
||||
op->type = R_ANAL_OP_TYPE_SUB;
|
||||
op->stackop = R_ANAL_STACK_INCSTACK;
|
||||
op->value = -b[0];
|
||||
} else
|
||||
if( (code[i] == 0x1eff2fe1) ||(code[i] == 0xe12fff1e)) { // bx lr
|
||||
aop->type = R_ANAL_OP_TYPE_RET;
|
||||
aop->eob = 1;
|
||||
op->type = R_ANAL_OP_TYPE_RET;
|
||||
op->eob = 1;
|
||||
} else
|
||||
if ((code[i] & ARM_DTX_LOAD)) { //IS_LOAD(code[i])) {
|
||||
ut32 ptr = 0;
|
||||
aop->type = R_ANAL_OP_TYPE_MOV;
|
||||
op->type = R_ANAL_OP_TYPE_MOV;
|
||||
if (b[2]==0x1b) {
|
||||
/* XXX pretty incomplete */
|
||||
aop->stackop = R_ANAL_STACK_GET;
|
||||
aop->ref = b[0];
|
||||
op->stackop = R_ANAL_STACK_GET;
|
||||
op->ref = b[0];
|
||||
//var_add_access(addr, -b[0], 1, 0); // TODO: set/get (the last 0)
|
||||
} else {
|
||||
//ut32 oaddr = addr+8+b[0];
|
||||
//XXX TODO ret = radare_read_at(oaddr, (ut8*)&ptr, 4);
|
||||
if (anal->bits == 32) {
|
||||
b = (ut8*)&ptr;
|
||||
aop->ref = b[0] + (b[1]<<8) + (b[2]<<16) + (b[3]<<24);
|
||||
//XXX data_xrefs_add(oaddr, aop->ref, 1);
|
||||
op->ref = b[0] + (b[1]<<8) + (b[2]<<16) + (b[3]<<24);
|
||||
//XXX data_xrefs_add(oaddr, op->ref, 1);
|
||||
//TODO change data type to pointer
|
||||
} else aop->ref = 0;
|
||||
} else op->ref = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (IS_EXITPOINT (code[i])) {
|
||||
branch_dst_addr = disarm_branch_offset (addr, code[i]&0x00FFFFFF);
|
||||
aop->ref = 0;
|
||||
op->ref = 0;
|
||||
if (IS_BRANCHL (code[i])) {
|
||||
if (IS_BRANCH (code[i])) {
|
||||
aop->type = R_ANAL_OP_TYPE_CALL;
|
||||
aop->jump = branch_dst_addr;
|
||||
aop->fail = addr + 4 ;
|
||||
aop->eob = 1;
|
||||
op->type = R_ANAL_OP_TYPE_CALL;
|
||||
op->jump = branch_dst_addr;
|
||||
op->fail = addr + 4 ;
|
||||
op->eob = 1;
|
||||
} else {
|
||||
aop->type = R_ANAL_OP_TYPE_RET;
|
||||
aop->eob = 1;
|
||||
op->type = R_ANAL_OP_TYPE_RET;
|
||||
op->eob = 1;
|
||||
}
|
||||
} else if (IS_BRANCH (code[i])) {
|
||||
if (IS_CONDAL (code[i])) {
|
||||
aop->type = R_ANAL_OP_TYPE_JMP;
|
||||
aop->jump = branch_dst_addr;
|
||||
aop->eob = 1;
|
||||
op->type = R_ANAL_OP_TYPE_JMP;
|
||||
op->jump = branch_dst_addr;
|
||||
op->eob = 1;
|
||||
} else {
|
||||
aop->type = R_ANAL_OP_TYPE_CJMP;
|
||||
aop->jump = branch_dst_addr;
|
||||
aop->fail = addr + 4;
|
||||
aop->eob = 1;
|
||||
op->type = R_ANAL_OP_TYPE_CJMP;
|
||||
op->jump = branch_dst_addr;
|
||||
op->fail = addr + 4;
|
||||
op->eob = 1;
|
||||
}
|
||||
} else {
|
||||
//unknown jump o return
|
||||
aop->type = R_ANAL_OP_TYPE_UJMP;
|
||||
aop->eob = 1;
|
||||
op->type = R_ANAL_OP_TYPE_UJMP;
|
||||
op->eob = 1;
|
||||
}
|
||||
}
|
||||
return aop->length;
|
||||
return op->length;
|
||||
}
|
||||
static int set_reg_profile(RAnal *anal) {
|
||||
/* XXX Dupped Profiles */
|
||||
|
@ -274,7 +274,7 @@ struct r_anal_plugin_t r_anal_plugin_arm = {
|
|||
.desc = "ARM code analysis plugin",
|
||||
.init = NULL,
|
||||
.fini = NULL,
|
||||
.aop = &aop
|
||||
.op = &arm_op
|
||||
};
|
||||
|
||||
#ifndef CORELIB
|
||||
|
|
|
@ -6,38 +6,38 @@
|
|||
#include <r_asm.h>
|
||||
#include <r_anal.h>
|
||||
|
||||
static int aop(RAnal *anal, RAnalOp *aop, ut64 addr, const ut8 *buf, int len) {
|
||||
static int avr_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *buf, int len) {
|
||||
ut16 *ins = (ut16*)buf;
|
||||
if (aop == NULL)
|
||||
if (op == NULL)
|
||||
return 2;
|
||||
|
||||
aop->length = 2;
|
||||
op->length = 2;
|
||||
if (*ins == 0) {
|
||||
aop->type = R_ANAL_OP_TYPE_NOP;
|
||||
op->type = R_ANAL_OP_TYPE_NOP;
|
||||
} else
|
||||
if (buf[1]>=0x0c && buf[1]<=0x0f) { // hacky
|
||||
aop->type = R_ANAL_OP_TYPE_ADD;
|
||||
op->type = R_ANAL_OP_TYPE_ADD;
|
||||
} else
|
||||
if (buf[1]>=0x18 && buf[1]<=0x1b) { // hacky
|
||||
aop->type = R_ANAL_OP_TYPE_SUB;
|
||||
op->type = R_ANAL_OP_TYPE_SUB;
|
||||
} else
|
||||
if ((buf[1] & 0xf0 ) == 0x80) {
|
||||
aop->type = R_ANAL_OP_TYPE_CALL; // call (absolute)
|
||||
op->type = R_ANAL_OP_TYPE_CALL; // call (absolute)
|
||||
// TODO: calculate dest address
|
||||
} else
|
||||
if ((buf[1] & 0xf0 ) == 0xd0) {
|
||||
aop->type = R_ANAL_OP_TYPE_CALL; // rcall (relative)
|
||||
op->type = R_ANAL_OP_TYPE_CALL; // rcall (relative)
|
||||
// TODO: calculate dest address
|
||||
} else
|
||||
if ((buf[1] & 0xf0 ) == 0xf0) {
|
||||
aop->type = R_ANAL_OP_TYPE_CJMP; // breq
|
||||
op->type = R_ANAL_OP_TYPE_CJMP; // breq
|
||||
// TODO: calculate dest address
|
||||
} else
|
||||
if ((buf[1] & 0xf0 ) == 0xc0) {
|
||||
aop->type = R_ANAL_OP_TYPE_JMP;
|
||||
op->type = R_ANAL_OP_TYPE_JMP;
|
||||
// TODO: calculate dest address
|
||||
} else aop->type = R_ANAL_OP_TYPE_UNK;
|
||||
return aop->length;
|
||||
} else op->type = R_ANAL_OP_TYPE_UNK;
|
||||
return op->length;
|
||||
}
|
||||
|
||||
struct r_anal_plugin_t r_anal_plugin_avr = {
|
||||
|
@ -45,7 +45,7 @@ struct r_anal_plugin_t r_anal_plugin_avr = {
|
|||
.desc = "AVR code analysis plugin",
|
||||
.init = NULL,
|
||||
.fini = NULL,
|
||||
.aop = &aop,
|
||||
.op = &avr_op,
|
||||
.set_reg_profile = NULL
|
||||
};
|
||||
|
||||
|
|
|
@ -51,14 +51,14 @@ static inline ut16 i2ut16(struct instruction *in) {
|
|||
return *((uint16_t*)in);
|
||||
}
|
||||
|
||||
static int aop(RAnal *anal, RAnalOp *aop, ut64 addr, const ut8 *bytes, int len) {
|
||||
static int csr_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *bytes, int len) {
|
||||
struct instruction *in = (struct instruction *)bytes;
|
||||
ut16 lol, ins;
|
||||
struct directive d;
|
||||
struct state s;
|
||||
int rel = 0;
|
||||
|
||||
if (aop == NULL)
|
||||
if (op == NULL)
|
||||
return 2;
|
||||
|
||||
memcpy (&ins, bytes, sizeof (ins));
|
||||
|
@ -72,22 +72,22 @@ static int aop(RAnal *anal, RAnalOp *aop, ut64 addr, const ut8 *bytes, int len)
|
|||
csr_decode (&s, &d);
|
||||
d.d_operand = get_operand (&s, &d);
|
||||
|
||||
memset (aop, 0, sizeof (RAnalOp));
|
||||
aop->type = R_ANAL_OP_TYPE_UNK;
|
||||
aop->length = 2;
|
||||
memset (op, 0, sizeof (RAnalOp));
|
||||
op->type = R_ANAL_OP_TYPE_UNK;
|
||||
op->length = 2;
|
||||
|
||||
switch (i2ut16 (in)) {
|
||||
case INST_NOP:
|
||||
aop->type = R_ANAL_OP_TYPE_NOP;
|
||||
op->type = R_ANAL_OP_TYPE_NOP;
|
||||
break;
|
||||
case INST_BRK:
|
||||
aop->type = R_ANAL_OP_TYPE_TRAP;
|
||||
op->type = R_ANAL_OP_TYPE_TRAP;
|
||||
break;
|
||||
case INST_BC:
|
||||
aop->type = R_ANAL_OP_TYPE_TRAP;
|
||||
op->type = R_ANAL_OP_TYPE_TRAP;
|
||||
break;
|
||||
case INST_BRXL:
|
||||
aop->type = R_ANAL_OP_TYPE_TRAP;
|
||||
op->type = R_ANAL_OP_TYPE_TRAP;
|
||||
break;
|
||||
default:
|
||||
switch (in->in_opcode) {
|
||||
|
@ -97,107 +97,107 @@ static int aop(RAnal *anal, RAnalOp *aop, ut64 addr, const ut8 *bytes, int len)
|
|||
case 2:
|
||||
case 3:
|
||||
case 0xa:
|
||||
aop->type = R_ANAL_OP_TYPE_PUSH;
|
||||
op->type = R_ANAL_OP_TYPE_PUSH;
|
||||
break;
|
||||
case 4:
|
||||
case 5:
|
||||
case 6:
|
||||
case 7:
|
||||
case 0xe:
|
||||
aop->type = R_ANAL_OP_TYPE_POP;
|
||||
op->type = R_ANAL_OP_TYPE_POP;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
aop->type = R_ANAL_OP_TYPE_POP;
|
||||
op->type = R_ANAL_OP_TYPE_POP;
|
||||
break;
|
||||
case 2:
|
||||
aop->type = R_ANAL_OP_TYPE_PUSH;
|
||||
op->type = R_ANAL_OP_TYPE_PUSH;
|
||||
break;
|
||||
case 3:
|
||||
case 4:
|
||||
case 7:
|
||||
aop->type = R_ANAL_OP_TYPE_ADD;
|
||||
op->type = R_ANAL_OP_TYPE_ADD;
|
||||
break;
|
||||
case 5:
|
||||
case 6:
|
||||
aop->type = R_ANAL_OP_TYPE_SUB;
|
||||
op->type = R_ANAL_OP_TYPE_SUB;
|
||||
break;
|
||||
case 8:
|
||||
aop->type = R_ANAL_OP_TYPE_CMP;
|
||||
op->type = R_ANAL_OP_TYPE_CMP;
|
||||
break;
|
||||
case 9:
|
||||
switch(in->in_reg) {
|
||||
case 0:
|
||||
aop->type = R_ANAL_OP_TYPE_MUL;
|
||||
op->type = R_ANAL_OP_TYPE_MUL;
|
||||
break;
|
||||
case 1:
|
||||
aop->type = R_ANAL_OP_TYPE_DIV;
|
||||
op->type = R_ANAL_OP_TYPE_DIV;
|
||||
break;
|
||||
case 2:
|
||||
aop->type = R_ANAL_OP_TYPE_CMP;
|
||||
op->type = R_ANAL_OP_TYPE_CMP;
|
||||
break;
|
||||
case 3:
|
||||
// BSR
|
||||
aop->type = R_ANAL_OP_TYPE_CALL;
|
||||
op->type = R_ANAL_OP_TYPE_CALL;
|
||||
if (in->in_mode == ADDR_MODE_RELATIVE)
|
||||
rel = 1;
|
||||
aop->jump = label_off (&d);
|
||||
op->jump = label_off (&d);
|
||||
rel = 0;
|
||||
if (aop->jump&1)
|
||||
aop->jump+=3;
|
||||
aop->fail = addr+2;
|
||||
aop->eob = 1;
|
||||
if (op->jump&1)
|
||||
op->jump+=3;
|
||||
op->fail = addr+2;
|
||||
op->eob = 1;
|
||||
break;
|
||||
|
||||
}
|
||||
break;
|
||||
case 0xb:
|
||||
aop->type = R_ANAL_OP_TYPE_OR;
|
||||
op->type = R_ANAL_OP_TYPE_OR;
|
||||
break;
|
||||
case 0xc:
|
||||
aop->type = R_ANAL_OP_TYPE_AND;
|
||||
op->type = R_ANAL_OP_TYPE_AND;
|
||||
break;
|
||||
case 0xd:
|
||||
aop->type = R_ANAL_OP_TYPE_XOR;
|
||||
op->type = R_ANAL_OP_TYPE_XOR;
|
||||
break;
|
||||
case 0xe:
|
||||
if (in->in_mode == ADDR_MODE_RELATIVE)
|
||||
rel = 1;
|
||||
switch (in->in_reg) {
|
||||
case 0: // BRA
|
||||
aop->type = R_ANAL_OP_TYPE_JMP;
|
||||
aop->jump = label_off (&d)+4;
|
||||
if (aop->jump&1)
|
||||
aop->jump+=3;
|
||||
aop->eob = 1;
|
||||
op->type = R_ANAL_OP_TYPE_JMP;
|
||||
op->jump = label_off (&d)+4;
|
||||
if (op->jump&1)
|
||||
op->jump+=3;
|
||||
op->eob = 1;
|
||||
break;
|
||||
case 1:
|
||||
// BLT
|
||||
aop->type = R_ANAL_OP_TYPE_CJMP;
|
||||
aop->jump = label_off (&d);
|
||||
if (aop->jump&1)
|
||||
aop->jump+=3;
|
||||
aop->fail = addr + 2;
|
||||
aop->eob = 1;
|
||||
op->type = R_ANAL_OP_TYPE_CJMP;
|
||||
op->jump = label_off (&d);
|
||||
if (op->jump&1)
|
||||
op->jump+=3;
|
||||
op->fail = addr + 2;
|
||||
op->eob = 1;
|
||||
break;
|
||||
case 2:
|
||||
// BPL
|
||||
aop->type = R_ANAL_OP_TYPE_CJMP;
|
||||
aop->jump = label_off (&d);
|
||||
if (aop->jump&1)
|
||||
aop->jump+=3;
|
||||
aop->fail = addr + 2;
|
||||
aop->eob = 1;
|
||||
op->type = R_ANAL_OP_TYPE_CJMP;
|
||||
op->jump = label_off (&d);
|
||||
if (op->jump&1)
|
||||
op->jump+=3;
|
||||
op->fail = addr + 2;
|
||||
op->eob = 1;
|
||||
break;
|
||||
case 3:
|
||||
// BMI
|
||||
aop->type = R_ANAL_OP_TYPE_CJMP;
|
||||
aop->jump = label_off (&d);
|
||||
if (aop->jump&1)
|
||||
aop->jump+=3;
|
||||
aop->fail = addr + 2;
|
||||
aop->eob = 1;
|
||||
op->type = R_ANAL_OP_TYPE_CJMP;
|
||||
op->jump = label_off (&d);
|
||||
if (op->jump&1)
|
||||
op->jump+=3;
|
||||
op->fail = addr + 2;
|
||||
op->eob = 1;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
@ -207,19 +207,19 @@ static int aop(RAnal *anal, RAnalOp *aop, ut64 addr, const ut8 *bytes, int len)
|
|||
case 1: // BEQ
|
||||
case 2: // BCC
|
||||
case 3: // BCS
|
||||
aop->type = R_ANAL_OP_TYPE_CJMP;
|
||||
op->type = R_ANAL_OP_TYPE_CJMP;
|
||||
rel = 0;
|
||||
aop->jump = label_off (&d);
|
||||
if (aop->jump&1)
|
||||
aop->jump+=3;
|
||||
aop->fail = addr+2;
|
||||
op->jump = label_off (&d);
|
||||
if (op->jump&1)
|
||||
op->jump+=3;
|
||||
op->fail = addr+2;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return aop->length;
|
||||
return op->length;
|
||||
}
|
||||
|
||||
struct r_anal_plugin_t r_anal_plugin_csr = {
|
||||
|
@ -227,7 +227,7 @@ struct r_anal_plugin_t r_anal_plugin_csr = {
|
|||
.desc = "CSR code analysis plugin",
|
||||
.init = NULL,
|
||||
.fini = NULL,
|
||||
.aop = &aop,
|
||||
.op = &csr_op,
|
||||
.set_reg_profile = NULL
|
||||
};
|
||||
|
||||
|
|
|
@ -7,40 +7,40 @@
|
|||
|
||||
#include "../../asm/arch/dalvik/opcode.h"
|
||||
|
||||
static int dalvik_aop(RAnal *anal, RAnalOp *aop, ut64 addr, const ut8 *data, int len) {
|
||||
static int dalvik_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *data, int len) {
|
||||
int sz = 1;
|
||||
|
||||
sz = dalvik_opcodes[data[0]].len;
|
||||
if (aop == NULL)
|
||||
if (op == NULL)
|
||||
return sz;
|
||||
|
||||
memset (aop, '\0', sizeof (RAnalOp));
|
||||
aop->type = R_ANAL_OP_TYPE_UNK;
|
||||
aop->length = sz;
|
||||
aop->nopcode = 1; // Necesary??
|
||||
memset (op, '\0', sizeof (RAnalOp));
|
||||
op->type = R_ANAL_OP_TYPE_UNK;
|
||||
op->length = sz;
|
||||
op->nopcode = 1; // Necesary??
|
||||
|
||||
switch(data[0]) {
|
||||
case 0x0e: // return-void
|
||||
case 0x0f: // return
|
||||
case 0x10: // return-wide
|
||||
case 0x11: // return-object
|
||||
aop->type = R_ANAL_OP_TYPE_RET;
|
||||
aop->eob = 1;
|
||||
op->type = R_ANAL_OP_TYPE_RET;
|
||||
op->eob = 1;
|
||||
break;
|
||||
case 0x28: // goto
|
||||
aop->jump = addr + ((char)data[1])*2;
|
||||
aop->type = R_ANAL_OP_TYPE_JMP;
|
||||
aop->eob = 1;
|
||||
op->jump = addr + ((char)data[1])*2;
|
||||
op->type = R_ANAL_OP_TYPE_JMP;
|
||||
op->eob = 1;
|
||||
break;
|
||||
case 0x29: // goto/16
|
||||
aop->jump = addr + (short)(data[2]|data[3]<<8)*2;
|
||||
aop->type = R_ANAL_OP_TYPE_JMP;
|
||||
aop->eob = 1;
|
||||
op->jump = addr + (short)(data[2]|data[3]<<8)*2;
|
||||
op->type = R_ANAL_OP_TYPE_JMP;
|
||||
op->eob = 1;
|
||||
break;
|
||||
case 0x2a: // goto/32
|
||||
aop->jump = addr + (int)(data[2]|(data[3]<<8)|(data[4]<<16)|(data[5]<<24))*2;
|
||||
aop->type = R_ANAL_OP_TYPE_JMP;
|
||||
aop->eob = 1;
|
||||
op->jump = addr + (int)(data[2]|(data[3]<<8)|(data[4]<<16)|(data[5]<<24))*2;
|
||||
op->type = R_ANAL_OP_TYPE_JMP;
|
||||
op->eob = 1;
|
||||
break;
|
||||
case 0x2d: // cmpl-float
|
||||
case 0x2e: // cmpg-float
|
||||
|
@ -59,21 +59,21 @@ static int dalvik_aop(RAnal *anal, RAnalOp *aop, ut64 addr, const ut8 *data, int
|
|||
case 0x3b: // if-gez
|
||||
case 0x3c: // if-gtz
|
||||
case 0x3d: // if-lez
|
||||
aop->type = R_ANAL_OP_TYPE_JMP;
|
||||
aop->jump = addr + (short)(data[2]|data[3]<<8)*2;
|
||||
aop->fail = addr + sz;
|
||||
aop->eob = 1;
|
||||
op->type = R_ANAL_OP_TYPE_JMP;
|
||||
op->jump = addr + (short)(data[2]|data[3]<<8)*2;
|
||||
op->fail = addr + sz;
|
||||
op->eob = 1;
|
||||
break;
|
||||
case 0xec: // breakpoint
|
||||
aop->type = R_ANAL_OP_TYPE_TRAP;
|
||||
op->type = R_ANAL_OP_TYPE_TRAP;
|
||||
break;
|
||||
/* JAVA
|
||||
case 0xa8: // jsr
|
||||
case 0xc9: // jsr_w
|
||||
aop->type = R_ANAL_OP_TYPE_CALL;
|
||||
aop->jump = 0x0; // TODO
|
||||
aop->fail = addr + sz;
|
||||
aop->eob = 1;
|
||||
op->type = R_ANAL_OP_TYPE_CALL;
|
||||
op->jump = 0x0; // TODO
|
||||
op->fail = addr + sz;
|
||||
op->eob = 1;
|
||||
break;
|
||||
case 0xb9: // invokeinterface
|
||||
case 0xb7: // invokespecial
|
||||
|
@ -82,23 +82,23 @@ static int dalvik_aop(RAnal *anal, RAnalOp *aop, ut64 addr, const ut8 *data, int
|
|||
case 0xbb: // new
|
||||
case 0xbc: // newarray
|
||||
case 0xc5: // multi new array
|
||||
aop->type = R_ANAL_OP_TYPE_SWI;
|
||||
op->type = R_ANAL_OP_TYPE_SWI;
|
||||
break;
|
||||
*/
|
||||
case 0x27: // throw
|
||||
case 0xed: // throw-verification-error
|
||||
aop->type = R_ANAL_OP_TYPE_TRAP;
|
||||
op->type = R_ANAL_OP_TYPE_TRAP;
|
||||
break;
|
||||
case 0x00: // nop
|
||||
aop->type = R_ANAL_OP_TYPE_NOP;
|
||||
op->type = R_ANAL_OP_TYPE_NOP;
|
||||
break;
|
||||
/* JAVA
|
||||
case 0xba:
|
||||
aop->type = R_ANAL_OP_TYPE_ILL;
|
||||
op->type = R_ANAL_OP_TYPE_ILL;
|
||||
break;
|
||||
case 0x57: // pop
|
||||
case 0x58: // pop2
|
||||
aop->type = R_ANAL_OP_TYPE_POP;
|
||||
op->type = R_ANAL_OP_TYPE_POP;
|
||||
break;
|
||||
case 0x10: // bipush
|
||||
case 0x11: // sipush
|
||||
|
@ -108,7 +108,7 @@ static int dalvik_aop(RAnal *anal, RAnalOp *aop, ut64 addr, const ut8 *data, int
|
|||
case 0x5c: // dup2
|
||||
case 0x5d: // dup2_x1
|
||||
case 0x5e: // dup2_x2
|
||||
aop->type = R_ANAL_OP_TYPE_PUSH;
|
||||
op->type = R_ANAL_OP_TYPE_PUSH;
|
||||
break;
|
||||
*/
|
||||
case 0x90: // add-int
|
||||
|
@ -121,54 +121,54 @@ static int dalvik_aop(RAnal *anal, RAnalOp *aop, ut64 addr, const ut8 *data, int
|
|||
case 0xcb: // add-double/2addr
|
||||
case 0xd0: // add-int/lit16
|
||||
case 0xd8: // add-int/lit8
|
||||
aop->type = R_ANAL_OP_TYPE_ADD;
|
||||
op->type = R_ANAL_OP_TYPE_ADD;
|
||||
break;
|
||||
/* TODO JAVA
|
||||
case 0x64: // isub
|
||||
case 0x65: // lsub
|
||||
case 0x66: // fsub
|
||||
case 0x67: // dsub
|
||||
aop->type = R_ANAL_OP_TYPE_SUB;
|
||||
op->type = R_ANAL_OP_TYPE_SUB;
|
||||
break;
|
||||
*/
|
||||
case 0x7b: // neg-int
|
||||
case 0x7d: // neg-long
|
||||
case 0x7f: // neg-float
|
||||
case 0x80: // neg-double
|
||||
aop->type = R_ANAL_OP_TYPE_NOT;
|
||||
op->type = R_ANAL_OP_TYPE_NOT;
|
||||
break;
|
||||
/* TODO JAVA
|
||||
case 0x78: //ishl
|
||||
case 0x79: //lshl
|
||||
aop->type = R_ANAL_OP_TYPE_SHL;
|
||||
op->type = R_ANAL_OP_TYPE_SHL;
|
||||
break;
|
||||
case 0x7a: //ishr
|
||||
case 0x7b: //lshr
|
||||
aop->type = R_ANAL_OP_TYPE_SHR;
|
||||
op->type = R_ANAL_OP_TYPE_SHR;
|
||||
break;
|
||||
case 0x80: // ior
|
||||
case 0x81: // lor
|
||||
aop->type = R_ANAL_OP_TYPE_OR;
|
||||
op->type = R_ANAL_OP_TYPE_OR;
|
||||
break;
|
||||
case 0x82: // ixor
|
||||
case 0x83: // lxor
|
||||
aop->type = R_ANAL_OP_TYPE_XOR;
|
||||
op->type = R_ANAL_OP_TYPE_XOR;
|
||||
break;
|
||||
case 0x7e: // iand
|
||||
case 0x7f: // land
|
||||
aop->type = R_ANAL_OP_TYPE_AND;
|
||||
op->type = R_ANAL_OP_TYPE_AND;
|
||||
break;
|
||||
case 0x68: // imul
|
||||
case 0x69: // lmul
|
||||
case 0x6a: // fmul
|
||||
case 0x6b: // dmul
|
||||
aop->type = R_ANAL_OP_TYPE_MUL;
|
||||
op->type = R_ANAL_OP_TYPE_MUL;
|
||||
break;
|
||||
case 0x6c: // idiv
|
||||
case 0x6d: // ldiv
|
||||
case 0x6e: // fdiv
|
||||
case 0x6f: // ddiv
|
||||
aop->type = R_ANAL_OP_TYPE_DIV;
|
||||
op->type = R_ANAL_OP_TYPE_DIV;
|
||||
break;
|
||||
*/
|
||||
}
|
||||
|
@ -181,7 +181,7 @@ struct r_anal_plugin_t r_anal_plugin_dalvik = {
|
|||
.desc = "Dalvik (Android VM) bytecode analysis plugin",
|
||||
.init = NULL,
|
||||
.fini = NULL,
|
||||
.aop = &dalvik_aop
|
||||
.op = &dalvik_op
|
||||
};
|
||||
|
||||
#ifndef CORELIB
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
|
||||
/* code analysis functions */
|
||||
|
||||
/* arch_aop for java */
|
||||
/* arch_op for java */
|
||||
// CMP ARG1
|
||||
// 837d0801 cmp dword [ebp+0x8], 0x1
|
||||
// SET VAR_41c
|
||||
|
@ -25,7 +25,7 @@
|
|||
|
||||
// NOTE: buf should be at least 16 bytes!
|
||||
// XXX addr should be off_t for 64 love
|
||||
static int aop(RAnal *anal, RAnalOp *aop, ut64 addr, const ut8 *data, int len) {
|
||||
static int java_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *data, int len) {
|
||||
unsigned int i;
|
||||
int sz = 1;
|
||||
|
||||
|
@ -34,12 +34,12 @@ static int aop(RAnal *anal, RAnalOp *aop, ut64 addr, const ut8 *data, int len) {
|
|||
if (data[0] == java_ops[i].byte)
|
||||
sz = java_ops[i].size;
|
||||
|
||||
if (aop == NULL)
|
||||
if (op == NULL)
|
||||
return sz;
|
||||
|
||||
memset (aop, '\0', sizeof (RAnalOp));
|
||||
aop->type = R_ANAL_OP_TYPE_UNK;
|
||||
aop->length = sz;
|
||||
memset (op, '\0', sizeof (RAnalOp));
|
||||
op->type = R_ANAL_OP_TYPE_UNK;
|
||||
op->length = sz;
|
||||
|
||||
switch(data[0]) {
|
||||
case 0xa9: // ret
|
||||
|
@ -49,14 +49,14 @@ static int aop(RAnal *anal, RAnalOp *aop, ut64 addr, const ut8 *data, int len) {
|
|||
case 0xae: // freturn
|
||||
case 0xac: // ireturn
|
||||
case 0xad: // lreturn
|
||||
aop->type = R_ANAL_OP_TYPE_RET;
|
||||
aop->eob = 1;
|
||||
op->type = R_ANAL_OP_TYPE_RET;
|
||||
op->eob = 1;
|
||||
break;
|
||||
case 0xa7: // goto
|
||||
case 0xc8: // goto_w
|
||||
aop->type = R_ANAL_OP_TYPE_JMP;
|
||||
aop->jump = 0; // TODO
|
||||
aop->eob = 1;
|
||||
op->type = R_ANAL_OP_TYPE_JMP;
|
||||
op->jump = 0; // TODO
|
||||
op->eob = 1;
|
||||
break;
|
||||
case 0xa5: // acmpeq
|
||||
case 0xa6: // acmpne
|
||||
|
@ -74,17 +74,17 @@ static int aop(RAnal *anal, RAnalOp *aop, ut64 addr, const ut8 *data, int len) {
|
|||
case 0x9e: // ifle
|
||||
case 0xc7: // ifnonnull
|
||||
case 0xc6: // ifnull
|
||||
aop->type = R_ANAL_OP_TYPE_CJMP;
|
||||
aop->jump = 0x0; // TODO
|
||||
aop->fail = addr + sz;
|
||||
aop->eob = 1;
|
||||
op->type = R_ANAL_OP_TYPE_CJMP;
|
||||
op->jump = 0x0; // TODO
|
||||
op->fail = addr + sz;
|
||||
op->eob = 1;
|
||||
break;
|
||||
case 0xa8: // jsr
|
||||
case 0xc9: // jsr_w
|
||||
aop->type = R_ANAL_OP_TYPE_CALL;
|
||||
aop->jump = 0x0; // TODO
|
||||
aop->fail = addr + sz;
|
||||
aop->eob = 1;
|
||||
op->type = R_ANAL_OP_TYPE_CALL;
|
||||
op->jump = 0x0; // TODO
|
||||
op->fail = addr + sz;
|
||||
op->eob = 1;
|
||||
break;
|
||||
case 0xb9: // invokeinterface
|
||||
case 0xb7: // invokespecial
|
||||
|
@ -93,23 +93,23 @@ static int aop(RAnal *anal, RAnalOp *aop, ut64 addr, const ut8 *data, int len) {
|
|||
case 0xbb: // new
|
||||
case 0xbc: // newarray
|
||||
case 0xc5: // multi new array
|
||||
aop->type = R_ANAL_OP_TYPE_SWI;
|
||||
op->type = R_ANAL_OP_TYPE_SWI;
|
||||
break;
|
||||
case 0xca: // breakpoint
|
||||
aop->type = R_ANAL_OP_TYPE_TRAP;
|
||||
op->type = R_ANAL_OP_TYPE_TRAP;
|
||||
break;
|
||||
case 0xbf: // athrow
|
||||
aop->type = R_ANAL_OP_TYPE_TRAP;
|
||||
op->type = R_ANAL_OP_TYPE_TRAP;
|
||||
break;
|
||||
case 0x00: // nop
|
||||
aop->type = R_ANAL_OP_TYPE_NOP;
|
||||
op->type = R_ANAL_OP_TYPE_NOP;
|
||||
break;
|
||||
case 0xba:
|
||||
aop->type = R_ANAL_OP_TYPE_ILL;
|
||||
op->type = R_ANAL_OP_TYPE_ILL;
|
||||
break;
|
||||
case 0x57: // pop
|
||||
case 0x58: // pop2
|
||||
aop->type = R_ANAL_OP_TYPE_POP;
|
||||
op->type = R_ANAL_OP_TYPE_POP;
|
||||
break;
|
||||
case 0x10: // bipush
|
||||
case 0x11: // sipush
|
||||
|
@ -119,54 +119,54 @@ static int aop(RAnal *anal, RAnalOp *aop, ut64 addr, const ut8 *data, int len) {
|
|||
case 0x5c: // dup2
|
||||
case 0x5d: // dup2_x1
|
||||
case 0x5e: // dup2_x2
|
||||
aop->type = R_ANAL_OP_TYPE_PUSH;
|
||||
op->type = R_ANAL_OP_TYPE_PUSH;
|
||||
break;
|
||||
case 0x60: // iadd
|
||||
case 0x61: // ladd
|
||||
case 0x62: // fadd
|
||||
case 0x63: // dadd
|
||||
aop->type = R_ANAL_OP_TYPE_ADD;
|
||||
op->type = R_ANAL_OP_TYPE_ADD;
|
||||
break;
|
||||
case 0x64: // isub
|
||||
case 0x65: // lsub
|
||||
case 0x66: // fsub
|
||||
case 0x67: // dsub
|
||||
aop->type = R_ANAL_OP_TYPE_SUB;
|
||||
op->type = R_ANAL_OP_TYPE_SUB;
|
||||
break;
|
||||
case 0x76: // neg
|
||||
aop->type = R_ANAL_OP_TYPE_NOT;
|
||||
op->type = R_ANAL_OP_TYPE_NOT;
|
||||
break;
|
||||
case 0x78: //ishl
|
||||
case 0x79: //lshl
|
||||
aop->type = R_ANAL_OP_TYPE_SHL;
|
||||
op->type = R_ANAL_OP_TYPE_SHL;
|
||||
break;
|
||||
case 0x7a: //ishr
|
||||
case 0x7b: //lshr
|
||||
aop->type = R_ANAL_OP_TYPE_SHR;
|
||||
op->type = R_ANAL_OP_TYPE_SHR;
|
||||
break;
|
||||
case 0x80: // ior
|
||||
case 0x81: // lor
|
||||
aop->type = R_ANAL_OP_TYPE_OR;
|
||||
op->type = R_ANAL_OP_TYPE_OR;
|
||||
break;
|
||||
case 0x82: // ixor
|
||||
case 0x83: // lxor
|
||||
aop->type = R_ANAL_OP_TYPE_XOR;
|
||||
op->type = R_ANAL_OP_TYPE_XOR;
|
||||
break;
|
||||
case 0x7e: // iand
|
||||
case 0x7f: // land
|
||||
aop->type = R_ANAL_OP_TYPE_AND;
|
||||
op->type = R_ANAL_OP_TYPE_AND;
|
||||
break;
|
||||
case 0x68: // imul
|
||||
case 0x69: // lmul
|
||||
case 0x6a: // fmul
|
||||
case 0x6b: // dmul
|
||||
aop->type = R_ANAL_OP_TYPE_MUL;
|
||||
op->type = R_ANAL_OP_TYPE_MUL;
|
||||
break;
|
||||
case 0x6c: // idiv
|
||||
case 0x6d: // ldiv
|
||||
case 0x6e: // fdiv
|
||||
case 0x6f: // ddiv
|
||||
aop->type = R_ANAL_OP_TYPE_DIV;
|
||||
op->type = R_ANAL_OP_TYPE_DIV;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -178,7 +178,7 @@ struct r_anal_plugin_t r_anal_plugin_java = {
|
|||
.desc = "Java bytecode analysis plugin",
|
||||
.init = NULL,
|
||||
.fini = NULL,
|
||||
.aop = &aop
|
||||
.op = &java_op
|
||||
};
|
||||
|
||||
#ifndef CORELIB
|
||||
|
|
|
@ -6,32 +6,32 @@
|
|||
#include <r_asm.h>
|
||||
#include <r_anal.h>
|
||||
|
||||
static int aop(RAnal *anal, RAnalOp *aop, ut64 addr, const ut8 *bytes, int len) {
|
||||
unsigned long op;
|
||||
static int mips_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *bytes, int len) {
|
||||
unsigned long opcode;
|
||||
char buf[10];
|
||||
int reg;
|
||||
int oplen = (anal->bits==16)?2:4;
|
||||
|
||||
if (aop == NULL)
|
||||
if (op == NULL)
|
||||
return oplen;
|
||||
|
||||
memset (aop, 0, sizeof (RAnalOp));
|
||||
aop->type = R_ANAL_OP_TYPE_UNK;
|
||||
aop->length = oplen;
|
||||
memset (op, 0, sizeof (RAnalOp));
|
||||
op->type = R_ANAL_OP_TYPE_UNK;
|
||||
op->length = oplen;
|
||||
|
||||
r_mem_copyendian ((ut8*)&op, bytes, 4, anal->big_endian);
|
||||
aop->type = R_ANAL_OP_TYPE_UNK;
|
||||
r_mem_copyendian ((ut8*)&opcode, bytes, 4, anal->big_endian);
|
||||
op->type = R_ANAL_OP_TYPE_UNK;
|
||||
|
||||
switch (op & 0x3f) {
|
||||
switch (opcode & 0x3f) {
|
||||
// J-Type
|
||||
case 2: // j
|
||||
break;
|
||||
// branch to register
|
||||
//XXX TODO
|
||||
//eprintf("UJUMP\n");
|
||||
//aop->type = R_ANAL_OP_TYPE_UJMP;
|
||||
//op->type = R_ANAL_OP_TYPE_UJMP;
|
||||
break;
|
||||
aop->type = R_ANAL_OP_TYPE_CJMP;
|
||||
op->type = R_ANAL_OP_TYPE_CJMP;
|
||||
break;
|
||||
// R-Type
|
||||
case 1: // bltz
|
||||
|
@ -42,69 +42,69 @@ static int aop(RAnal *anal, RAnalOp *aop, ut64 addr, const ut8 *bytes, int len)
|
|||
case 7: // bgtz
|
||||
case 16: //beqz
|
||||
case 20: //bnel
|
||||
aop->type = R_ANAL_OP_TYPE_CJMP;
|
||||
reg = (((op&0x00ff0000)>>16) + ((op&0xff000000)>>24));
|
||||
aop->jump = addr+(reg<<2) + 4;
|
||||
aop->fail = addr+8;
|
||||
op->type = R_ANAL_OP_TYPE_CJMP;
|
||||
reg = (((opcode&0x00ff0000)>>16) + ((opcode&0xff000000)>>24));
|
||||
op->jump = addr+(reg<<2) + 4;
|
||||
op->fail = addr+8;
|
||||
// calculate jump
|
||||
break;
|
||||
case 3: // jalr
|
||||
//case 9: // jalr
|
||||
reg = op>>24;
|
||||
reg = opcode>>24;
|
||||
if (reg<10) {
|
||||
aop->type = R_ANAL_OP_TYPE_UCALL;
|
||||
op->type = R_ANAL_OP_TYPE_UCALL;
|
||||
snprintf (buf, sizeof (buf), "t%d", reg); // XXX must be rN...!regs* should be synced here
|
||||
aop->jump = 1234;//flag_get_addr(buf);
|
||||
aop->fail = addr+8;
|
||||
op->jump = 1234;//flag_get_addr(buf);
|
||||
op->fail = addr+8;
|
||||
}
|
||||
break;
|
||||
case 8: // jr
|
||||
aop->type = R_ANAL_OP_TYPE_RET;
|
||||
op->type = R_ANAL_OP_TYPE_RET;
|
||||
break;
|
||||
case 12:
|
||||
aop->type = R_ANAL_OP_TYPE_SWI;
|
||||
op->type = R_ANAL_OP_TYPE_SWI;
|
||||
break;
|
||||
case 13:
|
||||
aop->type = R_ANAL_OP_TYPE_TRAP;
|
||||
op->type = R_ANAL_OP_TYPE_TRAP;
|
||||
break;
|
||||
default:
|
||||
switch(op) {
|
||||
switch(opcode) {
|
||||
case 32: // add
|
||||
case 33: // addu
|
||||
aop->type = R_ANAL_OP_TYPE_ADD;
|
||||
op->type = R_ANAL_OP_TYPE_ADD;
|
||||
break;
|
||||
case 34: // sub
|
||||
case 35: // subu
|
||||
aop->type = R_ANAL_OP_TYPE_SUB;
|
||||
op->type = R_ANAL_OP_TYPE_SUB;
|
||||
break;
|
||||
case 0x03e00008:
|
||||
case 0x0800e003: // jr ra
|
||||
aop->type = R_ANAL_OP_TYPE_RET;
|
||||
op->type = R_ANAL_OP_TYPE_RET;
|
||||
break;
|
||||
case 0x0000000d: // case 26:
|
||||
case 0x0d000000: // break
|
||||
aop->type = R_ANAL_OP_TYPE_TRAP;
|
||||
op->type = R_ANAL_OP_TYPE_TRAP;
|
||||
break;
|
||||
case 0:
|
||||
aop->type = R_ANAL_OP_TYPE_NOP;
|
||||
op->type = R_ANAL_OP_TYPE_NOP;
|
||||
break;
|
||||
default:
|
||||
//switch((op<<24)&0xff) { //bytes[3]) { // TODO handle endian ?
|
||||
//switch((opcode<<24)&0xff) { //bytes[3]) { // TODO handle endian ?
|
||||
switch((bytes[3])) {
|
||||
case 0xc:
|
||||
aop->type = R_ANAL_OP_TYPE_SWI;
|
||||
op->type = R_ANAL_OP_TYPE_SWI;
|
||||
break;
|
||||
case 0x9:
|
||||
case 0x8:
|
||||
aop->type = R_ANAL_OP_TYPE_UJMP;
|
||||
op->type = R_ANAL_OP_TYPE_UJMP;
|
||||
break;
|
||||
case 0x21:
|
||||
aop->type = R_ANAL_OP_TYPE_PUSH; // XXX move
|
||||
op->type = R_ANAL_OP_TYPE_PUSH; // XXX move
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return aop->length;
|
||||
return op->length;
|
||||
}
|
||||
|
||||
struct r_anal_plugin_t r_anal_plugin_mips = {
|
||||
|
@ -112,7 +112,7 @@ struct r_anal_plugin_t r_anal_plugin_mips = {
|
|||
.desc = "MIPS code analysis plugin",
|
||||
.init = NULL,
|
||||
.fini = NULL,
|
||||
.aop = &aop
|
||||
.op = &mips_op
|
||||
};
|
||||
|
||||
#ifndef CORELIB
|
||||
|
|
|
@ -7,8 +7,8 @@
|
|||
|
||||
// NOTE: buf should be at least 16 bytes!
|
||||
// XXX addr should be off_t for 64 love
|
||||
int aop(RAnal *anal, RAnalOp *aop, ut64 addr, const ut8 *bytes, int len) {
|
||||
//int arch_ppc_aop(ut64 addr, const u8 *bytes, struct aop_t *aop)
|
||||
int ppc_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *bytes, int len) {
|
||||
//int arch_ppc_op(ut64 addr, const u8 *bytes, struct op_t *op)
|
||||
// TODO swap endian here??
|
||||
int opcode = (bytes[0] & 0xf8) >> 3; // bytes 0-5
|
||||
short baddr = ((bytes[2]<<8) | (bytes[3]&0xfc));// 16-29
|
||||
|
@ -17,61 +17,61 @@ int aop(RAnal *anal, RAnalOp *aop, ut64 addr, const ut8 *bytes, int len) {
|
|||
//if (baddr>0x7fff)
|
||||
// baddr = -baddr;
|
||||
|
||||
memset (aop, '\0', sizeof (RAnalOp));
|
||||
aop->addr = addr;
|
||||
aop->type = R_ANAL_OP_TYPE_NOP;
|
||||
aop->length = 4;
|
||||
memset (op, '\0', sizeof (RAnalOp));
|
||||
op->addr = addr;
|
||||
op->type = R_ANAL_OP_TYPE_NOP;
|
||||
op->length = 4;
|
||||
|
||||
//printf("OPCODE IS %08x : %02x (opcode=%d) baddr = %d\n", addr, bytes[0], opcode, baddr);
|
||||
|
||||
switch(opcode) {
|
||||
case 11: // cmpi
|
||||
aop->type = R_ANAL_OP_TYPE_CMP;
|
||||
op->type = R_ANAL_OP_TYPE_CMP;
|
||||
break;
|
||||
case 9: // pure branch
|
||||
if (bytes[0] == 0x4e) {
|
||||
// bctr
|
||||
} else {
|
||||
aop->jump = (aa)?(baddr):(addr+baddr);
|
||||
if (lk) aop->fail = addr+4;
|
||||
op->jump = (aa)?(baddr):(addr+baddr);
|
||||
if (lk) op->fail = addr+4;
|
||||
}
|
||||
aop->eob = 1;
|
||||
op->eob = 1;
|
||||
break;
|
||||
case 6: // bc // conditional jump
|
||||
aop->type = R_ANAL_OP_TYPE_JMP;
|
||||
aop->jump = (aa)?(baddr):(addr+baddr+4);
|
||||
aop->eob = 1;
|
||||
op->type = R_ANAL_OP_TYPE_JMP;
|
||||
op->jump = (aa)?(baddr):(addr+baddr+4);
|
||||
op->eob = 1;
|
||||
break;
|
||||
case 7: // sc/svc
|
||||
aop->type = R_ANAL_OP_TYPE_SWI;
|
||||
op->type = R_ANAL_OP_TYPE_SWI;
|
||||
break;
|
||||
#if 0
|
||||
case 15: // bl
|
||||
// OK
|
||||
aop->type = R_ANAL_OP_TYPE_CJMP;
|
||||
aop->jump = (aa)?(baddr):(addr+baddr);
|
||||
aop->fail = addr+4;
|
||||
aop->eob = 1;
|
||||
op->type = R_ANAL_OP_TYPE_CJMP;
|
||||
op->jump = (aa)?(baddr):(addr+baddr);
|
||||
op->fail = addr+4;
|
||||
op->eob = 1;
|
||||
break;
|
||||
#endif
|
||||
case 8: // bne i tal
|
||||
// OK
|
||||
aop->type = R_ANAL_OP_TYPE_CJMP;
|
||||
aop->jump = (aa)?(baddr):(addr+baddr+4);
|
||||
aop->fail = addr+4;
|
||||
aop->eob = 1;
|
||||
op->type = R_ANAL_OP_TYPE_CJMP;
|
||||
op->jump = (aa)?(baddr):(addr+baddr+4);
|
||||
op->fail = addr+4;
|
||||
op->eob = 1;
|
||||
break;
|
||||
case 19: // bclr/bcr/bcctr/bcc
|
||||
aop->type = R_ANAL_OP_TYPE_RET; // jump to LR
|
||||
op->type = R_ANAL_OP_TYPE_RET; // jump to LR
|
||||
if (lk) {
|
||||
aop->jump = 0xFFFFFFFF; // LR ?!?
|
||||
aop->fail = addr+4;
|
||||
op->jump = 0xFFFFFFFF; // LR ?!?
|
||||
op->fail = addr+4;
|
||||
}
|
||||
aop->eob = 1;
|
||||
op->eob = 1;
|
||||
break;
|
||||
}
|
||||
aop->length = 4;
|
||||
return aop->length;
|
||||
op->length = 4;
|
||||
return op->length;
|
||||
}
|
||||
|
||||
static int set_reg_profile(RAnal *anal) {
|
||||
|
@ -137,7 +137,7 @@ struct r_anal_plugin_t r_anal_plugin_ppc = {
|
|||
.desc = "PowerPC analysis plugin",
|
||||
.init = NULL,
|
||||
.fini = NULL,
|
||||
.aop = &aop,
|
||||
.op = &ppc_op,
|
||||
.set_reg_profile = &set_reg_profile
|
||||
};
|
||||
|
||||
|
|
|
@ -102,176 +102,176 @@ static RAnalValue *anal_fill_ai_mm(RAnal *anal, x86im_instr_object io) {
|
|||
return ret;
|
||||
}
|
||||
|
||||
static void anal_jmp(RAnal *anal, RAnalOp *aop, x86im_instr_object io) {
|
||||
static void anal_jmp(RAnal *anal, RAnalOp *op, x86im_instr_object io) {
|
||||
st64 imm, disp;
|
||||
imm = r_hex_bin_truncate (io.imm, io.imm_size);
|
||||
disp = r_hex_bin_truncate (io.disp, io.disp_size);
|
||||
|
||||
aop->eob = R_TRUE;
|
||||
op->eob = R_TRUE;
|
||||
switch (io.id) {
|
||||
case X86IM_IO_ID_JMP_N_R_S: /* jmp short 0x0ff */
|
||||
case X86IM_IO_ID_JMP_N_R: /* jmp 0x0ff */
|
||||
aop->type = R_ANAL_OP_TYPE_JMP;
|
||||
aop->dst = anal_fill_r (anal, io, aop->addr);
|
||||
aop->jump = aop->addr + io.len + imm;
|
||||
op->type = R_ANAL_OP_TYPE_JMP;
|
||||
op->dst = anal_fill_r (anal, io, op->addr);
|
||||
op->jump = op->addr + io.len + imm;
|
||||
break;
|
||||
case X86IM_IO_ID_JMP_N_AI_MM: /* jmp [0x0ff | reg1+reg2+0x0ff] */
|
||||
case X86IM_IO_ID_JMP_F_AI_MM: /* jmp dword far [0x0ff | reg1+reg2+0x0ff] */
|
||||
aop->type = R_ANAL_OP_TYPE_UJMP;
|
||||
aop->dst = anal_fill_ai_mm (anal, io);
|
||||
op->type = R_ANAL_OP_TYPE_UJMP;
|
||||
op->dst = anal_fill_ai_mm (anal, io);
|
||||
/* TODO: Deprecate */
|
||||
if (io.mem_base == 0)
|
||||
aop->ref = disp;
|
||||
op->ref = disp;
|
||||
break;
|
||||
case X86IM_IO_ID_JMP_N_AI_RG: /* jmp reg */
|
||||
aop->type = R_ANAL_OP_TYPE_UJMP;
|
||||
aop->dst = anal_fill_ai_rg (anal, io, 0);
|
||||
op->type = R_ANAL_OP_TYPE_UJMP;
|
||||
op->dst = anal_fill_ai_rg (anal, io, 0);
|
||||
break;
|
||||
case X86IM_IO_ID_JMP_F_A: /* jmp dword sel:0x0ff */
|
||||
aop->type = R_ANAL_OP_TYPE_UJMP;
|
||||
aop->dst = anal_fill_f (anal, io);
|
||||
op->type = R_ANAL_OP_TYPE_UJMP;
|
||||
op->dst = anal_fill_f (anal, io);
|
||||
/* TODO: Deprecate */
|
||||
aop->selector = io.selector;
|
||||
aop->ref = imm;
|
||||
op->selector = io.selector;
|
||||
op->ref = imm;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void anal_cjmp(RAnal *anal, RAnalOp *aop, x86im_instr_object io) {
|
||||
static void anal_cjmp(RAnal *anal, RAnalOp *op, x86im_instr_object io) {
|
||||
st64 imm;
|
||||
imm = r_hex_bin_truncate (io.imm, io.imm_size);
|
||||
|
||||
aop->eob = R_TRUE;
|
||||
op->eob = R_TRUE;
|
||||
switch (io.id) {
|
||||
case X86IM_IO_ID_JCC_S: /* j* 0x0ff */
|
||||
case X86IM_IO_ID_JCC_N: /* j* dword 0x0ff */
|
||||
aop->type = R_ANAL_OP_TYPE_CJMP;
|
||||
aop->dst = anal_fill_r (anal, io, aop->addr);
|
||||
aop->fail = aop->addr + io.len;
|
||||
aop->jump = aop->addr + io.len + imm;
|
||||
op->type = R_ANAL_OP_TYPE_CJMP;
|
||||
op->dst = anal_fill_r (anal, io, op->addr);
|
||||
op->fail = op->addr + io.len;
|
||||
op->jump = op->addr + io.len + imm;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void anal_call(RAnal *anal, RAnalOp *aop, x86im_instr_object io) {
|
||||
static void anal_call(RAnal *anal, RAnalOp *op, x86im_instr_object io) {
|
||||
st64 imm, disp;
|
||||
imm = r_hex_bin_truncate (io.imm, io.imm_size);
|
||||
disp = r_hex_bin_truncate (io.disp, io.disp_size);
|
||||
|
||||
switch (io.id) {
|
||||
case X86IM_IO_ID_CALL_N_R: /* call 0x0ff */
|
||||
aop->type = R_ANAL_OP_TYPE_CALL;
|
||||
aop->dst = anal_fill_r (anal, io, aop->addr);
|
||||
aop->jump = aop->addr + io.len + imm;
|
||||
aop->fail = aop->addr + io.len;
|
||||
op->type = R_ANAL_OP_TYPE_CALL;
|
||||
op->dst = anal_fill_r (anal, io, op->addr);
|
||||
op->jump = op->addr + io.len + imm;
|
||||
op->fail = op->addr + io.len;
|
||||
break;
|
||||
case X86IM_IO_ID_CALL_N_AI_MM: /* call [0x0ff | reg1+reg2+0x0ff] */
|
||||
case X86IM_IO_ID_CALL_F_AI_MM: /* call dword far [0x0ff | reg1+reg2+0x0ff] */
|
||||
aop->type = R_ANAL_OP_TYPE_UCALL;
|
||||
aop->dst = anal_fill_ai_mm (anal, io);
|
||||
op->type = R_ANAL_OP_TYPE_UCALL;
|
||||
op->dst = anal_fill_ai_mm (anal, io);
|
||||
/* TODO: Deprecate */
|
||||
if (io.mem_base == 0)
|
||||
aop->ref = disp;
|
||||
op->ref = disp;
|
||||
break;
|
||||
case X86IM_IO_ID_CALL_N_AI_RG: /* call reg */
|
||||
aop->type = R_ANAL_OP_TYPE_UCALL;
|
||||
aop->dst = anal_fill_ai_rg (anal, io, 0);
|
||||
aop->fail = aop->addr + io.len;
|
||||
op->type = R_ANAL_OP_TYPE_UCALL;
|
||||
op->dst = anal_fill_ai_rg (anal, io, 0);
|
||||
op->fail = op->addr + io.len;
|
||||
break;
|
||||
case X86IM_IO_ID_CALL_F_A: /* call dword sel:0x0ff */
|
||||
aop->type = R_ANAL_OP_TYPE_UCALL;
|
||||
aop->dst = anal_fill_f (anal, io);
|
||||
op->type = R_ANAL_OP_TYPE_UCALL;
|
||||
op->dst = anal_fill_f (anal, io);
|
||||
/* TODO: Deprecate */
|
||||
aop->selector = io.selector;
|
||||
aop->ref = imm;
|
||||
aop->fail = aop->addr + io.len;
|
||||
op->selector = io.selector;
|
||||
op->ref = imm;
|
||||
op->fail = op->addr + io.len;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void anal_ret(RAnal *anal, RAnalOp *aop, x86im_instr_object io) {
|
||||
static void anal_ret(RAnal *anal, RAnalOp *op, x86im_instr_object io) {
|
||||
st64 imm;
|
||||
imm = r_hex_bin_truncate (io.imm, io.imm_size);
|
||||
|
||||
aop->eob = R_TRUE;
|
||||
aop->type = R_ANAL_OP_TYPE_RET;
|
||||
op->eob = R_TRUE;
|
||||
op->type = R_ANAL_OP_TYPE_RET;
|
||||
switch (io.id) {
|
||||
case X86IM_IO_ID_RET_N: /* ret */
|
||||
case X86IM_IO_ID_RET_F: /* retf */
|
||||
aop->stackptr = anal->bits/8;
|
||||
op->stackptr = anal->bits/8;
|
||||
break;
|
||||
case X86IM_IO_ID_RET_N_IM: /* ret n */
|
||||
case X86IM_IO_ID_RET_F_IM: /* retf n */
|
||||
aop->dst = anal_fill_im (anal, io);
|
||||
aop->stackptr = anal->bits/8 + imm;
|
||||
op->dst = anal_fill_im (anal, io);
|
||||
op->stackptr = anal->bits/8 + imm;
|
||||
/* TODO: Deprecate */
|
||||
aop->value = imm;
|
||||
op->value = imm;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void anal_hlt(RAnal *anal, RAnalOp *aop, x86im_instr_object io) {
|
||||
aop->eob = R_TRUE;
|
||||
aop->type = R_ANAL_OP_TYPE_RET;
|
||||
static void anal_hlt(RAnal *anal, RAnalOp *op, x86im_instr_object io) {
|
||||
op->eob = R_TRUE;
|
||||
op->type = R_ANAL_OP_TYPE_RET;
|
||||
}
|
||||
|
||||
static void anal_mov(RAnal *anal, RAnalOp *aop, x86im_instr_object io) {
|
||||
static void anal_mov(RAnal *anal, RAnalOp *op, x86im_instr_object io) {
|
||||
st64 imm, disp;
|
||||
imm = r_hex_bin_truncate (io.imm, io.imm_size);
|
||||
disp = r_hex_bin_truncate (io.disp, io.disp_size);
|
||||
|
||||
aop->type = R_ANAL_OP_TYPE_MOV;
|
||||
op->type = R_ANAL_OP_TYPE_MOV;
|
||||
switch (io.id) {
|
||||
case X86IM_IO_ID_MOV_MM_RG: /* mov [0x0ff | reg1+reg2+0x0ff], reg */
|
||||
case X86IM_IO_ID_MOV_MM_AC:
|
||||
aop->dst = anal_fill_ai_mm (anal, io);
|
||||
aop->src[0] = anal_fill_ai_rg (anal, io, 0);
|
||||
op->dst = anal_fill_ai_mm (anal, io);
|
||||
op->src[0] = anal_fill_ai_rg (anal, io, 0);
|
||||
/* TODO: Deprecate */
|
||||
if (io.mem_base == 0) { /* mov [0x0ff], reg */
|
||||
aop->ref = disp;
|
||||
op->ref = disp;
|
||||
} else
|
||||
if ((X86IM_IO_ROP_GET_ID (io.mem_base) == X86IM_IO_ROP_ID_EBP) &&
|
||||
io.mem_index == 0) { /* mov [ebp+0x0ff], reg */
|
||||
aop->stackop = R_ANAL_STACK_SET;
|
||||
aop->ref = disp;
|
||||
op->stackop = R_ANAL_STACK_SET;
|
||||
op->ref = disp;
|
||||
}
|
||||
break;
|
||||
case X86IM_IO_ID_MOV_R2_R1: /* mov reg2, reg1 */
|
||||
case X86IM_IO_ID_MOV_R1_R2:
|
||||
aop->dst = anal_fill_ai_rg (anal, io, 0);
|
||||
aop->src[0] = anal_fill_ai_rg (anal, io, 1);
|
||||
op->dst = anal_fill_ai_rg (anal, io, 0);
|
||||
op->src[0] = anal_fill_ai_rg (anal, io, 1);
|
||||
break;
|
||||
case X86IM_IO_ID_MOV_RG_MM: /* mov reg, [0x0ff | reg1+reg2+0x0ff] */
|
||||
case X86IM_IO_ID_MOV_AC_MM:
|
||||
aop->dst = anal_fill_ai_rg (anal, io, 0);
|
||||
aop->src[0] = anal_fill_ai_mm (anal, io);
|
||||
op->dst = anal_fill_ai_rg (anal, io, 0);
|
||||
op->src[0] = anal_fill_ai_mm (anal, io);
|
||||
/* TODO: Deprecate */
|
||||
if (io.mem_base == 0) { /* mov reg, [0x0ff] */
|
||||
aop->ref = disp;
|
||||
op->ref = disp;
|
||||
} else
|
||||
if ((X86IM_IO_ROP_GET_ID (io.mem_base) == X86IM_IO_ROP_ID_EBP) &&
|
||||
io.mem_index == 0) { /* mov reg, [ebp+0x0ff] */
|
||||
aop->stackop = R_ANAL_STACK_GET;
|
||||
aop->ref = disp;
|
||||
op->stackop = R_ANAL_STACK_GET;
|
||||
op->ref = disp;
|
||||
}
|
||||
break;
|
||||
case X86IM_IO_ID_MOV_MM_IM: /* mov [0x0ff | reg1+reg2+0x0ff], 0x1 */
|
||||
aop->dst = anal_fill_ai_mm (anal, io);
|
||||
aop->src[0] = anal_fill_im (anal, io);
|
||||
op->dst = anal_fill_ai_mm (anal, io);
|
||||
op->src[0] = anal_fill_im (anal, io);
|
||||
/* TODO: Deprecate */
|
||||
if (io.mem_base == 0) { /* [0x0ff], 0x1 */
|
||||
aop->ref = disp;
|
||||
op->ref = disp;
|
||||
} else
|
||||
if ((X86IM_IO_ROP_GET_ID (io.mem_base) == X86IM_IO_ROP_ID_EBP) &&
|
||||
io.mem_index == 0) { /* mov [ebp+0x0ff], 0x1 */
|
||||
aop->stackop = R_ANAL_STACK_SET;
|
||||
aop->ref = disp;
|
||||
op->stackop = R_ANAL_STACK_SET;
|
||||
op->ref = disp;
|
||||
}
|
||||
break;
|
||||
case X86IM_IO_ID_MOV_RG_IM: /* mov reg, 0x1 */
|
||||
case X86IM_IO_ID_MOV_AC_IM:
|
||||
aop->dst = anal_fill_ai_rg (anal, io, 0);
|
||||
aop->src[0] = anal_fill_im (anal, io);
|
||||
op->dst = anal_fill_ai_rg (anal, io, 0);
|
||||
op->src[0] = anal_fill_im (anal, io);
|
||||
break;
|
||||
case X86IM_IO_ID_MOV_CR0_RG: /* mov cr0, reg */
|
||||
case X86IM_IO_ID_MOV_CR2_RG: /* mov cr2, reg */
|
||||
|
@ -306,173 +306,173 @@ static void anal_mov(RAnal *anal, RAnalOp *aop, x86im_instr_object io) {
|
|||
}
|
||||
}
|
||||
|
||||
static void anal_cmp(RAnal *anal, RAnalOp *aop, x86im_instr_object io) {
|
||||
static void anal_cmp(RAnal *anal, RAnalOp *op, x86im_instr_object io) {
|
||||
st64 imm, disp;
|
||||
imm = r_hex_bin_truncate (io.imm, io.imm_size);
|
||||
disp = r_hex_bin_truncate (io.disp, io.disp_size);
|
||||
|
||||
aop->type = R_ANAL_OP_TYPE_CMP;
|
||||
op->type = R_ANAL_OP_TYPE_CMP;
|
||||
switch (io.id) {
|
||||
case X86IM_IO_ID_CMP_MM_RG: /* cmp [0x0ff | reg1+reg2+0x0ff], reg */
|
||||
aop->dst = anal_fill_ai_mm (anal, io);
|
||||
aop->src[0] = anal_fill_ai_rg (anal, io, 0);
|
||||
op->dst = anal_fill_ai_mm (anal, io);
|
||||
op->src[0] = anal_fill_ai_rg (anal, io, 0);
|
||||
/* TODO: Deprecate */
|
||||
if (io.mem_base == 0) { /* cmp [0x0ff], reg */
|
||||
aop->ref = disp;
|
||||
op->ref = disp;
|
||||
}
|
||||
break;
|
||||
case X86IM_IO_ID_CMP_R1_R2: /* cmp reg2, reg1 */
|
||||
case X86IM_IO_ID_CMP_R2_R1:
|
||||
aop->dst = anal_fill_ai_rg (anal, io, 0);
|
||||
aop->src[0] = anal_fill_ai_rg (anal, io, 1);
|
||||
op->dst = anal_fill_ai_rg (anal, io, 0);
|
||||
op->src[0] = anal_fill_ai_rg (anal, io, 1);
|
||||
break;
|
||||
case X86IM_IO_ID_CMP_RG_MM: /* cmp reg, [0x0ff | reg1+reg2+0x0ff] */
|
||||
aop->dst = anal_fill_ai_rg (anal, io, 0);
|
||||
aop->src[0] = anal_fill_ai_mm (anal, io);
|
||||
op->dst = anal_fill_ai_rg (anal, io, 0);
|
||||
op->src[0] = anal_fill_ai_mm (anal, io);
|
||||
/* TODO: Deprecate */
|
||||
if (io.mem_base == 0) { /* cmp reg, [0x0ff] */
|
||||
aop->ref = disp;
|
||||
op->ref = disp;
|
||||
}
|
||||
break;
|
||||
case X86IM_IO_ID_CMP_MM_IM: /* cmp [0x0ff | reg1+reg2+0x0ff], 0x1 */
|
||||
aop->dst = anal_fill_ai_mm (anal, io);
|
||||
aop->src[0] = anal_fill_im (anal, io);
|
||||
op->dst = anal_fill_ai_mm (anal, io);
|
||||
op->src[0] = anal_fill_im (anal, io);
|
||||
/* TODO: Deprecate */
|
||||
if (io.mem_base == 0) { /* cmp [0x0ff], 0x1 */
|
||||
aop->ref = disp;
|
||||
op->ref = disp;
|
||||
} else
|
||||
if ((X86IM_IO_ROP_GET_ID (io.mem_base) == X86IM_IO_ROP_ID_EBP) &&
|
||||
io.mem_index == 0) { /* cmp [ebp+0x0ff], 0x1*/
|
||||
aop->stackop = R_ANAL_STACK_GET;
|
||||
aop->ref = disp;
|
||||
op->stackop = R_ANAL_STACK_GET;
|
||||
op->ref = disp;
|
||||
}
|
||||
break;
|
||||
case X86IM_IO_ID_CMP_RG_IM: /* cmp reg, 0x1 */
|
||||
case X86IM_IO_ID_CMP_AC_IM:
|
||||
aop->dst = anal_fill_ai_rg (anal, io, 0);
|
||||
aop->src[0] = anal_fill_im (anal, io);
|
||||
op->dst = anal_fill_ai_rg (anal, io, 0);
|
||||
op->src[0] = anal_fill_im (anal, io);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void anal_test(RAnal *anal, RAnalOp *aop, x86im_instr_object io) {
|
||||
static void anal_test(RAnal *anal, RAnalOp *op, x86im_instr_object io) {
|
||||
st64 imm, disp;
|
||||
imm = r_hex_bin_truncate (io.imm, io.imm_size);
|
||||
disp = r_hex_bin_truncate (io.disp, io.disp_size);
|
||||
|
||||
aop->type = R_ANAL_OP_TYPE_CMP;
|
||||
op->type = R_ANAL_OP_TYPE_CMP;
|
||||
switch (io.id) {
|
||||
case X86IM_IO_ID_TEST_MM_R1: /* test [0x0ff | reg1+reg2+0x0ff], reg */
|
||||
aop->dst = anal_fill_ai_mm (anal, io);
|
||||
aop->src[0] = anal_fill_ai_rg (anal, io, 0);
|
||||
op->dst = anal_fill_ai_mm (anal, io);
|
||||
op->src[0] = anal_fill_ai_rg (anal, io, 0);
|
||||
/* TODO: Deprecate */
|
||||
if (io.mem_base == 0) { /* test [0x0ff], reg */
|
||||
aop->ref = disp;
|
||||
op->ref = disp;
|
||||
}
|
||||
break;
|
||||
case X86IM_IO_ID_TEST_R1_R2: /* test reg2, reg1 */
|
||||
aop->dst = anal_fill_ai_rg (anal, io, 0);
|
||||
aop->src[0] = anal_fill_ai_rg (anal, io, 1);
|
||||
op->dst = anal_fill_ai_rg (anal, io, 0);
|
||||
op->src[0] = anal_fill_ai_rg (anal, io, 1);
|
||||
break;
|
||||
case X86IM_IO_ID_TEST_MM_IM: /* test [0x0ff | reg1+reg2+0x0ff], 0x1 */
|
||||
aop->dst = anal_fill_ai_mm (anal, io);
|
||||
aop->src[0] = anal_fill_im (anal, io);
|
||||
op->dst = anal_fill_ai_mm (anal, io);
|
||||
op->src[0] = anal_fill_im (anal, io);
|
||||
/* TODO: Deprecate */
|
||||
if (io.mem_base == 0) { /* test [0x0ff], 0x1 */
|
||||
aop->ref = disp;
|
||||
op->ref = disp;
|
||||
} else
|
||||
if ((X86IM_IO_ROP_GET_ID (io.mem_base) == X86IM_IO_ROP_ID_EBP) &&
|
||||
io.mem_index == 0) { /* test [ebp+0x0ff], 0x1*/
|
||||
aop->stackop = R_ANAL_STACK_GET;
|
||||
aop->ref = disp;
|
||||
op->stackop = R_ANAL_STACK_GET;
|
||||
op->ref = disp;
|
||||
}
|
||||
break;
|
||||
case X86IM_IO_ID_TEST_RG_IM: /* test reg, 0x1 */
|
||||
case X86IM_IO_ID_TEST_AC_IM:
|
||||
aop->dst = anal_fill_ai_rg (anal, io, 0);
|
||||
aop->src[0] = anal_fill_im (anal, io);
|
||||
op->dst = anal_fill_ai_rg (anal, io, 0);
|
||||
op->src[0] = anal_fill_im (anal, io);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void anal_push(RAnal *anal, RAnalOp *aop, x86im_instr_object io) {
|
||||
static void anal_push(RAnal *anal, RAnalOp *op, x86im_instr_object io) {
|
||||
st64 imm, disp;
|
||||
imm = r_hex_bin_truncate (io.imm, io.imm_size);
|
||||
disp = r_hex_bin_truncate (io.disp, io.disp_size);
|
||||
|
||||
switch (io.id) {
|
||||
case X86IM_IO_ID_PUSH_MM: /* push [0x0ff | reg1+reg2+0x0ff] */
|
||||
aop->type = R_ANAL_OP_TYPE_UPUSH;
|
||||
aop->src[0] = anal_fill_ai_mm (anal, io);
|
||||
op->type = R_ANAL_OP_TYPE_UPUSH;
|
||||
op->src[0] = anal_fill_ai_mm (anal, io);
|
||||
/* TODO: Deprecate */
|
||||
aop->stackptr = io.mem_size;
|
||||
op->stackptr = io.mem_size;
|
||||
if (io.mem_base == 0) { /* push [0x0ff] */
|
||||
aop->ref = disp;
|
||||
op->ref = disp;
|
||||
} else
|
||||
if ((X86IM_IO_ROP_GET_ID (io.mem_base) == X86IM_IO_ROP_ID_EBP) &&
|
||||
io.mem_index == 0) { /* push [ebp+0x0ff] */
|
||||
aop->stackop = R_ANAL_STACK_GET;
|
||||
aop->ref = disp;
|
||||
op->stackop = R_ANAL_STACK_GET;
|
||||
op->ref = disp;
|
||||
}
|
||||
break;
|
||||
case X86IM_IO_ID_PUSH_RG1: /* push reg */
|
||||
case X86IM_IO_ID_PUSH_RG2:
|
||||
aop->type = R_ANAL_OP_TYPE_UPUSH;
|
||||
aop->src[0] = anal_fill_ai_rg (anal, io, 0);
|
||||
op->type = R_ANAL_OP_TYPE_UPUSH;
|
||||
op->src[0] = anal_fill_ai_rg (anal, io, 0);
|
||||
/* TODO: Deprecate */
|
||||
if (X86IM_IO_ROP_IS_GPR16(io.rop[0]))
|
||||
aop->stackptr = 2;
|
||||
op->stackptr = 2;
|
||||
else if (X86IM_IO_ROP_IS_GPR32(io.rop[0]))
|
||||
aop->stackptr = 4;
|
||||
op->stackptr = 4;
|
||||
else if (X86IM_IO_ROP_IS_GPR64(io.rop[0]))
|
||||
aop->stackptr = 8;
|
||||
op->stackptr = 8;
|
||||
break;
|
||||
case X86IM_IO_ID_PUSH_IM: /* push 0x1 */
|
||||
aop->type = R_ANAL_OP_TYPE_PUSH;
|
||||
aop->src[0] = anal_fill_im (anal, io);
|
||||
op->type = R_ANAL_OP_TYPE_PUSH;
|
||||
op->src[0] = anal_fill_im (anal, io);
|
||||
/* TODO: Deprecate */
|
||||
aop->value = imm;
|
||||
aop->stackptr = io.imm_size;
|
||||
op->value = imm;
|
||||
op->stackptr = io.imm_size;
|
||||
break;
|
||||
case X86IM_IO_ID_PUSH_SR1: /* push sr */
|
||||
case X86IM_IO_ID_PUSH_SR2:
|
||||
/* io.rop[0] = sr */
|
||||
aop->type = R_ANAL_OP_TYPE_UPUSH;
|
||||
op->type = R_ANAL_OP_TYPE_UPUSH;
|
||||
break;
|
||||
case X86IM_IO_ID_PUSHAD: /* pushad */
|
||||
case X86IM_IO_ID_PUSHF: /* pushf */
|
||||
aop->type = R_ANAL_OP_TYPE_UPUSH;
|
||||
op->type = R_ANAL_OP_TYPE_UPUSH;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void anal_pop(RAnal *anal, RAnalOp *aop, x86im_instr_object io) {
|
||||
static void anal_pop(RAnal *anal, RAnalOp *op, x86im_instr_object io) {
|
||||
st64 imm, disp;
|
||||
imm = r_hex_bin_truncate (io.imm, io.imm_size);
|
||||
disp = r_hex_bin_truncate (io.disp, io.disp_size);
|
||||
|
||||
aop->type = R_ANAL_OP_TYPE_POP;
|
||||
op->type = R_ANAL_OP_TYPE_POP;
|
||||
switch (io.id) {
|
||||
case X86IM_IO_ID_POP_MM: /* pop [0x0ff | reg1+reg2+0x0ff] */
|
||||
aop->dst = anal_fill_ai_mm (anal, io);
|
||||
op->dst = anal_fill_ai_mm (anal, io);
|
||||
/* TODO: Deprecate */
|
||||
if (io.mem_base == 0) { /* pop [0x0ff] */
|
||||
aop->ref = disp;
|
||||
op->ref = disp;
|
||||
}
|
||||
aop->stackptr = -io.mem_size;
|
||||
op->stackptr = -io.mem_size;
|
||||
break;
|
||||
case X86IM_IO_ID_POP_RG1: /* pop reg */
|
||||
case X86IM_IO_ID_POP_RG2:
|
||||
aop->dst = anal_fill_ai_rg (anal, io, 0);
|
||||
op->dst = anal_fill_ai_rg (anal, io, 0);
|
||||
/* TODO: Deprecate */
|
||||
if (X86IM_IO_ROP_IS_GPR16 (io.rop[0]))
|
||||
aop->stackptr = -2;
|
||||
op->stackptr = -2;
|
||||
else
|
||||
if (X86IM_IO_ROP_IS_GPR32 (io.rop[0]))
|
||||
aop->stackptr = -4;
|
||||
op->stackptr = -4;
|
||||
else
|
||||
if (X86IM_IO_ROP_IS_GPR64 (io.rop[0]))
|
||||
aop->stackptr = -8;
|
||||
op->stackptr = -8;
|
||||
break;
|
||||
case X86IM_IO_ID_POP_SR2: /* pop sr */
|
||||
case X86IM_IO_ID_POP_SR1:
|
||||
|
@ -484,130 +484,130 @@ static void anal_pop(RAnal *anal, RAnalOp *aop, x86im_instr_object io) {
|
|||
}
|
||||
}
|
||||
|
||||
static void anal_add(RAnal *anal, RAnalOp *aop, x86im_instr_object io) {
|
||||
static void anal_add(RAnal *anal, RAnalOp *op, x86im_instr_object io) {
|
||||
st64 imm, disp;
|
||||
imm = r_hex_bin_truncate (io.imm, io.imm_size);
|
||||
disp = r_hex_bin_truncate (io.disp, io.disp_size);
|
||||
|
||||
aop->type = R_ANAL_OP_TYPE_ADD;
|
||||
op->type = R_ANAL_OP_TYPE_ADD;
|
||||
switch (io.id) {
|
||||
case X86IM_IO_ID_ADD_MM_RG: /* add [0x0ff | reg1+reg2+0x0ff], reg */
|
||||
aop->dst = anal_fill_ai_mm (anal, io);
|
||||
aop->src[0] = anal_fill_ai_rg (anal, io, 0);
|
||||
op->dst = anal_fill_ai_mm (anal, io);
|
||||
op->src[0] = anal_fill_ai_rg (anal, io, 0);
|
||||
/* TODO: Deprecate */
|
||||
if (io.mem_base == 0) { /* add [0x0ff], reg */
|
||||
aop->ref = disp;
|
||||
op->ref = disp;
|
||||
} else
|
||||
if ((X86IM_IO_ROP_GET_ID (io.mem_base) == X86IM_IO_ROP_ID_EBP) &&
|
||||
io.mem_index == 0) { /* add [ebp+0x0ff], reg*/
|
||||
aop->stackop = R_ANAL_STACK_SET;
|
||||
aop->ref = disp;
|
||||
op->stackop = R_ANAL_STACK_SET;
|
||||
op->ref = disp;
|
||||
}
|
||||
break;
|
||||
case X86IM_IO_ID_ADD_RG_MM: /* add reg, [0x0ff | reg1+reg2+0x0ff] */
|
||||
aop->dst = anal_fill_ai_rg (anal, io, 0);
|
||||
aop->src[0] = anal_fill_ai_mm (anal, io);
|
||||
op->dst = anal_fill_ai_rg (anal, io, 0);
|
||||
op->src[0] = anal_fill_ai_mm (anal, io);
|
||||
/* TODO: Deprecate */
|
||||
if (io.mem_base == 0) { /* add reg, [0x0ff] */
|
||||
aop->ref = disp;
|
||||
op->ref = disp;
|
||||
} else
|
||||
if ((X86IM_IO_ROP_GET_ID (io.mem_base) == X86IM_IO_ROP_ID_EBP) &&
|
||||
io.mem_index == 0) { /* add reg, [ebp+0x0ff] */
|
||||
aop->stackop = R_ANAL_STACK_GET;
|
||||
aop->ref = disp;
|
||||
op->stackop = R_ANAL_STACK_GET;
|
||||
op->ref = disp;
|
||||
}
|
||||
break;
|
||||
case X86IM_IO_ID_ADD_R1_R2: /* add reg2, reg1 */
|
||||
case X86IM_IO_ID_ADD_R2_R1:
|
||||
aop->dst = anal_fill_ai_rg (anal, io, 0);
|
||||
aop->src[0] = anal_fill_ai_rg (anal, io, 1);
|
||||
op->dst = anal_fill_ai_rg (anal, io, 0);
|
||||
op->src[0] = anal_fill_ai_rg (anal, io, 1);
|
||||
break;
|
||||
case X86IM_IO_ID_ADD_MM_IM: /* add [0x0ff | reg1+reg2+0x0ff], 0x1 */
|
||||
aop->dst = anal_fill_ai_mm (anal, io);
|
||||
aop->src[0] = anal_fill_im (anal, io);
|
||||
op->dst = anal_fill_ai_mm (anal, io);
|
||||
op->src[0] = anal_fill_im (anal, io);
|
||||
/* TODO: Deprecate */
|
||||
if (io.mem_base == 0) { /* add [0x0ff], 0x1 */
|
||||
aop->ref = disp;
|
||||
op->ref = disp;
|
||||
}
|
||||
break;
|
||||
case X86IM_IO_ID_ADD_RG_IM: /* add reg, 0x1 */
|
||||
case X86IM_IO_ID_ADD_AC_IM:
|
||||
aop->dst = anal_fill_ai_rg (anal, io, 0);
|
||||
aop->src[0] = anal_fill_im (anal, io);
|
||||
op->dst = anal_fill_ai_rg (anal, io, 0);
|
||||
op->src[0] = anal_fill_im (anal, io);
|
||||
/* TODO: Deprecate */
|
||||
if (X86IM_IO_ROP_GET_ID (io.rop[0]) == X86IM_IO_ROP_ID_ESP) { /* add esp, 0x1 */
|
||||
aop->stackop = R_ANAL_STACK_INCSTACK;
|
||||
aop->value = imm;
|
||||
aop->stackptr = -imm;
|
||||
op->stackop = R_ANAL_STACK_INCSTACK;
|
||||
op->value = imm;
|
||||
op->stackptr = -imm;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void anal_sub(RAnal *anal, RAnalOp *aop, x86im_instr_object io) {
|
||||
static void anal_sub(RAnal *anal, RAnalOp *op, x86im_instr_object io) {
|
||||
st64 imm, disp;
|
||||
imm = r_hex_bin_truncate (io.imm, io.imm_size);
|
||||
disp = r_hex_bin_truncate (io.disp, io.disp_size);
|
||||
|
||||
aop->type = R_ANAL_OP_TYPE_SUB;
|
||||
op->type = R_ANAL_OP_TYPE_SUB;
|
||||
switch (io.id) {
|
||||
case X86IM_IO_ID_SUB_MM_RG: /* sub [0x0ff | reg1+reg2+0x0ff], reg */
|
||||
aop->dst = anal_fill_ai_mm (anal, io);
|
||||
aop->src[0] = anal_fill_ai_rg (anal, io, 0);
|
||||
op->dst = anal_fill_ai_mm (anal, io);
|
||||
op->src[0] = anal_fill_ai_rg (anal, io, 0);
|
||||
/* TODO: Deprecate */
|
||||
if (io.mem_base == 0) { /* sub [0x0ff], reg */
|
||||
aop->ref = disp;
|
||||
op->ref = disp;
|
||||
}
|
||||
break;
|
||||
case X86IM_IO_ID_SUB_R1_R2: /* sub reg2, reg1 */
|
||||
case X86IM_IO_ID_SUB_R2_R1:
|
||||
aop->dst = anal_fill_ai_rg (anal, io, 0);
|
||||
aop->src[0] = anal_fill_ai_rg (anal, io, 1);
|
||||
op->dst = anal_fill_ai_rg (anal, io, 0);
|
||||
op->src[0] = anal_fill_ai_rg (anal, io, 1);
|
||||
break;
|
||||
case X86IM_IO_ID_SUB_RG_MM: /* sub reg, [0x0ff | reg1+reg2+0x0ff] */
|
||||
aop->dst = anal_fill_ai_rg (anal, io, 0);
|
||||
aop->src[0] = anal_fill_ai_mm (anal, io);
|
||||
op->dst = anal_fill_ai_rg (anal, io, 0);
|
||||
op->src[0] = anal_fill_ai_mm (anal, io);
|
||||
/* TODO: Deprecate */
|
||||
if (io.mem_base == 0) { /* sub reg, [0x0ff] */
|
||||
aop->ref = disp;
|
||||
op->ref = disp;
|
||||
}
|
||||
break;
|
||||
case X86IM_IO_ID_SUB_MM_IM: /* sub [0x0ff | reg1+reg2+0x0ff], 0x1 */
|
||||
aop->dst = anal_fill_ai_mm (anal, io);
|
||||
aop->src[0] = anal_fill_im (anal, io);
|
||||
op->dst = anal_fill_ai_mm (anal, io);
|
||||
op->src[0] = anal_fill_im (anal, io);
|
||||
/* TODO: Deprecate */
|
||||
if (io.mem_base == 0) { /* sub [0x0ff], 0x1 */
|
||||
aop->ref = disp;
|
||||
op->ref = disp;
|
||||
}
|
||||
break;
|
||||
case X86IM_IO_ID_SUB_RG_IM: /* sub reg, 0x1 */
|
||||
case X86IM_IO_ID_SUB_AC_IM:
|
||||
aop->dst = anal_fill_ai_rg (anal, io, 0);
|
||||
aop->src[0] = anal_fill_im (anal, io);
|
||||
op->dst = anal_fill_ai_rg (anal, io, 0);
|
||||
op->src[0] = anal_fill_im (anal, io);
|
||||
/* TODO: Deprecate */
|
||||
if (X86IM_IO_ROP_GET_ID (io.rop[0]) == X86IM_IO_ROP_ID_ESP) { /* sub esp, 0x1*/
|
||||
aop->stackop = R_ANAL_STACK_INCSTACK;
|
||||
aop->value = imm;
|
||||
aop->stackptr = imm;
|
||||
op->stackop = R_ANAL_STACK_INCSTACK;
|
||||
op->value = imm;
|
||||
op->stackptr = imm;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void anal_int(RAnal *anal, RAnalOp *aop, x86im_instr_object io) {
|
||||
aop->type = R_ANAL_OP_TYPE_SWI;
|
||||
static void anal_int(RAnal *anal, RAnalOp *op, x86im_instr_object io) {
|
||||
op->type = R_ANAL_OP_TYPE_SWI;
|
||||
switch (io.id) {
|
||||
case X86IM_IO_ID_INTN:
|
||||
aop->value = io.imm; /* io.imm doesn't need to be trucated here */
|
||||
op->value = io.imm; /* io.imm doesn't need to be trucated here */
|
||||
break;
|
||||
case X86IM_IO_ID_INT3:
|
||||
aop->value = 3;
|
||||
op->value = 3;
|
||||
break;
|
||||
case X86IM_IO_ID_INTO:
|
||||
break;
|
||||
}
|
||||
}
|
||||
static int aop(RAnal *anal, RAnalOp *aop, ut64 addr, const ut8 *data, int len) {
|
||||
static int x86_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *data, int len) {
|
||||
x86im_instr_object io;
|
||||
st64 imm, disp;
|
||||
char mnem[256];
|
||||
|
@ -615,11 +615,11 @@ static int aop(RAnal *anal, RAnalOp *aop, ut64 addr, const ut8 *data, int len) {
|
|||
if (data == NULL)
|
||||
return 0;
|
||||
|
||||
memset (aop, '\0', sizeof (RAnalOp));
|
||||
aop->type = R_ANAL_OP_TYPE_UNK;
|
||||
aop->addr = addr;
|
||||
aop->jump = aop->fail = -1;
|
||||
aop->ref = aop->value = -1;
|
||||
memset (op, '\0', sizeof (RAnalOp));
|
||||
op->type = R_ANAL_OP_TYPE_UNK;
|
||||
op->addr = addr;
|
||||
op->jump = op->fail = -1;
|
||||
op->ref = op->value = -1;
|
||||
|
||||
if ((x86im_dec (&io,
|
||||
anal->bits == 32 ? X86IM_IO_MODE_32BIT : X86IM_IO_MODE_64BIT,
|
||||
|
@ -627,85 +627,85 @@ static int aop(RAnal *anal, RAnalOp *aop, ut64 addr, const ut8 *data, int len) {
|
|||
if (io.len > len)
|
||||
return 0;
|
||||
x86im_fmt_format_name (&io, mnem);
|
||||
aop->mnemonic = strdup (mnem);
|
||||
op->mnemonic = strdup (mnem);
|
||||
imm = r_hex_bin_truncate (io.imm, io.imm_size);
|
||||
disp = r_hex_bin_truncate (io.disp, io.disp_size);
|
||||
if (X86IM_IO_IS_GPI_JMP (&io)) /* jump */
|
||||
anal_jmp (anal, aop, io);
|
||||
anal_jmp (anal, op, io);
|
||||
else
|
||||
if (X86IM_IO_IS_GPI_JCC (&io)) /* conditional jump*/
|
||||
anal_cjmp (anal, aop, io);
|
||||
anal_cjmp (anal, op, io);
|
||||
else
|
||||
if (X86IM_IO_IS_GPI_CALL (&io)) /* call */
|
||||
anal_call (anal, aop, io);
|
||||
anal_call (anal, op, io);
|
||||
else
|
||||
if (X86IM_IO_IS_GPI_RET (&io)) /* ret */
|
||||
anal_ret (anal, aop, io);
|
||||
anal_ret (anal, op, io);
|
||||
else
|
||||
if (io.id == X86IM_IO_ID_HLT) /* htl */
|
||||
anal_hlt (anal, aop, io);
|
||||
anal_hlt (anal, op, io);
|
||||
else
|
||||
if (X86IM_IO_IS_GPI_MOV (&io)) /* mov */
|
||||
anal_mov (anal, aop, io);
|
||||
anal_mov (anal, op, io);
|
||||
else
|
||||
if (X86IM_IO_IS_GPI_CMP (&io)) /* cmp */
|
||||
anal_cmp (anal, aop, io);
|
||||
anal_cmp (anal, op, io);
|
||||
else
|
||||
if (X86IM_IO_IS_GPI_TEST (&io)) /* test */
|
||||
anal_test (anal, aop, io);
|
||||
anal_test (anal, op, io);
|
||||
else
|
||||
if (X86IM_IO_IS_GPI_PUSH (&io)) /* push */
|
||||
anal_push (anal, aop, io);
|
||||
anal_push (anal, op, io);
|
||||
else
|
||||
if (X86IM_IO_IS_GPI_POP (&io)) /* pop */
|
||||
anal_pop (anal, aop, io);
|
||||
anal_pop (anal, op, io);
|
||||
else
|
||||
if (X86IM_IO_IS_GPI_ADD (&io)) /* add */
|
||||
anal_add (anal, aop, io);
|
||||
anal_add (anal, op, io);
|
||||
else
|
||||
if (X86IM_IO_IS_GPI_SUB (&io)) /* sub */
|
||||
anal_sub (anal, aop, io);
|
||||
anal_sub (anal, op, io);
|
||||
else
|
||||
if (X86IM_IO_IS_GPI_INT (&io)) /* int */
|
||||
anal_int (anal, aop, io);
|
||||
anal_int (anal, op, io);
|
||||
else
|
||||
if (X86IM_IO_IS_GPI_MUL (&io)) { /* mul */
|
||||
aop->type = R_ANAL_OP_TYPE_MUL;
|
||||
aop->value = imm;
|
||||
op->type = R_ANAL_OP_TYPE_MUL;
|
||||
op->value = imm;
|
||||
} else
|
||||
if (X86IM_IO_IS_GPI_DIV (&io)) { /* div */
|
||||
aop->type = R_ANAL_OP_TYPE_DIV;
|
||||
aop->value = imm;
|
||||
op->type = R_ANAL_OP_TYPE_DIV;
|
||||
op->value = imm;
|
||||
} else
|
||||
if (X86IM_IO_IS_GPI_SHR (&io)) { /* shr */
|
||||
aop->type = R_ANAL_OP_TYPE_SHR;
|
||||
aop->value = imm;
|
||||
op->type = R_ANAL_OP_TYPE_SHR;
|
||||
op->value = imm;
|
||||
} else
|
||||
if (X86IM_IO_IS_GPI_SHL (&io)) { /* shl */
|
||||
aop->type = R_ANAL_OP_TYPE_SHL;
|
||||
aop->value = imm;
|
||||
op->type = R_ANAL_OP_TYPE_SHL;
|
||||
op->value = imm;
|
||||
} else
|
||||
if (X86IM_IO_IS_GPI_OR (&io)) { /* or */
|
||||
aop->type = R_ANAL_OP_TYPE_OR;
|
||||
aop->value = imm;
|
||||
op->type = R_ANAL_OP_TYPE_OR;
|
||||
op->value = imm;
|
||||
} else
|
||||
if (X86IM_IO_IS_GPI_AND (&io)) { /* and */
|
||||
aop->type = R_ANAL_OP_TYPE_AND;
|
||||
aop->value = imm;
|
||||
op->type = R_ANAL_OP_TYPE_AND;
|
||||
op->value = imm;
|
||||
} else
|
||||
if (X86IM_IO_IS_GPI_XOR (&io)) { /* xor */
|
||||
aop->type = R_ANAL_OP_TYPE_XOR;
|
||||
aop->value = imm;
|
||||
op->type = R_ANAL_OP_TYPE_XOR;
|
||||
op->value = imm;
|
||||
} else
|
||||
if (X86IM_IO_IS_GPI_NOT (&io)) { /* not */
|
||||
aop->type = R_ANAL_OP_TYPE_NOT;
|
||||
aop->value = imm;
|
||||
op->type = R_ANAL_OP_TYPE_NOT;
|
||||
op->value = imm;
|
||||
}
|
||||
aop->length = io.len;
|
||||
aop->nopcode = io.opcode_count;
|
||||
op->length = io.len;
|
||||
op->nopcode = io.opcode_count;
|
||||
}
|
||||
|
||||
return aop->length;
|
||||
return op->length;
|
||||
}
|
||||
|
||||
static int set_reg_profile(RAnal *anal) {
|
||||
|
@ -860,7 +860,7 @@ struct r_anal_plugin_t r_anal_plugin_x86 = {
|
|||
.desc = "X86 analysis plugin (x86im backend)",
|
||||
.init = NULL,
|
||||
.fini = NULL,
|
||||
.aop = &aop,
|
||||
.op = &x86_op,
|
||||
.set_reg_profile = &set_reg_profile
|
||||
};
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
|
||||
/* code analysis functions */
|
||||
|
||||
/* arch_aop for x86 */
|
||||
/* arch_op for x86 */
|
||||
// CMP ARG1
|
||||
// 837d0801 cmp dword [ebp+0x8], 0x1
|
||||
// 803db501060800 cmp byte [0x80601b5], 0x0
|
||||
|
@ -36,15 +36,15 @@ static const char *testregs[] = {
|
|||
|
||||
// NOTE: buf should be at least 16 bytes!
|
||||
// XXX addr should be off_t for 64 love
|
||||
static int myaop(RAnal *anal, RAnalOp *aop, ut64 addr, const ut8 *data, int len) {
|
||||
static int myop(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *data, int len) {
|
||||
ut8 *buf = (ut8*)data;
|
||||
if (data == NULL)
|
||||
return 0;
|
||||
memset (aop, 0, sizeof (RAnalOp));
|
||||
aop->type = R_ANAL_OP_TYPE_UNK;
|
||||
aop->addr = addr;
|
||||
aop->jump = aop->fail = -1;
|
||||
aop->ref = aop->value = -1;
|
||||
memset (op, 0, sizeof (RAnalOp));
|
||||
op->type = R_ANAL_OP_TYPE_UNK;
|
||||
op->addr = addr;
|
||||
op->jump = op->fail = -1;
|
||||
op->ref = op->value = -1;
|
||||
|
||||
switch (buf[0]) {
|
||||
case 0x8a:
|
||||
|
@ -57,20 +57,20 @@ static int myaop(RAnal *anal, RAnalOp *aop, ut64 addr, const ut8 *data, int len)
|
|||
case 0x5d:
|
||||
case 0x7d:
|
||||
/* mov -0xc(%ebp, %eax */
|
||||
aop->ref = (st64)((char)buf[2]);
|
||||
aop->stackop = R_ANAL_STACK_GET;
|
||||
op->ref = (st64)((char)buf[2]);
|
||||
op->stackop = R_ANAL_STACK_GET;
|
||||
break;
|
||||
case 0x95:
|
||||
if (buf[2]==0xe0) { // ebp
|
||||
aop->ref = (st64)((int)(buf[3]+(buf[4]<<8)+(buf[5]<<16)+(buf[6]<<24)));
|
||||
aop->stackop = R_ANAL_STACK_GET;
|
||||
op->ref = (st64)((int)(buf[3]+(buf[4]<<8)+(buf[5]<<16)+(buf[6]<<24)));
|
||||
op->stackop = R_ANAL_STACK_GET;
|
||||
}
|
||||
//aop->ref = -(buf[2]+(buf[3]<<8)+(buf[4]<<16)+(buf[5]<<24));
|
||||
//op->ref = -(buf[2]+(buf[3]<<8)+(buf[4]<<16)+(buf[5]<<24));
|
||||
break;
|
||||
case 0xbd:
|
||||
aop->ref = (st64)((int)(buf[2]+(buf[3]<<8)+(buf[4]<<16)+(buf[5]<<24)));
|
||||
//aop->ref = -(buf[2]+(buf[3]<<8)+(buf[4]<<16)+(buf[5]<<24));
|
||||
aop->stackop = R_ANAL_STACK_GET;
|
||||
op->ref = (st64)((int)(buf[2]+(buf[3]<<8)+(buf[4]<<16)+(buf[5]<<24)));
|
||||
//op->ref = -(buf[2]+(buf[3]<<8)+(buf[4]<<16)+(buf[5]<<24));
|
||||
op->stackop = R_ANAL_STACK_GET;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
@ -80,78 +80,78 @@ static int myaop(RAnal *anal, RAnalOp *aop, ut64 addr, const ut8 *data, int len)
|
|||
case 0x45:
|
||||
case 0x4d: // 894de0 mov [ebp-0x20], ecx
|
||||
case 0x55:
|
||||
aop->stackop = R_ANAL_STACK_SET;
|
||||
aop->ref = (st64)((char)buf[2]);
|
||||
op->stackop = R_ANAL_STACK_SET;
|
||||
op->ref = (st64)((char)buf[2]);
|
||||
break;
|
||||
case 0x85:
|
||||
aop->stackop = R_ANAL_STACK_SET;
|
||||
aop->ref = (st64)((int)(buf[2]+(buf[3]<<8)+(buf[4]<<16)+(buf[5]<<24)));
|
||||
op->stackop = R_ANAL_STACK_SET;
|
||||
op->ref = (st64)((int)(buf[2]+(buf[3]<<8)+(buf[4]<<16)+(buf[5]<<24)));
|
||||
break;
|
||||
case 0x75:
|
||||
aop->stackop = R_ANAL_STACK_GET;
|
||||
aop->ref = (st64)((char)buf[2]); //+(buf[3]<<8)+(buf[4]<<16)+(buf[5]<<24));
|
||||
op->stackop = R_ANAL_STACK_GET;
|
||||
op->ref = (st64)((char)buf[2]); //+(buf[3]<<8)+(buf[4]<<16)+(buf[5]<<24));
|
||||
break;
|
||||
}
|
||||
// XXX: maybe store or mov depending on opcode
|
||||
// 89c3 mov ebx, eax
|
||||
// 897c2408 mov [esp+0x8], edi
|
||||
aop->type = R_ANAL_OP_TYPE_STORE;
|
||||
op->type = R_ANAL_OP_TYPE_STORE;
|
||||
break;
|
||||
case 0xf4: // hlt
|
||||
aop->type = R_ANAL_OP_TYPE_RET;
|
||||
aop->length = 1;
|
||||
op->type = R_ANAL_OP_TYPE_RET;
|
||||
op->length = 1;
|
||||
break;
|
||||
case 0xc3: // ret
|
||||
case 0xc2: // ret + 2 bytes
|
||||
case 0xcb: // lret
|
||||
case 0xcf: // iret
|
||||
aop->type = R_ANAL_OP_TYPE_RET;
|
||||
aop->eob = 1;
|
||||
op->type = R_ANAL_OP_TYPE_RET;
|
||||
op->eob = 1;
|
||||
break;
|
||||
//case 0xea: // far jmp
|
||||
// TODO moar
|
||||
case 0x3b: //cmp
|
||||
aop->ref = (st64)((char)buf[2]);
|
||||
aop->stackop = R_ANAL_STACK_GET;
|
||||
op->ref = (st64)((char)buf[2]);
|
||||
op->stackop = R_ANAL_STACK_GET;
|
||||
case 0x39:
|
||||
case 0x3c:
|
||||
case 0x3d:
|
||||
// 3d 00 40 00 00 cmp eax, 0x4000
|
||||
aop->src[0] = r_anal_value_new ();
|
||||
aop->src[0]->reg = r_reg_get (anal->reg, testregs[(buf[0]&7)%8], R_REG_TYPE_GPR);
|
||||
aop->src[1] = r_anal_value_new ();
|
||||
aop->src[1]->base = buf[1]+(buf[2]<<8)+(buf[3]<<16)+(buf[4]<<24);
|
||||
aop->type = R_ANAL_OP_TYPE_CMP;
|
||||
op->src[0] = r_anal_value_new ();
|
||||
op->src[0]->reg = r_reg_get (anal->reg, testregs[(buf[0]&7)%8], R_REG_TYPE_GPR);
|
||||
op->src[1] = r_anal_value_new ();
|
||||
op->src[1]->base = buf[1]+(buf[2]<<8)+(buf[3]<<16)+(buf[4]<<24);
|
||||
op->type = R_ANAL_OP_TYPE_CMP;
|
||||
break;
|
||||
case 0x80:
|
||||
aop->type = R_ANAL_OP_TYPE_CMP;
|
||||
op->type = R_ANAL_OP_TYPE_CMP;
|
||||
switch (buf[1]) {
|
||||
case 0x3d: // 80 3d b5010608 00 cmp byte [0x80601b5], 0x0
|
||||
aop->src[0] = r_anal_value_new ();
|
||||
aop->src[0]->memref = 1;
|
||||
aop->src[0]->base = buf[2]+(buf[3]<<8)+(buf[4]<<16)+(buf[5]<<24);
|
||||
aop->src[1] = r_anal_value_new ();
|
||||
aop->src[1]->base = buf[6];
|
||||
op->src[0] = r_anal_value_new ();
|
||||
op->src[0]->memref = 1;
|
||||
op->src[0]->base = buf[2]+(buf[3]<<8)+(buf[4]<<16)+(buf[5]<<24);
|
||||
op->src[1] = r_anal_value_new ();
|
||||
op->src[1]->base = buf[6];
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 0x85:
|
||||
aop->type = R_ANAL_OP_TYPE_CMP;
|
||||
op->type = R_ANAL_OP_TYPE_CMP;
|
||||
if (buf[1]>=0xc0 && buf[1]<=0xff) { // test eax, eax
|
||||
int src = buf[1]&7;
|
||||
int dst = (buf[1]&0x38)>>3;
|
||||
aop->src[0] = r_anal_value_new ();
|
||||
aop->src[0]->reg = r_reg_get (anal->reg, testregs[src%8], R_REG_TYPE_GPR);
|
||||
aop->src[1] = r_anal_value_new ();
|
||||
aop->src[1]->reg = r_reg_get (anal->reg, testregs[dst%8], R_REG_TYPE_GPR);
|
||||
aop->src[2] = NULL;
|
||||
op->src[0] = r_anal_value_new ();
|
||||
op->src[0]->reg = r_reg_get (anal->reg, testregs[src%8], R_REG_TYPE_GPR);
|
||||
op->src[1] = r_anal_value_new ();
|
||||
op->src[1]->reg = r_reg_get (anal->reg, testregs[dst%8], R_REG_TYPE_GPR);
|
||||
op->src[2] = NULL;
|
||||
//eprintf ("REGZ (%s)\n", anal->reg);
|
||||
//eprintf ("REG IZ: (%s)\n", testregs[src%8]);
|
||||
//eprintf ("REG IZ: %p (%s)\n", aop->src[0], aop->src[0]->reg->name);
|
||||
if (aop->src[0]->reg == aop->src[1]->reg) {
|
||||
//eprintf ("REG IZ: %p (%s)\n", op->src[0], op->src[0]->reg->name);
|
||||
if (op->src[0]->reg == op->src[1]->reg) {
|
||||
//eprintf ("fruity\n");
|
||||
r_anal_value_free (aop->src[1]);
|
||||
aop->src[1] = NULL;
|
||||
r_anal_value_free (op->src[1]);
|
||||
op->src[1] = NULL;
|
||||
}
|
||||
//eprintf ("0x%"PFMT64x": (%02x) %d %d\n", addr, buf[1], src, dst);
|
||||
} else if (buf[1]<0xc0) { // test [eax+delta], eax
|
||||
|
@ -163,46 +163,46 @@ static int myaop(RAnal *anal, RAnalOp *aop, ut64 addr, const ut8 *data, int len)
|
|||
// 85c9 test ecx, ecx
|
||||
break;
|
||||
case 0x90:
|
||||
aop->type = R_ANAL_OP_TYPE_NOP;
|
||||
aop->length = 1;
|
||||
op->type = R_ANAL_OP_TYPE_NOP;
|
||||
op->length = 1;
|
||||
break;
|
||||
case 0x0f: // 3 byte nop
|
||||
//0fbe55ff movsx edx, byte [ebp-0x1]
|
||||
if (buf[1]==0xbe) {
|
||||
aop->ref = (st64)((char)buf[3]);
|
||||
aop->stackop = R_ANAL_STACK_GET;
|
||||
op->ref = (st64)((char)buf[3]);
|
||||
op->stackop = R_ANAL_STACK_GET;
|
||||
} else
|
||||
if (buf[1]==0x31) {
|
||||
// RDTSC // colorize or sthg?
|
||||
aop->eob = 0;
|
||||
op->eob = 0;
|
||||
} else
|
||||
if (buf[1]>=0x18 && buf[1]<=0x1f) {
|
||||
aop->type = R_ANAL_OP_TYPE_NOP;
|
||||
aop->length = 3;
|
||||
op->type = R_ANAL_OP_TYPE_NOP;
|
||||
op->length = 3;
|
||||
} else
|
||||
if (buf[1]>=0x80 && buf[1]<=0x8f) {
|
||||
aop->type = R_ANAL_OP_TYPE_CJMP;
|
||||
aop->jump = addr+6+buf[2]+(buf[3]<<8)+(buf[4]<<16)+(buf[5]<<24);//((unsigned long)((buf+2))+6);
|
||||
aop->fail = addr+6;
|
||||
aop->length = 6;
|
||||
//aop->eob = 1;
|
||||
op->type = R_ANAL_OP_TYPE_CJMP;
|
||||
op->jump = addr+6+buf[2]+(buf[3]<<8)+(buf[4]<<16)+(buf[5]<<24);//((unsigned long)((buf+2))+6);
|
||||
op->fail = addr+6;
|
||||
op->length = 6;
|
||||
//op->eob = 1;
|
||||
} else
|
||||
if (buf[1]>=0x40 && buf[1]<=0x4f) { /* Conditional MOV */
|
||||
aop->type = R_ANAL_OP_TYPE_MOV;
|
||||
aop->eob = 0;
|
||||
aop->length = 4;
|
||||
op->type = R_ANAL_OP_TYPE_MOV;
|
||||
op->eob = 0;
|
||||
op->length = 4;
|
||||
return 4;
|
||||
}
|
||||
break;
|
||||
case 0xcc: // int3
|
||||
// aop->eob = 1;
|
||||
aop->value = 3;
|
||||
aop->type = R_ANAL_OP_TYPE_SWI;
|
||||
// op->eob = 1;
|
||||
op->value = 3;
|
||||
op->type = R_ANAL_OP_TYPE_SWI;
|
||||
break;
|
||||
case 0xf1: // int1
|
||||
aop->length = 1;
|
||||
aop->value = 1;
|
||||
aop->type = R_ANAL_OP_TYPE_SWI;
|
||||
op->length = 1;
|
||||
op->value = 1;
|
||||
op->type = R_ANAL_OP_TYPE_SWI;
|
||||
break;
|
||||
case 0xb8: // mov eax, <inmedate>
|
||||
case 0xb9: // mov ecx, <inmedate>
|
||||
|
@ -211,74 +211,74 @@ static int myaop(RAnal *anal, RAnalOp *aop, ut64 addr, const ut8 *data, int len)
|
|||
case 0xbc: // mov esp, <inmedate>
|
||||
case 0xbd: // mov esp, <inmedate>
|
||||
case 0xbf:
|
||||
aop->type = R_ANAL_OP_TYPE_MOV; // bfdc054000 mov edi, 0x4005dc
|
||||
aop->ref = (st64)((int)buf[1]+(buf[2]<<8)+(buf[3]<<16)+(buf[4]<<24));//((unsigned long)((buf+2))+6);
|
||||
op->type = R_ANAL_OP_TYPE_MOV; // bfdc054000 mov edi, 0x4005dc
|
||||
op->ref = (st64)((int)buf[1]+(buf[2]<<8)+(buf[3]<<16)+(buf[4]<<24));//((unsigned long)((buf+2))+6);
|
||||
break;
|
||||
case 0xcd:
|
||||
aop->length = 2;
|
||||
aop->type = R_ANAL_OP_TYPE_SWI;
|
||||
aop->value = buf[1];
|
||||
op->length = 2;
|
||||
op->type = R_ANAL_OP_TYPE_SWI;
|
||||
op->value = buf[1];
|
||||
break;
|
||||
case 0xe8: // call
|
||||
aop->type = R_ANAL_OP_TYPE_CALL;
|
||||
aop->length = 5;
|
||||
//aop->jump = addr+*ptr+5; //(unsigned long)((buf+1)+5);
|
||||
aop->jump = addr+5+buf[1]+(buf[2]<<8)+(buf[3]<<16)+(buf[4]<<24);//((unsigned long)((buf+2))+6);
|
||||
aop->fail = addr+5;
|
||||
//printf("addr: %08"PFMT64x"\n call %08"PFMT64x" \n ret %08"PFMT64x"\n", addr, aop->jump, aop->fail);
|
||||
// aop->eob = 1;
|
||||
op->type = R_ANAL_OP_TYPE_CALL;
|
||||
op->length = 5;
|
||||
//op->jump = addr+*ptr+5; //(unsigned long)((buf+1)+5);
|
||||
op->jump = addr+5+buf[1]+(buf[2]<<8)+(buf[3]<<16)+(buf[4]<<24);//((unsigned long)((buf+2))+6);
|
||||
op->fail = addr+5;
|
||||
//printf("addr: %08"PFMT64x"\n call %08"PFMT64x" \n ret %08"PFMT64x"\n", addr, op->jump, op->fail);
|
||||
// op->eob = 1;
|
||||
break;
|
||||
case 0xe9: // jmp
|
||||
aop->type = R_ANAL_OP_TYPE_JMP;
|
||||
aop->length = 5;
|
||||
//aop->jump = (unsigned long)((buf+1)+5);
|
||||
aop->jump = addr+5+buf[1]+(buf[2]<<8)+(buf[3]<<16)+(buf[4]<<24);//((unsigned long)((buf+2))+6);
|
||||
aop->fail = 0L;
|
||||
aop->eob = 1;
|
||||
op->type = R_ANAL_OP_TYPE_JMP;
|
||||
op->length = 5;
|
||||
//op->jump = (unsigned long)((buf+1)+5);
|
||||
op->jump = addr+5+buf[1]+(buf[2]<<8)+(buf[3]<<16)+(buf[4]<<24);//((unsigned long)((buf+2))+6);
|
||||
op->fail = 0L;
|
||||
op->eob = 1;
|
||||
break;
|
||||
case 0xeb: // short jmp
|
||||
aop->type = R_ANAL_OP_TYPE_JMP;
|
||||
aop->length = 2;
|
||||
aop->jump = addr+((unsigned long)((char)buf[1])+2);
|
||||
aop->fail = 0L;
|
||||
aop->eob = 1;
|
||||
op->type = R_ANAL_OP_TYPE_JMP;
|
||||
op->length = 2;
|
||||
op->jump = addr+((unsigned long)((char)buf[1])+2);
|
||||
op->fail = 0L;
|
||||
op->eob = 1;
|
||||
break;
|
||||
case 0xf2: // repnz
|
||||
case 0xf3: // repz
|
||||
aop->type = R_ANAL_OP_TYPE_REP;
|
||||
//aop->length = dislen((unsigned char *)&buf); //instLength(buf, 16, 0);
|
||||
aop->jump = 0L;
|
||||
aop->fail = 0L;
|
||||
op->type = R_ANAL_OP_TYPE_REP;
|
||||
//op->length = dislen((unsigned char *)&buf); //instLength(buf, 16, 0);
|
||||
op->jump = 0L;
|
||||
op->fail = 0L;
|
||||
break;
|
||||
case 0xff:
|
||||
if (buf[1]== 0x75) {
|
||||
aop->type = R_ANAL_OP_TYPE_PUSH;
|
||||
aop->stackop = R_ANAL_STACK_GET;
|
||||
aop->ref = 0LL;
|
||||
aop->ref = (st64)((char)(buf[2]));
|
||||
aop->stackptr = 4;
|
||||
op->type = R_ANAL_OP_TYPE_PUSH;
|
||||
op->stackop = R_ANAL_STACK_GET;
|
||||
op->ref = 0LL;
|
||||
op->ref = (st64)((char)(buf[2]));
|
||||
op->stackptr = 4;
|
||||
} else
|
||||
if (buf[1]== 0x45) {
|
||||
aop->type = R_ANAL_OP_TYPE_ADD;
|
||||
aop->stackop = R_ANAL_STACK_SET;
|
||||
aop->ref = (st64)((char)buf[2]);
|
||||
op->type = R_ANAL_OP_TYPE_ADD;
|
||||
op->stackop = R_ANAL_STACK_SET;
|
||||
op->ref = (st64)((char)buf[2]);
|
||||
} else
|
||||
if (buf[1]>=0x50 && buf[1]<=0x6f) {
|
||||
aop->type = R_ANAL_OP_TYPE_UJMP;
|
||||
aop->eob = 1;
|
||||
op->type = R_ANAL_OP_TYPE_UJMP;
|
||||
op->eob = 1;
|
||||
} else
|
||||
if (buf[1]>=0xd0 && buf[1]<=0xd7) {
|
||||
aop->type = R_ANAL_OP_TYPE_CALL;
|
||||
aop->length = 2;
|
||||
aop->eob = 1;
|
||||
//aop->jump = vm_arch_x86_regs[VM_X86_EAX+buf[1]-0xd0];
|
||||
aop->fail = addr+2;
|
||||
op->type = R_ANAL_OP_TYPE_CALL;
|
||||
op->length = 2;
|
||||
op->eob = 1;
|
||||
//op->jump = vm_arch_x86_regs[VM_X86_EAX+buf[1]-0xd0];
|
||||
op->fail = addr+2;
|
||||
} else
|
||||
if (buf[1]>=0xe0 && buf[1]<=0xe7) {
|
||||
aop->type = R_ANAL_OP_TYPE_UJMP;
|
||||
aop->length = 2;
|
||||
//aop->jump = vm_arch_x86_regs[VM_X86_EAX+buf[1]-0xd0];
|
||||
aop->eob = 1;
|
||||
op->type = R_ANAL_OP_TYPE_UJMP;
|
||||
op->length = 2;
|
||||
//op->jump = vm_arch_x86_regs[VM_X86_EAX+buf[1]-0xd0];
|
||||
op->eob = 1;
|
||||
}
|
||||
break;
|
||||
case 0x50:
|
||||
|
@ -291,14 +291,14 @@ static int myaop(RAnal *anal, RAnalOp *aop, ut64 addr, const ut8 *data, int len)
|
|||
case 0x57:
|
||||
case 0x58:
|
||||
case 0x59:
|
||||
aop->type = R_ANAL_OP_TYPE_UPUSH;
|
||||
aop->ref = 0; // TODO value of register here! get_offset
|
||||
aop->stackptr = 4;
|
||||
op->type = R_ANAL_OP_TYPE_UPUSH;
|
||||
op->ref = 0; // TODO value of register here! get_offset
|
||||
op->stackptr = 4;
|
||||
break;
|
||||
case 0x6a: // push $7
|
||||
aop->type = R_ANAL_OP_TYPE_PUSH;
|
||||
aop->ref = buf[1];
|
||||
aop->stackptr = 4;
|
||||
op->type = R_ANAL_OP_TYPE_PUSH;
|
||||
op->ref = buf[1];
|
||||
op->stackptr = 4;
|
||||
break;
|
||||
break;
|
||||
case 0x5a:
|
||||
|
@ -307,15 +307,15 @@ static int myaop(RAnal *anal, RAnalOp *aop, ut64 addr, const ut8 *data, int len)
|
|||
case 0x5d:
|
||||
case 0x5e:
|
||||
case 0x5f:
|
||||
aop->type = R_ANAL_OP_TYPE_POP;
|
||||
aop->length = 1;
|
||||
aop->stackptr = -4;
|
||||
op->type = R_ANAL_OP_TYPE_POP;
|
||||
op->length = 1;
|
||||
op->stackptr = -4;
|
||||
break;
|
||||
case 0x2e: // 2e64796e jns 0xb770a4ab !!
|
||||
if (buf[1]>=0x64 && buf[1]<=0x67) {
|
||||
int ret = myaop (anal, aop, addr, data+1, len-1);
|
||||
aop->jump++;
|
||||
aop->length++;
|
||||
int ret = myop (anal, op, addr, data+1, len-1);
|
||||
op->jump++;
|
||||
op->length++;
|
||||
return ret;
|
||||
}
|
||||
break;
|
||||
|
@ -323,29 +323,29 @@ static int myaop(RAnal *anal, RAnalOp *aop, ut64 addr, const ut8 *data, int len)
|
|||
case 0x65:
|
||||
case 0x66:
|
||||
case 0x67:
|
||||
aop->type = R_ANAL_OP_TYPE_CJMP;
|
||||
aop->jump = addr+3+buf[2]; //+(buf[2]<<8)+(buf[3]<<16); // XXX
|
||||
aop->length = 3;
|
||||
aop->fail = addr+aop->length;
|
||||
//aop->eob = 1;
|
||||
op->type = R_ANAL_OP_TYPE_CJMP;
|
||||
op->jump = addr+3+buf[2]; //+(buf[2]<<8)+(buf[3]<<16); // XXX
|
||||
op->length = 3;
|
||||
op->fail = addr+op->length;
|
||||
//op->eob = 1;
|
||||
break;
|
||||
case 0x68:
|
||||
aop->type = R_ANAL_OP_TYPE_PUSH;
|
||||
aop->ref = (st64)((int)buf[1]+(buf[2]<<8)+(buf[3]<<16)+(buf[4]<<24));
|
||||
aop->stackptr = 4;
|
||||
op->type = R_ANAL_OP_TYPE_PUSH;
|
||||
op->ref = (st64)((int)buf[1]+(buf[2]<<8)+(buf[3]<<16)+(buf[4]<<24));
|
||||
op->stackptr = 4;
|
||||
break;
|
||||
case 0x81:
|
||||
aop->type = R_ANAL_OP_TYPE_ADD;
|
||||
op->type = R_ANAL_OP_TYPE_ADD;
|
||||
if (buf[1] == 0xec) {
|
||||
/* sub $0x????????, $esp*/
|
||||
// 81ece00d0000 sub esp, 0xde0 ;
|
||||
aop->value = buf[2]+(buf[3]<<8)+(buf[4]<<16)+(buf[5]<<24);
|
||||
aop->stackop = R_ANAL_STACK_INCSTACK;
|
||||
aop->stackptr = aop->value;
|
||||
op->value = buf[2]+(buf[3]<<8)+(buf[4]<<16)+(buf[5]<<24);
|
||||
op->stackop = R_ANAL_STACK_INCSTACK;
|
||||
op->stackptr = op->value;
|
||||
break;
|
||||
} else
|
||||
if (buf[1] == 0xfa) {
|
||||
aop->type = R_ANAL_OP_TYPE_CMP;
|
||||
op->type = R_ANAL_OP_TYPE_CMP;
|
||||
// 81fa00c00000 cmp edx, 0xc000
|
||||
// XXX TODO
|
||||
}
|
||||
|
@ -353,80 +353,80 @@ static int myaop(RAnal *anal, RAnalOp *aop, ut64 addr, const ut8 *data, int len)
|
|||
case 0x83:
|
||||
switch (buf[1]) {
|
||||
case 0xe4: // and
|
||||
aop->value = (ut64)(unsigned char)buf[2];
|
||||
aop->type = R_ANAL_OP_TYPE_AND;
|
||||
op->value = (ut64)(unsigned char)buf[2];
|
||||
op->type = R_ANAL_OP_TYPE_AND;
|
||||
break;
|
||||
case 0xc4:
|
||||
/* inc $0x????????, $esp*/
|
||||
aop->value = -(ut64)(unsigned char)buf[2];
|
||||
aop->stackop = R_ANAL_STACK_INCSTACK;
|
||||
aop->stackptr = aop->value;
|
||||
op->value = -(ut64)(unsigned char)buf[2];
|
||||
op->stackop = R_ANAL_STACK_INCSTACK;
|
||||
op->stackptr = op->value;
|
||||
break;
|
||||
case 0xf8:
|
||||
case 0xf9:
|
||||
case 0xfa:
|
||||
{
|
||||
int src = buf[1]&7;
|
||||
aop->src[0] = r_anal_value_new ();
|
||||
aop->src[0]->reg = r_reg_get (anal->reg, testregs[src%8], R_REG_TYPE_GPR);
|
||||
aop->src[1] = r_anal_value_new ();
|
||||
aop->src[1]->base = buf[2];
|
||||
op->src[0] = r_anal_value_new ();
|
||||
op->src[0]->reg = r_reg_get (anal->reg, testregs[src%8], R_REG_TYPE_GPR);
|
||||
op->src[1] = r_anal_value_new ();
|
||||
op->src[1]->base = buf[2];
|
||||
// 83f821 cmp eax, 0x21
|
||||
aop->type = R_ANAL_OP_TYPE_CMP;
|
||||
aop->length = 3;
|
||||
op->type = R_ANAL_OP_TYPE_CMP;
|
||||
op->length = 3;
|
||||
}
|
||||
break;
|
||||
case 0xec:
|
||||
/* sub $0x????????, $esp*/
|
||||
aop->value = (ut64)(unsigned char)buf[2];
|
||||
aop->stackop = R_ANAL_STACK_INCSTACK;
|
||||
aop->stackptr = aop->value;
|
||||
op->value = (ut64)(unsigned char)buf[2];
|
||||
op->stackop = R_ANAL_STACK_INCSTACK;
|
||||
op->stackptr = op->value;
|
||||
break;
|
||||
case 0xbd: /* 837dfc02 cmp dword [ebp-0x4], 0x2 */
|
||||
switch (buf[2]) {
|
||||
case 0xe0: // ebp
|
||||
if ((char)buf[2]>0) {
|
||||
aop->stackop = R_ANAL_STACK_GET;
|
||||
aop->value = buf[3]+(buf[4]<<8)+(buf[5]<<16)+(buf[6]<<24);
|
||||
op->stackop = R_ANAL_STACK_GET;
|
||||
op->value = buf[3]+(buf[4]<<8)+(buf[5]<<16)+(buf[6]<<24);
|
||||
} else {
|
||||
aop->stackop = R_ANAL_STACK_GET;
|
||||
aop->value = buf[3]+(buf[4]<<8)+(buf[5]<<16)+(buf[6]<<24);
|
||||
op->stackop = R_ANAL_STACK_GET;
|
||||
op->value = buf[3]+(buf[4]<<8)+(buf[5]<<16)+(buf[6]<<24);
|
||||
}
|
||||
aop->type = R_ANAL_OP_TYPE_CMP;
|
||||
op->type = R_ANAL_OP_TYPE_CMP;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 0x7d: /* 837dfc02 cmp dword [ebp-0x4], 0x2 */
|
||||
if ((char)buf[2]>0) {
|
||||
aop->stackop = R_ANAL_STACK_GET;
|
||||
aop->value = (ut64)(char)buf[2];
|
||||
op->stackop = R_ANAL_STACK_GET;
|
||||
op->value = (ut64)(char)buf[2];
|
||||
} else {
|
||||
aop->stackop = R_ANAL_STACK_GET;
|
||||
aop->value = (ut64)-(char)buf[2];
|
||||
op->stackop = R_ANAL_STACK_GET;
|
||||
op->value = (ut64)-(char)buf[2];
|
||||
}
|
||||
aop->type = R_ANAL_OP_TYPE_CMP;
|
||||
op->type = R_ANAL_OP_TYPE_CMP;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 0x8d:
|
||||
/* LEA */
|
||||
if (buf[1] == 0x85) {
|
||||
aop->ref = (st64)((int)(buf[2]+(buf[3]<<8)+(buf[4]<<16)+(buf[5]<<24)));
|
||||
aop->stackop = R_ANAL_STACK_GET;
|
||||
op->ref = (st64)((int)(buf[2]+(buf[3]<<8)+(buf[4]<<16)+(buf[5]<<24)));
|
||||
op->stackop = R_ANAL_STACK_GET;
|
||||
}
|
||||
aop->type =R_ANAL_OP_TYPE_MOV;
|
||||
op->type =R_ANAL_OP_TYPE_MOV;
|
||||
break;
|
||||
case 0xc6:
|
||||
case 0xc7:
|
||||
/* mov dword [ebp-0xc], 0x0 || c7 45 f4 00000000 */
|
||||
switch (buf[1]) {
|
||||
case 0x85:
|
||||
aop->ref = (st64)(((int)(buf[2]+(buf[3]<<8)+(buf[4]<<16)+(buf[5]<<24))));
|
||||
op->ref = (st64)(((int)(buf[2]+(buf[3]<<8)+(buf[4]<<16)+(buf[5]<<24))));
|
||||
break;
|
||||
//c785 e4fbffff 00. mov dword [ebp+0xfffffbe4], 0x0
|
||||
case 0x45:
|
||||
aop->stackop = R_ANAL_STACK_SET;
|
||||
aop->ref = (st64)((char)buf[2]);
|
||||
op->stackop = R_ANAL_STACK_SET;
|
||||
op->ref = (st64)((char)buf[2]);
|
||||
break;
|
||||
case 0x05:
|
||||
// c7050c0106080000. mov dword [0x806010c], 0x0
|
||||
|
@ -435,27 +435,27 @@ static int myaop(RAnal *anal, RAnalOp *aop, ut64 addr, const ut8 *data, int len)
|
|||
break;
|
||||
case 0x04:
|
||||
// c7042496850408 dword [esp] = 0x8048596 ; LOL
|
||||
aop->refptr = 4;
|
||||
aop->ref = (st64)(((int)(buf[3]+(buf[4]<<8)+(buf[5]<<16)+(buf[6]<<24))));
|
||||
op->refptr = 4;
|
||||
op->ref = (st64)(((int)(buf[3]+(buf[4]<<8)+(buf[5]<<16)+(buf[6]<<24))));
|
||||
break;
|
||||
}
|
||||
aop->type = R_ANAL_OP_TYPE_STORE;
|
||||
op->type = R_ANAL_OP_TYPE_STORE;
|
||||
break;
|
||||
case 0x82:
|
||||
aop->type = R_ANAL_OP_TYPE_ADD;
|
||||
op->type = R_ANAL_OP_TYPE_ADD;
|
||||
break;
|
||||
case 0x29:
|
||||
aop->type = R_ANAL_OP_TYPE_SUB;
|
||||
op->type = R_ANAL_OP_TYPE_SUB;
|
||||
break;
|
||||
case 0x31:
|
||||
aop->type = R_ANAL_OP_TYPE_XOR;
|
||||
op->type = R_ANAL_OP_TYPE_XOR;
|
||||
break;
|
||||
case 0x32:
|
||||
aop->type = R_ANAL_OP_TYPE_AND;
|
||||
op->type = R_ANAL_OP_TYPE_AND;
|
||||
break;
|
||||
|
||||
case 0xa1: // mov eax, [addr]
|
||||
aop->type = R_ANAL_OP_TYPE_MOV;
|
||||
op->type = R_ANAL_OP_TYPE_MOV;
|
||||
//vm_arch_x86_regs[VM_X86_EAX] = addr+buf[1]+(buf[2]<<8)+(buf[3]<<16)+(buf[4]<<24);
|
||||
//radare_read_at((ut64)vm_arch_x86_regs[VM_X86_EAX], (unsigned char *)&(vm_arch_x86_regs[VM_X86_EAX]), 4);
|
||||
break;
|
||||
|
@ -463,11 +463,11 @@ static int myaop(RAnal *anal, RAnalOp *aop, ut64 addr, const ut8 *data, int len)
|
|||
case0xF
|
||||
/* conditional jump */
|
||||
if (buf[1]>=0x80&&buf[1]<=0x8F) {
|
||||
aop->type = R_ANAL_OP_TYPE_CJMP;
|
||||
aop->length = 6;
|
||||
aop->jump = (unsigned long)((buf+2)+6);
|
||||
aop->fail = addr+6;
|
||||
aop->eob = 1;
|
||||
op->type = R_ANAL_OP_TYPE_CJMP;
|
||||
op->length = 6;
|
||||
op->jump = (unsigned long)((buf+2)+6);
|
||||
op->fail = addr+6;
|
||||
op->eob = 1;
|
||||
return 5;
|
||||
}
|
||||
break;
|
||||
|
@ -491,25 +491,25 @@ static int myaop(RAnal *anal, RAnalOp *aop, ut64 addr, const ut8 *data, int len)
|
|||
int bo = (int)((char) buf[1]);
|
||||
/* conditional jump */
|
||||
//if (buf[1]>=0x80&&buf[1]<=0x8F) {
|
||||
aop->type = R_ANAL_OP_TYPE_CJMP;
|
||||
aop->length = 2;
|
||||
// aop->jump = (unsigned long)((buf+2)+6);
|
||||
aop->jump = addr+bo+2; //(unsigned long)((buf+1)+5);
|
||||
aop->fail = addr+2;
|
||||
aop->eob = 1;
|
||||
op->type = R_ANAL_OP_TYPE_CJMP;
|
||||
op->length = 2;
|
||||
// op->jump = (unsigned long)((buf+2)+6);
|
||||
op->jump = addr+bo+2; //(unsigned long)((buf+1)+5);
|
||||
op->fail = addr+2;
|
||||
op->eob = 1;
|
||||
//return 2;
|
||||
}
|
||||
break;
|
||||
//default:
|
||||
//aop->type = R_ANAL_OP_TYPE_UNK;
|
||||
//op->type = R_ANAL_OP_TYPE_UNK;
|
||||
}
|
||||
|
||||
//if (aop->length == 0)
|
||||
aop->length = dislen ((unsigned char *)buf, 64); //instLength(buf, 16, 0);
|
||||
//aop->length = instLength(buf, 16, 0);
|
||||
if (!(aop->jump>>33))
|
||||
aop->jump &= 0xFFFFFFFF; // XXX may break on 64 bits here
|
||||
return aop->length;
|
||||
//if (op->length == 0)
|
||||
op->length = dislen ((unsigned char *)buf, 64); //instLength(buf, 16, 0);
|
||||
//op->length = instLength(buf, 16, 0);
|
||||
if (!(op->jump>>33))
|
||||
op->jump &= 0xFFFFFFFF; // XXX may break on 64 bits here
|
||||
return op->length;
|
||||
}
|
||||
|
||||
struct r_anal_plugin_t r_anal_plugin_x86_simple = {
|
||||
|
@ -517,7 +517,7 @@ struct r_anal_plugin_t r_anal_plugin_x86_simple = {
|
|||
.desc = "X86 analysis plugin",
|
||||
.init = NULL,
|
||||
.fini = NULL,
|
||||
.aop = &myaop,
|
||||
.op = &myop,
|
||||
.set_reg_profile = NULL
|
||||
};
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ R_API struct r_anal_refline_t *r_anal_reflines_get(struct r_anal_t *anal,
|
|||
ut64 addr, ut8 *buf, ut64 len, int nlines, int linesout, int linescall)
|
||||
{
|
||||
RAnalRefline *list2, *list = R_NEW (RAnalRefline);
|
||||
RAnalOp aop;
|
||||
RAnalOp op;
|
||||
ut8 *ptr = buf;
|
||||
ut8 *end = buf + len;
|
||||
ut64 opc = addr;
|
||||
|
@ -36,22 +36,22 @@ R_API struct r_anal_refline_t *r_anal_reflines_get(struct r_anal_t *anal,
|
|||
#endif
|
||||
|
||||
addr += sz;
|
||||
sz = r_anal_aop (anal, &aop, addr, ptr, (int)(end-ptr));
|
||||
sz = r_anal_op (anal, &op, addr, ptr, (int)(end-ptr));
|
||||
if (sz > 0) {
|
||||
/* store data */
|
||||
switch(aop.type) {
|
||||
switch(op.type) {
|
||||
case R_ANAL_OP_TYPE_CALL:
|
||||
if (!linescall)
|
||||
break;
|
||||
case R_ANAL_OP_TYPE_CJMP:
|
||||
case R_ANAL_OP_TYPE_JMP:
|
||||
if (!linesout && (aop.jump > opc+len || aop.jump < opc))
|
||||
if (!linesout && (op.jump > opc+len || op.jump < opc))
|
||||
goto __next;
|
||||
if (aop.jump == 0LL)
|
||||
if (op.jump == 0LL)
|
||||
goto __next;
|
||||
list2 = R_NEW (RAnalRefline);
|
||||
list2->from = addr;
|
||||
list2->to = aop.jump;
|
||||
list2->to = op.jump;
|
||||
list2->index = index++;
|
||||
list_add_tail (&(list2->list), &(list->list));
|
||||
break;
|
||||
|
|
|
@ -8,14 +8,14 @@
|
|||
#include <r_core.h>
|
||||
|
||||
static char *r_core_anal_graph_label(RCore *core, struct r_anal_bb_t *bb, int opts) {
|
||||
RAnalOp *aopi;
|
||||
RAnalOp *opi;
|
||||
RListIter *iter;
|
||||
char cmd[1024], file[1024], *cmdstr = NULL, *filestr = NULL, *str = NULL;
|
||||
int i, j, line = 0, oline = 0, idx = 0;
|
||||
|
||||
if (opts & R_CORE_ANAL_GRAPHLINES) {
|
||||
r_list_foreach (bb->aops, iter, aopi) {
|
||||
r_bin_meta_get_line (core->bin, aopi->addr, file, sizeof (file)-1, &line);
|
||||
r_list_foreach (bb->ops, iter, opi) {
|
||||
r_bin_meta_get_line (core->bin, opi->addr, file, sizeof (file)-1, &line);
|
||||
if (line != 0 && line != oline && strcmp (file, "??")) {
|
||||
filestr = r_file_slurp_line (file, line, 0);
|
||||
if (filestr) {
|
||||
|
@ -464,7 +464,7 @@ R_API int r_core_anal_search(RCore *core, ut64 from, ut64 to, ut64 ref) {
|
|||
if (ret != core->blocksize)
|
||||
break;
|
||||
for (i=0; i<core->blocksize-OPSZ; i++) {
|
||||
if (!r_anal_aop (core->anal, &op, at+i, buf+i, core->blocksize-i))
|
||||
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) {
|
||||
|
|
|
@ -185,7 +185,7 @@ core->inc = 0;
|
|||
#endif
|
||||
if (core->print->cur_enabled) {
|
||||
// TODO: support in-the-middle-of-instruction too
|
||||
if (r_anal_aop (core->anal, &analop, core->offset+core->print->cur,
|
||||
if (r_anal_op (core->anal, &analop, core->offset+core->print->cur,
|
||||
buf+core->print->cur, (int)(len-core->print->cur))) {
|
||||
// TODO: check for analop.type and ret
|
||||
dest = analop.jump;
|
||||
|
@ -223,7 +223,7 @@ core->inc = 0;
|
|||
}
|
||||
if (core->inc == 0)
|
||||
core->inc = ret;
|
||||
r_anal_aop (core->anal, &analop, at, buf+idx, (int)(len-idx));
|
||||
r_anal_op (core->anal, &analop, at, buf+idx, (int)(len-idx));
|
||||
// Show xrefs
|
||||
if (show_xrefs) {
|
||||
RList *xrefs;
|
||||
|
@ -411,7 +411,7 @@ r_cons_printf ("%s ", pre);
|
|||
if (decode) {
|
||||
// TODO: Use data from code analysis..not raw analop here
|
||||
// if we want to get more information
|
||||
opstr = r_anal_aop_to_string (core->anal, &analop);
|
||||
opstr = r_anal_op_to_string (core->anal, &analop);
|
||||
} else
|
||||
if (pseudo) {
|
||||
r_parse_parse (core->parser, asmop.buf_asm, str);
|
||||
|
@ -2202,7 +2202,7 @@ static int cmd_anal(void *data, const char *input) {
|
|||
RAnalOp aop;
|
||||
|
||||
for (idx=ret=0; idx<len; idx+=ret) {
|
||||
ret = r_anal_aop (core->anal, &aop,
|
||||
ret = r_anal_op (core->anal, &aop,
|
||||
core->offset+idx, buf + idx, (len-idx));
|
||||
if (ret<1) {
|
||||
eprintf ("Oops at 0x%08"PFMT64x"\n", core->offset+idx);
|
||||
|
@ -2457,7 +2457,7 @@ static int cmd_anal(void *data, const char *input) {
|
|||
RDebugTracepoint *tp = r_debug_trace_add (core->dbg, addr, aop->length);
|
||||
tp->count = atoi (ptr+1);
|
||||
r_anal_trace_bb (core->anal, addr);
|
||||
r_anal_aop_free (aop);
|
||||
r_anal_op_free (aop);
|
||||
} else eprintf ("Cannot analyze opcode at 0x%"PFMT64x"\n", addr);
|
||||
}
|
||||
break;
|
||||
|
@ -4242,7 +4242,7 @@ static void cmd_debug_pid(RCore *core, const char *input) {
|
|||
|
||||
static int cmd_debug(void *data, const char *input) {
|
||||
RCore *core = (RCore *)data;
|
||||
struct r_anal_aop_t analop;
|
||||
struct r_anal_op_t analop;
|
||||
int len, times, sig;
|
||||
ut64 addr;
|
||||
char *ptr;
|
||||
|
@ -4444,7 +4444,7 @@ static int cmd_debug(void *data, const char *input) {
|
|||
/* XXX Bottleneck..we need to reuse the bytes read by traptrace */
|
||||
// XXX Do asm.arch should define the max size of opcode?
|
||||
r_core_read_at (core, addr, buf, 32); // XXX longer opcodes?
|
||||
r_anal_aop (core->anal, &analop, addr, buf, sizeof (buf));
|
||||
r_anal_op (core->anal, &analop, addr, buf, sizeof (buf));
|
||||
} while (r_bp_traptrace_at (core->dbg->bp, addr, analop.length));
|
||||
r_bp_traptrace_enable (core->dbg->bp, R_FALSE);
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ static ut64 num_callback(RNum *userptr, const char *str, int *ok) {
|
|||
*ok = 0;
|
||||
if (str[0]=='$') {
|
||||
*ok = 1;
|
||||
r_anal_aop (core->anal, &aop, core->offset,
|
||||
r_anal_op (core->anal, &aop, core->offset,
|
||||
core->block, core->blocksize);
|
||||
switch (str[1]) {
|
||||
case '{':
|
||||
|
@ -465,7 +465,7 @@ R_API RAnalOp *r_core_op_anal(RCore *core, ut64 addr) {
|
|||
ut8 buf[64];
|
||||
RAnalOp *aop = R_NEW (RAnalOp);
|
||||
r_core_read_at (core, addr, buf, sizeof (buf));
|
||||
r_anal_aop (core->anal, aop, addr, buf, sizeof (buf));
|
||||
r_anal_op (core->anal, aop, addr, buf, sizeof (buf));
|
||||
return aop;
|
||||
}
|
||||
|
||||
|
|
|
@ -12,25 +12,25 @@
|
|||
#define THRESHOLDBB 0.7F
|
||||
|
||||
static ut8* gdiff_fingerprint(RAnal *a, ut8* buf, int len) {
|
||||
RAnalOp *aop;
|
||||
RAnalOp *op;
|
||||
ut8 *ret = NULL;
|
||||
int oplen, idx = 0;
|
||||
|
||||
if (!(ret = malloc (len)))
|
||||
return NULL;
|
||||
memcpy (ret, buf, len);
|
||||
if (!(aop = r_anal_aop_new ())) {
|
||||
if (!(op = r_anal_op_new ())) {
|
||||
free (ret);
|
||||
return NULL;
|
||||
}
|
||||
while (idx < len) {
|
||||
if ((oplen = r_anal_aop (a, aop, 0, buf+idx, len-idx)) == 0)
|
||||
if ((oplen = r_anal_op (a, op, 0, buf+idx, len-idx)) == 0)
|
||||
break;
|
||||
if (aop->nopcode != 0)
|
||||
memset (ret+idx+aop->nopcode, 0, oplen-aop->nopcode);
|
||||
if (op->nopcode != 0)
|
||||
memset (ret+idx+op->nopcode, 0, oplen-op->nopcode);
|
||||
idx += oplen;
|
||||
}
|
||||
free (aop);
|
||||
free (op);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -184,7 +184,7 @@ R_API int r_debug_step_soft(RDebug *dbg) {
|
|||
RAnalOp op;
|
||||
ut64 pc0, pc1, pc2;
|
||||
pc0 = r_debug_reg_get (dbg, dbg->reg->name[R_REG_NAME_PC]);
|
||||
int ret = r_anal_aop (dbg->anal, &op, pc0, buf, sizeof (buf));
|
||||
int ret = r_anal_op (dbg->anal, &op, pc0, buf, sizeof (buf));
|
||||
pc1 = pc0 + op.length;
|
||||
// XXX: Does not works for 'ret'
|
||||
pc2 = op.jump?op.jump:0;
|
||||
|
@ -232,7 +232,7 @@ R_API int r_debug_step_over(RDebug *dbg, int steps) {
|
|||
if (dbg->anal && dbg->reg) {
|
||||
ut64 pc = r_debug_reg_get (dbg, dbg->reg->name[R_REG_NAME_PC]);
|
||||
dbg->iob.read_at (dbg->iob.io, pc, buf, sizeof (buf));
|
||||
r_anal_aop (dbg->anal, &op, pc, buf, sizeof (buf));
|
||||
r_anal_op (dbg->anal, &op, pc, buf, sizeof (buf));
|
||||
if (op.type & R_ANAL_OP_TYPE_CALL) {
|
||||
ut64 bpaddr = pc + op.length;
|
||||
r_bp_add_sw (dbg->bp, bpaddr, 1, R_BP_PROT_EXEC);
|
||||
|
@ -293,7 +293,7 @@ R_API int r_debug_continue_until_optype(RDebug *dbg, int type, int over) {
|
|||
}
|
||||
pc = r_debug_reg_get (dbg, dbg->reg->name[R_REG_NAME_PC]);
|
||||
dbg->iob.read_at (dbg->iob.io, pc, buf, sizeof (buf));
|
||||
r_anal_aop (dbg->anal, &op, pc, buf, sizeof (buf));
|
||||
r_anal_op (dbg->anal, &op, pc, buf, sizeof (buf));
|
||||
n++;
|
||||
} while (!(op.type&type));
|
||||
} else eprintf ("Undefined pointer at dbg->anal\n");
|
||||
|
|
|
@ -30,15 +30,15 @@ R_API int r_debug_trace_tag (RDebug *dbg, int tag) {
|
|||
R_API int r_debug_trace_pc (RDebug *dbg) {
|
||||
ut8 buf[32];
|
||||
RRegItem *ri;
|
||||
RAnalOp aop;
|
||||
RAnalOp op;
|
||||
static ut64 oldpc = 0LL; // Must trace the previously traced instruction
|
||||
r_debug_reg_sync (dbg, R_REG_TYPE_GPR, R_FALSE);
|
||||
if ((ri = r_reg_get (dbg->reg, dbg->reg->name[R_REG_NAME_PC], -1))) {
|
||||
ut64 addr = r_reg_get_value (dbg->reg, ri);
|
||||
if (dbg->iob.read_at (dbg->iob.io, addr, buf, sizeof (buf))>0) {
|
||||
if (r_anal_aop (dbg->anal, &aop, addr, buf, sizeof (buf))>0) {
|
||||
if (r_anal_op (dbg->anal, &op, addr, buf, sizeof (buf))>0) {
|
||||
if (oldpc!=0LL)
|
||||
r_debug_trace_add (dbg, oldpc, aop.length);
|
||||
r_debug_trace_add (dbg, oldpc, op.length);
|
||||
oldpc = addr;
|
||||
return R_TRUE;
|
||||
} else eprintf ("trace_pc: cannot get opcode size at 0x%"PFMT64x"\n", addr);
|
||||
|
|
|
@ -149,7 +149,7 @@ typedef struct r_anal_value_t {
|
|||
RRegItem *regdelta; // register index used (-1 if no reg)
|
||||
} RAnalValue;
|
||||
|
||||
typedef struct r_anal_aop_t {
|
||||
typedef struct r_anal_op_t {
|
||||
char *mnemonic; /* mnemonic */
|
||||
ut64 addr; /* address */
|
||||
int type; /* type of opcode */
|
||||
|
@ -201,7 +201,7 @@ typedef struct r_anal_bb_t {
|
|||
int traced;
|
||||
ut8 *fingerprint;
|
||||
RAnalDiff *diff;
|
||||
RList *aops;
|
||||
RList *ops;
|
||||
RAnalCond *cond;
|
||||
} RAnalBlock;
|
||||
|
||||
|
@ -309,7 +309,7 @@ typedef struct r_anal_refline_t {
|
|||
struct list_head list;
|
||||
} RAnalRefline;
|
||||
|
||||
typedef int (*RAnalAopCallback)(RAnal *a, RAnalOp *aop, ut64 addr, const ut8 *data, int len);
|
||||
typedef int (*RAnalOpCallback)(RAnal *a, RAnalOp *op, ut64 addr, const ut8 *data, int len);
|
||||
typedef int (*RAnalRegProfCallback)(RAnal *a);
|
||||
|
||||
typedef struct r_anal_plugin_t {
|
||||
|
@ -317,7 +317,7 @@ typedef struct r_anal_plugin_t {
|
|||
char *desc;
|
||||
int (*init)(void *user);
|
||||
int (*fini)(void *user);
|
||||
RAnalAopCallback aop;
|
||||
RAnalOpCallback op;
|
||||
RAnalRegProfCallback set_reg_profile;
|
||||
struct list_head list;
|
||||
} RAnalPlugin;
|
||||
|
@ -345,13 +345,13 @@ R_API void r_anal_bb_free(void *bb);
|
|||
R_API int r_anal_bb(RAnal *anal, RAnalBlock *bb,
|
||||
ut64 addr, ut8 *buf, ut64 len, int head);
|
||||
|
||||
/* aop.c */
|
||||
R_API RAnalOp *r_anal_aop_new();
|
||||
R_API void r_anal_aop_free(void *aop);
|
||||
R_API RList *r_anal_aop_list_new();
|
||||
R_API int r_anal_aop(RAnal *anal, RAnalOp *aop, ut64 addr,
|
||||
/* op.c */
|
||||
R_API RAnalOp *r_anal_op_new();
|
||||
R_API void r_anal_op_free(void *op);
|
||||
R_API RList *r_anal_op_list_new();
|
||||
R_API int r_anal_op(RAnal *anal, RAnalOp *op, ut64 addr,
|
||||
const ut8 *data, int len);
|
||||
R_API char *r_anal_aop_to_string(RAnal *anal, RAnalOp *op);
|
||||
R_API char *r_anal_op_to_string(RAnal *anal, RAnalOp *op);
|
||||
|
||||
/* fcn.c */
|
||||
R_API RAnalFcn *r_anal_fcn_new();
|
||||
|
@ -415,7 +415,7 @@ R_API int r_anal_value_set_ut64(RAnal *anal, RAnalValue *val, ut64 num);
|
|||
R_API void r_anal_value_free(RAnalValue *value);
|
||||
|
||||
R_API RAnalCond *r_anal_cond_new();
|
||||
R_API RAnalCond *r_anal_cond_new_from_aop(RAnalOp *op);
|
||||
R_API RAnalCond *r_anal_cond_new_from_op(RAnalOp *op);
|
||||
#define r_anal_cond_free(x) free(x);
|
||||
R_API char *r_anal_cond_to_string(RAnalCond *cond);
|
||||
R_API int r_anal_cond_eval (RAnal *anal, RAnalCond *cond);
|
||||
|
|
|
@ -179,11 +179,11 @@ public class RAnal {
|
|||
public uint64 fail;
|
||||
public BlockType type;
|
||||
public BlockDiff diff;
|
||||
public RList<RAnal.Op> aops;
|
||||
public RList<RAnal.Op> ops;
|
||||
}
|
||||
|
||||
[Compact]
|
||||
[CCode (cprefix="r_anal_aop_", cname="RAnalOp")]
|
||||
[CCode (cprefix="r_anal_op_", cname="RAnalOp")]
|
||||
public class Op {
|
||||
public uint64 addr;
|
||||
public int type;
|
||||
|
|
Loading…
Reference in New Issue