mirror of
https://github.com/radareorg/radare2.git
synced 2025-01-23 14:28:07 +00:00
Make zignatures database more flexible, add realname, comments and xrefs ##sign (#13655)
Use more r_return and a lot of code cleanup, but still not finished, more PRs to come
This commit is contained in:
parent
44eb2e26e4
commit
b67a28bd3a
734
libr/anal/sign.c
734
libr/anal/sign.c
File diff suppressed because it is too large
Load Diff
@ -1,4 +1,4 @@
|
||||
/* radare - LGPL - Copyright 2009-2018 - pancake, nibble */
|
||||
/* radare - LGPL - Copyright 2009-2019 - pancake, nibble */
|
||||
|
||||
#include <r_core.h>
|
||||
#include <r_anal.h>
|
||||
@ -11,8 +11,11 @@
|
||||
static const char *help_msg_z[] = {
|
||||
"Usage:", "z[*j-aof/cs] [args] ", "# Manage zignatures",
|
||||
"z", "", "show zignatures",
|
||||
"z.", "", "find matching zignatures in current offset",
|
||||
"z*", "", "show zignatures in radare format",
|
||||
"zq", "", "show zignatures in quiet mode",
|
||||
"zj", "", "show zignatures in json format",
|
||||
"zk", "", "show zignatures in sdb format",
|
||||
"z-", "zignature", "delete zignature",
|
||||
"z-", "*", "delete all zignatures",
|
||||
"za", "[?]", "add zignature",
|
||||
@ -20,7 +23,7 @@ static const char *help_msg_z[] = {
|
||||
"zo", "[?]", "manage zignature files",
|
||||
"zf", "[?]", "manage FLIRT signatures",
|
||||
"z/", "[?]", "search zignatures",
|
||||
"zc", "", "check zignatures at address",
|
||||
"zc", " [zspace]", "compare current zignspace zignatures with others",
|
||||
"zs", "[?]", "manage zignspaces",
|
||||
"zi", "", "show zignatures matching information",
|
||||
NULL
|
||||
@ -82,17 +85,12 @@ static void cmd_zign_init(RCore *core) {
|
||||
}
|
||||
|
||||
static bool addFcnHash(RCore *core, RAnalFunction *fcn, const char *name) {
|
||||
if (!core || !fcn || !name) {
|
||||
return false;
|
||||
}
|
||||
|
||||
r_return_val_if_fail (core && fcn && name, false);
|
||||
return r_sign_add_bb_hash (core->anal, fcn, name);
|
||||
}
|
||||
|
||||
static bool addFcnBytes(RCore *core, RAnalFunction *fcn, const char *name) {
|
||||
if (!core || !fcn || !name) {
|
||||
return false;
|
||||
}
|
||||
r_return_val_if_fail (core && fcn && name, false);
|
||||
int maxsz = r_config_get_i (core->config, "zign.maxsz");
|
||||
int fcnlen = r_anal_fcn_realsize (fcn);
|
||||
int len = R_MIN (core->io->addrbytes * fcnlen, maxsz);
|
||||
@ -103,16 +101,13 @@ static bool addFcnBytes(RCore *core, RAnalFunction *fcn, const char *name) {
|
||||
}
|
||||
|
||||
bool retval = false;
|
||||
if (!r_io_is_valid_offset (core->io, fcn->addr, 0)) {
|
||||
if (r_io_is_valid_offset (core->io, fcn->addr, 0)) {
|
||||
(void)r_io_read_at (core->io, fcn->addr, buf, len);
|
||||
retval = r_sign_add_anal (core->anal, name, len, buf, fcn->addr);
|
||||
} else {
|
||||
eprintf ("error: cannot read at 0x%08"PFMT64x"\n", fcn->addr);
|
||||
goto out;
|
||||
}
|
||||
(void)r_io_read_at (core->io, fcn->addr, buf, len);
|
||||
retval = r_sign_add_anal (core->anal, name, len, buf, fcn->addr);
|
||||
|
||||
out:
|
||||
free (buf);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
@ -127,6 +122,16 @@ static bool addFcnGraph(RCore *core, RAnalFunction *fcn, const char *name) {
|
||||
return r_sign_add_graph (core->anal, name, graph);
|
||||
}
|
||||
|
||||
static bool addFcnXRefs(RCore *core, RAnalFunction *fcn, const char *name) {
|
||||
bool retval = false;
|
||||
RList *xrefs = r_sign_fcn_xrefs (core->anal, fcn);
|
||||
if (xrefs) {
|
||||
retval = r_sign_add_xrefs (core->anal, name, xrefs);
|
||||
r_list_free (xrefs);
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
static bool addFcnRefs(RCore *core, RAnalFunction *fcn, const char *name) {
|
||||
RList *refs = r_sign_fcn_refs (core->anal, fcn);
|
||||
if (!refs) {
|
||||
@ -147,6 +152,15 @@ static bool addFcnVars(RCore *core, RAnalFunction *fcn, const char *name) {
|
||||
return retval;
|
||||
}
|
||||
|
||||
static char *getFcnComments(RCore *core, RAnalFunction *fcn) {
|
||||
char *r = r_core_cmd_strf (core, "CCf* @ 0x%08"PFMT64x, fcn->addr);
|
||||
if (r && *r) {
|
||||
return r;
|
||||
}
|
||||
//
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void addFcnZign(RCore *core, RAnalFunction *fcn, const char *name) {
|
||||
char *zigname = NULL;
|
||||
const RSpace *curspace = r_spaces_current (&core->anal->zign_spaces);
|
||||
@ -155,16 +169,24 @@ static void addFcnZign(RCore *core, RAnalFunction *fcn, const char *name) {
|
||||
zigname = r_str_new (name);
|
||||
} else {
|
||||
if (curspace) {
|
||||
zigname = r_str_newf ("%s.", curspace->name);
|
||||
zigname = r_str_newf ("%s:", curspace->name);
|
||||
}
|
||||
zigname = r_str_appendf (zigname, "%s", fcn->name);
|
||||
}
|
||||
|
||||
addFcnGraph (core, fcn, zigname);
|
||||
addFcnBytes (core, fcn, zigname);
|
||||
addFcnXRefs (core, fcn, zigname);
|
||||
addFcnRefs (core, fcn, zigname);
|
||||
addFcnVars (core, fcn, zigname);
|
||||
addFcnHash (core, fcn, zigname);
|
||||
if (strcmp (zigname, fcn->name)) {
|
||||
r_sign_add_name (core->anal, zigname, fcn->name);
|
||||
}
|
||||
char *comments = getFcnComments (core, fcn);
|
||||
if (comments) {
|
||||
r_sign_add_comment (core->anal, zigname, comments);
|
||||
}
|
||||
r_sign_add_addr (core->anal, zigname, fcn->addr);
|
||||
|
||||
free (zigname);
|
||||
@ -196,10 +218,19 @@ static bool parseGraphMetrics(const char *args0, int nargs, RSignGraph *graph) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool addCommentZign(RCore *core, const char *name, const char *args0, int nargs) {
|
||||
const char *comment = args0;
|
||||
return r_sign_add_comment (core->anal, name, comment);
|
||||
}
|
||||
|
||||
static bool addNameZign(RCore *core, const char *name, const char *args0, int nargs) {
|
||||
const char *realname = r_str_word_get0 (args0, 0);
|
||||
return r_sign_add_name (core->anal, name, realname);
|
||||
}
|
||||
|
||||
static bool addGraphZign(RCore *core, const char *name, const char *args0, int nargs) {
|
||||
RSignGraph graph = {0};
|
||||
if (!parseGraphMetrics (args0, nargs, &graph)) {
|
||||
@ -292,6 +323,23 @@ static bool addRefsZign(RCore *core, const char *name, const char *args0, int na
|
||||
return retval;
|
||||
}
|
||||
|
||||
static bool addXRefsZign(RCore *core, const char *name, const char *args0, int nargs) {
|
||||
int i = 0;
|
||||
if (nargs < 1) {
|
||||
eprintf ("error: invalid syntax\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
RList *refs = r_list_newf ((RListFree) free);
|
||||
for (i = 0; i < nargs; i++) {
|
||||
r_list_append (refs, r_str_new (r_str_word_get0 (args0, i)));
|
||||
}
|
||||
|
||||
bool retval = r_sign_add_xrefs (core->anal, name, refs);
|
||||
r_list_free (refs);
|
||||
return retval;
|
||||
}
|
||||
|
||||
static bool addVarsZign(RCore *core, const char *name, const char *args0, int nargs) {
|
||||
int i = 0;
|
||||
if (nargs < 1) {
|
||||
@ -316,10 +364,16 @@ static bool addZign(RCore *core, const char *name, int type, const char *args0,
|
||||
return addBytesZign (core, name, type, args0, nargs);
|
||||
case R_SIGN_GRAPH:
|
||||
return addGraphZign (core, name, args0, nargs);
|
||||
case R_SIGN_COMMENT:
|
||||
return addCommentZign (core, name, args0, nargs);
|
||||
case R_SIGN_NAME:
|
||||
return addNameZign (core, name, args0, nargs);
|
||||
case R_SIGN_OFFSET:
|
||||
return addOffsetZign (core, name, args0, nargs);
|
||||
case R_SIGN_REFS:
|
||||
return addRefsZign (core, name, args0, nargs);
|
||||
case R_SIGN_XREFS:
|
||||
return addXRefsZign (core, name, args0, nargs);
|
||||
case R_SIGN_VARS:
|
||||
return addVarsZign (core, name, args0, nargs);
|
||||
case R_SIGN_BBHASH:
|
||||
@ -431,13 +485,16 @@ out_case_fcn:
|
||||
// TODO #7967 help refactor: move to detail
|
||||
r_cons_printf ("Adding Zignatures (examples and documentation)\n\n"
|
||||
"Zignature types:\n"
|
||||
" b: bytes pattern\n"
|
||||
" a: bytes pattern (anal mask)\n"
|
||||
" b: bytes pattern\n"
|
||||
" c: base64 comment\n"
|
||||
" n: real function name\n"
|
||||
" g: graph metrics\n"
|
||||
" o: original offset\n"
|
||||
" r: references\n\n"
|
||||
" h: bbhash (hashing of fcn basic blocks)\n\n"
|
||||
" v: vars (and args)\n\n"
|
||||
" r: references\n"
|
||||
" x: cross references\n"
|
||||
" h: bbhash (hashing of fcn basic blocks)\n"
|
||||
" v: vars (and args)\n"
|
||||
"Bytes patterns:\n"
|
||||
" bytes can contain '..' (dots) to specify a binary mask\n\n"
|
||||
"Graph metrics:\n"
|
||||
@ -452,6 +509,7 @@ out_case_fcn:
|
||||
" za foo g nbbs=3 edges=3\n"
|
||||
" za foo v b-32 b-48 b-64\n"
|
||||
" za foo o 0x08048123\n"
|
||||
" za foo c this is a comment (base64?)\n"
|
||||
" za foo r sym.imp.strcpy sym.imp.sprintf sym.imp.strlen\n"
|
||||
" za foo h 2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae\n");
|
||||
} else {
|
||||
@ -605,6 +663,9 @@ static void addFlag(RCore *core, RSignItem *it, ut64 addr, int size, int count,
|
||||
}
|
||||
if (rad) {
|
||||
r_cons_printf ("f %s %d @ 0x%08"PFMT64x"\n", name, size, addr);
|
||||
if (it->realname) {
|
||||
r_cons_printf ("\"afn %s @ 0x%08"PFMT64x"\"\n", it->realname, addr); // XXX command injection
|
||||
}
|
||||
} else {
|
||||
r_flag_set (core->flags, name, addr, size);
|
||||
}
|
||||
@ -730,6 +791,9 @@ static bool search(RCore *core, bool rad) {
|
||||
if (useHash) {
|
||||
r_sign_match_hash (core->anal, fcni, fcnMatchCB, &hash_match_ctx);
|
||||
}
|
||||
#if 0
|
||||
TODO: add useXRefs, useName
|
||||
#endif
|
||||
}
|
||||
r_cons_break_pop ();
|
||||
}
|
||||
@ -750,22 +814,9 @@ static bool search(RCore *core, bool rad) {
|
||||
return retval;
|
||||
}
|
||||
|
||||
static int cmdSearch(void *data, const char *input) {
|
||||
RCore *core = (RCore *) data;
|
||||
|
||||
switch (*input) {
|
||||
case 0:
|
||||
case '*':
|
||||
return search (core, input[0] == '*');
|
||||
case '?':
|
||||
r_core_cmd_help (core, help_msg_z_slash);
|
||||
break;
|
||||
default:
|
||||
eprintf ("usage: z/[*]\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
static int cmdCompare(void *data, const char *input) {
|
||||
eprintf ("TODO\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cmdCheck(void *data, const char *input) {
|
||||
@ -857,6 +908,24 @@ static int cmdCheck(void *data, const char *input) {
|
||||
return retval;
|
||||
}
|
||||
|
||||
static int cmdSearch(void *data, const char *input) {
|
||||
RCore *core = (RCore *) data;
|
||||
|
||||
switch (*input) {
|
||||
case 0:
|
||||
case '*':
|
||||
return search (core, input[0] == '*');
|
||||
case '?':
|
||||
r_core_cmd_help (core, help_msg_z_slash);
|
||||
break;
|
||||
default:
|
||||
eprintf ("usage: z/[*]\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static int cmdInfo(void *data, const char *input) {
|
||||
if (!data || !input) {
|
||||
return false;
|
||||
@ -874,12 +943,18 @@ static int cmd_zign(void *data, const char *input) {
|
||||
switch (*input) {
|
||||
case '\0':
|
||||
case '*':
|
||||
case 'q':
|
||||
case 'j':
|
||||
r_sign_list (core->anal, input[0]);
|
||||
break;
|
||||
case 'k':
|
||||
r_core_cmd0 (core, "k anal/zigns/*");
|
||||
break;
|
||||
case '-':
|
||||
r_sign_delete (core->anal, input + 1);
|
||||
break;
|
||||
case '.':
|
||||
return cmdCheck (data, input + 1);
|
||||
case 'o': // "zo"
|
||||
return cmdOpen (data, input + 1);
|
||||
case 'g': // "zg"
|
||||
@ -891,7 +966,7 @@ static int cmd_zign(void *data, const char *input) {
|
||||
case '/': // "z/"
|
||||
return cmdSearch (data, input + 1);
|
||||
case 'c': // "zc"
|
||||
return cmdCheck (data, input + 1);
|
||||
return cmdCompare (data, input + 1);
|
||||
case 's': // "zs"
|
||||
return cmdSpace (data, input + 1);
|
||||
case 'i': // "zi"
|
||||
@ -900,7 +975,7 @@ static int cmd_zign(void *data, const char *input) {
|
||||
r_core_cmd_help (core, help_msg_z);
|
||||
break;
|
||||
default:
|
||||
eprintf ("usage: z[*j-aof/cs] [args]\n");
|
||||
r_core_cmd_help (core, help_msg_z);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -11,21 +11,27 @@ extern "C" {
|
||||
|
||||
R_LIB_VERSION_HEADER(r_sign);
|
||||
|
||||
// XXX those limits should go away
|
||||
#define R_SIGN_KEY_MAXSZ 1024
|
||||
#define R_SIGN_VAL_MAXSZ 10240
|
||||
|
||||
#define ZIGN_HASH "sha256"
|
||||
#define R_ZIGN_HASH R_HASH_SHA256
|
||||
|
||||
enum {
|
||||
typedef enum {
|
||||
R_SIGN_BYTES = 'b', // bytes pattern
|
||||
R_SIGN_ANAL = 'a', // bytes pattern (anal mask)
|
||||
R_SIGN_BYTES_MASK= 'm', // bytes pattern
|
||||
R_SIGN_BYTES_SIZE= 's', // bytes pattern
|
||||
R_SIGN_ANAL = 'a', // bytes pattern (anal mask) // wtf ?
|
||||
R_SIGN_COMMENT = 'c', // comment
|
||||
R_SIGN_GRAPH = 'g', // graph metrics
|
||||
R_SIGN_OFFSET = 'o', // addr
|
||||
R_SIGN_NAME = 'n', // real name
|
||||
R_SIGN_REFS = 'r', // references
|
||||
R_SIGN_XREFS = 'x', // xrefs
|
||||
R_SIGN_VARS = 'v', // variables
|
||||
R_SIGN_BBHASH = 'h', // basic block hash
|
||||
};
|
||||
} RSignType;
|
||||
|
||||
typedef struct r_sign_graph_t {
|
||||
int cc;
|
||||
@ -47,12 +53,15 @@ typedef struct r_sign_hash_t {
|
||||
|
||||
typedef struct r_sign_item_t {
|
||||
char *name;
|
||||
char *realname;
|
||||
char *comment;
|
||||
const RSpace *space;
|
||||
|
||||
RSignBytes *bytes;
|
||||
RSignGraph *graph;
|
||||
ut64 addr;
|
||||
RList *refs;
|
||||
RList *xrefs;
|
||||
RList *vars;
|
||||
RSignHash *hash;
|
||||
} RSignItem;
|
||||
@ -77,7 +86,10 @@ R_API bool r_sign_add_bytes(RAnal *a, const char *name, ut64 size, const ut8 *by
|
||||
R_API bool r_sign_add_anal(RAnal *a, const char *name, ut64 size, const ut8 *bytes, ut64 at);
|
||||
R_API bool r_sign_add_graph(RAnal *a, const char *name, RSignGraph graph);
|
||||
R_API bool r_sign_add_addr(RAnal *a, const char *name, ut64 addr);
|
||||
R_API bool r_sign_add_name(RAnal *a, const char *name, const char *realname);
|
||||
R_API bool r_sign_add_comment(RAnal *a, const char *name, const char *comment);
|
||||
R_API bool r_sign_add_refs(RAnal *a, const char *name, RList *refs);
|
||||
R_API bool r_sign_add_xrefs(RAnal *a, const char *name, RList *xrefs);
|
||||
R_API bool r_sign_add_vars(RAnal *a, const char *name, RList *vars);
|
||||
R_API bool r_sign_delete(RAnal *a, const char *name);
|
||||
R_API void r_sign_list(RAnal *a, int format);
|
||||
@ -108,9 +120,9 @@ R_API RSignItem *r_sign_item_dup(RSignItem *it);
|
||||
R_API void r_sign_item_free(RSignItem *item);
|
||||
|
||||
R_API RList *r_sign_fcn_refs(RAnal *a, RAnalFunction *fcn);
|
||||
R_API RList *r_sign_fcn_xrefs(RAnal *a, RAnalFunction *fcn);
|
||||
R_API RList *r_sign_fcn_vars(RAnal *a, RAnalFunction *fcn);
|
||||
|
||||
// TODO
|
||||
R_API int r_sign_is_flirt(RBuffer *buf);
|
||||
R_API void r_sign_flirt_dump(const RAnal *anal, const char *flirt_file);
|
||||
R_API void r_sign_flirt_scan(RAnal *anal, const char *flirt_file);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* radare - LGPL - Copyright 2013-2018 - pancake */
|
||||
/* radare - LGPL - Copyright 2013-2019 - pancake */
|
||||
|
||||
#include "r_types.h"
|
||||
#include "r_util.h"
|
||||
@ -13,7 +13,8 @@ R_API RStrBuf *r_strbuf_new(const char *str) {
|
||||
}
|
||||
|
||||
R_API bool r_strbuf_equals(RStrBuf *sa, RStrBuf *sb) {
|
||||
if (!sa || !sb || sa->len != sb->len) { // faster comparisons
|
||||
r_return_val_if_fail (sa && sb, false);
|
||||
if (sa->len != sb->len) {
|
||||
return false;
|
||||
}
|
||||
return strcmp (r_strbuf_get (sa), r_strbuf_get (sb)) == 0;
|
||||
|
Loading…
x
Reference in New Issue
Block a user