Make .a2f work (fix afbb and such)

This commit is contained in:
pancake 2014-11-13 11:17:43 +01:00
parent ee1c3b4282
commit 07568e4f4c
4 changed files with 93 additions and 16 deletions

View File

@ -521,6 +521,7 @@ fcn.<offset>.bbs
R_API int r_anal_fcn_add(RAnal *a, ut64 addr, ut64 size, const char *name, int type, RAnalDiff *diff) { R_API int r_anal_fcn_add(RAnal *a, ut64 addr, ut64 size, const char *name, int type, RAnalDiff *diff) {
int append = 0; int append = 0;
RAnalFunction *fcn; RAnalFunction *fcn;
//eprintf ("f+ 0x%llx %d (%s)\n", addr, size, name);
if (size<1) if (size<1)
return R_FALSE; return R_FALSE;
fcn = r_anal_get_fcn_in (a, addr, R_ANAL_FCN_TYPE_ROOT); fcn = r_anal_get_fcn_in (a, addr, R_ANAL_FCN_TYPE_ROOT);

View File

@ -329,7 +329,8 @@ static void r_core_anal_bytes (RCore *core, const ut8 *buf, int len, int nops, i
} }
static int anal_fcn_add_bb (RCore *core, const char *input) { static int anal_fcn_add_bb (RCore *core, const char *input) {
char *ptr = strdup(input); // fcn_addr bb_addr bb_size [jump] [fail]
char *ptr;
const char *ptr2 = NULL; const char *ptr2 = NULL;
ut64 fcnaddr = -1LL, addr = -1LL; ut64 fcnaddr = -1LL, addr = -1LL;
ut64 size = 0LL; ut64 size = 0LL;
@ -339,6 +340,9 @@ static int anal_fcn_add_bb (RCore *core, const char *input) {
RAnalFunction *fcn = NULL; RAnalFunction *fcn = NULL;
RAnalDiff *diff = NULL; RAnalDiff *diff = NULL;
while (*input==' ') input++;
ptr = strdup (input);
switch (r_str_word_set0 (ptr)) { switch (r_str_word_set0 (ptr)) {
case 7: case 7:
ptr2 = r_str_word_get0 (ptr, 6); ptr2 = r_str_word_get0 (ptr, 6);
@ -380,6 +384,7 @@ static int anal_fcn_add_bb (RCore *core, const char *input) {
free (ptr); free (ptr);
return R_TRUE; return R_TRUE;
} }
static int setFunctionName(RCore *core, ut64 off, const char *name) { static int setFunctionName(RCore *core, ut64 off, const char *name) {
RAnalFunction *fcn = r_anal_get_fcn_in (core->anal, off, RAnalFunction *fcn = r_anal_get_fcn_in (core->anal, off,
R_ANAL_FCN_TYPE_FCN|R_ANAL_FCN_TYPE_SYM|R_ANAL_FCN_TYPE_LOC); R_ANAL_FCN_TYPE_FCN|R_ANAL_FCN_TYPE_SYM|R_ANAL_FCN_TYPE_LOC);
@ -546,15 +551,24 @@ static int cmd_anal_fcn(RCore *core, const char *input) {
} }
break; break;
case 'b': // "afb" case 'b': // "afb"
if (input[2] == 'b') { switch (input[2]) {
anal_fcn_add_bb (core, input+3); case 'b': // "afbb"
} else { case '+': // "afb+"
anal_fcn_add_bb (core, input+3);
break;
case '?':
eprintf ("Usage: afb+ or afbb or afb\n");
break;
default:
{
RAnalFunction *fcn = r_anal_get_fcn_in (core->anal, core->offset, RAnalFunction *fcn = r_anal_get_fcn_in (core->anal, core->offset,
R_ANAL_FCN_TYPE_FCN|R_ANAL_FCN_TYPE_SYM); R_ANAL_FCN_TYPE_FCN|R_ANAL_FCN_TYPE_SYM);
if (fcn) fcn->bits = atoi (input+3); if (fcn) fcn->bits = atoi (input+3);
else eprintf ("Cannot find function to set bits\n"); else eprintf ("Cannot find function to set bits\n");
} }
break; break;
}
break;
case 'n': // "afn" case 'n': // "afn"
if (input[2]=='a') { // afna autoname if (input[2]=='a') { // afna autoname
char *name = r_core_anal_fcn_autoname (core, core->offset); char *name = r_core_anal_fcn_autoname (core, core->offset);
@ -703,7 +717,7 @@ static int cmd_anal_fcn(RCore *core, const char *input) {
"afa", "[?] [idx] [type] [name]", "add function argument", "afa", "[?] [idx] [type] [name]", "add function argument",
"af[aAv?]", "[arg]", "manipulate args, fastargs and variables in function", "af[aAv?]", "[arg]", "manipulate args, fastargs and variables in function",
"afb", " 16", "set current function as thumb", "afb", " 16", "set current function as thumb",
"afbb", " fcnaddr addr size name [type] [diff]", "add bb to function @ fcnaddr", "afbb", " fcn_at bbat bbsz [jump] [fail] ([type] ([diff]))", "add bb to function @ fcnaddr",
"afc", "@[addr]", "calculate the Cyclomatic Complexity (starting at addr)", "afc", "@[addr]", "calculate the Cyclomatic Complexity (starting at addr)",
"afC[a]", " type @[addr]", "set calling convention for function (afC?=list cc types)", "afC[a]", " type @[addr]", "set calling convention for function (afC?=list cc types)",
"aff", "", "re-adjust function boundaries to fit", "aff", "", "re-adjust function boundaries to fit",

View File

@ -1460,7 +1460,7 @@ static void handle_comment_align (RCore *core, RDisasmState *ds) {
if (ll) { if (ll) {
int cols = r_cons_get_size (NULL); int cols = r_cons_get_size (NULL);
int ansilen = r_str_ansi_len (ll); int ansilen = r_str_ansi_len (ll);
if (cmtcol+10>=cols) { if (cmtcol+16>=cols) {
#if 0 #if 0
r_cons_newline (); r_cons_newline ();
r_cons_memset (' ', 10); r_cons_memset (' ', 10);

View File

@ -27,6 +27,27 @@ static ut64 sdb_array_get_closer_num (Sdb *db, const char *key, ut64 addr) {
} }
#define Fbb(x) sdb_fmt(0,"bb.%"PFMT64x,x) #define Fbb(x) sdb_fmt(0,"bb.%"PFMT64x,x)
#define FbbTo(x) sdb_fmt(0,"bb.%"PFMT64x".to",x) #define FbbTo(x) sdb_fmt(0,"bb.%"PFMT64x".to",x)
#define Fmin(x) "min"
#define Fmax(x) "max"
// TODO: move into sdb, and use CAS
static int sdb_num_min(Sdb *db, const char *k, ut64 n) {
ut64 a = sdb_num_get (db, k, NULL);
if (n<a || !a) {
sdb_num_set (db, k, n, 0);
return 1;
}
return 0;
}
static int sdb_num_max(Sdb *db, const char *k, ut64 n) {
ut64 a = sdb_num_get (db, k, NULL);
if (n>a || !a) {
sdb_num_set (db, k, n, 0);
return 1;
}
return 0;
}
static int bbAdd (Sdb *db, ut64 from, ut64 to, ut64 jump, ut64 fail) { static int bbAdd (Sdb *db, ut64 from, ut64 to, ut64 jump, ut64 fail) {
ut64 last, addr = sdb_array_get_closer_num (db, "bbs", from); ut64 last, addr = sdb_array_get_closer_num (db, "bbs", from);
@ -54,6 +75,8 @@ eprintf ("ADD NEW BB %llx\n", from);
sdb_array_set_num (db, FbbTo(from), 0, jump, 0); sdb_array_set_num (db, FbbTo(from), 0, jump, 0);
if (fail != UT64_MAX) if (fail != UT64_MAX)
sdb_array_set_num (db, FbbTo(from), 1, fail, 0); sdb_array_set_num (db, FbbTo(from), 1, fail, 0);
sdb_num_min (db, "min", from);
sdb_num_max (db, "max", to);
} }
return 0; return 0;
} }
@ -78,7 +101,7 @@ int analyzeIterative (RCore *core, Sdb *db, ut64 addr) {
for (;;) { for (;;) {
op = r_core_anal_op (core, addr + cur); op = r_core_anal_op (core, addr + cur);
if (!op) { if (!op) {
eprintf ("Cannot analyze opcode at %d\n", addr+cur); eprintf ("Cannot analyze opcode at %"PFMT64d"\n", addr+cur);
return R_FALSE; return R_FALSE;
} }
eprintf ("0x%08"PFMT64x" %s\n", addr + cur, op->mnemonic); eprintf ("0x%08"PFMT64x" %s\n", addr + cur, op->mnemonic);
@ -205,13 +228,49 @@ static int analyzeFunction (RCore *core, ut64 addr) {
eprintf ("ujmps: %s\n", sdb_const_get (db, "ujmps", NULL)); eprintf ("ujmps: %s\n", sdb_const_get (db, "ujmps", NULL));
eprintf ("rets: %s\n", sdb_const_get (db, "rets", NULL)); eprintf ("rets: %s\n", sdb_const_get (db, "rets", NULL));
eprintf ("bbs: %s\n", sdb_const_get (db, "bbs", NULL)); eprintf ("bbs: %s\n", sdb_const_get (db, "bbs", NULL));
// fcnfit to get fcn size
{ {
#if 1
ut64 min = sdb_num_get (db, Fmin (addr), NULL);
ut64 max = sdb_num_get (db, Fmax (addr), NULL);
#else
ut64 min, max; ut64 min, max;
char *c, *bbs = sdb_get (db, "bbs", NULL); char *c, *bbs = sdb_get (db, "bbs", NULL);
int first = 1; int first = 1;
sdb_aforeach (c, bbs) { sdb_aforeach (c, bbs) {
ut64 addr = sdb_atoi (c); ut64 addr = sdb_atoi (c);
ut64 addr_end = sdb_num_get (db, sdb_fmt(0, "bb.%"PFMT64x, addr), NULL); ut64 addr_end = sdb_num_get (db, Fbb(addr), NULL);
if (first) {
min = addr;
max = addr_end;
first = 0;
} else {
if (addr<min)
min = addr;
if (addr_end>max)
max = addr_end;
}
sdb_aforeach_next (c);
}
free (bbs);
#endif
sdb_num_set (db, "size", max-min, 0);
}
r_cons_printf ("af+ 0x%08"PFMT64x" %d fcn2.0x%08"PFMT64x"\n",
sdb_num_get (db, "addr", NULL),
(int)sdb_num_get (db, "size", NULL),
sdb_num_get (db, "addr", NULL)
);
// list bbs
{
ut64 min, max;
char *c, *bbs = sdb_get (db, "bbs", NULL);
int first = 1;
sdb_aforeach (c, bbs) {
ut64 jump, fail;
ut64 addr = sdb_atoi (c);
ut64 addr_end = sdb_num_get (db, Fbb(addr), NULL);
if (first) { if (first) {
min = addr; min = addr;
max = addr_end; max = addr_end;
@ -224,18 +283,21 @@ static int analyzeFunction (RCore *core, ut64 addr) {
} }
// check if call destination is inside the function boundaries // check if call destination is inside the function boundaries
eprintf ("BB 0x%08"PFMT64x" - 0x%08"PFMT64x" %d\n", eprintf ("BB 0x%08"PFMT64x" - 0x%08"PFMT64x" %d\n",
addr, addr_end, addr_end-addr); addr, addr_end, (int)(addr_end-addr));
eprintf (" -> %s\n", sdb_const_get (db, FbbTo (addr), 0)); eprintf (" -> %s\n", sdb_const_get (db, FbbTo (addr), 0));
r_cons_printf ("afb+ 0x%"PFMT64x" 0x%"PFMT64x" %d",
sdb_num_get (db, "addr", NULL),
addr, (int)(addr_end-addr));
jump = sdb_array_get_num (db, FbbTo(addr), 0, NULL);
fail = sdb_array_get_num (db, FbbTo(addr), 1, NULL);
if (jump || fail)
r_cons_printf (" 0x%"PFMT64x" 0x%"PFMT64x"\n", jump, fail);
else r_cons_newline ();
sdb_aforeach_next (c); sdb_aforeach_next (c);
} }
free (bbs); free (bbs);
sdb_num_set (db, "size", max-min, 0); sdb_num_set (db, "size", max-min, 0);
} }
r_cons_printf ("af+ 0x%08"PFMT64x" %d fcn2.0x%08"PFMT64x,
sdb_num_get (db, "addr", NULL),
sdb_num_get (db, "size", NULL),
sdb_num_get (db, "addr", NULL)
);
eprintf ("size: %s\n", sdb_const_get (db, "size", NULL)); eprintf ("size: %s\n", sdb_const_get (db, "size", NULL));
sdb_free (db); sdb_free (db);
return R_TRUE; return R_TRUE;