diff --git a/libr/anal/sign.c b/libr/anal/sign.c index c46413a632..a58f097ca8 100644 --- a/libr/anal/sign.c +++ b/libr/anal/sign.c @@ -64,6 +64,32 @@ R_API RList *r_sign_fcn_vars(RAnal *a, RAnalFunction *fcn) { return ret; } +R_API RList *r_sign_fcn_xrefs(RAnal *a, RAnalFunction *fcn) { + RListIter *iter = NULL; + RAnalRef *refi = NULL; + + r_return_val_if_fail (a && fcn, NULL); + + RCore *core = a->coreb.core; + + if (!core) { + return NULL; + } + + RList *ret = r_list_newf ((RListFree) free); + RList *xrefs = r_anal_fcn_get_xrefs (a, fcn); + r_list_foreach (xrefs, iter, refi) { + if (refi->type == R_ANAL_REF_TYPE_CODE || refi->type == R_ANAL_REF_TYPE_CALL) { + const char *flag = getRealRef (core, refi->addr); + if (flag) { + r_list_append (ret, r_str_newf (flag)); + } + } + } + r_list_free (xrefs); + return ret; +} + R_API RList *r_sign_fcn_refs(RAnal *a, RAnalFunction *fcn) { RListIter *iter = NULL; RAnalRef *refi = NULL; @@ -94,8 +120,9 @@ R_API bool r_sign_deserialize(RAnal *a, RSignItem *it, const char *k, const char char *refs = NULL; char *vars = NULL; const char *token = NULL; - int i = 0, n = 0, nrefs = 0, nvars = 0, size = 0; - bool retval = true; + int i = 0, n = 0, nrefs = 0, nvars = 0, size = 0, w = 0; + + r_return_val_if_fail (a && it && k && v, false); char *k2 = r_str_new (k); char *v2 = r_str_new (v); @@ -108,7 +135,10 @@ R_API bool r_sign_deserialize(RAnal *a, RSignItem *it, const char *k, const char // Deserialize key: zign|space|name n = r_str_split (k2, '|'); if (n != 3) { - retval = false; + goto out; + } + if (strcmp (r_str_word_get0 (k2, 0), "zign")) { + eprintf ("Invalid entry in the zigns database\n"); goto out; } @@ -117,107 +147,138 @@ R_API bool r_sign_deserialize(RAnal *a, RSignItem *it, const char *k, const char // name (2) it->name = r_str_new (r_str_word_get0 (k2, 2)); +// it->space = r_spaces_current (&a->zign_spaces); - // Deserialize val: size|bytes|mask|graph|addr|refs|bbhash + // Deserialize value: |k:v|k:v|k:v|... n = r_str_split (v2, '|'); - if (n != 8) { - retval = false; - goto out; - } - - // pattern size (0) - size = atoi (r_str_word_get0 (v2, 0)); - if (size > 0) { - it->bytes = R_NEW0 (RSignBytes); - if (!it->bytes) { - retval = false; - goto out; + for (w = 0; w < n; w++) { + const char *word = r_str_word_get0 (v2, w); + if (!word) { + break; } - it->bytes->size = size; - - // bytes (1) - token = r_str_word_get0 (v2, 1); - if (strlen (token) != 2 * it->bytes->size) { - retval = false; - goto out; + if (!*word) { + continue; } - it->bytes->bytes = malloc (it->bytes->size); - if (!it->bytes->bytes) { - retval = false; - goto out; + token = word + 2; + if (strlen (word) < 3 || word[1] != ':') { + eprintf ("Corrupted zignatures database (%s)\n", word); + break; } - r_hex_str2bin (token, it->bytes->bytes); - - // mask (2) - token = r_str_word_get0 (v2, 2); - if (strlen (token) != 2 * it->bytes->size) { - retval = false; - goto out; + RSignType st = (RSignType)*word; + switch (st) { + case R_SIGN_ANAL: + eprintf ("Unsupported\n"); + break; + case R_SIGN_NAME: + it->realname = strdup (token); + break; + case R_SIGN_COMMENT: + it->comment = strdup (token); + break; + case R_SIGN_GRAPH: + if (strlen (token) == 2 * sizeof (RSignGraph)) { + it->graph = R_NEW0 (RSignGraph); + if (it->graph) { + r_hex_str2bin (token, (ut8 *) it->graph); + } + } + break; + case R_SIGN_OFFSET: + it->addr = atoll (token); + break; + case R_SIGN_REFS: + refs = r_str_new (token); + nrefs = r_str_split (refs, ','); + if (nrefs > 0) { + it->refs = r_list_newf ((RListFree) free); + for (i = 0; i < nrefs; i++) { + r_list_append (it->refs, r_str_newf (r_str_word_get0 (refs, i))); + } + } + break; + case R_SIGN_XREFS: + refs = r_str_new (token); + nrefs = r_str_split (refs, ','); + if (nrefs > 0) { + it->xrefs = r_list_newf ((RListFree) free); + for (i = 0; i < nrefs; i++) { + r_list_append (it->xrefs, r_str_newf (r_str_word_get0 (refs, i))); + } + } + break; + case R_SIGN_VARS: + vars = r_str_new (token); + nvars = r_str_split (vars, ','); + if (nvars > 0) { + it->vars = r_list_newf ((RListFree) free); + for (i = 0; i < nvars; i++) { + r_list_append (it->vars, r_str_newf (r_str_word_get0 (vars, i))); + } + } + break; + case R_SIGN_BBHASH: + if (token[0] != 0) { + it->hash = R_NEW0 (RSignHash); + if (it->hash) { + it->hash->bbhash = r_str_new (token); + } + } + break; + case R_SIGN_BYTES: + if (!it->bytes) { + eprintf ("Missing bytes-size command before bytes\n"); + break; + } + if (strlen (token) != 2 * it->bytes->size) { + goto out; + } + it->bytes->bytes = malloc (it->bytes->size); + if (it->bytes->bytes) { + r_hex_str2bin (token, it->bytes->bytes); + } + break; + case R_SIGN_BYTES_MASK: + if (!it->bytes) { + eprintf ("Missing bytes-size command before bytes-mask\n"); + break; + } + if (strlen (token) != 2 * it->bytes->size) { + goto out; + } + free (it->bytes->mask); + it->bytes->mask = malloc (it->bytes->size); + if (!it->bytes->mask) { + goto out; + } + r_hex_str2bin (token, it->bytes->mask); + break; + case R_SIGN_BYTES_SIZE: + // allocate + size = atoi (token); + if (size > 0) { + free (it->bytes); + it->bytes = R_NEW0 (RSignBytes); + if (!it->bytes) { + goto out; + } + it->bytes->size = size; + } + break; + default: + eprintf ("Unsupported (%s)\n", word); + break; } - it->bytes->mask = malloc (it->bytes->size); - if (!it->bytes->mask) { - retval = false; - goto out; - } - r_hex_str2bin (token, it->bytes->mask); - } - - // graph metrics (3) - token = r_str_word_get0 (v2, 3); - if (strlen (token) == 2 * sizeof (RSignGraph)) { - it->graph = R_NEW0 (RSignGraph); - if (it->graph) { - r_hex_str2bin (token, (ut8 *) it->graph); - } - } - - // addr (4) - token = r_str_word_get0 (v2, 4); - it->addr = atoll (token); - - // refs (5) - token = r_str_word_get0 (v2, 5); - refs = r_str_new (token); - nrefs = r_str_split (refs, ','); - if (nrefs > 0) { - it->refs = r_list_newf ((RListFree) free); - for (i = 0; i < nrefs; i++) { - r_list_append (it->refs, r_str_newf (r_str_word_get0 (refs, i))); - } - } - - // vars (6) - token = r_str_word_get0 (v2, 6); - vars = r_str_new (token); - nvars = r_str_split (vars, ','); - if (nvars > 0) { - it->vars = r_list_newf ((RListFree) free); - for (i = 0; i < nvars; i++) { - r_list_append (it->vars, r_str_newf (r_str_word_get0 (vars, i))); - } - } - - // basic blocks hash (7) - token = r_str_word_get0 (v2, 7); - if (token[0] != 0) { - it->hash = R_NEW0 (RSignHash); - if (!it->hash) { - goto out; - } - it->hash->bbhash = r_str_new (token); } out: free (k2); free (v2); free (refs); free (vars); - - return retval; + return (w == n); } static void serializeKey(RAnal *a, const RSpace *space, const char* name, char *k) { - snprintf (k, R_SIGN_KEY_MAXSZ, "zign|%s|%s", - space? space->name: "*", name); + snprintf (k, R_SIGN_KEY_MAXSZ, "zign|%s|%s", space? space->name: "*", name); } static void serializeKeySpaceStr(RAnal *a, const char *space, const char* name, char *k) { @@ -227,7 +288,7 @@ static void serializeKeySpaceStr(RAnal *a, const char *space, const char* name, static void serialize(RAnal *a, RSignItem *it, char *k, char *v) { RListIter *iter = NULL; char *hexbytes = NULL, *hexmask = NULL, *hexgraph = NULL; - char *refs = NULL, *ref = NULL, *var, *vars = NULL; + char *refs = NULL, *xrefs = NULL, *ref = NULL, *var, *vars = NULL; int i = 0, len = 0; RSignBytes *bytes = it->bytes; RSignGraph *graph = it->graph; @@ -236,7 +297,6 @@ static void serialize(RAnal *a, RSignItem *it, char *k, char *v) { if (k) { serializeKey (a, it->space, it->name, k); } - if (v) { if (bytes) { len = bytes->size * 2 + 1; @@ -247,7 +307,13 @@ static void serialize(RAnal *a, RSignItem *it, char *k, char *v) { free (hexmask); return; } + if (!bytes->bytes) { + bytes->bytes = malloc ((bytes->size + 1) * 3); + } r_hex_bin2str (bytes->bytes, bytes->size, hexbytes); + if (!bytes->mask) { + bytes->mask = malloc ((bytes->size + 1) * 3); + } r_hex_bin2str (bytes->mask, bytes->size, hexmask); } if (graph) { @@ -265,6 +331,14 @@ static void serialize(RAnal *a, RSignItem *it, char *k, char *v) { i++; } i = 0; + r_list_foreach (it->xrefs, iter, ref) { + if (i > 0) { + xrefs = r_str_appendch (xrefs, ','); + } + xrefs = r_str_append (xrefs, ref); + i++; + } + i = 0; r_list_foreach (it->vars, iter, var) { if (i > 0) { vars = r_str_appendch (vars, ','); @@ -272,15 +346,45 @@ static void serialize(RAnal *a, RSignItem *it, char *k, char *v) { vars = r_str_append (vars, var); i++; } - snprintf (v, R_SIGN_VAL_MAXSZ, "%d|%s|%s|%s|%"PFMT64d"|%s|%s|%s", - bytes? bytes->size: 0, - bytes? hexbytes: "", - bytes? hexmask: "", - graph? hexgraph: "", - it->addr, - refs? refs: "", - vars? vars: "", - hash? hash->bbhash: ""); + RStrBuf *sb = r_strbuf_new (""); + if (bytes) { + // TODO: do not hardcoded s,b,m here, use RSignType enum + r_strbuf_appendf (sb, "|s:%d|b:%s|m:%s", bytes->size, hexbytes, hexmask); + } + if (it->addr != UT64_MAX) { + r_strbuf_appendf (sb, "|%c:%"PFMT64d, R_SIGN_OFFSET, it->addr); + } + if (graph) { + r_strbuf_appendf (sb, "|%c:%s", R_SIGN_GRAPH, hexgraph); + } + if (refs) { + r_strbuf_appendf (sb, "|%c:%s", R_SIGN_REFS, refs); + } + if (xrefs) { + r_strbuf_appendf (sb, "|%c:%s", R_SIGN_XREFS, xrefs); + } + if (vars) { + r_strbuf_appendf (sb, "|%c:%s", R_SIGN_VARS, vars); + } + if (it->comment) { + // b64 encoded + r_strbuf_appendf (sb, "|%c:%s", R_SIGN_COMMENT, it->comment); + } + if (it->realname) { + // b64 encoded + r_strbuf_appendf (sb, "|%c:%s", R_SIGN_NAME, it->realname); + } + if (hash && hash->bbhash) { + r_strbuf_appendf (sb, "|%c:%s", R_SIGN_BBHASH, hash->bbhash); + } + if (r_strbuf_length (sb) >= R_SIGN_VAL_MAXSZ) { + eprintf ("Signature limit reached for 0x%08"PFMT64x" (%s)\n", it->addr, it->name); + } + char *res = r_strbuf_drain (sb); + if (res) { + strncpy (v, res, R_SIGN_VAL_MAXSZ); + free (res); + } free (hexbytes); free (hexmask); @@ -304,6 +408,7 @@ static void mergeItem(RSignItem *dst, RSignItem *src) { if (!dst->bytes) { return; } + dst->space = src->space; dst->bytes->size = src->bytes->size; dst->bytes->bytes = malloc (src->bytes->size); if (!dst->bytes->bytes) { @@ -329,6 +434,14 @@ static void mergeItem(RSignItem *dst, RSignItem *src) { *dst->graph = *src->graph; } + if (src->comment) { + dst->comment = strdup (src->comment); + } + + if (src->realname) { + dst->realname = strdup (src->realname); + } + if (src->addr != UT64_MAX) { dst->addr = src->addr; } @@ -354,10 +467,10 @@ static void mergeItem(RSignItem *dst, RSignItem *src) { if (src->hash) { if (!dst->hash) { dst->hash = R_NEW0 (RSignHash); - } if (!dst->hash) { return; } + } if (src->hash->bbhash) { dst->hash->bbhash = strdup (src->hash->bbhash); } @@ -408,15 +521,17 @@ static bool addHash(RAnal *a, const char *name, int type, const char *val) { r_sign_item_free (it); return false; } + it->space = r_spaces_current (&a->zign_spaces); + bool retval = false; switch (type) { case R_SIGN_BBHASH: - it->hash->bbhash = strdup(val); + it->hash->bbhash = strdup (val); + retval = addItem (a, it); + r_sign_item_free (it); break; } - bool retval = addItem (a, it); - r_sign_item_free (it); return retval; } @@ -431,6 +546,7 @@ static bool addBBHash(RAnal *a, RAnalFunction *fcn, const char *name) { goto beach; } it->hash = R_NEW0 (RSignHash); + it->space = r_spaces_current (&a->zign_spaces); if (!it->hash) { goto beach; } @@ -516,24 +632,17 @@ R_API bool r_sign_add_bb_hash(RAnal *a, RAnalFunction *fcn, const char *name) { R_API bool r_sign_add_bytes(RAnal *a, const char *name, ut64 size, const ut8 *bytes, const ut8 *mask) { r_return_val_if_fail (a && name && size > 0 && bytes && mask, false); - return addBytes (a, name, size, bytes, mask); } R_API bool r_sign_add_anal(RAnal *a, const char *name, ut64 size, const ut8 *bytes, ut64 at) { - ut8 *mask = NULL; - bool retval = true; - + bool retval = false; r_return_val_if_fail (a && name && size > 0 && bytes, false); - - mask = r_anal_mask (a, size, bytes, at); - if (!mask) { - return false; + ut8 *mask = r_anal_mask (a, size, bytes, at); + if (mask) { + retval = addBytes (a, name, size, bytes, mask); + free (mask); } - - retval = addBytes (a, name, size, bytes, mask); - - free (mask); return retval; } @@ -565,6 +674,35 @@ R_API bool r_sign_add_graph(RAnal *a, const char *name, RSignGraph graph) { return retval; } +R_API bool r_sign_add_comment(RAnal *a, const char *name, const char *comment) { + r_return_val_if_fail (a && name && comment, false); + + RSignItem *it = r_sign_item_new (); + if (it) { + return false; + } + it->name = r_str_new (name); + it->space = r_spaces_current (&a->zign_spaces); + it->comment = strdup (comment); + bool retval = addItem (a, it); + r_sign_item_free (it); + return retval; +} + +R_API bool r_sign_add_name(RAnal *a, const char *name, const char *realname) { + r_return_val_if_fail (a && name && realname, false); + RSignItem *it = r_sign_item_new (); + if (it) { + it->name = r_str_new (name); + it->realname = strdup (realname); + it->space = r_spaces_current (&a->zign_spaces); + bool retval = addItem (a, it); + r_sign_item_free (it); + return retval; + } + return false; +} + R_API bool r_sign_add_addr(RAnal *a, const char *name, ut64 addr) { r_return_val_if_fail (a && name && addr != UT64_MAX, false); @@ -612,8 +750,8 @@ R_API bool r_sign_add_vars(RAnal *a, const char *name, RList *vars) { R_API bool r_sign_add_refs(RAnal *a, const char *name, RList *refs) { r_return_val_if_fail (a && name && refs, false); - RListIter *iter = NULL; - char *ref = NULL; + char *ref; + RListIter *iter; RSignItem *it = r_sign_item_new (); if (!it) { return false; @@ -634,6 +772,31 @@ R_API bool r_sign_add_refs(RAnal *a, const char *name, RList *refs) { return retval; } +R_API bool r_sign_add_xrefs(RAnal *a, const char *name, RList *xrefs) { + r_return_val_if_fail (a && name && xrefs, false); + + RListIter *iter = NULL; + char *ref = NULL; + RSignItem *it = r_sign_item_new (); + if (!it) { + return false; + } + it->name = r_str_new (name); + if (!it->name) { + free (it); + return false; + } + it->space = r_spaces_current (&a->zign_spaces); + it->xrefs = r_list_newf ((RListFree) free); + r_list_foreach (xrefs, iter, ref) { + r_list_append (it->xrefs, strdup (ref)); + } + bool retval = addItem (a, it); + r_sign_item_free (it); + + return retval; +} + struct ctxDeleteCB { RAnal *anal; char buf[R_SIGN_KEY_MAXSZ]; @@ -641,11 +804,9 @@ struct ctxDeleteCB { static int deleteBySpaceCB(void *user, const char *k, const char *v) { struct ctxDeleteCB *ctx = (struct ctxDeleteCB *) user; - if (!strncmp (k, ctx->buf, strlen (ctx->buf))) { sdb_remove (ctx->anal->sdb_zigns, k, 0); } - return 1; } @@ -688,22 +849,31 @@ static void listBytes(RAnal *a, RSignItem *it, int format) { char *strbytes = NULL; int i = 0; + int masked = 0; + if (!bytes->bytes) { + return; + } for (i = 0; i < bytes->size; i++) { if (bytes->mask[i] & 0xf0) { + masked++; strbytes = r_str_appendf (strbytes, "%x", (bytes->bytes[i] & 0xf0) >> 4); } else { strbytes = r_str_appendf (strbytes, "."); } if (bytes->mask[i] & 0xf) { + masked++; strbytes = r_str_appendf (strbytes, "%x", bytes->bytes[i] & 0xf); } else { strbytes = r_str_appendf (strbytes, "."); } } + masked /= 2; /* nibbles to bytes */ if (strbytes) { if (format == '*') { a->cb_printf ("za %s b %s\n", it->name, strbytes); + } else if (format == 'q') { + a->cb_printf (" b(%d/%d)", masked, bytes->size); } else if (format == 'j') { a->cb_printf ("\"bytes\":\"%s\",", strbytes); } else { @@ -716,7 +886,10 @@ static void listBytes(RAnal *a, RSignItem *it, int format) { static void listGraph(RAnal *a, RSignItem *it, int format) { RSignGraph *graph = it->graph; - if (format == '*') { + if (format == 'q') { + a->cb_printf (" g(cc=%d,nb=%d,e=%d,eb=%d,h=%d)", + graph->cc, graph->nbbs, graph->edges, graph->ebbs, graph->bbsum); + } else if (format == '*') { a->cb_printf ("za %s g cc=%d nbbs=%d edges=%d ebbs=%d bbsum=%d\n", it->name, graph->cc, graph->nbbs, graph->edges, graph->ebbs, graph->bbsum); } else if (format == 'j') { @@ -728,8 +901,40 @@ static void listGraph(RAnal *a, RSignItem *it, int format) { } } +static void listComment(RAnal *a, RSignItem *it, int format) { + if (it->comment) { + if (format == 'q') { + // a->cb_printf (" addr(0x%08"PFMT64x")", it->addr); + a->cb_printf ("\n ; %s\n", it->comment); + } else if (format == '*') { + a->cb_printf ("%s\n", it->comment); // comment injection via CCu.. + } else if (format == 'j') { + a->cb_printf ("\"comments\":\"%s\",", it->comment); + } else { + a->cb_printf (" comment: 0x%08"PFMT64x"\n", it->addr); + } + } +} + +static void listRealname(RAnal *a, RSignItem *it, int format) { + if (it->realname) { + if (format == 'q') { + // a->cb_printf (" addr(0x%08"PFMT64x")", it->addr); + } else if (format == '*') { + a->cb_printf ("za %s %s\n", it->name, it->realname); + a->cb_printf ("afn %s @ 0x%08"PFMT64x"\n", it->realname, it->addr); + } else if (format == 'j') { + a->cb_printf ("\"realname\":\"%s\",", it->realname); + } else { + a->cb_printf (" realname: %s\n", it->realname); + } + } +} + static void listOffset(RAnal *a, RSignItem *it, int format) { - if (format == '*') { + if (format == 'q') { + // a->cb_printf (" addr(0x%08"PFMT64x")", it->addr); + } else if (format == '*') { a->cb_printf ("za %s o 0x%08"PFMT64x"\n", it->name, it->addr); } else if (format == 'j') { a->cb_printf ("\"addr\":%"PFMT64d",", it->addr); @@ -745,6 +950,9 @@ static void listVars(RAnal *a, RSignItem *it, int format) { if (format == '*') { a->cb_printf ("za %s v ", it->name); + } else if (format == 'q') { + a->cb_printf (" vars(%d)", r_list_length (it->vars)); + return; } else if (format == 'j') { a->cb_printf ("\"vars\":["); } else { @@ -776,6 +984,49 @@ static void listVars(RAnal *a, RSignItem *it, int format) { } } +static void listXRefs(RAnal *a, RSignItem *it, int format) { + RListIter *iter = NULL; + char *ref = NULL; + int i = 0; + + if (format == '*') { + a->cb_printf ("za %s x ", it->name); + } else if (format == 'q') { + a->cb_printf (" xrefs(%d)", r_list_length (it->xrefs)); + return; + } else if (format == 'j') { + a->cb_printf ("\"xrefs\":["); + } else { + if (it->xrefs && !r_list_empty (it->xrefs)) { + a->cb_printf (" xrefs: "); + } + } + + r_list_foreach (it->xrefs, iter, ref) { + if (i > 0) { + if (format == '*') { + a->cb_printf (" "); + } else if (format == 'j') { + a->cb_printf (","); + } else { + a->cb_printf (", "); + } + } + if (format == 'j') { + a->cb_printf ("\"%s\"", ref); + } else { + a->cb_printf ("%s", ref); + } + i++; + } + + if (format == 'j') { + a->cb_printf ("],"); + } else { + a->cb_printf ("\n"); + } +} + static void listRefs(RAnal *a, RSignItem *it, int format) { RListIter *iter = NULL; char *ref = NULL; @@ -783,10 +1034,15 @@ static void listRefs(RAnal *a, RSignItem *it, int format) { if (format == '*') { a->cb_printf ("za %s r ", it->name); + } else if (format == 'q') { + a->cb_printf (" refs(%d)", r_list_length (it->refs)); + return; } else if (format == 'j') { a->cb_printf ("\"refs\":["); } else { - a->cb_printf (" refs: "); + if (it->refs && !r_list_empty (it->refs)) { + a->cb_printf (" refs: "); + } } r_list_foreach (it->refs, iter, ref) { @@ -815,22 +1071,32 @@ static void listRefs(RAnal *a, RSignItem *it, int format) { } static void listHash(RAnal *a, RSignItem *it, int format) { - if (it->hash) { - if (format == '*') { - if (it->hash->bbhash) { - a->cb_printf ("za %s h %s\n", it->name, it->hash->bbhash); - } - } else if (format == 'j') { - a->cb_printf ("\"hash\":{"); - if (it->hash->bbhash) { - a->cb_printf ("\"bbhash\":\"%s\"", it->hash->bbhash); - } - a->cb_printf ("}"); - } else { - if (it->hash->bbhash) { - a->cb_printf (" bbhash: %s\n", it->hash->bbhash); - } + if (!it->hash) { + return; + } + switch (format) { + case 'q': + if (it->hash->bbhash) { + a->cb_printf (" h(%08x)", r_str_hash(it->hash->bbhash)); } + break; + case '*': + if (it->hash->bbhash) { + a->cb_printf ("za %s h %s\n", it->name, it->hash->bbhash); + } + break; + case 'j': + a->cb_printf ("\"hash\":{"); + if (it->hash->bbhash) { + a->cb_printf ("\"bbhash\":\"%s\"", it->hash->bbhash); + } + a->cb_printf ("}"); + break; + default: + if (it->hash->bbhash) { + a->cb_printf (" bbhash: %s\n", it->hash->bbhash); + } + break; } } @@ -864,6 +1130,10 @@ static int listCB(void *user, const char *k, const char *v) { } else { a->cb_printf ("zs *\n"); } + } else if (ctx->format == 'q') { + a->cb_printf ("0x%08"PFMT64x" ", it->addr); + const char *pad = r_str_pad (' ', 30- strlen (it->name)); + a->cb_printf ("%s:%s", it->name, pad); } else if (ctx->format == 'j') { if (it->space) { a->cb_printf ("{\"zignspace\":\"%s\",", it->space->name); @@ -896,21 +1166,31 @@ static int listCB(void *user, const char *k, const char *v) { } else if (ctx->format == 'j') { a->cb_printf ("\"addr\":-1,"); } - + // Name + if (it->realname) { + listRealname (a, it, ctx->format); + } + if (it->comment) { + listComment (a, it, ctx->format); + } // References if (it->refs) { listRefs (a, it, ctx->format); } else if (ctx->format == 'j') { a->cb_printf ("\"refs\":[],"); } - + // XReferences + if (it->xrefs) { + listXRefs (a, it, ctx->format); + } else if (ctx->format == 'j') { + a->cb_printf ("\"xrefs\":[],"); + } // Vars if (it->vars) { listVars (a, it, ctx->format); } else if (ctx->format == 'j') { a->cb_printf ("\"vars\":[],"); } - // Hash if (it->hash) { listHash (a, it, ctx->format); @@ -924,6 +1204,9 @@ static int listCB(void *user, const char *k, const char *v) { } ctx->idx++; + if (ctx->format == 'q') { + a->cb_printf ("\n"); + } out: r_sign_item_free (it); @@ -964,9 +1247,7 @@ static int listGetCB(void *user, const char *key, const char *val) { R_API RList *r_sign_get_list(RAnal *a) { r_return_val_if_fail (a, NULL); struct ctxGetListCB ctx = { a, r_list_newf ((RListFree)r_sign_item_free) }; - sdb_foreach (a->sdb_zigns, listGetCB, &ctx); - return ctx.list; } @@ -1016,16 +1297,13 @@ static int countForCB(void *user, const char *k, const char *v) { struct ctxCountForCB *ctx = (struct ctxCountForCB *) user; RSignItem *it = r_sign_item_new (); - if (!r_sign_deserialize (ctx->anal, it, k, v)) { + if (r_sign_deserialize (ctx->anal, it, k, v)) { + if (it->space == ctx->space) { + ctx->count++; + } + } else { eprintf ("error: cannot deserialize zign\n"); - goto out; } - - if (it->space == ctx->space) { - ctx->count++; - } - -out: r_sign_item_free (it); return 1; @@ -1033,13 +1311,8 @@ out: R_API int r_sign_space_count_for(RAnal *a, const RSpace *space) { struct ctxCountForCB ctx = { a, space, 0 }; - - if (!a) { - return 0; - } - + r_return_val_if_fail (a, 0); sdb_foreach (a->sdb_zigns, countForCB, &ctx); - return ctx.count; } @@ -1053,37 +1326,25 @@ static int unsetForCB(void *user, const char *k, const char *v) { char nk[R_SIGN_KEY_MAXSZ], nv[R_SIGN_VAL_MAXSZ]; RSignItem *it = r_sign_item_new (); Sdb *db = ctx->anal->sdb_zigns; - RAnal *a = ctx->anal; - if (!r_sign_deserialize (a, it, k, v)) { + if (r_sign_deserialize (ctx->anal, it, k, v)) { + if (it->space && it->space == ctx->space) { + it->space = NULL; + serialize (ctx->anal, it, nk, nv); + sdb_remove (db, k, 0); + sdb_set (db, nk, nv, 0); + } + } else { eprintf ("error: cannot deserialize zign\n"); - goto out; } - - if (it->space != ctx->space) { - goto out; - } - - if (it->space) { - it->space = NULL; - serialize (a, it, nk, nv); - sdb_remove (db, k, 0); - sdb_set (db, nk, nv, 0); - } - -out: r_sign_item_free (it); return 1; } R_API void r_sign_space_unset_for(RAnal *a, const RSpace *space) { + r_return_if_fail (a); struct ctxUnsetForCB ctx = { a, space }; - - if (!a) { - return; - } - sdb_foreach (a->sdb_zigns, unsetForCB, &ctx); } @@ -1111,16 +1372,10 @@ static int renameForCB(void *user, const char *k, const char *v) { } R_API void r_sign_space_rename_for(RAnal *a, const RSpace *space, const char *oname, const char *nname) { - struct ctxRenameForCB ctx; - - if (!a || !oname || !nname) { - return; - } - - ctx.anal = a; + r_return_if_fail (a && space && oname && nname); + struct ctxRenameForCB ctx = {.anal = a}; serializeKeySpaceStr (a, oname, "", ctx.oprefix); serializeKeySpaceStr (a, nname, "", ctx.nprefix); - sdb_foreach (a->sdb_zigns, renameForCB, &ctx); } @@ -1136,42 +1391,30 @@ static int foreachCB(void *user, const char *k, const char *v) { RAnal *a = ctx->anal; int retval = 1; - if (!r_sign_deserialize (a, it, k, v)) { + if (r_sign_deserialize (a, it, k, v)) { + RSpace *cur = r_spaces_current (&a->zign_spaces); + if (ctx->cb && cur == it->space) { + ctx->cb (it, ctx->user); + } + } else { eprintf ("error: cannot deserialize zign\n"); - goto out; } - - RSpace *cur = r_spaces_current (&a->zign_spaces); - if (cur != it->space && cur) { - goto out; - } - - if (ctx->cb) { - retval = ctx->cb (it, ctx->user); - } - -out: r_sign_item_free (it); - return retval; } R_API bool r_sign_foreach(RAnal *a, RSignForeachCallback cb, void *user) { + r_return_val_if_fail (a && cb, false); struct ctxForeachCB ctx = { a, cb, user }; - - if (!a || !cb) { - return false; - } - return sdb_foreach (a->sdb_zigns, foreachCB, &ctx); } R_API RSignSearch *r_sign_search_new() { RSignSearch *ret = R_NEW0 (RSignSearch); - - ret->search = r_search_new (R_SEARCH_KEYWORD); - ret->items = r_list_newf ((RListFree) r_sign_item_free); - + if (ret) { + ret->search = r_search_new (R_SEARCH_KEYWORD); + ret->items = r_list_newf ((RListFree) r_sign_item_free); + } return ret; } @@ -1179,7 +1422,6 @@ R_API void r_sign_search_free(RSignSearch *ss) { if (!ss) { return; } - r_search_free (ss->search); r_list_free (ss->items); free (ss); @@ -1187,12 +1429,7 @@ R_API void r_sign_search_free(RSignSearch *ss) { static int searchHitCB(RSearchKeyword *kw, void *user, ut64 addr) { RSignSearch *ss = (RSignSearch *) user; - - if (ss->cb) { - return ss->cb ((RSignItem *) kw->data, kw, addr, ss->user); - } - - return 1; + return ss->cb? ss->cb ((RSignItem *) kw->data, kw, addr, ss->user): 1; } struct ctxAddSearchKwCB { @@ -1205,48 +1442,39 @@ static int addSearchKwCB(RSignItem *it, void *user) { RSignSearch *ss = ctx->ss; RSignBytes *bytes = it->bytes; RSearchKeyword *kw = NULL; - RSignItem *it2 = NULL; if (!bytes) { + eprintf ("Cannot find bytes for this signature: %s\n", it->name); return 1; } - if (bytes->size < ctx->minsz) { + if (ctx->minsz && bytes->size < ctx->minsz) { return 1; } - - it2 = r_sign_item_dup (it); - r_list_append (ss->items, it2); - - // TODO(nibble): change arg data in r_search_keyword_new to void* - kw = r_search_keyword_new (bytes->bytes, bytes->size, bytes->mask, bytes->size, (const char *) it2); - r_search_kw_add (ss->search, kw); - + RSignItem *it2 = r_sign_item_dup (it); + if (it2) { + r_list_append (ss->items, it2); + // TODO(nibble): change arg data in r_search_keyword_new to void* + kw = r_search_keyword_new (bytes->bytes, bytes->size, bytes->mask, bytes->size, (const char *) it2); + r_search_kw_add (ss->search, kw); + } return 1; } R_API void r_sign_search_init(RAnal *a, RSignSearch *ss, int minsz, RSignSearchCallback cb, void *user) { struct ctxAddSearchKwCB ctx = { ss, minsz }; - - if (!a || !ss || !cb) { - return; - } - + r_return_if_fail (a && ss && cb); ss->cb = cb; ss->user = user; - r_list_purge (ss->items); r_search_reset (ss->search, R_SEARCH_KEYWORD); - r_sign_foreach (a, addSearchKwCB, &ctx); r_search_begin (ss->search); r_search_set_callback (ss->search, searchHitCB, ss); } R_API int r_sign_search_update(RAnal *a, RSignSearch *ss, ut64 *at, const ut8 *buf, int len) { - if (!a || !ss || !buf || len <= 0) { - return 0; - } + r_return_val_if_fail (a && ss && buf && len > 0, 0); return r_search_update (ss->search, *at, buf, len); } @@ -1311,12 +1539,8 @@ static int graphMatchCB(RSignItem *it, void *user) { } R_API bool r_sign_match_graph(RAnal *a, RAnalFunction *fcn, int mincc, RSignGraphMatchCallback cb, void *user) { + r_return_val_if_fail (a && fcn && cb, false); struct ctxFcnMatchCB ctx = { a, fcn, cb, user, mincc }; - - if (!a || !fcn || !cb) { - return false; - } - return r_sign_foreach (a, graphMatchCB, &ctx); } @@ -1339,12 +1563,8 @@ static int addrMatchCB(RSignItem *it, void *user) { } R_API bool r_sign_match_addr(RAnal *a, RAnalFunction *fcn, RSignOffsetMatchCallback cb, void *user) { + r_return_val_if_fail (a && fcn && cb, false); struct ctxFcnMatchCB ctx = { a, fcn, cb, user, 0 }; - - if (!a || !fcn || !cb) { - return false; - } - return r_sign_foreach (a, addrMatchCB, &ctx); } @@ -1352,11 +1572,7 @@ static int hashMatchCB(RSignItem *it, void *user) { struct ctxFcnMatchCB *ctx = (struct ctxFcnMatchCB *) user; RSignHash *hash = it->hash; - if (!hash) { - return 1; - } - - if (!hash->bbhash || hash->bbhash[0] == 0) { + if (!hash || !hash->bbhash || hash->bbhash[0] == 0) { return 1; } @@ -1376,10 +1592,8 @@ beach: } R_API bool r_sign_match_hash(RAnal *a, RAnalFunction *fcn, RSignHashMatchCallback cb, void *user) { - struct ctxFcnMatchCB ctx = { a, fcn, cb, user, 0 }; - r_return_val_if_fail (a && fcn && cb, false); - + struct ctxFcnMatchCB ctx = { a, fcn, cb, user, 0 }; return r_sign_foreach (a, hashMatchCB, &ctx); } @@ -1505,6 +1719,12 @@ R_API RSignItem *r_sign_item_dup(RSignItem *it) { return NULL; } ret->name = r_str_new (it->name); + if (it->realname) { + ret->realname = r_str_newf (it->realname); + } + if (it->comment) { + ret->comment = r_str_newf (it->comment); + } ret->space = it->space; if (it->bytes) { @@ -1541,6 +1761,10 @@ R_API RSignItem *r_sign_item_dup(RSignItem *it) { r_list_foreach (it->refs, iter, ref) { r_list_append (ret->refs, r_str_new (ref)); } + ret->xrefs = r_list_newf ((RListFree) free); + r_list_foreach (it->xrefs, iter, ref) { + r_list_append (ret->xrefs, r_str_new (ref)); + } return ret; } @@ -1560,6 +1784,8 @@ R_API void r_sign_item_free(RSignItem *item) { free (item->hash); } free (item->graph); + free (item->comment); + free (item->realname); r_list_free (item->refs); r_list_free (item->vars); free (item); diff --git a/libr/core/cmd_zign.c b/libr/core/cmd_zign.c index d369f653dc..02fef9abd4 100644 --- a/libr/core/cmd_zign.c +++ b/libr/core/cmd_zign.c @@ -1,4 +1,4 @@ -/* radare - LGPL - Copyright 2009-2018 - pancake, nibble */ +/* radare - LGPL - Copyright 2009-2019 - pancake, nibble */ #include #include @@ -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; } diff --git a/libr/include/r_sign.h b/libr/include/r_sign.h index 1affb8c2bf..8d033089ec 100644 --- a/libr/include/r_sign.h +++ b/libr/include/r_sign.h @@ -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); diff --git a/libr/util/strbuf.c b/libr/util/strbuf.c index 14278392b7..48facd6db0 100644 --- a/libr/util/strbuf.c +++ b/libr/util/strbuf.c @@ -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;