Add 'afC' for calling convention changes in function definitions

This commit is contained in:
pancake 2014-10-14 17:09:42 +02:00
parent 0b9abbd87a
commit 676ed9e861
5 changed files with 92 additions and 2 deletions

View File

@ -21,6 +21,42 @@ R_API void r_anal_cc_init (RAnalCC *cc) {
memset (cc, 0, sizeof (RAnalCC));
}
R_API int r_anal_cc_str2type (const char *str) {
if (!strcmp (str, "none")) return R_ANAL_CC_TYPE_NONE;
if (!strcmp (str, "cdecl")) return R_ANAL_CC_TYPE_CDECL;
if (!strcmp (str, "stdcall")) return R_ANAL_CC_TYPE_STDCALL;
if (!strcmp (str, "fastcall")) return R_ANAL_CC_TYPE_FASTCALL;
if (!strcmp (str, "pascal")) return R_ANAL_CC_TYPE_PASCAL;
if (!strcmp (str, "winapi")) return R_ANAL_CC_TYPE_WINAPI;
if (!strcmp (str, "msfastcall")) return R_ANAL_CC_TYPE_MSFASTCALL;
if (!strcmp (str, "bofastcall")) return R_ANAL_CC_TYPE_BOFASTCALL;
if (!strcmp (str, "wafastcall")) return R_ANAL_CC_TYPE_WAFASTCALL;
if (!strcmp (str, "clarion")) return R_ANAL_CC_TYPE_CLARION;
if (!strcmp (str, "safecall")) return R_ANAL_CC_TYPE_SAFECALL;
if (!strcmp (str, "sysv")) return R_ANAL_CC_TYPE_SYSV;
if (!strcmp (str, "thiscall")) return R_ANAL_CC_TYPE_THISCALL;
return -1;
}
R_API const char *r_anal_cc_type2str(int type) {
switch (type) {
case R_ANAL_CC_TYPE_NONE: return "none";
case R_ANAL_CC_TYPE_CDECL: return "cdecl";
case R_ANAL_CC_TYPE_STDCALL: return "stdcall";
case R_ANAL_CC_TYPE_FASTCALL: return "fastcall";
case R_ANAL_CC_TYPE_PASCAL: return "pascal";
case R_ANAL_CC_TYPE_WINAPI: return "winapi";
case R_ANAL_CC_TYPE_MSFASTCALL: return "msfastcall";
case R_ANAL_CC_TYPE_BOFASTCALL: return "bofastcall";
case R_ANAL_CC_TYPE_WAFASTCALL: return "wafastcall";
case R_ANAL_CC_TYPE_CLARION: return "clarion";
case R_ANAL_CC_TYPE_SAFECALL: return "safecall";
case R_ANAL_CC_TYPE_SYSV: return "sysv";
case R_ANAL_CC_TYPE_THISCALL: return "thiscall";
}
return NULL;
}
R_API RAnalCC* r_anal_cc_new_from_string (const char *str, int type) {
// str = 0x804899 (123, 930, 0x804800)
return NULL;

View File

@ -84,6 +84,7 @@ R_API RAnalOp* r_core_anal_op(RCore *core, ut64 addr) {
// decode instruction here
{
RAsmOp asmop;
r_asm_set_pc (core->assembler, addr);
if (r_asm_disassemble (core->assembler, &asmop, buf, len)>0) {
op.mnemonic = strdup (asmop.buf_asm);
}
@ -999,6 +1000,7 @@ R_API int r_core_anal_fcn_list(RCore *core, const char *input, int rad) {
r_cons_printf ("%s{\"offset\":%"PFMT64d",\"name\":\"%s\",\"size\":%d",
count>1? ",":"", fcn->addr, fcn->name, fcn->size);
r_cons_printf (",\"cc\":%d", r_anal_fcn_cc (fcn));
r_cons_printf (",\"calltype\":\"%s\"", r_anal_cc_type2str (fcn->call));
r_cons_printf (",\"type\":\"%s\"",
fcn->type==R_ANAL_FCN_TYPE_SYM?"sym":
fcn->type==R_ANAL_FCN_TYPE_IMP?"imp":"fcn");
@ -1075,10 +1077,14 @@ R_API int r_core_anal_fcn_list(RCore *core, const char *input, int rad) {
fcn->type==R_ANAL_FCN_TYPE_IMP?'i':'f',
fcn->diff->type==R_ANAL_DIFF_TYPE_MATCH?'m':
fcn->diff->type==R_ANAL_DIFF_TYPE_UNMATCH?'u':'n');
if (fcn->call != R_ANAL_CC_TYPE_NONE)
r_cons_printf ("afC %s @ 0x%08"PFMT64x"\n",
r_anal_cc_type2str (fcn->call), fcn->addr);
fcn_list_bbs (fcn);
} else {
r_cons_printf ("#\n offset: 0x%08"PFMT64x"\n name: %s\n size: %"PFMT64d,
fcn->addr, fcn->name, (ut64)fcn->size);
r_cons_printf ("\n call-convention: %s", r_anal_cc_type2str (fcn->call));
r_cons_printf ("\n cyclomatic-complexity: %d", r_anal_fcn_cc (fcn));
r_cons_printf ("\n type: %s",
fcn->type==R_ANAL_FCN_TYPE_SYM?"sym":

View File

@ -481,6 +481,41 @@ static int cmd_anal_fcn(RCore *core, const char *input) {
} else eprintf ("Error: Cannot find function at 0x08%"PFMT64x"\n", core->offset);
}
break;
case 'C':
if (input[2]=='?') {
int i;
for (i=0; ; i++) {
const char *s = r_anal_cc_type2str (i);
if (!s) break;
r_cons_printf ("%s\n", s);
}
} else {
RAnalFunction *fcn = r_anal_get_fcn_in (core->anal, core->offset, 0);
if (fcn) {
if (input[2]=='a') {
eprintf ("TODO: analyze function to guess its calling convention\n");
} else
if (input[2]==' ') {
int type = r_anal_cc_str2type (input+3);
if (type == -1) {
eprintf ("Unknown calling convention '%s'\n", input+3);
} else {
// set calling convention for current function
fcn->call = type;
}
} else {
const char *type = r_anal_cc_type2str (fcn->call);
if (type) {
r_cons_printf ("%s\n", type);
} else {
eprintf ("Unknown calling convention\n");
}
}
} else {
eprintf ("Cannot find function\n");
}
}
break;
case 'b':
if (input[2] == 'b') {
anal_fcn_add_bb (core, input+3);
@ -658,6 +693,7 @@ static int cmd_anal_fcn(RCore *core, const char *input) {
"afa", "[?] [idx] [type] [name]", "add function argument",
"af[aAv?]", "[arg]", "manipulate args, fastargs and variables in function",
"afc", "@[addr]", "calculate the Cyclomatic Complexity (starting at addr)",
"afC[a]", " type @[addr]", "set calling convention for function (afC?=list cc types)",
"af*", "", "output radare commands",
NULL};
r_core_cmd_help (core, help_msg);

View File

@ -856,9 +856,8 @@ static int cmd_search(void *data, const char *input) {
char *res;
ut64 nres, addr = from;
r_cons_break (NULL, NULL);
if (!core->anal->esil) {
if (!core->anal->esil)
core->anal->esil = r_anal_esil_new ();
}
r_anal_esil_setup (core->anal->esil, core->anal, 1, 0);
r_anal_esil_stack_free (core->anal->esil);
core->anal->esil->debug = 0;
@ -868,6 +867,17 @@ static int cmd_search(void *data, const char *input) {
continue;
}
}
#if 0
// we need a way to retrieve info from a speicif address, and make it accessible from the esil search
// maybe we can just do it like this: 0x804840,AddressType,3,&, ... bitmask
// executable = 1
// writable = 2
// inprogram
// instack
// inlibrary
// inheap
r_anal_esil_set_op (core->anal->esil, "AddressInfo", esil_search_address_info);
#endif
if (r_cons_singleton ()->breaked) {
eprintf ("Breaked at 0x%08"PFMT64x"\n", addr);
break;

View File

@ -1129,6 +1129,8 @@ R_API void r_anal_cc_free (RAnalCC* cc);
R_API void r_anal_cc_reset (RAnalCC *cc);
R_API char *r_anal_cc_to_string (RAnal *anal, RAnalCC* cc);
R_API boolt r_anal_cc_update (RAnal *anal, RAnalCC *cc, RAnalOp *op);
R_API const char *r_anal_cc_type2str(int type);
R_API int r_anal_cc_str2type (const char *str);
//R_API int r_anal_cc_register (RAnal *anal, RAnalCC *cc);
//R_API int r_anal_cc_unregister (RAnal *anal, RAnalCC *cc);