mirror of
https://github.com/radareorg/radare2.git
synced 2024-12-03 19:01:31 +00:00
Remove fcn->vars and reindent anal/fcn.c var.c and flirt.c
This commit is contained in:
parent
526699a4d3
commit
e8f80a165c
330
libr/anal/fcn.c
330
libr/anal/fcn.c
@ -5,7 +5,7 @@
|
|||||||
#include <r_list.h>
|
#include <r_list.h>
|
||||||
|
|
||||||
#define USE_SDB_CACHE 0
|
#define USE_SDB_CACHE 0
|
||||||
#define SDB_KEY_BB "bb.0x%"PFMT64x".0x%"PFMT64x
|
#define SDB_KEY_BB "bb.0x%"PFMT64x ".0x%"PFMT64x
|
||||||
// XXX must be configurable by the user
|
// XXX must be configurable by the user
|
||||||
#define FCN_DEPTH 512
|
#define FCN_DEPTH 512
|
||||||
|
|
||||||
@ -23,16 +23,16 @@
|
|||||||
|
|
||||||
// 64KB max size
|
// 64KB max size
|
||||||
// 256KB max function size
|
// 256KB max function size
|
||||||
#define MAX_FCN_SIZE (1024*256)
|
#define MAX_FCN_SIZE (1024 * 256)
|
||||||
|
|
||||||
#define MAX_JMPTBL_SIZE 1000
|
#define MAX_JMPTBL_SIZE 1000
|
||||||
#define MAX_JMPTBL_JMP 10000
|
#define MAX_JMPTBL_JMP 10000
|
||||||
|
|
||||||
#define DB a->sdb_fcns
|
#define DB a->sdb_fcns
|
||||||
#define EXISTS(x,y...) snprintf (key, sizeof(key)-1,x,##y),sdb_exists(DB,key)
|
#define EXISTS(x, y ...) snprintf (key, sizeof(key) - 1, x, ## y), sdb_exists (DB, key)
|
||||||
#define SETKEY(x,y...) snprintf (key, sizeof (key)-1, x,##y);
|
#define SETKEY(x, y ...) snprintf (key, sizeof (key) - 1, x, ## y);
|
||||||
|
|
||||||
#define VERBOSE_DELAY if(0)
|
#define VERBOSE_DELAY if (0)
|
||||||
|
|
||||||
#if USE_SDB_CACHE
|
#if USE_SDB_CACHE
|
||||||
static Sdb *HB = NULL;
|
static Sdb *HB = NULL;
|
||||||
@ -51,7 +51,7 @@ R_API const char *r_anal_fcn_type_tostring(int type) {
|
|||||||
return "unk";
|
return "unk";
|
||||||
}
|
}
|
||||||
|
|
||||||
static int cmpaddr (const void *_a, const void *_b) {
|
static int cmpaddr(const void *_a, const void *_b) {
|
||||||
const RAnalBlock *a = _a, *b = _b;
|
const RAnalBlock *a = _a, *b = _b;
|
||||||
return (a->addr > b->addr);
|
return (a->addr > b->addr);
|
||||||
}
|
}
|
||||||
@ -143,10 +143,10 @@ R_API void r_anal_fcn_free(void *_fcn) {
|
|||||||
r_list_free (fcn->refs);
|
r_list_free (fcn->refs);
|
||||||
r_list_free (fcn->xrefs);
|
r_list_free (fcn->xrefs);
|
||||||
#endif
|
#endif
|
||||||
//all functions are freed in anal->fcns
|
// all functions are freed in anal->fcns
|
||||||
fcn->fcn_locs = NULL;
|
fcn->fcn_locs = NULL;
|
||||||
if (fcn->bbs) {
|
if (fcn->bbs) {
|
||||||
fcn->bbs->free = (RListFree)r_anal_bb_free;
|
fcn->bbs->free = (RListFree) r_anal_bb_free;
|
||||||
r_list_free (fcn->bbs);
|
r_list_free (fcn->bbs);
|
||||||
fcn->bbs = NULL;
|
fcn->bbs = NULL;
|
||||||
}
|
}
|
||||||
@ -195,10 +195,10 @@ R_API int r_anal_fcn_xref_add(RAnal *a, RAnalFunction *fcn, ut64 at, ut64 addr,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#if FCN_SDB
|
#if FCN_SDB
|
||||||
sdb_add (DB, sdb_fmt (0, "fcn.0x%08"PFMT64x".name", fcn->addr), fcn->name, 0);
|
sdb_add (DB, sdb_fmt (0, "fcn.0x%08"PFMT64x ".name", fcn->addr), fcn->name, 0);
|
||||||
// encode the name in base64 ?
|
// encode the name in base64 ?
|
||||||
sdb_num_add (DB, sdb_fmt (0, "fcn.name.%s", fcn->name), fcn->addr, 0);
|
sdb_num_add (DB, sdb_fmt (0, "fcn.name.%s", fcn->name), fcn->addr, 0);
|
||||||
sdb_array_add_num (DB, sdb_fmt (0, "fcn.0x%08"PFMT64x".xrefs", fcn->addr), at, 0);
|
sdb_array_add_num (DB, sdb_fmt (0, "fcn.0x%08"PFMT64x ".xrefs", fcn->addr), at, 0);
|
||||||
#endif
|
#endif
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -209,17 +209,17 @@ R_API int r_anal_fcn_xref_del(RAnal *a, RAnalFunction *fcn, ut64 at, ut64 addr,
|
|||||||
RListIter *iter;
|
RListIter *iter;
|
||||||
/* No need for _safe loop coz we return immediately after the delete. */
|
/* No need for _safe loop coz we return immediately after the delete. */
|
||||||
r_list_foreach (fcn->xrefs, iter, ref) {
|
r_list_foreach (fcn->xrefs, iter, ref) {
|
||||||
if ((type != -1 || type == ref->type) &&
|
if ((type != -1 || type == ref->type) &&
|
||||||
(at == 0LL || at == ref->at) &&
|
(at == 0LL || at == ref->at) &&
|
||||||
(addr == 0LL || addr == ref->addr)) {
|
(addr == 0LL || addr == ref->addr)) {
|
||||||
r_list_delete (fcn->xrefs, iter);
|
r_list_delete (fcn->xrefs, iter);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#if FCN_SDB
|
#if FCN_SDB
|
||||||
// TODO
|
// TODO
|
||||||
//sdb_array_delete_num (DB, key, at, 0);
|
// sdb_array_delete_num (DB, key, at, 0);
|
||||||
#endif
|
#endif
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -239,7 +239,7 @@ static RAnalBlock *bbget(RAnalFunction *fcn, ut64 addr) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static RAnalBlock* appendBasicBlock (RAnal *anal, RAnalFunction *fcn, ut64 addr) {
|
static RAnalBlock *appendBasicBlock(RAnal *anal, RAnalFunction *fcn, ut64 addr) {
|
||||||
RAnalBlock *bb = r_anal_bb_new ();
|
RAnalBlock *bb = r_anal_bb_new ();
|
||||||
if (!bb) {
|
if (!bb) {
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -257,11 +257,11 @@ static RAnalBlock* appendBasicBlock (RAnal *anal, RAnalFunction *fcn, ut64 addr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#define FITFCNSZ() {\
|
#define FITFCNSZ() {\
|
||||||
st64 n = bb->addr + bb->size-fcn->addr; \
|
st64 n = bb->addr + bb->size - fcn->addr;\
|
||||||
if (n >= 0 && r_anal_fcn_size (fcn) <n) {r_anal_fcn_set_size (fcn, n); } } \
|
if (n >= 0 && r_anal_fcn_size (fcn) < n) { r_anal_fcn_set_size (fcn, n); } }\
|
||||||
if (r_anal_fcn_size (fcn) > MAX_FCN_SIZE) { \
|
if (r_anal_fcn_size (fcn) > MAX_FCN_SIZE) {\
|
||||||
/* eprintf ("Function too big at 0x%"PFMT64x" + %d\n", bb->addr, fcn->size); */ \
|
/* eprintf ("Function too big at 0x%"PFMT64x" + %d\n", bb->addr, fcn->size); */\
|
||||||
r_anal_fcn_set_size (fcn, 0); \
|
r_anal_fcn_set_size (fcn, 0);\
|
||||||
return R_ANAL_RET_ERROR; }
|
return R_ANAL_RET_ERROR; }
|
||||||
|
|
||||||
#define VARPREFIX "local"
|
#define VARPREFIX "local"
|
||||||
@ -293,12 +293,12 @@ static char *get_varname(RAnal *a, RAnalFunction *fcn, char type, const char *pf
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int fcn_recurse(RAnal *anal, RAnalFunction *fcn, ut64 addr, ut8 *buf, ut64 len, int depth);
|
static int fcn_recurse(RAnal *anal, RAnalFunction *fcn, ut64 addr, ut8 *buf, ut64 len, int depth);
|
||||||
#define recurseAt(x) { \
|
#define recurseAt(x) {\
|
||||||
ut8 *bbuf = malloc (MAXBBSIZE);\
|
ut8 *bbuf = malloc (MAXBBSIZE);\
|
||||||
anal->iob.read_at (anal->iob.io, x, bbuf, MAXBBSIZE); \
|
anal->iob.read_at (anal->iob.io, x, bbuf, MAXBBSIZE);\
|
||||||
ret = fcn_recurse (anal, fcn, x, bbuf, MAXBBSIZE, depth - 1); \
|
ret = fcn_recurse (anal, fcn, x, bbuf, MAXBBSIZE, depth - 1);\
|
||||||
update_tinyrange_bbs (fcn); \
|
update_tinyrange_bbs (fcn);\
|
||||||
free (bbuf); \
|
free (bbuf);\
|
||||||
}
|
}
|
||||||
|
|
||||||
static int try_walkthrough_jmptbl(RAnal *anal, RAnalFunction *fcn, int depth, ut64 ip, ut64 ptr, int ret0) {
|
static int try_walkthrough_jmptbl(RAnal *anal, RAnalFunction *fcn, int depth, ut64 ip, ut64 ptr, int ret0) {
|
||||||
@ -328,7 +328,7 @@ static int try_walkthrough_jmptbl(RAnal *anal, RAnalFunction *fcn, int depth, ut
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!anal->iob.is_valid_offset (anal->iob.io, jmpptr, 0)) {
|
if (!anal->iob.is_valid_offset (anal->iob.io, jmpptr, 0)) {
|
||||||
jmpptr = ptr + (st32)jmpptr;
|
jmpptr = ptr + (st32) jmpptr;
|
||||||
if (!anal->iob.is_valid_offset (anal->iob.io, jmpptr, 0)) {
|
if (!anal->iob.is_valid_offset (anal->iob.io, jmpptr, 0)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -347,21 +347,25 @@ static int try_walkthrough_jmptbl(RAnal *anal, RAnalFunction *fcn, int depth, ut
|
|||||||
|
|
||||||
static ut64 search_reg_val(RAnal *anal, ut8 *buf, ut64 len, ut64 addr, char *regsz) {
|
static ut64 search_reg_val(RAnal *anal, ut8 *buf, ut64 len, ut64 addr, char *regsz) {
|
||||||
ut64 offs, oplen;
|
ut64 offs, oplen;
|
||||||
RAnalOp op = {0};
|
RAnalOp op = {
|
||||||
|
0
|
||||||
|
};
|
||||||
ut64 ret = UT64_MAX;
|
ut64 ret = UT64_MAX;
|
||||||
for (offs = 0; offs < len; offs += oplen) {
|
for (offs = 0; offs < len; offs += oplen) {
|
||||||
r_anal_op_fini (&op);
|
r_anal_op_fini (&op);
|
||||||
if ((oplen = r_anal_op (anal, &op, addr + offs, buf + offs, len - offs)) < 1) {
|
if ((oplen = r_anal_op (anal, &op, addr + offs, buf + offs, len - offs)) < 1) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (op.dst && op.dst->reg && op.dst->reg->name && !strcmp(op.dst->reg->name, regsz)) {
|
if (op.dst && op.dst->reg && op.dst->reg->name && !strcmp (op.dst->reg->name, regsz)) {
|
||||||
if (op.src[0]) ret = op.src[0]->delta;
|
if (op.src[0]) {
|
||||||
|
ret = op.src[0]->delta;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define gotoBeach(x) ret=x;goto beach;
|
#define gotoBeach(x) ret = x; goto beach;
|
||||||
#define gotoBeachRet() goto beach;
|
#define gotoBeachRet() goto beach;
|
||||||
|
|
||||||
static void extract_arg(RAnal *anal, RAnalFunction *fcn, RAnalOp *op, const char *reg, const char *sign, char type) {
|
static void extract_arg(RAnal *anal, RAnalFunction *fcn, RAnalOp *op, const char *reg, const char *sign, char type) {
|
||||||
@ -391,7 +395,7 @@ static void extract_arg(RAnal *anal, RAnalFunction *fcn, RAnalOp *op, const char
|
|||||||
*ptr_end = 0;
|
*ptr_end = 0;
|
||||||
addr = ptr_end;
|
addr = ptr_end;
|
||||||
while ((*addr != '0' || *(addr + 1) != 'x') &&
|
while ((*addr != '0' || *(addr + 1) != 'x') &&
|
||||||
addr >= esil_buf + 1 && *addr != ',' ) {
|
addr >= esil_buf + 1 && *addr != ',') {
|
||||||
addr--;
|
addr--;
|
||||||
}
|
}
|
||||||
if (strncmp (addr, "0x", 2)) {
|
if (strncmp (addr, "0x", 2)) {
|
||||||
@ -399,9 +403,9 @@ static void extract_arg(RAnal *anal, RAnalFunction *fcn, RAnalOp *op, const char
|
|||||||
free (esil_buf);
|
free (esil_buf);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ptr = (st64)r_num_get (NULL, addr);
|
ptr = (st64) r_num_get (NULL, addr);
|
||||||
if(*sign =='+') {
|
if (*sign == '+') {
|
||||||
if (ptr < fcn->maxstack && type == 's') {
|
if (ptr < fcn->maxstack && type == 's') {
|
||||||
varname = get_varname (anal, fcn, type, VARPREFIX, R_ABS (ptr));
|
varname = get_varname (anal, fcn, type, VARPREFIX, R_ABS (ptr));
|
||||||
} else {
|
} else {
|
||||||
varname = get_varname (anal, fcn, type, ARGPREFIX, R_ABS (ptr));
|
varname = get_varname (anal, fcn, type, ARGPREFIX, R_ABS (ptr));
|
||||||
@ -411,7 +415,7 @@ static void extract_arg(RAnal *anal, RAnalFunction *fcn, RAnalOp *op, const char
|
|||||||
} else {
|
} else {
|
||||||
varname = get_varname (anal, fcn, type, VARPREFIX, R_ABS (ptr));
|
varname = get_varname (anal, fcn, type, VARPREFIX, R_ABS (ptr));
|
||||||
r_anal_var_add (anal, fcn->addr, 1, -ptr, type, NULL, anal->bits / 8, varname);
|
r_anal_var_add (anal, fcn->addr, 1, -ptr, type, NULL, anal->bits / 8, varname);
|
||||||
r_anal_var_access (anal, fcn->addr, type, 1,-ptr, 1, op->addr);
|
r_anal_var_access (anal, fcn->addr, type, 1, -ptr, 1, op->addr);
|
||||||
|
|
||||||
}
|
}
|
||||||
free (varname);
|
free (varname);
|
||||||
@ -421,9 +425,9 @@ static void extract_arg(RAnal *anal, RAnalFunction *fcn, RAnalOp *op, const char
|
|||||||
|
|
||||||
R_API void fill_args(RAnal *anal, RAnalFunction *fcn, RAnalOp *op) {
|
R_API void fill_args(RAnal *anal, RAnalFunction *fcn, RAnalOp *op) {
|
||||||
if (anal && anal->reg) {
|
if (anal && anal->reg) {
|
||||||
extract_arg (anal, fcn, op, anal->reg->name [R_REG_NAME_BP], "+", 'b');
|
extract_arg (anal, fcn, op, anal->reg->name[R_REG_NAME_BP], "+", 'b');
|
||||||
extract_arg (anal, fcn, op, anal->reg->name [R_REG_NAME_BP], "-", 'b');
|
extract_arg (anal, fcn, op, anal->reg->name[R_REG_NAME_BP], "-", 'b');
|
||||||
extract_arg (anal, fcn, op, anal->reg->name [R_REG_NAME_SP], "+", 's');
|
extract_arg (anal, fcn, op, anal->reg->name[R_REG_NAME_SP], "+", 's');
|
||||||
}
|
}
|
||||||
extract_arg (anal, fcn, op, "bp", "+", 'b');
|
extract_arg (anal, fcn, op, "bp", "+", 'b');
|
||||||
extract_arg (anal, fcn, op, "bp", "-", 'b');
|
extract_arg (anal, fcn, op, "bp", "-", 'b');
|
||||||
@ -439,8 +443,10 @@ static bool isInvalidMemory(const ut8 *buf, int len) {
|
|||||||
static bool is_delta_pointer_table(RAnal *anal, ut64 ptr) {
|
static bool is_delta_pointer_table(RAnal *anal, ut64 ptr) {
|
||||||
int i;
|
int i;
|
||||||
ut64 dst;
|
ut64 dst;
|
||||||
st32 jmptbl[32] = {0};
|
st32 jmptbl[32] = {
|
||||||
anal->iob.read_at (anal->iob.io, ptr, (ut8*)&jmptbl, 32);
|
0
|
||||||
|
};
|
||||||
|
anal->iob.read_at (anal->iob.io, ptr, (ut8 *) &jmptbl, 32);
|
||||||
// XXX this is not endian safe
|
// XXX this is not endian safe
|
||||||
for (i = 0; i < 4; i++) {
|
for (i = 0; i < 4; i++) {
|
||||||
dst = ptr + jmptbl[0];
|
dst = ptr + jmptbl[0];
|
||||||
@ -455,10 +461,10 @@ static bool regs_exist(RAnalValue *src, RAnalValue *dst) {
|
|||||||
return src && dst && src->reg && dst->reg && src->reg->name && dst->reg->name;
|
return src && dst && src->reg && dst->reg && src->reg->name && dst->reg->name;
|
||||||
}
|
}
|
||||||
|
|
||||||
//0 if not skipped; 1 if skipped; 2 if skipped before
|
// 0 if not skipped; 1 if skipped; 2 if skipped before
|
||||||
static int skip_hp(RAnal *anal, RAnalFunction *fcn, RAnalOp *op, RAnalBlock *bb, ut64 addr,
|
static int skip_hp(RAnal *anal, RAnalFunction *fcn, RAnalOp *op, RAnalBlock *bb, ut64 addr,
|
||||||
char *tmp_buf, int oplen, int un_idx, int *idx) {
|
char *tmp_buf, int oplen, int un_idx, int *idx) {
|
||||||
//this step is required in order to prevent infinite recursion in some cases
|
// this step is required in order to prevent infinite recursion in some cases
|
||||||
if ((addr + un_idx - oplen) == fcn->addr) {
|
if ((addr + un_idx - oplen) == fcn->addr) {
|
||||||
if (!anal->flb.exist_at (anal->flb.f, "skip", 4, op->addr)) {
|
if (!anal->flb.exist_at (anal->flb.f, "skip", 4, op->addr)) {
|
||||||
snprintf (tmp_buf + 5, MAX_FLG_NAME_SIZE - 6, "%"PFMT64u, op->addr);
|
snprintf (tmp_buf + 5, MAX_FLG_NAME_SIZE - 6, "%"PFMT64u, op->addr);
|
||||||
@ -475,7 +481,9 @@ static int skip_hp(RAnal *anal, RAnalFunction *fcn, RAnalOp *op, RAnalBlock *bb,
|
|||||||
}
|
}
|
||||||
|
|
||||||
R_API int r_anal_case(RAnal *anal, RAnalFunction *fcn, ut64 addr_bbsw, ut64 addr, ut8 *buf, ut64 len, int reftype) {
|
R_API int r_anal_case(RAnal *anal, RAnalFunction *fcn, ut64 addr_bbsw, ut64 addr, ut8 *buf, ut64 len, int reftype) {
|
||||||
RAnalOp op = {0};
|
RAnalOp op = {
|
||||||
|
0
|
||||||
|
};
|
||||||
int oplen, idx = 0;
|
int oplen, idx = 0;
|
||||||
while (idx < len) {
|
while (idx < len) {
|
||||||
if ((len - idx) < 5) {
|
if ((len - idx) < 5) {
|
||||||
@ -490,10 +498,10 @@ R_API int r_anal_case(RAnal *anal, RAnalFunction *fcn, ut64 addr_bbsw, ut64 addr
|
|||||||
case R_ANAL_OP_TYPE_RET:
|
case R_ANAL_OP_TYPE_RET:
|
||||||
case R_ANAL_OP_TYPE_JMP:
|
case R_ANAL_OP_TYPE_JMP:
|
||||||
// eprintf ("CASE AT 0x%llx size %d\n", addr, idx + oplen);
|
// eprintf ("CASE AT 0x%llx size %d\n", addr, idx + oplen);
|
||||||
eprintf ("afb+ 0x%"PFMT64x" 0x%"PFMT64x" %d\n",
|
eprintf ("afb+ 0x%"PFMT64x " 0x%"PFMT64x " %d\n",
|
||||||
fcn->addr, addr, idx + oplen);
|
fcn->addr, addr, idx + oplen);
|
||||||
eprintf ("afbe 0x%"PFMT64x" 0x%"PFMT64x"\n",
|
eprintf ("afbe 0x%"PFMT64x " 0x%"PFMT64x "\n",
|
||||||
addr_bbsw, addr);
|
addr_bbsw, addr);
|
||||||
return idx + oplen;
|
return idx + oplen;
|
||||||
}
|
}
|
||||||
idx += oplen;
|
idx += oplen;
|
||||||
@ -504,7 +512,7 @@ R_API int r_anal_case(RAnal *anal, RAnalFunction *fcn, ut64 addr_bbsw, ut64 addr
|
|||||||
static int walk_switch(RAnal *anal, RAnalFunction *fcn, ut64 from, ut64 at) {
|
static int walk_switch(RAnal *anal, RAnalFunction *fcn, ut64 from, ut64 at) {
|
||||||
ut8 buf[1024];
|
ut8 buf[1024];
|
||||||
int i;
|
int i;
|
||||||
eprintf ("WALK SWITCH TABLE INTO (0x%"PFMT64x") %"PFMT64x"\n", from, at);
|
eprintf ("WALK SWITCH TABLE INTO (0x%"PFMT64x ") %"PFMT64x "\n", from, at);
|
||||||
for (i = 0; i < 10; i++) {
|
for (i = 0; i < 10; i++) {
|
||||||
anal->iob.read_at (anal->iob.io, at, buf, sizeof (buf));
|
anal->iob.read_at (anal->iob.io, at, buf, sizeof (buf));
|
||||||
int sz = r_anal_case (anal, fcn, from, at, buf, sizeof (buf), 0);
|
int sz = r_anal_case (anal, fcn, from, at, buf, sizeof (buf), 0);
|
||||||
@ -524,7 +532,9 @@ static int fcn_recurse(RAnal *anal, RAnalFunction *fcn, ut64 addr, ut8 *buf, ut6
|
|||||||
int ret = R_ANAL_RET_END, skip_ret = 0;
|
int ret = R_ANAL_RET_END, skip_ret = 0;
|
||||||
int overlapped = 0;
|
int overlapped = 0;
|
||||||
char *varname;
|
char *varname;
|
||||||
RAnalOp op = {0};
|
RAnalOp op = {
|
||||||
|
0
|
||||||
|
};
|
||||||
int oplen, idx = 0;
|
int oplen, idx = 0;
|
||||||
struct {
|
struct {
|
||||||
int cnt;
|
int cnt;
|
||||||
@ -533,7 +543,9 @@ static int fcn_recurse(RAnal *anal, RAnalFunction *fcn, ut64 addr, ut8 *buf, ut6
|
|||||||
int pending;
|
int pending;
|
||||||
int adjust;
|
int adjust;
|
||||||
int un_idx; // delay.un_idx
|
int un_idx; // delay.un_idx
|
||||||
} delay = {0};
|
} delay = {
|
||||||
|
0
|
||||||
|
};
|
||||||
char tmp_buf[MAX_FLG_NAME_SIZE + 5] = "skip";
|
char tmp_buf[MAX_FLG_NAME_SIZE + 5] = "skip";
|
||||||
|
|
||||||
if (anal->sleep) {
|
if (anal->sleep) {
|
||||||
@ -551,7 +563,7 @@ static int fcn_recurse(RAnal *anal, RAnalFunction *fcn, ut64 addr, ut8 *buf, ut6
|
|||||||
// check if address is readable //:
|
// check if address is readable //:
|
||||||
if (!anal->iob.is_valid_offset (anal->iob.io, addr, 0)) {
|
if (!anal->iob.is_valid_offset (anal->iob.io, addr, 0)) {
|
||||||
if (addr != UT64_MAX && !anal->iob.io->va) {
|
if (addr != UT64_MAX && !anal->iob.io->va) {
|
||||||
eprintf ("Invalid address 0x%"PFMT64x". Try with io.va=true\n", addr);
|
eprintf ("Invalid address 0x%"PFMT64x ". Try with io.va=true\n", addr);
|
||||||
}
|
}
|
||||||
return R_ANAL_RET_ERROR; // MUST BE TOO DEEP
|
return R_ANAL_RET_ERROR; // MUST BE TOO DEEP
|
||||||
}
|
}
|
||||||
@ -570,14 +582,14 @@ static int fcn_recurse(RAnal *anal, RAnalFunction *fcn, ut64 addr, ut8 *buf, ut6
|
|||||||
|
|
||||||
bb = appendBasicBlock (anal, fcn, addr);
|
bb = appendBasicBlock (anal, fcn, addr);
|
||||||
|
|
||||||
VERBOSE_ANAL eprintf ("Append bb at 0x%08"PFMT64x
|
VERBOSE_ANAL eprintf("Append bb at 0x%08"PFMT64x
|
||||||
" (fcn 0x%08"PFMT64x")\n", addr, fcn->addr);
|
" (fcn 0x%08"PFMT64x ")\n", addr, fcn->addr);
|
||||||
|
|
||||||
bool last_is_push = false;
|
bool last_is_push = false;
|
||||||
ut64 last_push_addr = UT64_MAX;
|
ut64 last_push_addr = UT64_MAX;
|
||||||
while (idx < len) {
|
while (idx < len) {
|
||||||
if (anal->limit) {
|
if (anal->limit) {
|
||||||
if ((addr + idx) < anal->limit->from || (addr + idx + 1) >anal->limit->to) {
|
if ((addr + idx) < anal->limit->from || (addr + idx + 1) > anal->limit->to) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -587,14 +599,14 @@ repeat:
|
|||||||
}
|
}
|
||||||
r_anal_op_fini (&op);
|
r_anal_op_fini (&op);
|
||||||
if (isInvalidMemory (buf + idx, len - idx)) {
|
if (isInvalidMemory (buf + idx, len - idx)) {
|
||||||
FITFCNSZ();
|
FITFCNSZ ();
|
||||||
VERBOSE_ANAL eprintf ("FFFF opcode at 0x%08"PFMT64x"\n", addr+idx);
|
VERBOSE_ANAL eprintf("FFFF opcode at 0x%08"PFMT64x "\n", addr + idx);
|
||||||
return R_ANAL_RET_ERROR;
|
return R_ANAL_RET_ERROR;
|
||||||
}
|
}
|
||||||
// check if opcode is in another basic block
|
// check if opcode is in another basic block
|
||||||
// in that case we break
|
// in that case we break
|
||||||
if ((oplen = r_anal_op (anal, &op, addr + idx, buf + idx, len - idx)) < 1) {
|
if ((oplen = r_anal_op (anal, &op, addr + idx, buf + idx, len - idx)) < 1) {
|
||||||
VERBOSE_ANAL eprintf ("Unknown opcode at 0x%08"PFMT64x"\n", addr + idx);
|
VERBOSE_ANAL eprintf("Unknown opcode at 0x%08"PFMT64x "\n", addr + idx);
|
||||||
if (!idx) {
|
if (!idx) {
|
||||||
gotoBeach (R_ANAL_RET_END);
|
gotoBeach (R_ANAL_RET_END);
|
||||||
} else {
|
} else {
|
||||||
@ -606,16 +618,16 @@ repeat:
|
|||||||
if (bbg && bbg != bb) {
|
if (bbg && bbg != bb) {
|
||||||
bb->jump = addr + idx;
|
bb->jump = addr + idx;
|
||||||
overlapped = 1;
|
overlapped = 1;
|
||||||
VERBOSE_ANAL eprintf ("Overlapped at 0x%08"PFMT64x"\n", addr + idx);
|
VERBOSE_ANAL eprintf("Overlapped at 0x%08"PFMT64x "\n", addr + idx);
|
||||||
//return R_ANAL_RET_END;
|
// return R_ANAL_RET_END;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!overlapped) {
|
if (!overlapped) {
|
||||||
r_anal_bb_set_offset (bb, bb->ninstr++, addr + idx - bb->addr);
|
r_anal_bb_set_offset (bb, bb->ninstr++, addr + idx - bb->addr);
|
||||||
bb->size += oplen;
|
bb->size += oplen;
|
||||||
fcn->ninstr++;
|
fcn->ninstr++;
|
||||||
// FITFCNSZ(); // defer this, in case this instruction is a branch delay entry
|
// FITFCNSZ(); // defer this, in case this instruction is a branch delay entry
|
||||||
// fcn->size += oplen; /// XXX. must be the sum of all the bblocks
|
// fcn->size += oplen; /// XXX. must be the sum of all the bblocks
|
||||||
}
|
}
|
||||||
idx += oplen;
|
idx += oplen;
|
||||||
delay.un_idx = idx;
|
delay.un_idx = idx;
|
||||||
@ -625,7 +637,7 @@ repeat:
|
|||||||
// Save the location of it in `delay.idx`
|
// Save the location of it in `delay.idx`
|
||||||
// note, we have still increased size of basic block
|
// note, we have still increased size of basic block
|
||||||
// (and function)
|
// (and function)
|
||||||
VERBOSE_DELAY eprintf ("Enter branch delay at 0x%08"PFMT64x ". bb->sz=%d\n", addr+idx-oplen, bb->size);
|
VERBOSE_DELAY eprintf("Enter branch delay at 0x%08"PFMT64x ". bb->sz=%d\n", addr + idx - oplen, bb->size);
|
||||||
delay.idx = idx - oplen;
|
delay.idx = idx - oplen;
|
||||||
delay.cnt = op.delay;
|
delay.cnt = op.delay;
|
||||||
delay.pending = 1; // we need this in case the actual idx is zero...
|
delay.pending = 1; // we need this in case the actual idx is zero...
|
||||||
@ -638,7 +650,7 @@ repeat:
|
|||||||
// track of how many still to process.
|
// track of how many still to process.
|
||||||
delay.cnt--;
|
delay.cnt--;
|
||||||
if (!delay.cnt) {
|
if (!delay.cnt) {
|
||||||
VERBOSE_DELAY eprintf ("Last branch delayed opcode at 0x%08"PFMT64x ". bb->sz=%d\n", addr+idx-oplen, bb->size);
|
VERBOSE_DELAY eprintf("Last branch delayed opcode at 0x%08"PFMT64x ". bb->sz=%d\n", addr + idx - oplen, bb->size);
|
||||||
delay.after = idx;
|
delay.after = idx;
|
||||||
idx = delay.idx;
|
idx = delay.idx;
|
||||||
// At this point, we are still looking at the
|
// At this point, we are still looking at the
|
||||||
@ -648,16 +660,16 @@ repeat:
|
|||||||
// the branch delay.
|
// the branch delay.
|
||||||
}
|
}
|
||||||
} else if (op.delay > 0 && delay.pending) {
|
} else if (op.delay > 0 && delay.pending) {
|
||||||
VERBOSE_DELAY eprintf ("Revisit branch delay jump at 0x%08"PFMT64x ". bb->sz=%d\n", addr+idx-oplen, bb->size);
|
VERBOSE_DELAY eprintf("Revisit branch delay jump at 0x%08"PFMT64x ". bb->sz=%d\n", addr + idx - oplen, bb->size);
|
||||||
// This is the second pass of the branch delaying opcode
|
// This is the second pass of the branch delaying opcode
|
||||||
// But we also already counted this instruction in the
|
// But we also already counted this instruction in the
|
||||||
// size of the current basic block, so we need to fix that
|
// size of the current basic block, so we need to fix that
|
||||||
if (delay.adjust) {
|
if (delay.adjust) {
|
||||||
bb->size -= oplen;
|
bb->size -= oplen;
|
||||||
fcn->ninstr--;
|
fcn->ninstr--;
|
||||||
VERBOSE_DELAY eprintf ("Correct for branch delay @ %08"PFMT64x " bb.addr=%08"PFMT64x " corrected.bb=%d f.uncorr=%d\n",
|
VERBOSE_DELAY eprintf("Correct for branch delay @ %08"PFMT64x " bb.addr=%08"PFMT64x " corrected.bb=%d f.uncorr=%d\n",
|
||||||
addr + idx - oplen, bb->addr, bb->size, r_anal_fcn_size (fcn));
|
addr + idx - oplen, bb->addr, bb->size, r_anal_fcn_size (fcn));
|
||||||
FITFCNSZ();
|
FITFCNSZ ();
|
||||||
}
|
}
|
||||||
// Next time, we go to the opcode after the delay count
|
// Next time, we go to the opcode after the delay count
|
||||||
// Take care not to use this below, use delay.un_idx instead ...
|
// Take care not to use this below, use delay.un_idx instead ...
|
||||||
@ -682,10 +694,10 @@ repeat:
|
|||||||
break;
|
break;
|
||||||
// TODO: use fcn->maxstack to know our stackframe
|
// TODO: use fcn->maxstack to know our stackframe
|
||||||
case R_ANAL_STACK_SET:
|
case R_ANAL_STACK_SET:
|
||||||
if ((int)op.ptr > 0) {
|
if ((int) op.ptr > 0) {
|
||||||
varname = get_varname (anal, fcn, 'b', ARGPREFIX, R_ABS(op.ptr));
|
varname = get_varname (anal, fcn, 'b', ARGPREFIX, R_ABS (op.ptr));
|
||||||
} else {
|
} else {
|
||||||
varname = get_varname (anal, fcn, 'b', VARPREFIX, R_ABS(op.ptr));
|
varname = get_varname (anal, fcn, 'b', VARPREFIX, R_ABS (op.ptr));
|
||||||
}
|
}
|
||||||
r_anal_var_add (anal, fcn->addr, 1, op.ptr, 'b', NULL, anal->bits / 8, varname);
|
r_anal_var_add (anal, fcn->addr, 1, op.ptr, 'b', NULL, anal->bits / 8, varname);
|
||||||
r_anal_var_access (anal, fcn->addr, 'b', 1, op.ptr, 1, op.addr);
|
r_anal_var_access (anal, fcn->addr, 'b', 1, op.ptr, 1, op.addr);
|
||||||
@ -693,12 +705,12 @@ repeat:
|
|||||||
break;
|
break;
|
||||||
// TODO: use fcn->maxstack to know our stackframe
|
// TODO: use fcn->maxstack to know our stackframe
|
||||||
case R_ANAL_STACK_GET:
|
case R_ANAL_STACK_GET:
|
||||||
if (((int)op.ptr) > 0) {
|
if (((int) op.ptr) > 0) {
|
||||||
varname = get_varname (anal, fcn, 'b', ARGPREFIX, R_ABS(op.ptr));
|
varname = get_varname (anal, fcn, 'b', ARGPREFIX, R_ABS (op.ptr));
|
||||||
} else {
|
} else {
|
||||||
varname = get_varname (anal, fcn, 'b', VARPREFIX, R_ABS(op.ptr));
|
varname = get_varname (anal, fcn, 'b', VARPREFIX, R_ABS (op.ptr));
|
||||||
}
|
}
|
||||||
r_anal_var_add (anal, fcn->addr, 1, op.ptr, 'b', NULL, anal->bits/8, varname);
|
r_anal_var_add (anal, fcn->addr, 1, op.ptr, 'b', NULL, anal->bits / 8, varname);
|
||||||
r_anal_var_access (anal, fcn->addr, 'b', 1, op.ptr, 0, op.addr);
|
r_anal_var_access (anal, fcn->addr, 'b', 1, op.ptr, 0, op.addr);
|
||||||
free (varname);
|
free (varname);
|
||||||
break;
|
break;
|
||||||
@ -711,9 +723,9 @@ repeat:
|
|||||||
|
|
||||||
switch (op.type & R_ANAL_OP_TYPE_MASK) {
|
switch (op.type & R_ANAL_OP_TYPE_MASK) {
|
||||||
case R_ANAL_OP_TYPE_MOV:
|
case R_ANAL_OP_TYPE_MOV:
|
||||||
//skip mov reg,reg
|
// skip mov reg,reg
|
||||||
if (anal->opt.hpskip && regs_exist(op.src[0], op.dst)
|
if (anal->opt.hpskip && regs_exist (op.src[0], op.dst)
|
||||||
&& !strcmp (op.src[0]->reg->name, op.dst->reg->name)) {
|
&& !strcmp (op.src[0]->reg->name, op.dst->reg->name)) {
|
||||||
skip_ret = skip_hp (anal, fcn, &op, bb, addr, tmp_buf, oplen, delay.un_idx, &idx);
|
skip_ret = skip_hp (anal, fcn, &op, bb, addr, tmp_buf, oplen, delay.un_idx, &idx);
|
||||||
if (skip_ret == 1) {
|
if (skip_ret == 1) {
|
||||||
goto repeat;
|
goto repeat;
|
||||||
@ -724,9 +736,9 @@ repeat:
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case R_ANAL_OP_TYPE_LEA:
|
case R_ANAL_OP_TYPE_LEA:
|
||||||
//skip lea reg,[reg]
|
// skip lea reg,[reg]
|
||||||
if (anal->opt.hpskip && regs_exist(op.src[0], op.dst)
|
if (anal->opt.hpskip && regs_exist (op.src[0], op.dst)
|
||||||
&& !strcmp (op.src[0]->reg->name, op.dst->reg->name)) {
|
&& !strcmp (op.src[0]->reg->name, op.dst->reg->name)) {
|
||||||
skip_ret = skip_hp (anal, fcn, &op, bb, addr, tmp_buf, oplen, delay.un_idx, &idx);
|
skip_ret = skip_hp (anal, fcn, &op, bb, addr, tmp_buf, oplen, delay.un_idx, &idx);
|
||||||
if (skip_ret == 1) {
|
if (skip_ret == 1) {
|
||||||
goto repeat;
|
goto repeat;
|
||||||
@ -737,10 +749,10 @@ repeat:
|
|||||||
}
|
}
|
||||||
if (anal->opt.jmptbl) {
|
if (anal->opt.jmptbl) {
|
||||||
if (is_delta_pointer_table (anal, op.ptr)) {
|
if (is_delta_pointer_table (anal, op.ptr)) {
|
||||||
anal->cb_printf ("pxt. 0x%08"PFMT64x" @ 0x%08"PFMT64x"\n", op.addr, op.ptr);
|
anal->cb_printf ("pxt. 0x%08"PFMT64x " @ 0x%08"PFMT64x "\n", op.addr, op.ptr);
|
||||||
//jmptbl_addr = op.ptr;
|
// jmptbl_addr = op.ptr;
|
||||||
//jmptbl_size = -1;
|
// jmptbl_size = -1;
|
||||||
//ret = try_walkthrough_jmptbl (anal, fcn, depth, op.addr, op.ptr, 4);
|
// ret = try_walkthrough_jmptbl (anal, fcn, depth, op.addr, op.ptr, 4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -778,7 +790,7 @@ repeat:
|
|||||||
case R_ANAL_OP_TYPE_NOP:
|
case R_ANAL_OP_TYPE_NOP:
|
||||||
if (anal->opt.nopskip) {
|
if (anal->opt.nopskip) {
|
||||||
if (!strcmp (anal->cur->arch, "mips")) {
|
if (!strcmp (anal->cur->arch, "mips")) {
|
||||||
//Looks like this flags check is useful only for mips
|
// Looks like this flags check is useful only for mips
|
||||||
// do not skip nops if there's a flag at starting address
|
// do not skip nops if there's a flag at starting address
|
||||||
RFlagItem *fi = anal->flb.get_at (anal->flb.f, addr, false);
|
RFlagItem *fi = anal->flb.get_at (anal->flb.f, addr, false);
|
||||||
if (!fi || strncmp (fi->name, "sym.", 4)) {
|
if (!fi || strncmp (fi->name, "sym.", 4)) {
|
||||||
@ -832,7 +844,7 @@ repeat:
|
|||||||
must_eob = s != d;
|
must_eob = s != d;
|
||||||
}
|
}
|
||||||
if (must_eob) {
|
if (must_eob) {
|
||||||
FITFCNSZ();
|
FITFCNSZ ();
|
||||||
op.jump = UT64_MAX;
|
op.jump = UT64_MAX;
|
||||||
recurseAt (op.jump);
|
recurseAt (op.jump);
|
||||||
recurseAt (op.fail);
|
recurseAt (op.fail);
|
||||||
@ -844,7 +856,7 @@ repeat:
|
|||||||
#if FIX_JMP_FWD
|
#if FIX_JMP_FWD
|
||||||
bb->jump = op.jump;
|
bb->jump = op.jump;
|
||||||
bb->fail = UT64_MAX;
|
bb->fail = UT64_MAX;
|
||||||
FITFCNSZ();
|
FITFCNSZ ();
|
||||||
return R_ANAL_RET_END;
|
return R_ANAL_RET_END;
|
||||||
#else
|
#else
|
||||||
if (!overlapped) {
|
if (!overlapped) {
|
||||||
@ -852,7 +864,7 @@ repeat:
|
|||||||
bb->fail = UT64_MAX;
|
bb->fail = UT64_MAX;
|
||||||
}
|
}
|
||||||
recurseAt (op.jump);
|
recurseAt (op.jump);
|
||||||
FITFCNSZ();
|
FITFCNSZ ();
|
||||||
gotoBeachRet ();
|
gotoBeachRet ();
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
@ -867,14 +879,14 @@ repeat:
|
|||||||
bb->jump = op.jump;
|
bb->jump = op.jump;
|
||||||
bb->fail = UT64_MAX;
|
bb->fail = UT64_MAX;
|
||||||
}
|
}
|
||||||
FITFCNSZ();
|
FITFCNSZ ();
|
||||||
return R_ANAL_RET_END;
|
return R_ANAL_RET_END;
|
||||||
#else
|
#else
|
||||||
// hardcoded jmp size // must be checked at the end wtf?
|
// hardcoded jmp size // must be checked at the end wtf?
|
||||||
// always fitfcnsz and retend
|
// always fitfcnsz and retend
|
||||||
if (r_anal_fcn_is_in_offset (fcn, op.jump)) {
|
if (r_anal_fcn_is_in_offset (fcn, op.jump)) {
|
||||||
/* jump inside the same function */
|
/* jump inside the same function */
|
||||||
FITFCNSZ();
|
FITFCNSZ ();
|
||||||
return R_ANAL_RET_END;
|
return R_ANAL_RET_END;
|
||||||
#if JMP_IS_EOB_RANGE > 0
|
#if JMP_IS_EOB_RANGE > 0
|
||||||
} else {
|
} else {
|
||||||
@ -894,7 +906,7 @@ repeat:
|
|||||||
bb->jump = op.jump;
|
bb->jump = op.jump;
|
||||||
bb->fail = UT64_MAX;
|
bb->fail = UT64_MAX;
|
||||||
}
|
}
|
||||||
FITFCNSZ();
|
FITFCNSZ ();
|
||||||
return R_ANAL_RET_END;
|
return R_ANAL_RET_END;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -921,7 +933,7 @@ repeat:
|
|||||||
bb->jump = op.jump;
|
bb->jump = op.jump;
|
||||||
bb->fail = UT64_MAX;
|
bb->fail = UT64_MAX;
|
||||||
}
|
}
|
||||||
FITFCNSZ();
|
FITFCNSZ ();
|
||||||
recurseAt (op.jump);
|
recurseAt (op.jump);
|
||||||
recurseAt (op.fail);
|
recurseAt (op.fail);
|
||||||
return R_ANAL_RET_END;
|
return R_ANAL_RET_END;
|
||||||
@ -931,11 +943,11 @@ repeat:
|
|||||||
if (op.jump > fcn->addr + JMP_IS_EOB_RANGE) {
|
if (op.jump > fcn->addr + JMP_IS_EOB_RANGE) {
|
||||||
recurseAt (op.fail);
|
recurseAt (op.fail);
|
||||||
/* jump inside the same function */
|
/* jump inside the same function */
|
||||||
FITFCNSZ();
|
FITFCNSZ ();
|
||||||
return R_ANAL_RET_END;
|
return R_ANAL_RET_END;
|
||||||
#if JMP_IS_EOB_RANGE > 0
|
#if JMP_IS_EOB_RANGE > 0
|
||||||
} else {
|
} else {
|
||||||
if (op.jump < addr - JMP_IS_EOB_RANGE && op.jump<addr) {
|
if (op.jump < addr - JMP_IS_EOB_RANGE && op.jump < addr) {
|
||||||
gotoBeach (R_ANAL_RET_END);
|
gotoBeach (R_ANAL_RET_END);
|
||||||
}
|
}
|
||||||
if (op.jump > addr + JMP_IS_EOB_RANGE) {
|
if (op.jump > addr + JMP_IS_EOB_RANGE) {
|
||||||
@ -955,7 +967,7 @@ repeat:
|
|||||||
bb->jump = op.jump;
|
bb->jump = op.jump;
|
||||||
bb->fail = UT64_MAX;
|
bb->fail = UT64_MAX;
|
||||||
}
|
}
|
||||||
FITFCNSZ();
|
FITFCNSZ ();
|
||||||
return R_ANAL_RET_END;
|
return R_ANAL_RET_END;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -980,7 +992,7 @@ repeat:
|
|||||||
return R_ANAL_RET_END;
|
return R_ANAL_RET_END;
|
||||||
}
|
}
|
||||||
// XXX: this is TYPE_MCALL or indirect-call
|
// XXX: this is TYPE_MCALL or indirect-call
|
||||||
(void)r_anal_fcn_xref_add (anal, fcn, op.addr, op.ptr, R_ANAL_REF_TYPE_CALL);
|
(void) r_anal_fcn_xref_add (anal, fcn, op.addr, op.ptr, R_ANAL_REF_TYPE_CALL);
|
||||||
break;
|
break;
|
||||||
case R_ANAL_OP_TYPE_CCALL:
|
case R_ANAL_OP_TYPE_CCALL:
|
||||||
case R_ANAL_OP_TYPE_CALL:
|
case R_ANAL_OP_TYPE_CALL:
|
||||||
@ -990,7 +1002,7 @@ repeat:
|
|||||||
r_anal_op_fini (&op);
|
r_anal_op_fini (&op);
|
||||||
return R_ANAL_RET_END;
|
return R_ANAL_RET_END;
|
||||||
}
|
}
|
||||||
(void)r_anal_fcn_xref_add (anal, fcn, op.addr, op.jump, R_ANAL_REF_TYPE_CALL);
|
(void) r_anal_fcn_xref_add (anal, fcn, op.addr, op.jump, R_ANAL_REF_TYPE_CALL);
|
||||||
#if CALL_IS_EOB
|
#if CALL_IS_EOB
|
||||||
recurseAt (op.jump);
|
recurseAt (op.jump);
|
||||||
recurseAt (op.fail);
|
recurseAt (op.fail);
|
||||||
@ -1008,10 +1020,10 @@ repeat:
|
|||||||
RAnalRef *last_ref = fcn->refs->tail->data;
|
RAnalRef *last_ref = fcn->refs->tail->data;
|
||||||
last_ref->type = R_ANAL_REF_TYPE_NULL;
|
last_ref->type = R_ANAL_REF_TYPE_NULL;
|
||||||
}
|
}
|
||||||
if (op.ptr != UT64_MAX) { // direct jump
|
if (op.ptr != UT64_MAX) { // direct jump
|
||||||
ret = try_walkthrough_jmptbl (anal, fcn, depth, addr + idx, op.ptr, ret);
|
ret = try_walkthrough_jmptbl (anal, fcn, depth, addr + idx, op.ptr, ret);
|
||||||
|
|
||||||
} else { // indirect jump: table pointer is unknown
|
} else { // indirect jump: table pointer is unknown
|
||||||
if (op.src[0] && op.src[0]->reg) {
|
if (op.src[0] && op.src[0]->reg) {
|
||||||
ut64 ptr = search_reg_val (anal, buf, idx, addr, op.src[0]->reg->name);
|
ut64 ptr = search_reg_val (anal, buf, idx, addr, op.src[0]->reg->name);
|
||||||
if (ptr && ptr != UT64_MAX) {
|
if (ptr && ptr != UT64_MAX) {
|
||||||
@ -1032,7 +1044,9 @@ repeat:
|
|||||||
}
|
}
|
||||||
if (anal->cur->arch && strstr (anal->cur->arch, "arm")) {
|
if (anal->cur->arch && strstr (anal->cur->arch, "arm")) {
|
||||||
if (anal->bits == 64) {
|
if (anal->bits == 64) {
|
||||||
if (!in_plt) goto river;
|
if (!in_plt) {
|
||||||
|
goto river;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (in_plt) {
|
if (in_plt) {
|
||||||
@ -1046,12 +1060,12 @@ repeat:
|
|||||||
return R_ANAL_RET_END;
|
return R_ANAL_RET_END;
|
||||||
river:
|
river:
|
||||||
break;
|
break;
|
||||||
/* fallthru */
|
/* fallthru */
|
||||||
case R_ANAL_OP_TYPE_PUSH:
|
case R_ANAL_OP_TYPE_PUSH:
|
||||||
last_is_push = true;
|
last_is_push = true;
|
||||||
last_push_addr = op.val;
|
last_push_addr = op.val;
|
||||||
if (anal->iob.is_valid_offset (anal->iob.io, op.val, 1)) {
|
if (anal->iob.is_valid_offset (anal->iob.io, op.val, 1)) {
|
||||||
(void)r_anal_fcn_xref_add (anal, fcn, op.addr, op.val, R_ANAL_REF_TYPE_DATA);
|
(void) r_anal_fcn_xref_add (anal, fcn, op.addr, op.val, R_ANAL_REF_TYPE_DATA);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case R_ANAL_OP_TYPE_RET:
|
case R_ANAL_OP_TYPE_RET:
|
||||||
@ -1066,9 +1080,9 @@ river:
|
|||||||
gotoBeachRet ();
|
gotoBeachRet ();
|
||||||
} else {
|
} else {
|
||||||
if (!op.cond) {
|
if (!op.cond) {
|
||||||
VERBOSE_ANAL eprintf ("RET 0x%08"PFMT64x". %d %d %d\n",
|
VERBOSE_ANAL eprintf("RET 0x%08"PFMT64x ". %d %d %d\n",
|
||||||
addr + delay.un_idx-oplen, overlapped,
|
addr + delay.un_idx - oplen, overlapped,
|
||||||
bb->size, r_anal_fcn_size (fcn));
|
bb->size, r_anal_fcn_size (fcn));
|
||||||
FITFCNSZ ();
|
FITFCNSZ ();
|
||||||
r_anal_op_fini (&op);
|
r_anal_op_fini (&op);
|
||||||
return R_ANAL_RET_END;
|
return R_ANAL_RET_END;
|
||||||
@ -1090,22 +1104,24 @@ static int check_preludes(ut8 *buf, ut16 bufsz) {
|
|||||||
if (bufsz < 10) {
|
if (bufsz < 10) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!memcmp (buf, (const ut8 *)"\x55\x89\xe5", 3)) {
|
if (!memcmp (buf, (const ut8 *) "\x55\x89\xe5", 3)) {
|
||||||
return true;
|
return true;
|
||||||
} else if (!memcmp (buf, (const ut8 *)"\x55\x8b\xec", 3)) {
|
} else if (!memcmp (buf, (const ut8 *) "\x55\x8b\xec", 3)) {
|
||||||
return true;
|
return true;
|
||||||
} else if (!memcmp (buf, (const ut8 *)"\x8b\xff", 2)) {
|
} else if (!memcmp (buf, (const ut8 *) "\x8b\xff", 2)) {
|
||||||
return true;
|
return true;
|
||||||
} else if (!memcmp (buf, (const ut8 *)"\x55\x48\x89\xe5", 4)) {
|
} else if (!memcmp (buf, (const ut8 *) "\x55\x48\x89\xe5", 4)) {
|
||||||
return true;
|
return true;
|
||||||
} else if (!memcmp (buf, (const ut8 *)"\x55\x48\x8b\xec", 4)) {
|
} else if (!memcmp (buf, (const ut8 *) "\x55\x48\x8b\xec", 4)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
R_API bool r_anal_check_fcn(RAnal *anal, ut8 *buf, ut16 bufsz, ut64 addr, ut64 low, ut64 high) {
|
R_API bool r_anal_check_fcn(RAnal *anal, ut8 *buf, ut16 bufsz, ut64 addr, ut64 low, ut64 high) {
|
||||||
RAnalOp op = {0};
|
RAnalOp op = {
|
||||||
|
0
|
||||||
|
};
|
||||||
int i, oplen, opcnt = 0, pushcnt = 0, movcnt = 0, brcnt = 0;
|
int i, oplen, opcnt = 0, pushcnt = 0, movcnt = 0, brcnt = 0;
|
||||||
if (check_preludes (buf, bufsz)) {
|
if (check_preludes (buf, bufsz)) {
|
||||||
return true;
|
return true;
|
||||||
@ -1139,17 +1155,17 @@ R_API bool r_anal_check_fcn(RAnal *anal, ut8 *buf, ut16 bufsz, ut64 addr, ut64 l
|
|||||||
return (pushcnt + movcnt + brcnt > 5);
|
return (pushcnt + movcnt + brcnt > 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void fcnfit (RAnal *a, RAnalFunction *f) {
|
static void fcnfit(RAnal *a, RAnalFunction *f) {
|
||||||
// find next function
|
// find next function
|
||||||
RAnalFunction *next = r_anal_fcn_next (a, f->addr);
|
RAnalFunction *next = r_anal_fcn_next (a, f->addr);
|
||||||
if (next) {
|
if (next) {
|
||||||
if ((f->addr + r_anal_fcn_size (f))> next->addr) {
|
if ((f->addr + r_anal_fcn_size (f)) > next->addr) {
|
||||||
r_anal_fcn_resize (f, (next->addr - f->addr));
|
r_anal_fcn_resize (f, (next->addr - f->addr));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
R_API void r_anal_fcn_fit_overlaps (RAnal *anal, RAnalFunction *fcn) {
|
R_API void r_anal_fcn_fit_overlaps(RAnal *anal, RAnalFunction *fcn) {
|
||||||
if (fcn) {
|
if (fcn) {
|
||||||
fcnfit (anal, fcn);
|
fcnfit (anal, fcn);
|
||||||
} else {
|
} else {
|
||||||
@ -1177,7 +1193,7 @@ R_API int r_anal_fcn(RAnal *anal, RAnalFunction *fcn, ut64 addr, ut8 *buf, ut64
|
|||||||
r_anal_fcn_set_size (fcn, 0);
|
r_anal_fcn_set_size (fcn, 0);
|
||||||
/* defines fcn. or loc. prefix */
|
/* defines fcn. or loc. prefix */
|
||||||
fcn->type = (reftype == R_ANAL_REF_TYPE_CODE)
|
fcn->type = (reftype == R_ANAL_REF_TYPE_CODE)
|
||||||
? R_ANAL_FCN_TYPE_LOC
|
? R_ANAL_FCN_TYPE_LOC
|
||||||
: R_ANAL_FCN_TYPE_FCN;
|
: R_ANAL_FCN_TYPE_FCN;
|
||||||
if (fcn->addr == UT64_MAX) {
|
if (fcn->addr == UT64_MAX) {
|
||||||
fcn->addr = addr;
|
fcn->addr = addr;
|
||||||
@ -1190,10 +1206,10 @@ R_API int r_anal_fcn(RAnal *anal, RAnalFunction *fcn, ut64 addr, ut8 *buf, ut64
|
|||||||
}
|
}
|
||||||
fcn->maxstack = 0;
|
fcn->maxstack = 0;
|
||||||
ret = fcn_recurse (anal, fcn, addr, buf, len, FCN_DEPTH);
|
ret = fcn_recurse (anal, fcn, addr, buf, len, FCN_DEPTH);
|
||||||
//update tinyrange for the function
|
// update tinyrange for the function
|
||||||
update_tinyrange_bbs (fcn);
|
update_tinyrange_bbs (fcn);
|
||||||
|
|
||||||
if (ret == R_ANAL_RET_END && r_anal_fcn_size (fcn)) { // cfg analysis completed
|
if (ret == R_ANAL_RET_END && r_anal_fcn_size (fcn)) { // cfg analysis completed
|
||||||
RListIter *iter;
|
RListIter *iter;
|
||||||
RAnalBlock *bb;
|
RAnalBlock *bb;
|
||||||
ut64 endaddr = fcn->addr;
|
ut64 endaddr = fcn->addr;
|
||||||
@ -1206,10 +1222,10 @@ R_API int r_anal_fcn(RAnal *anal, RAnalFunction *fcn, ut64 addr, ut8 *buf, ut64
|
|||||||
if (endaddr == bb->addr) {
|
if (endaddr == bb->addr) {
|
||||||
endaddr += bb->size;
|
endaddr += bb->size;
|
||||||
} else if (endaddr < bb->addr &&
|
} else if (endaddr < bb->addr &&
|
||||||
bb->addr - endaddr <
|
bb->addr - endaddr <
|
||||||
anal->opt.bbs_alignment &&
|
anal->opt.bbs_alignment &&
|
||||||
!(bb->addr &
|
!(bb->addr &
|
||||||
(anal->opt.bbs_alignment - 1))) {
|
(anal->opt.bbs_alignment - 1))) {
|
||||||
endaddr = bb->addr + bb->size;
|
endaddr = bb->addr + bb->size;
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
@ -1237,7 +1253,7 @@ R_API int r_anal_fcn(RAnal *anal, RAnalFunction *fcn, ut64 addr, ut8 *buf, ut64
|
|||||||
|
|
||||||
// TODO: need to implement r_anal_fcn_remove(RAnal *anal, RAnalFunction *fcn);
|
// TODO: need to implement r_anal_fcn_remove(RAnal *anal, RAnalFunction *fcn);
|
||||||
R_API int r_anal_fcn_insert(RAnal *anal, RAnalFunction *fcn) {
|
R_API int r_anal_fcn_insert(RAnal *anal, RAnalFunction *fcn) {
|
||||||
//RAnalFunction *f = r_anal_get_fcn_in (anal, fcn->addr, R_ANAL_FCN_TYPE_ROOT);
|
// RAnalFunction *f = r_anal_get_fcn_in (anal, fcn->addr, R_ANAL_FCN_TYPE_ROOT);
|
||||||
RAnalFunction *f = r_anal_get_fcn_at (anal, fcn->addr, R_ANAL_FCN_TYPE_ROOT);
|
RAnalFunction *f = r_anal_get_fcn_at (anal, fcn->addr, R_ANAL_FCN_TYPE_ROOT);
|
||||||
if (f) {
|
if (f) {
|
||||||
return false;
|
return false;
|
||||||
@ -1354,15 +1370,16 @@ R_API int r_anal_fcn_del(RAnal *a, ut64 addr) {
|
|||||||
R_API RAnalFunction *r_anal_get_fcn_in(RAnal *anal, ut64 addr, int type) {
|
R_API RAnalFunction *r_anal_get_fcn_in(RAnal *anal, ut64 addr, int type) {
|
||||||
#if USE_NEW_FCN_STORE
|
#if USE_NEW_FCN_STORE
|
||||||
// TODO: type is ignored here? wtf.. we need more work on fcnstore
|
// TODO: type is ignored here? wtf.. we need more work on fcnstore
|
||||||
//if (root) return r_listrange_find_root (anal->fcnstore, addr);
|
// if (root) return r_listrange_find_root (anal->fcnstore, addr);
|
||||||
return r_listrange_find_in_range (anal->fcnstore, addr);
|
return r_listrange_find_in_range (anal->fcnstore, addr);
|
||||||
#else
|
#else
|
||||||
RAnalFunction *fcn, *ret = NULL;
|
RAnalFunction *fcn, *ret = NULL;
|
||||||
RListIter *iter;
|
RListIter *iter;
|
||||||
if (type == R_ANAL_FCN_TYPE_ROOT) {
|
if (type == R_ANAL_FCN_TYPE_ROOT) {
|
||||||
r_list_foreach (anal->fcns, iter, fcn) {
|
r_list_foreach (anal->fcns, iter, fcn) {
|
||||||
if (addr == fcn->addr)
|
if (addr == fcn->addr) {
|
||||||
return fcn;
|
return fcn;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -1386,7 +1403,7 @@ R_API RAnalFunction *r_anal_get_fcn_in_bounds(RAnal *anal, ut64 addr, int type)
|
|||||||
#if USE_NEW_FCN_STORE
|
#if USE_NEW_FCN_STORE
|
||||||
#warning TODO: r_anal_get_fcn_in_bounds
|
#warning TODO: r_anal_get_fcn_in_bounds
|
||||||
// TODO: type is ignored here? wtf.. we need more work on fcnstore
|
// TODO: type is ignored here? wtf.. we need more work on fcnstore
|
||||||
//if (root) return r_listrange_find_root (anal->fcnstore, addr);
|
// if (root) return r_listrange_find_root (anal->fcnstore, addr);
|
||||||
return r_listrange_find_in_range (anal->fcnstore, addr);
|
return r_listrange_find_in_range (anal->fcnstore, addr);
|
||||||
#else
|
#else
|
||||||
RAnalFunction *fcn, *ret = NULL;
|
RAnalFunction *fcn, *ret = NULL;
|
||||||
@ -1437,7 +1454,7 @@ R_API int r_anal_fcn_add_bb(RAnal *anal, RAnalFunction *fcn, ut64 addr, ut64 siz
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (mid) {
|
if (mid) {
|
||||||
//eprintf ("Basic Block overlaps another one that should be shrinked\n");
|
// eprintf ("Basic Block overlaps another one that should be shrinked\n");
|
||||||
if (bbi) {
|
if (bbi) {
|
||||||
/* shrink overlapped basic block */
|
/* shrink overlapped basic block */
|
||||||
bbi->size = addr - (bbi->addr);
|
bbi->size = addr - (bbi->addr);
|
||||||
@ -1533,14 +1550,14 @@ R_API int r_anal_fcn_bb_overlaps(RAnalFunction *fcn, RAnalBlock *bb) {
|
|||||||
RAnalBlock *bbi;
|
RAnalBlock *bbi;
|
||||||
RListIter *iter;
|
RListIter *iter;
|
||||||
r_list_foreach (fcn->bbs, iter, bbi) {
|
r_list_foreach (fcn->bbs, iter, bbi) {
|
||||||
if (bb->addr + bb->size > bbi->addr && bb->addr + bb->size <= bbi->addr+bbi->size) {
|
if (bb->addr + bb->size > bbi->addr && bb->addr + bb->size <= bbi->addr + bbi->size) {
|
||||||
bb->size = bbi->addr - bb->addr;
|
bb->size = bbi->addr - bb->addr;
|
||||||
bb->jump = bbi->addr;
|
bb->jump = bbi->addr;
|
||||||
bb->fail = -1;
|
bb->fail = -1;
|
||||||
bb->conditional = false;
|
bb->conditional = false;
|
||||||
if (bbi->type & R_ANAL_BB_TYPE_HEAD) {
|
if (bbi->type & R_ANAL_BB_TYPE_HEAD) {
|
||||||
bb->type = R_ANAL_BB_TYPE_HEAD;
|
bb->type = R_ANAL_BB_TYPE_HEAD;
|
||||||
bbi->type = bbi->type^R_ANAL_BB_TYPE_HEAD;
|
bbi->type = bbi->type ^ R_ANAL_BB_TYPE_HEAD;
|
||||||
} else {
|
} else {
|
||||||
bb->type = R_ANAL_BB_TYPE_BODY;
|
bb->type = R_ANAL_BB_TYPE_BODY;
|
||||||
}
|
}
|
||||||
@ -1553,11 +1570,11 @@ R_API int r_anal_fcn_bb_overlaps(RAnalFunction *fcn, RAnalBlock *bb) {
|
|||||||
|
|
||||||
R_API int r_anal_fcn_cc(RAnalFunction *fcn) {
|
R_API int r_anal_fcn_cc(RAnalFunction *fcn) {
|
||||||
/*
|
/*
|
||||||
CC = E - N + 2P
|
CC = E - N + 2P
|
||||||
E = the number of edges of the graph.
|
E = the number of edges of the graph.
|
||||||
N = the number of nodes of the graph.
|
N = the number of nodes of the graph.
|
||||||
P = the number of connected components (exit nodes).
|
P = the number of connected components (exit nodes).
|
||||||
*/
|
*/
|
||||||
int E = 0, N = 0, P = 0;
|
int E = 0, N = 0, P = 0;
|
||||||
RListIter *iter;
|
RListIter *iter;
|
||||||
RAnalBlock *bb;
|
RAnalBlock *bb;
|
||||||
@ -1576,7 +1593,7 @@ R_API int r_anal_fcn_cc(RAnalFunction *fcn) {
|
|||||||
return E - N + 2; // (2 * P);
|
return E - N + 2; // (2 * P);
|
||||||
}
|
}
|
||||||
|
|
||||||
R_API char *r_anal_fcn_to_string(RAnal *a, RAnalFunction* fs) {
|
R_API char *r_anal_fcn_to_string(RAnal *a, RAnalFunction *fs) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1609,7 +1626,7 @@ R_API int r_anal_str_to_fcn(RAnal *a, RAnalFunction *f, const char *sig) {
|
|||||||
R_API RAnalFunction *r_anal_get_fcn_at(RAnal *anal, ut64 addr, int type) {
|
R_API RAnalFunction *r_anal_get_fcn_at(RAnal *anal, ut64 addr, int type) {
|
||||||
#if USE_NEW_FCN_STORE
|
#if USE_NEW_FCN_STORE
|
||||||
// TODO: type is ignored here? wtf.. we need more work on fcnstore
|
// TODO: type is ignored here? wtf.. we need more work on fcnstore
|
||||||
//if (root) return r_listrange_find_root (anal->fcnstore, addr);
|
// if (root) return r_listrange_find_root (anal->fcnstore, addr);
|
||||||
return r_listrange_find_root (anal->fcnstore, addr);
|
return r_listrange_find_root (anal->fcnstore, addr);
|
||||||
#else
|
#else
|
||||||
RAnalFunction *fcn, *ret = NULL;
|
RAnalFunction *fcn, *ret = NULL;
|
||||||
@ -1638,8 +1655,8 @@ R_API RAnalFunction *r_anal_fcn_next(RAnal *anal, ut64 addr) {
|
|||||||
RListIter *iter;
|
RListIter *iter;
|
||||||
RAnalFunction *closer = NULL;
|
RAnalFunction *closer = NULL;
|
||||||
r_list_foreach (anal->fcns, iter, fcni) {
|
r_list_foreach (anal->fcns, iter, fcni) {
|
||||||
//if (fcni->addr == addr)
|
// if (fcni->addr == addr)
|
||||||
if (fcni->addr > addr && (!closer || fcni->addr<closer->addr)) {
|
if (fcni->addr > addr && (!closer || fcni->addr < closer->addr)) {
|
||||||
closer = fcni;
|
closer = fcni;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1648,14 +1665,17 @@ R_API RAnalFunction *r_anal_fcn_next(RAnal *anal, ut64 addr) {
|
|||||||
|
|
||||||
/* getters */
|
/* getters */
|
||||||
#if FCN_OLD
|
#if FCN_OLD
|
||||||
R_API RList* r_anal_fcn_get_refs (RAnalFunction *anal) { return anal->refs; }
|
R_API RList *r_anal_fcn_get_refs(RAnalFunction *fcn) {
|
||||||
R_API RList* r_anal_fcn_get_xrefs (RAnalFunction *anal) { return anal->xrefs; }
|
return fcn->refs;
|
||||||
R_API RList* r_anal_fcn_get_vars (RAnalFunction *anal) { return anal->vars; }
|
}
|
||||||
|
R_API RList *r_anal_fcn_get_xrefs(RAnalFunction *fcn) {
|
||||||
|
return fcn->xrefs;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
R_API RList* r_anal_fcn_get_bbs (RAnalFunction *anal) {
|
R_API RList *r_anal_fcn_get_bbs(RAnalFunction *anal) {
|
||||||
// avoid received to free this thing
|
// avoid received to free this thing
|
||||||
//anal->bbs->rc++;
|
// anal->bbs->rc++;
|
||||||
anal->bbs->free = NULL;
|
anal->bbs->free = NULL;
|
||||||
return anal->bbs;
|
return anal->bbs;
|
||||||
}
|
}
|
||||||
@ -1671,7 +1691,7 @@ R_API int r_anal_fcn_is_in_offset(RAnalFunction *fcn, ut64 addr) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
R_API int r_anal_fcn_count (RAnal *anal, ut64 from, ut64 to) {
|
R_API int r_anal_fcn_count(RAnal *anal, ut64 from, ut64 to) {
|
||||||
int n = 0;
|
int n = 0;
|
||||||
RAnalFunction *fcni;
|
RAnalFunction *fcni;
|
||||||
RListIter *iter;
|
RListIter *iter;
|
||||||
@ -1718,7 +1738,7 @@ R_API void r_anal_fcn_set_size(RAnalFunction *fcn, ut32 size) {
|
|||||||
/* returns the size of the function.
|
/* returns the size of the function.
|
||||||
* IMPORTANT: this will change, one day, because it doesn't have much sense */
|
* IMPORTANT: this will change, one day, because it doesn't have much sense */
|
||||||
R_API ut32 r_anal_fcn_size(const RAnalFunction *fcn) {
|
R_API ut32 r_anal_fcn_size(const RAnalFunction *fcn) {
|
||||||
return fcn ? fcn->_size : 0;
|
return fcn? fcn->_size: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* return the "real" size of the function, that is the sum of the size of the
|
/* return the "real" size of the function, that is the sum of the size of the
|
||||||
@ -1740,16 +1760,16 @@ R_API ut32 r_anal_fcn_realsize(const RAnalFunction *fcn) {
|
|||||||
return sz;
|
return sz;
|
||||||
}
|
}
|
||||||
|
|
||||||
//continious function size without loc.*
|
// continious function size without loc.*
|
||||||
R_API ut32 r_anal_fcn_contsize(const RAnalFunction *fcn) {
|
R_API ut32 r_anal_fcn_contsize(const RAnalFunction *fcn) {
|
||||||
RListIter *iter;
|
RListIter *iter;
|
||||||
RAnalBlock *bb;
|
RAnalBlock *bb;
|
||||||
ut32 sz = 0;
|
ut32 sz = 0;
|
||||||
r_list_foreach (fcn->bbs, iter, bb) {
|
r_list_foreach (fcn->bbs, iter, bb) {
|
||||||
/* TODO: this if is an ugly hack and should be removed when r2 will be
|
/* TODO: this if is an ugly hack and should be removed when r2 will be
|
||||||
* able to handle BBs that comes before the function emtry point.
|
* able to handle BBs that comes before the function emtry point.
|
||||||
* Another way to remove this is to throw away BBs before the function
|
* Another way to remove this is to throw away BBs before the function
|
||||||
* entry point at the analysis time in the r_anal_fcn. */
|
* entry point at the analysis time in the r_anal_fcn. */
|
||||||
if (bb->addr >= fcn->addr) {
|
if (bb->addr >= fcn->addr) {
|
||||||
sz += bb->size;
|
sz += bb->size;
|
||||||
}
|
}
|
||||||
@ -1769,11 +1789,11 @@ R_API ut32 r_anal_fcn_cost(RAnal *anal, RAnalFunction *fcn) {
|
|||||||
RAnalOp op;
|
RAnalOp op;
|
||||||
ut64 at, end = bb->addr + bb->size;
|
ut64 at, end = bb->addr + bb->size;
|
||||||
ut8 *buf = malloc (bb->size);
|
ut8 *buf = malloc (bb->size);
|
||||||
anal->iob.read_at (anal->iob.io, bb->addr, (ut8 *)buf, bb->size);
|
anal->iob.read_at (anal->iob.io, bb->addr, (ut8 *) buf, bb->size);
|
||||||
int idx = 0;
|
int idx = 0;
|
||||||
for (at = bb->addr; at < end; ) {
|
for (at = bb->addr; at < end;) {
|
||||||
memset (&op, 0, sizeof (op));
|
memset (&op, 0, sizeof (op));
|
||||||
(void)r_anal_op (anal, &op, at, buf + idx, bb->size - idx);
|
(void) r_anal_op (anal, &op, at, buf + idx, bb->size - idx);
|
||||||
if (op.size < 1) {
|
if (op.size < 1) {
|
||||||
op.size = 1;
|
op.size = 1;
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -118,69 +118,6 @@ R_API int r_anal_type_get_size(RAnal *anal, const char *type) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
R_API RList *r_anal_type_fcn_list(RAnal *anal) {
|
|
||||||
SdbList *sdb_list = sdb_foreach_match (anal->sdb_types, "=^func$", false);
|
|
||||||
RList *list = r_list_newf ((RListFree)r_anal_fcn_free);
|
|
||||||
char *name, *value;
|
|
||||||
const char *key;
|
|
||||||
SdbListIter *sdb_iter;
|
|
||||||
int args_n, i;
|
|
||||||
SdbKv *kv;
|
|
||||||
|
|
||||||
if (!list || !sdb_list) {
|
|
||||||
r_list_free (list);
|
|
||||||
ls_free (sdb_list);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
ls_foreach (sdb_list, sdb_iter, kv) {
|
|
||||||
RAnalFunction *fcn = r_anal_fcn_new ();
|
|
||||||
r_list_append (list, fcn);
|
|
||||||
//setting function name and return type
|
|
||||||
fcn->name = strdup (kv->key);
|
|
||||||
//setting function return type
|
|
||||||
key = sdb_fmt (-1, "func.%s.ret", kv->key);
|
|
||||||
fcn->rets = sdb_get (anal->sdb_types, key, 0);
|
|
||||||
//setting calling conventions
|
|
||||||
key = sdb_fmt (-1, "func.%s.cc", kv->key);
|
|
||||||
fcn->cc = sdb_get (anal->sdb_types, key, 0);
|
|
||||||
//Filling function args
|
|
||||||
key = sdb_fmt (-1, "func.%s.args", kv->key);
|
|
||||||
value = sdb_get (anal->sdb_types, key, 0);
|
|
||||||
args_n = r_num_math (NULL, value);
|
|
||||||
free (value);
|
|
||||||
if (!args_n) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
//XXX we should handle as much calling conventions
|
|
||||||
//for as much architectures as we want here
|
|
||||||
fcn->vars = r_list_newf ((RListFree)r_anal_var_free);
|
|
||||||
if (!fcn->vars) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
for (i = 0; i < args_n; i++) {
|
|
||||||
key = r_str_newf ("func.%s.arg.%d", kv->key, i);
|
|
||||||
value = sdb_get (anal->sdb_types, key, 0);
|
|
||||||
if (value) {
|
|
||||||
name = strstr (value, ",");
|
|
||||||
*name++ = 0;
|
|
||||||
RAnalVar *arg = R_NEW0 (RAnalVar);
|
|
||||||
arg->name = strdup (name);
|
|
||||||
arg->type = value;
|
|
||||||
arg->kind = 'a';
|
|
||||||
//TODO Calculate the size and the delta
|
|
||||||
arg->delta = i;
|
|
||||||
r_list_append (fcn->vars, arg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ls_free (sdb_list);
|
|
||||||
if (r_list_empty (list)) {
|
|
||||||
r_list_free (list);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
R_API char* r_anal_type_to_str (RAnal *a, const char *type) {
|
R_API char* r_anal_type_to_str (RAnal *a, const char *type) {
|
||||||
// convert to C text... maybe that should be in format string..
|
// convert to C text... maybe that should be in format string..
|
||||||
return NULL;
|
return NULL;
|
||||||
|
230
libr/anal/var.c
230
libr/anal/var.c
@ -16,10 +16,10 @@ struct VarType {
|
|||||||
|
|
||||||
#define SDB_VARTYPE_FMT "czdz"
|
#define SDB_VARTYPE_FMT "czdz"
|
||||||
|
|
||||||
#define EXISTS(x,y...) snprintf (key, sizeof (key)-1, x, ##y), sdb_exists(DB,key)
|
#define EXISTS(x, y ...) snprintf (key, sizeof (key) - 1, x, ## y), sdb_exists (DB, key)
|
||||||
#define SETKEY(x,y...) snprintf (key, sizeof (key)-1, x, ##y);
|
#define SETKEY(x, y ...) snprintf (key, sizeof (key) - 1, x, ## y);
|
||||||
#define SETKEY2(x,y...) snprintf (key2, sizeof (key)-1, x, ##y);
|
#define SETKEY2(x, y ...) snprintf (key2, sizeof (key) - 1, x, ## y);
|
||||||
#define SETVAL(x,y...) snprintf (val, sizeof (val)-1, x, ##y);
|
#define SETVAL(x, y ...) snprintf (val, sizeof (val) - 1, x, ## y);
|
||||||
R_API bool r_anal_var_display(RAnal *anal, int delta, char kind, const char *type) {
|
R_API bool r_anal_var_display(RAnal *anal, int delta, char kind, const char *type) {
|
||||||
char *fmt = r_anal_type_format (anal, type);
|
char *fmt = r_anal_type_format (anal, type);
|
||||||
RRegItem *i;
|
RRegItem *i;
|
||||||
@ -68,7 +68,7 @@ R_API int r_anal_var_add(RAnal *a, ut64 addr, int scope, int delta, char kind, c
|
|||||||
eprintf ("Invalid var kind '%c'\n", kind);
|
eprintf ("Invalid var kind '%c'\n", kind);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
var_def = sdb_fmt (0,"%c,%s,%d,%s", kind, type, size, name);
|
var_def = sdb_fmt (0, "%c,%s,%d,%s", kind, type, size, name);
|
||||||
if (scope > 0) {
|
if (scope > 0) {
|
||||||
char *sign = "";
|
char *sign = "";
|
||||||
if (delta < 0) {
|
if (delta < 0) {
|
||||||
@ -76,9 +76,9 @@ R_API int r_anal_var_add(RAnal *a, ut64 addr, int scope, int delta, char kind, c
|
|||||||
sign = "_";
|
sign = "_";
|
||||||
}
|
}
|
||||||
/* local variable */
|
/* local variable */
|
||||||
char *fcn_key = sdb_fmt (1, "fcn.0x%"PFMT64x".%c", addr, kind);
|
char *fcn_key = sdb_fmt (1, "fcn.0x%"PFMT64x ".%c", addr, kind);
|
||||||
char *var_key = sdb_fmt (2, "var.0x%"PFMT64x".%c.%d.%s%d", addr, kind, scope, sign, delta);
|
char *var_key = sdb_fmt (2, "var.0x%"PFMT64x ".%c.%d.%s%d", addr, kind, scope, sign, delta);
|
||||||
char *name_key = sdb_fmt (3, "var.0x%"PFMT64x".%d.%s", addr, scope, name);
|
char *name_key = sdb_fmt (3, "var.0x%"PFMT64x ".%d.%s", addr, scope, name);
|
||||||
char *shortvar = sdb_fmt (4, "%d.%s%d", scope, sign, delta);
|
char *shortvar = sdb_fmt (4, "%d.%s%d", scope, sign, delta);
|
||||||
sdb_array_add (DB, fcn_key, shortvar, 0);
|
sdb_array_add (DB, fcn_key, shortvar, 0);
|
||||||
sdb_set (DB, var_key, var_def, 0);
|
sdb_set (DB, var_key, var_def, 0);
|
||||||
@ -90,10 +90,10 @@ R_API int r_anal_var_add(RAnal *a, ut64 addr, int scope, int delta, char kind, c
|
|||||||
} else {
|
} else {
|
||||||
/* global variable */
|
/* global variable */
|
||||||
char *var_global = sdb_fmt (1, "var.0x%"PFMT64x, addr);
|
char *var_global = sdb_fmt (1, "var.0x%"PFMT64x, addr);
|
||||||
char *var_def = sdb_fmt (2,"%c.%s,%d,%s", kind, type, size, name);
|
char *var_def = sdb_fmt (2, "%c.%s,%d,%s", kind, type, size, name);
|
||||||
sdb_array_add (DB, var_global, var_def, 0);
|
sdb_array_add (DB, var_global, var_def, 0);
|
||||||
}
|
}
|
||||||
// ls_sort (DB->ht->list, mystrcmp);
|
// ls_sort (DB->ht->list, mystrcmp);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -136,7 +136,7 @@ R_API int r_anal_var_retype(RAnal *a, ut64 addr, int scope, int delta, char kind
|
|||||||
eprintf ("Invalid var kind '%c'\n", kind);
|
eprintf ("Invalid var kind '%c'\n", kind);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
var_def = sdb_fmt (0,"%c,%s,%d,%s", kind, type, size, name);
|
var_def = sdb_fmt (0, "%c,%s,%d,%s", kind, type, size, name);
|
||||||
if (scope > 0) {
|
if (scope > 0) {
|
||||||
char *sign = "";
|
char *sign = "";
|
||||||
if (delta < 0) {
|
if (delta < 0) {
|
||||||
@ -144,9 +144,9 @@ R_API int r_anal_var_retype(RAnal *a, ut64 addr, int scope, int delta, char kind
|
|||||||
sign = "_";
|
sign = "_";
|
||||||
}
|
}
|
||||||
/* local variable */
|
/* local variable */
|
||||||
const char *fcn_key = sdb_fmt (1, "fcn.0x%"PFMT64x".%c", fcn->addr, kind);
|
const char *fcn_key = sdb_fmt (1, "fcn.0x%"PFMT64x ".%c", fcn->addr, kind);
|
||||||
const char *var_key = sdb_fmt (2, "var.0x%"PFMT64x".%c.%d.%s%d", fcn->addr, kind, scope, sign, delta);
|
const char *var_key = sdb_fmt (2, "var.0x%"PFMT64x ".%c.%d.%s%d", fcn->addr, kind, scope, sign, delta);
|
||||||
const char *name_key = sdb_fmt (3, "var.0x%"PFMT64x".%d.%s", fcn->addr, scope, name);
|
const char *name_key = sdb_fmt (3, "var.0x%"PFMT64x ".%d.%s", fcn->addr, scope, name);
|
||||||
const char *shortvar = sdb_fmt (4, "%d.%s%d", scope, sign, delta);
|
const char *shortvar = sdb_fmt (4, "%d.%s%d", scope, sign, delta);
|
||||||
const char *name_val = sdb_fmt (5, "%c,%d", kind, delta);
|
const char *name_val = sdb_fmt (5, "%c,%d", kind, delta);
|
||||||
sdb_array_add (DB, fcn_key, shortvar, 0);
|
sdb_array_add (DB, fcn_key, shortvar, 0);
|
||||||
@ -156,14 +156,14 @@ R_API int r_anal_var_retype(RAnal *a, ut64 addr, int scope, int delta, char kind
|
|||||||
}
|
}
|
||||||
sdb_set (DB, name_key, name_val, 0);
|
sdb_set (DB, name_key, name_val, 0);
|
||||||
Sdb *TDB = a->sdb_types;
|
Sdb *TDB = a->sdb_types;
|
||||||
const char* type_kind = sdb_const_get (TDB, type, 0);
|
const char *type_kind = sdb_const_get (TDB, type, 0);
|
||||||
if (type_kind && r_str_startswith (type_kind, "struct")) {
|
if (type_kind && r_str_startswith (type_kind, "struct")) {
|
||||||
char *field, *field_key, *field_type;
|
char *field, *field_key, *field_type;
|
||||||
int field_n, field_offset;
|
int field_n, field_offset;
|
||||||
char *type_key = r_str_newf ("%s.%s", type_kind, type);
|
char *type_key = r_str_newf ("%s.%s", type_kind, type);
|
||||||
for (field_n = 0;
|
for (field_n = 0;
|
||||||
(field = sdb_array_get (TDB, type_key, field_n, NULL));
|
(field = sdb_array_get (TDB, type_key, field_n, NULL));
|
||||||
field_n++) {
|
field_n++) {
|
||||||
field_key = r_str_newf ("%s.%s", type_key, field);
|
field_key = r_str_newf ("%s.%s", type_key, field);
|
||||||
field_type = sdb_array_get (TDB, field_key, 0, NULL);
|
field_type = sdb_array_get (TDB, field_key, 0, NULL);
|
||||||
field_offset = sdb_array_get_num (TDB, field_key, 1, NULL);
|
field_offset = sdb_array_get_num (TDB, field_key, 1, NULL);
|
||||||
@ -192,7 +192,7 @@ R_API int r_anal_var_delete_all(RAnal *a, ut64 addr, const char kind) {
|
|||||||
RListIter *iter;
|
RListIter *iter;
|
||||||
RList *list = r_anal_var_list (a, fcn, kind);
|
RList *list = r_anal_var_list (a, fcn, kind);
|
||||||
r_list_foreach (list, iter, v) {
|
r_list_foreach (list, iter, v) {
|
||||||
//r_anal_var_delete (a, addr, kind, v->scope, v->delta);
|
// r_anal_var_delete (a, addr, kind, v->scope, v->delta);
|
||||||
r_anal_var_delete (a, addr, kind, 1, v->delta);
|
r_anal_var_delete (a, addr, kind, 1, v->delta);
|
||||||
}
|
}
|
||||||
r_list_free (list);
|
r_list_free (list);
|
||||||
@ -202,24 +202,28 @@ R_API int r_anal_var_delete_all(RAnal *a, ut64 addr, const char kind) {
|
|||||||
|
|
||||||
R_API int r_anal_var_delete(RAnal *a, ut64 addr, const char kind, int scope, int delta) {
|
R_API int r_anal_var_delete(RAnal *a, ut64 addr, const char kind, int scope, int delta) {
|
||||||
RAnalVar *av = r_anal_var_get (a, addr, kind, scope, delta);
|
RAnalVar *av = r_anal_var_get (a, addr, kind, scope, delta);
|
||||||
if (!av) return false;
|
if (!av) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
if (scope > 0) {
|
if (scope > 0) {
|
||||||
char *sign = "";
|
char *sign = "";
|
||||||
if (delta < 0) {
|
if (delta < 0) {
|
||||||
delta = -delta;
|
delta = -delta;
|
||||||
sign = "_";
|
sign = "_";
|
||||||
}
|
}
|
||||||
char *fcn_key = sdb_fmt (1, "fcn.0x%"PFMT64x".%c", addr, kind);
|
char *fcn_key = sdb_fmt (1, "fcn.0x%"PFMT64x ".%c", addr, kind);
|
||||||
char *var_key = sdb_fmt (2, "var.0x%"PFMT64x".%c.%d.%s%d", addr, kind, scope, sign, delta);
|
char *var_key = sdb_fmt (2, "var.0x%"PFMT64x ".%c.%d.%s%d", addr, kind, scope, sign, delta);
|
||||||
char *name_key = sdb_fmt (3, "var.0x%"PFMT64x".%d.%s", addr, scope, av->name);
|
char *name_key = sdb_fmt (3, "var.0x%"PFMT64x ".%d.%s", addr, scope, av->name);
|
||||||
char *shortvar = sdb_fmt (4, "%d.%s%d", scope, sign, delta);
|
char *shortvar = sdb_fmt (4, "%d.%s%d", scope, sign, delta);
|
||||||
sdb_array_remove (DB, fcn_key, shortvar, 0);
|
sdb_array_remove (DB, fcn_key, shortvar, 0);
|
||||||
sdb_unset (DB, var_key, 0);
|
sdb_unset (DB, var_key, 0);
|
||||||
sdb_unset (DB, name_key, 0);
|
sdb_unset (DB, name_key, 0);
|
||||||
if (*sign) delta = -delta;
|
if (*sign) {
|
||||||
|
delta = -delta;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
char *var_global = sdb_fmt (1, "var.0x%"PFMT64x, addr);
|
char *var_global = sdb_fmt (1, "var.0x%"PFMT64x, addr);
|
||||||
char *var_def = sdb_fmt (2,"%c.%s,%d,%s", kind, av->type, av->size, av->name);
|
char *var_def = sdb_fmt (2, "%c.%s,%d,%s", kind, av->type, av->size, av->name);
|
||||||
sdb_array_remove (DB, var_global, var_def, 0);
|
sdb_array_remove (DB, var_global, var_def, 0);
|
||||||
}
|
}
|
||||||
r_anal_var_free (av);
|
r_anal_var_free (av);
|
||||||
@ -232,8 +236,8 @@ R_API bool r_anal_var_delete_byname(RAnal *a, RAnalFunction *fcn, int kind, cons
|
|||||||
if (!a || !fcn) {
|
if (!a || !fcn) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
varlist = sdb_get (DB, sdb_fmt (0, "fcn.0x%"PFMT64x".%c",
|
varlist = sdb_get (DB, sdb_fmt (0, "fcn.0x%"PFMT64x ".%c",
|
||||||
fcn->addr, kind), 0);
|
fcn->addr, kind), 0);
|
||||||
if (varlist) {
|
if (varlist) {
|
||||||
char *next, *ptr = varlist;
|
char *next, *ptr = varlist;
|
||||||
if (varlist && *varlist) {
|
if (varlist && *varlist) {
|
||||||
@ -241,12 +245,12 @@ R_API bool r_anal_var_delete_byname(RAnal *a, RAnalFunction *fcn, int kind, cons
|
|||||||
char *word = sdb_anext (ptr, &next);
|
char *word = sdb_anext (ptr, &next);
|
||||||
char *sign = strstr (word, "_");
|
char *sign = strstr (word, "_");
|
||||||
const char *vardef = sdb_const_get (DB, sdb_fmt (1,
|
const char *vardef = sdb_const_get (DB, sdb_fmt (1,
|
||||||
"var.0x%"PFMT64x".%c.%s",
|
"var.0x%"PFMT64x ".%c.%s",
|
||||||
fcn->addr, kind, word), 0);
|
fcn->addr, kind, word), 0);
|
||||||
if (sign) {
|
if (sign) {
|
||||||
*sign = '-';
|
*sign = '-';
|
||||||
}
|
}
|
||||||
int delta = strlen (word) < 3 ? -1 : atoi (word + 2);
|
int delta = strlen (word) < 3? -1: atoi (word + 2);
|
||||||
if (vardef) {
|
if (vardef) {
|
||||||
const char *p = strchr (vardef, ',');
|
const char *p = strchr (vardef, ',');
|
||||||
if (p) {
|
if (p) {
|
||||||
@ -273,11 +277,11 @@ R_API bool r_anal_var_delete_byname(RAnal *a, RAnalFunction *fcn, int kind, cons
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
R_API RAnalVar *r_anal_var_get_byname(RAnal *a, RAnalFunction *fcn, const char* name) {
|
R_API RAnalVar *r_anal_var_get_byname(RAnal *a, RAnalFunction *fcn, const char *name) {
|
||||||
if (!fcn || !a || !name) {
|
if (!fcn || !a || !name) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
char *name_key = sdb_fmt (-1, "var.0x%"PFMT64x".%d.%s", fcn->addr, 1, name);
|
char *name_key = sdb_fmt (-1, "var.0x%"PFMT64x ".%d.%s", fcn->addr, 1, name);
|
||||||
const char *name_value = sdb_const_get (DB, name_key, 0);
|
const char *name_value = sdb_const_get (DB, name_key, 0);
|
||||||
if (!name_value) {
|
if (!name_value) {
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -292,7 +296,9 @@ R_API RAnalVar *r_anal_var_get_byname(RAnal *a, RAnalFunction *fcn, const char*
|
|||||||
|
|
||||||
R_API RAnalVar *r_anal_var_get(RAnal *a, ut64 addr, char kind, int scope, int delta) {
|
R_API RAnalVar *r_anal_var_get(RAnal *a, ut64 addr, char kind, int scope, int delta) {
|
||||||
RAnalVar *av;
|
RAnalVar *av;
|
||||||
struct VarType vt = { 0 };
|
struct VarType vt = {
|
||||||
|
0
|
||||||
|
};
|
||||||
char *sign = "";
|
char *sign = "";
|
||||||
RAnalFunction *fcn = r_anal_get_fcn_in (a, addr, 0);
|
RAnalFunction *fcn = r_anal_get_fcn_in (a, addr, 0);
|
||||||
if (!fcn) {
|
if (!fcn) {
|
||||||
@ -303,7 +309,7 @@ R_API RAnalVar *r_anal_var_get(RAnal *a, ut64 addr, char kind, int scope, int de
|
|||||||
sign = "_";
|
sign = "_";
|
||||||
}
|
}
|
||||||
const char *vardef = sdb_const_get (DB,
|
const char *vardef = sdb_const_get (DB,
|
||||||
sdb_fmt (-1, "var.0x%"PFMT64x".%c.%d.%s%d",
|
sdb_fmt (-1, "var.0x%"PFMT64x ".%c.%d.%s%d",
|
||||||
fcn->addr, kind, scope, sign, delta), 0);
|
fcn->addr, kind, scope, sign, delta), 0);
|
||||||
if (*sign) {
|
if (*sign) {
|
||||||
delta = -delta;
|
delta = -delta;
|
||||||
@ -322,9 +328,9 @@ R_API RAnalVar *r_anal_var_get(RAnal *a, ut64 addr, char kind, int scope, int de
|
|||||||
av->addr = fcn->addr;
|
av->addr = fcn->addr;
|
||||||
av->scope = scope;
|
av->scope = scope;
|
||||||
av->delta = delta;
|
av->delta = delta;
|
||||||
av->name = vt.name? strdup (vt.name) : strdup ("unkown_var");
|
av->name = vt.name? strdup (vt.name): strdup ("unkown_var");
|
||||||
av->size = vt.size;
|
av->size = vt.size;
|
||||||
av->type = vt.type? strdup (vt.type) : strdup ("unkown_type");
|
av->type = vt.type? strdup (vt.type): strdup ("unkown_type");
|
||||||
av->kind = kind;
|
av->kind = kind;
|
||||||
sdb_fmt_free (&vt, SDB_VARTYPE_FMT);
|
sdb_fmt_free (&vt, SDB_VARTYPE_FMT);
|
||||||
// TODO:
|
// TODO:
|
||||||
@ -352,12 +358,24 @@ R_API int r_anal_var_check_name(const char *name) {
|
|||||||
// restrict length
|
// restrict length
|
||||||
// name is not base64'd . because no specials can be contained
|
// name is not base64'd . because no specials can be contained
|
||||||
// TODO: check that new_name is valid. this is a hack
|
// TODO: check that new_name is valid. this is a hack
|
||||||
if (*name=='0' || atoi (name)>0) return 0;
|
if (*name == '0' || atoi (name) > 0) {
|
||||||
if (strchr (name, '.')) return 0;
|
return 0;
|
||||||
if (strchr (name, ',')) return 0;
|
}
|
||||||
if (strchr (name, ' ')) return 0;
|
if (strchr (name, '.')) {
|
||||||
if (strchr (name, '=')) return 0;
|
return 0;
|
||||||
if (strchr (name, '/')) return 0;
|
}
|
||||||
|
if (strchr (name, ',')) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (strchr (name, ' ')) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (strchr (name, '=')) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (strchr (name, '/')) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -371,7 +389,7 @@ R_API int r_anal_var_rename(RAnal *a, ut64 var_addr, int scope, char kind, const
|
|||||||
}
|
}
|
||||||
RAnalFunction *fcn = r_anal_get_fcn_in (a, var_addr, 0);
|
RAnalFunction *fcn = r_anal_get_fcn_in (a, var_addr, 0);
|
||||||
RAnalVar *v1 = r_anal_var_get_byname (a, fcn, new_name);
|
RAnalVar *v1 = r_anal_var_get_byname (a, fcn, new_name);
|
||||||
if(v1) {
|
if (v1) {
|
||||||
r_anal_var_free (v1);
|
r_anal_var_free (v1);
|
||||||
eprintf ("variable or arg with name `%s` already exist\n", new_name);
|
eprintf ("variable or arg with name `%s` already exist\n", new_name);
|
||||||
return false;
|
return false;
|
||||||
@ -381,20 +399,20 @@ R_API int r_anal_var_rename(RAnal *a, ut64 var_addr, int scope, char kind, const
|
|||||||
// XXX. this is pretty weak, because oldname may not exist too and error returned.
|
// XXX. this is pretty weak, because oldname may not exist too and error returned.
|
||||||
if (scope > 0) { // local
|
if (scope > 0) { // local
|
||||||
const char *sign = "";
|
const char *sign = "";
|
||||||
SETKEY ("var.0x%"PFMT64x".%d.%s", var_addr, scope, old_name);
|
SETKEY ("var.0x%"PFMT64x ".%d.%s", var_addr, scope, old_name);
|
||||||
char *name_val = sdb_get (DB, key, 0);
|
char *name_val = sdb_get (DB, key, 0);
|
||||||
char *comma = strchr (name_val, ',');
|
char *comma = strchr (name_val, ',');
|
||||||
if (comma) {
|
if (comma) {
|
||||||
delta = r_num_math (NULL, comma + 1);
|
delta = r_num_math (NULL, comma + 1);
|
||||||
sdb_unset (DB, key, 0);
|
sdb_unset (DB, key, 0);
|
||||||
SETKEY ("var.0x%"PFMT64x".%d.%s", var_addr, scope, new_name);
|
SETKEY ("var.0x%"PFMT64x ".%d.%s", var_addr, scope, new_name);
|
||||||
sdb_set (DB, key, name_val, 0);
|
sdb_set (DB, key, name_val, 0);
|
||||||
free (name_val);
|
free (name_val);
|
||||||
if (delta < 0) {
|
if (delta < 0) {
|
||||||
delta = -delta;
|
delta = -delta;
|
||||||
sign = "_";
|
sign = "_";
|
||||||
}
|
}
|
||||||
SETKEY ("var.0x%"PFMT64x".%c.%d.%s%d", var_addr, kind, scope, sign, delta);
|
SETKEY ("var.0x%"PFMT64x ".%c.%d.%s%d", var_addr, kind, scope, sign, delta);
|
||||||
sdb_array_set (DB, key, R_ANAL_VAR_SDB_NAME, new_name, 0);
|
sdb_array_set (DB, key, R_ANAL_VAR_SDB_NAME, new_name, 0);
|
||||||
}
|
}
|
||||||
} else { // global
|
} else { // global
|
||||||
@ -419,62 +437,64 @@ R_API int r_anal_var_rename(RAnal *a, ut64 var_addr, int scope, char kind, const
|
|||||||
}
|
}
|
||||||
|
|
||||||
// avr
|
// avr
|
||||||
R_API int r_anal_var_access (RAnal *a, ut64 var_addr, char kind, int scope, int delta, int xs_type, ut64 xs_addr) {
|
R_API int r_anal_var_access(RAnal *a, ut64 var_addr, char kind, int scope, int delta, int xs_type, ut64 xs_addr) {
|
||||||
const char *var_global;
|
const char *var_global;
|
||||||
const char *xs_type_str = xs_type? "writes": "reads";
|
const char *xs_type_str = xs_type? "writes": "reads";
|
||||||
// TODO: kind is not used
|
// TODO: kind is not used
|
||||||
if (scope > 0) { // local
|
if (scope > 0) { // local
|
||||||
const char *var_local = sdb_fmt (0, "var.0x%"PFMT64x".%d.%d.%s",
|
const char *var_local = sdb_fmt (0, "var.0x%"PFMT64x ".%d.%d.%s",
|
||||||
var_addr, scope, delta, xs_type_str);
|
var_addr, scope, delta, xs_type_str);
|
||||||
const char *inst_key = sdb_fmt (1, "inst.0x%"PFMT64x".vars", xs_addr);
|
const char *inst_key = sdb_fmt (1, "inst.0x%"PFMT64x ".vars", xs_addr);
|
||||||
const char *var_def = sdb_fmt (2, "0x%"PFMT64x",%c,0x%x,0x%x", var_addr,
|
const char *var_def = sdb_fmt (2, "0x%"PFMT64x ",%c,0x%x,0x%x", var_addr,
|
||||||
kind, scope, delta);
|
kind, scope, delta);
|
||||||
sdb_set (DB, inst_key, var_def, 0);
|
sdb_set (DB, inst_key, var_def, 0);
|
||||||
return sdb_array_add_num (DB, var_local, xs_addr, 0);
|
return sdb_array_add_num (DB, var_local, xs_addr, 0);
|
||||||
}
|
}
|
||||||
// global
|
// global
|
||||||
sdb_add (DB, sdb_fmt (0,"var.0x%"PFMT64x, var_addr), "a,", 0);
|
sdb_add (DB, sdb_fmt (0, "var.0x%"PFMT64x, var_addr), "a,", 0);
|
||||||
var_global = sdb_fmt (0, "var.0x%"PFMT64x".%s", var_addr, xs_type_str);
|
var_global = sdb_fmt (0, "var.0x%"PFMT64x ".%s", var_addr, xs_type_str);
|
||||||
return sdb_array_add_num (DB, var_global, xs_addr, 0);
|
return sdb_array_add_num (DB, var_global, xs_addr, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
R_API void r_anal_var_access_clear (RAnal *a, ut64 var_addr, int scope, int delta) {
|
R_API void r_anal_var_access_clear(RAnal *a, ut64 var_addr, int scope, int delta) {
|
||||||
char key[128], key2[128];
|
char key[128], key2[128];
|
||||||
if (scope>0) { // local arg or var
|
if (scope > 0) { // local arg or var
|
||||||
SETKEY ("var.0x%"PFMT64x".%d.%d.%s", var_addr, scope, delta, "writes");
|
SETKEY ("var.0x%"PFMT64x ".%d.%d.%s", var_addr, scope, delta, "writes");
|
||||||
SETKEY2 ("var.0x%"PFMT64x".%d.%d.%s", var_addr, scope, delta, "reads");
|
SETKEY2 ("var.0x%"PFMT64x ".%d.%d.%s", var_addr, scope, delta, "reads");
|
||||||
} else { // global
|
} else { // global
|
||||||
SETKEY ("var.0x%"PFMT64x".%s", var_addr, "writes");
|
SETKEY ("var.0x%"PFMT64x ".%s", var_addr, "writes");
|
||||||
SETKEY2 ("var.0x%"PFMT64x".%s", var_addr, "reads");
|
SETKEY2 ("var.0x%"PFMT64x ".%s", var_addr, "reads");
|
||||||
}
|
}
|
||||||
sdb_unset (DB, key, 0);
|
sdb_unset (DB, key, 0);
|
||||||
sdb_unset (DB, key2, 0);
|
sdb_unset (DB, key2, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
R_API int r_anal_fcn_var_del_bydelta (RAnal *a, ut64 fna, const char kind, int scope, ut32 delta) {
|
R_API int r_anal_fcn_var_del_bydelta(RAnal *a, ut64 fna, const char kind, int scope, ut32 delta) {
|
||||||
int idx;
|
int idx;
|
||||||
char key[128], val[128], *v;
|
char key[128], val[128], *v;
|
||||||
SETKEY("fcn.0x%08"PFMT64x".%c", fna, kind);
|
SETKEY ("fcn.0x%08"PFMT64x ".%c", fna, kind);
|
||||||
v = sdb_itoa (delta, val, 10);
|
v = sdb_itoa (delta, val, 10);
|
||||||
idx = sdb_array_indexof (DB, key, v, 0);
|
idx = sdb_array_indexof (DB, key, v, 0);
|
||||||
if (idx != -1) {
|
if (idx != -1) {
|
||||||
sdb_array_delete (DB, key, idx, 0);
|
sdb_array_delete (DB, key, idx, 0);
|
||||||
SETKEY ("fcn.0x%08"PFMT64x".%c.%d", fna, kind, delta);
|
SETKEY ("fcn.0x%08"PFMT64x ".%c.%d", fna, kind, delta);
|
||||||
sdb_unset (DB, key, 0);
|
sdb_unset (DB, key, 0);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
R_API int r_anal_var_count(RAnal *a, RAnalFunction *fcn, int kind, int type) {
|
R_API int r_anal_var_count(RAnal *a, RAnalFunction *fcn, int kind, int type) {
|
||||||
//local: type = 0
|
// local: type = 0
|
||||||
//arg: type = 1
|
// arg: type = 1
|
||||||
RList *list = r_anal_var_list (a, fcn, kind);
|
RList *list = r_anal_var_list (a, fcn, kind);
|
||||||
RAnalVar *var;
|
RAnalVar *var;
|
||||||
RListIter *iter;
|
RListIter *iter;
|
||||||
int count[2] = {0};
|
int count[2] = {
|
||||||
|
0
|
||||||
|
};
|
||||||
r_list_foreach (list, iter, var) {
|
r_list_foreach (list, iter, var) {
|
||||||
if (kind == R_ANAL_VAR_KIND_REG) {
|
if (kind == R_ANAL_VAR_KIND_REG) {
|
||||||
count[1] ++;
|
count[1]++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
count[(kind == R_ANAL_VAR_KIND_BPV && var->delta > 0) || (kind == R_ANAL_VAR_KIND_SPV && var->delta > fcn->maxstack)]++;
|
count[(kind == R_ANAL_VAR_KIND_BPV && var->delta > 0) || (kind == R_ANAL_VAR_KIND_SPV && var->delta > fcn->maxstack)]++;
|
||||||
@ -483,7 +503,7 @@ R_API int r_anal_var_count(RAnal *a, RAnalFunction *fcn, int kind, int type) {
|
|||||||
return count[type];
|
return count[type];
|
||||||
}
|
}
|
||||||
|
|
||||||
static void var_add_structure_fields_to_list(RAnal *a, RAnalVar *av, const char* base_name, int delta, RList *list) {
|
static void var_add_structure_fields_to_list(RAnal *a, RAnalVar *av, const char *base_name, int delta, RList *list) {
|
||||||
/* ATTENTION: av->name might be freed and reassigned */
|
/* ATTENTION: av->name might be freed and reassigned */
|
||||||
Sdb *TDB = a->sdb_types;
|
Sdb *TDB = a->sdb_types;
|
||||||
const char *type_kind = sdb_const_get (TDB, av->type, 0);
|
const char *type_kind = sdb_const_get (TDB, av->type, 0);
|
||||||
@ -492,13 +512,13 @@ static void var_add_structure_fields_to_list(RAnal *a, RAnalVar *av, const char*
|
|||||||
int field_n, field_offset, field_count, field_size;
|
int field_n, field_offset, field_count, field_size;
|
||||||
char *type_key = r_str_newf ("%s.%s", type_kind, av->type);
|
char *type_key = r_str_newf ("%s.%s", type_kind, av->type);
|
||||||
for (field_n = 0;
|
for (field_n = 0;
|
||||||
(field_name = sdb_array_get (TDB, type_key, field_n, NULL));
|
(field_name = sdb_array_get (TDB, type_key, field_n, NULL));
|
||||||
field_n++) {
|
field_n++) {
|
||||||
field_key = r_str_newf ("%s.%s", type_key, field_name);
|
field_key = r_str_newf ("%s.%s", type_key, field_name);
|
||||||
field_type = sdb_array_get (TDB, field_key, 0, NULL);
|
field_type = sdb_array_get (TDB, field_key, 0, NULL);
|
||||||
field_offset = sdb_array_get_num (TDB, field_key, 1, NULL);
|
field_offset = sdb_array_get_num (TDB, field_key, 1, NULL);
|
||||||
field_count = sdb_array_get_num (TDB, field_key, 2, NULL);
|
field_count = sdb_array_get_num (TDB, field_key, 2, NULL);
|
||||||
field_size = r_anal_type_get_size (a, field_type) * (field_count ? field_count : 1);
|
field_size = r_anal_type_get_size (a, field_type) * (field_count? field_count: 1);
|
||||||
new_name = r_str_newf ( "%s.%s", base_name, field_name);
|
new_name = r_str_newf ( "%s.%s", base_name, field_name);
|
||||||
if (field_offset == 0) {
|
if (field_offset == 0) {
|
||||||
free (av->name);
|
free (av->name);
|
||||||
@ -531,20 +551,22 @@ static RList *var_generate_list(RAnal *a, RAnalFunction *fcn, int kind, bool dyn
|
|||||||
if (!a || !fcn) {
|
if (!a || !fcn) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
list = r_list_new ();
|
list = r_list_newf ((RListFree) r_anal_var_free);
|
||||||
if (kind < 1) {
|
if (kind < 1) {
|
||||||
kind = R_ANAL_VAR_KIND_BPV; // by default show vars
|
kind = R_ANAL_VAR_KIND_BPV; // by default show vars
|
||||||
}
|
}
|
||||||
varlist = sdb_get (DB, sdb_fmt (0, "fcn.0x%"PFMT64x".%c", fcn->addr, kind), 0);
|
varlist = sdb_get (DB, sdb_fmt (0, "fcn.0x%"PFMT64x ".%c", fcn->addr, kind), 0);
|
||||||
if (varlist) {
|
if (varlist) {
|
||||||
char *next, *ptr = varlist;
|
char *next, *ptr = varlist;
|
||||||
if (varlist && *varlist) {
|
if (varlist && *varlist) {
|
||||||
do {
|
do {
|
||||||
struct VarType vt = {0};
|
struct VarType vt = {
|
||||||
|
0
|
||||||
|
};
|
||||||
char *word = sdb_anext (ptr, &next);
|
char *word = sdb_anext (ptr, &next);
|
||||||
const char *vardef = sdb_const_get (DB, sdb_fmt (1,
|
const char *vardef = sdb_const_get (DB, sdb_fmt (1,
|
||||||
"var.0x%"PFMT64x".%c.%s",
|
"var.0x%"PFMT64x ".%c.%s",
|
||||||
fcn->addr, kind, word), 0);
|
fcn->addr, kind, word), 0);
|
||||||
if (word[2] == '_') {
|
if (word[2] == '_') {
|
||||||
word[2] = '-';
|
word[2] = '-';
|
||||||
}
|
}
|
||||||
@ -559,9 +581,9 @@ static RList *var_generate_list(RAnal *a, RAnalFunction *fcn, int kind, bool dyn
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (!vt.name || !vt.type) {
|
if (!vt.name || !vt.type) {
|
||||||
//This should be properly fixed
|
// This should be properly fixed
|
||||||
eprintf ("Warning null var in fcn.0x%"PFMT64x".%c.%s\n",
|
eprintf ("Warning null var in fcn.0x%"PFMT64x ".%c.%s\n",
|
||||||
fcn->addr, kind, word);
|
fcn->addr, kind, word);
|
||||||
free (av);
|
free (av);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -583,7 +605,19 @@ static RList *var_generate_list(RAnal *a, RAnalFunction *fcn, int kind, bool dyn
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
free (varlist);
|
free (varlist);
|
||||||
list->free = (RListFree)r_anal_var_free;
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
R_API RList *r_anal_var_all_list(RAnal *anal, RAnalFunction *fcn) {
|
||||||
|
// r_anal_var_list if there are not vars with that kind returns a list with
|
||||||
|
// zero element
|
||||||
|
RList *list = r_anal_var_list (anal, fcn, R_ANAL_VAR_KIND_ARG);
|
||||||
|
if (!list) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
r_list_join (list, r_anal_var_list (anal, fcn, R_ANAL_VAR_KIND_REG));
|
||||||
|
r_list_join (list, r_anal_var_list (anal, fcn, R_ANAL_VAR_KIND_BPV));
|
||||||
|
r_list_join (list, r_anal_var_list (anal, fcn, R_ANAL_VAR_KIND_SPV));
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -595,17 +629,17 @@ R_API RList *r_anal_var_list_dynamic(RAnal *a, RAnalFunction *fcn, int kind) {
|
|||||||
return var_generate_list (a, fcn, kind, true);
|
return var_generate_list (a, fcn, kind, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int var_comparator (const RAnalVar *a, const RAnalVar *b){
|
static int var_comparator(const RAnalVar *a, const RAnalVar *b){
|
||||||
//avoid NULL dereference
|
// avoid NULL dereference
|
||||||
return (a && b) ? a->delta > b->delta : false;
|
return (a && b)? a->delta > b->delta: false;
|
||||||
}
|
}
|
||||||
|
|
||||||
R_API void r_anal_var_list_show(RAnal *anal, RAnalFunction *fcn, int kind, int mode) {
|
R_API void r_anal_var_list_show(RAnal *anal, RAnalFunction *fcn, int kind, int mode) {
|
||||||
RList *list = r_anal_var_list (anal, fcn, kind);
|
RList *list = r_anal_var_list (anal, fcn, kind);
|
||||||
r_list_sort (list, (RListComparator)var_comparator);
|
r_list_sort (list, (RListComparator) var_comparator);
|
||||||
RAnalVar *var;
|
RAnalVar *var;
|
||||||
RListIter *iter;
|
RListIter *iter;
|
||||||
if (mode=='j') {
|
if (mode == 'j') {
|
||||||
anal->cb_printf ("[");
|
anal->cb_printf ("[");
|
||||||
}
|
}
|
||||||
r_list_foreach (list, iter, var) {
|
r_list_foreach (list, iter, var) {
|
||||||
@ -615,17 +649,17 @@ R_API void r_anal_var_list_show(RAnal *anal, RAnalFunction *fcn, int kind, int m
|
|||||||
switch (mode) {
|
switch (mode) {
|
||||||
case '*':
|
case '*':
|
||||||
// we cant express all type info here :(
|
// we cant express all type info here :(
|
||||||
if (kind == R_ANAL_VAR_KIND_REG) { //registers
|
if (kind == R_ANAL_VAR_KIND_REG) { // registers
|
||||||
RRegItem *i = r_reg_index_get (anal->reg, var->delta);
|
RRegItem *i = r_reg_index_get (anal->reg, var->delta);
|
||||||
if (!i) {
|
if (!i) {
|
||||||
eprintf ("Register not found");
|
eprintf ("Register not found");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
anal->cb_printf ("afv%c %s %s %s @ 0x%"PFMT64x"\n",
|
anal->cb_printf ("afv%c %s %s %s @ 0x%"PFMT64x "\n",
|
||||||
kind, i->name, var->name, var->type, fcn->addr);
|
kind, i->name, var->name, var->type, fcn->addr);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
anal->cb_printf ("afv%c %d %s %s @ 0x%"PFMT64x"\n",
|
anal->cb_printf ("afv%c %d %s %s @ 0x%"PFMT64x "\n",
|
||||||
kind, var->delta, var->name, var->type,
|
kind, var->delta, var->name, var->type,
|
||||||
fcn->addr);
|
fcn->addr);
|
||||||
}
|
}
|
||||||
@ -636,18 +670,18 @@ R_API void r_anal_var_list_show(RAnal *anal, RAnalFunction *fcn, int kind, int m
|
|||||||
if (var->delta > 0) {
|
if (var->delta > 0) {
|
||||||
anal->cb_printf ("{\"name\":\"%s\","
|
anal->cb_printf ("{\"name\":\"%s\","
|
||||||
"\"kind\":\"arg\",\"type\":\"%s\",\"ref\":"
|
"\"kind\":\"arg\",\"type\":\"%s\",\"ref\":"
|
||||||
"{\"base\":\"%s\", \"offset\":%"PFMT64d"}}",
|
"{\"base\":\"%s\", \"offset\":%"PFMT64d "}}",
|
||||||
var->name, var->type,anal->reg->name[R_REG_NAME_BP],
|
var->name, var->type, anal->reg->name[R_REG_NAME_BP],
|
||||||
var->delta);
|
var->delta);
|
||||||
} else {
|
} else {
|
||||||
anal->cb_printf ("{\"name\":\"%s\","
|
anal->cb_printf ("{\"name\":\"%s\","
|
||||||
"\"kind\":\"var\",\"type\":\"%s\",\"ref\":"
|
"\"kind\":\"var\",\"type\":\"%s\",\"ref\":"
|
||||||
"{\"base\":\"%s\", \"offset\":-%"PFMT64d"}}",
|
"{\"base\":\"%s\", \"offset\":-%"PFMT64d "}}",
|
||||||
var->name, var->type,anal->reg->name[R_REG_NAME_BP],
|
var->name, var->type, anal->reg->name[R_REG_NAME_BP],
|
||||||
-var->delta);
|
-var->delta);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case R_ANAL_VAR_KIND_REG:{
|
case R_ANAL_VAR_KIND_REG: {
|
||||||
RRegItem *i = r_reg_index_get (anal->reg, var->delta);
|
RRegItem *i = r_reg_index_get (anal->reg, var->delta);
|
||||||
if (!i) {
|
if (!i) {
|
||||||
eprintf ("Register not found");
|
eprintf ("Register not found");
|
||||||
@ -656,25 +690,25 @@ R_API void r_anal_var_list_show(RAnal *anal, RAnalFunction *fcn, int kind, int m
|
|||||||
anal->cb_printf ("{\"name\":\"%s\","
|
anal->cb_printf ("{\"name\":\"%s\","
|
||||||
"\"kind\":\"reg\",\"type\":\"%s\",\"ref\":\"%s\"}",
|
"\"kind\":\"reg\",\"type\":\"%s\",\"ref\":\"%s\"}",
|
||||||
var->name, var->type, i->name, anal->reg->name[var->delta]);
|
var->name, var->type, i->name, anal->reg->name[var->delta]);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case R_ANAL_VAR_KIND_SPV:
|
case R_ANAL_VAR_KIND_SPV:
|
||||||
if (var->delta < fcn->maxstack) {
|
if (var->delta < fcn->maxstack) {
|
||||||
anal->cb_printf ("{\"name\":\"%s\","
|
anal->cb_printf ("{\"name\":\"%s\","
|
||||||
"\"kind\":\"arg\",\"type\":\"%s\",\"ref\":"
|
"\"kind\":\"arg\",\"type\":\"%s\",\"ref\":"
|
||||||
"{\"base\":\"%s\", \"offset\":%"PFMT64d"}}",
|
"{\"base\":\"%s\", \"offset\":%"PFMT64d "}}",
|
||||||
var->name, var->type,anal->reg->name[R_REG_NAME_SP],
|
var->name, var->type, anal->reg->name[R_REG_NAME_SP],
|
||||||
var->delta);
|
var->delta);
|
||||||
} else {
|
} else {
|
||||||
anal->cb_printf ("{\"name\":\"%s\","
|
anal->cb_printf ("{\"name\":\"%s\","
|
||||||
"\"kind\":\"var\",\"type\":\"%s\",\"ref\":"
|
"\"kind\":\"var\",\"type\":\"%s\",\"ref\":"
|
||||||
"{\"base\":\"%s\", \"offset\":-%"PFMT64d"}}",
|
"{\"base\":\"%s\", \"offset\":-%"PFMT64d "}}",
|
||||||
var->name, var->type,anal->reg->name[R_REG_NAME_SP],
|
var->name, var->type, anal->reg->name[R_REG_NAME_SP],
|
||||||
var->delta);
|
var->delta);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (iter->n) {
|
if (iter->n) {
|
||||||
anal->cb_printf (",");
|
anal->cb_printf (",");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -696,13 +730,13 @@ R_API void r_anal_var_list_show(RAnal *anal, RAnalFunction *fcn, int kind, int m
|
|||||||
case R_ANAL_VAR_KIND_REG: {
|
case R_ANAL_VAR_KIND_REG: {
|
||||||
RRegItem *i = r_reg_index_get (anal->reg, var->delta);
|
RRegItem *i = r_reg_index_get (anal->reg, var->delta);
|
||||||
if (!i) {
|
if (!i) {
|
||||||
eprintf("Register not found");
|
eprintf ("Register not found");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
anal->cb_printf ("reg %s %s @ %s\n",
|
anal->cb_printf ("reg %s %s @ %s\n",
|
||||||
var->type, var->name, i->name);
|
var->type, var->name, i->name);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case R_ANAL_VAR_KIND_SPV:
|
case R_ANAL_VAR_KIND_SPV:
|
||||||
if (var->delta < fcn->maxstack) {
|
if (var->delta < fcn->maxstack) {
|
||||||
|
@ -291,7 +291,6 @@ typedef struct r_anal_type_function_t {
|
|||||||
RList *fcn_locs; //sorted list of a function *.loc refs
|
RList *fcn_locs; //sorted list of a function *.loc refs
|
||||||
//RList *locals; // list of local labels -> moved to anal->sdb_fcns
|
//RList *locals; // list of local labels -> moved to anal->sdb_fcns
|
||||||
RList *bbs;
|
RList *bbs;
|
||||||
RList *vars;
|
|
||||||
#if FCN_OLD
|
#if FCN_OLD
|
||||||
RList *refs;
|
RList *refs;
|
||||||
RList *xrefs;
|
RList *xrefs;
|
||||||
@ -1433,6 +1432,7 @@ R_API RList *r_anal_reflines_fcn_get(struct r_anal_t *anal, RAnalFunction *fcn,
|
|||||||
/* TODO move to r_core */
|
/* TODO move to r_core */
|
||||||
R_API void r_anal_var_list_show(RAnal *anal, RAnalFunction *fcn, int kind, int mode);
|
R_API void r_anal_var_list_show(RAnal *anal, RAnalFunction *fcn, int kind, int mode);
|
||||||
R_API RList *r_anal_var_list(RAnal *anal, RAnalFunction *fcn, int kind);
|
R_API RList *r_anal_var_list(RAnal *anal, RAnalFunction *fcn, int kind);
|
||||||
|
R_API RList *r_anal_var_all_list(RAnal *anal, RAnalFunction *fcn);
|
||||||
R_API RList *r_anal_var_list_dynamic(RAnal *anal, RAnalFunction *fcn, int kind);
|
R_API RList *r_anal_var_list_dynamic(RAnal *anal, RAnalFunction *fcn, int kind);
|
||||||
|
|
||||||
// calling conventions API
|
// calling conventions API
|
||||||
|
Loading…
Reference in New Issue
Block a user