From 61d9be3ff1d73a837ff124e8435159dee84c81ca Mon Sep 17 00:00:00 2001 From: Dennis Goodlett Date: Sun, 20 Sep 2020 18:04:05 -0400 Subject: [PATCH] Fix zig add type ##signatures (#17653) Co-authored-by: Dennis Goodlett --- libr/core/cmd_zign.c | 287 ++++++++++++++------------------------ test/db/cmd/cmd_zignature | 45 ++++++ 2 files changed, 152 insertions(+), 180 deletions(-) diff --git a/libr/core/cmd_zign.c b/libr/core/cmd_zign.c index 337c9976c9..8a7f2f1ec5 100644 --- a/libr/core/cmd_zign.c +++ b/libr/core/cmd_zign.c @@ -174,97 +174,90 @@ static void addFcnZign(RCore *core, RAnalFunction *fcn, const char *name) { } } -static bool parseGraphMetrics(const char *args0, int nargs, RSignGraph *graph) { - const char *ptr = NULL; - int i = 0; +static bool addCommentZign(RCore *core, const char *name, RList *args) { + if (r_list_length (args) != 1) { + eprintf ("Invalid number of arguments\n"); + return false; + } + const char *comment = (const char *)r_list_get_top (args); + return r_sign_add_comment (core->anal, name, comment); +} - graph->cc = -1; - graph->nbbs = -1; - graph->edges = -1; - graph->ebbs = -1; - graph->bbsum = 0; +static bool addNameZign(RCore *core, const char *name, RList *args) { + if (r_list_length (args) != 1) { + eprintf ("Invalid number of arguments\n"); + return false; + } + const char *realname = (const char *)r_list_get_top (args); + return r_sign_add_name (core->anal, name, realname); +} - for (i = 0; i < nargs; i++) { - ptr = r_str_word_get0 (args0, i); +static bool addGraphZign(RCore *core, const char *name, RList *args) { + RSignGraph graph = { .cc = -1, .nbbs = -1, .edges = -1, .ebbs = -1, .bbsum = 0 }; + + char *ptr; + RListIter *iter; + r_list_foreach (args, iter, ptr) { if (r_str_startswith (ptr, "cc=")) { - graph->cc = atoi (ptr + 3); + graph.cc = atoi (ptr + 3); } else if (r_str_startswith (ptr, "nbbs=")) { - graph->nbbs = atoi (ptr + 5); + graph.nbbs = atoi (ptr + 5); } else if (r_str_startswith (ptr, "edges=")) { - graph->edges = atoi (ptr + 6); + graph.edges = atoi (ptr + 6); } else if (r_str_startswith (ptr, "ebbs=")) { - graph->ebbs = atoi (ptr + 5); + graph.ebbs = atoi (ptr + 5); } else if (r_str_startswith (ptr, "bbsum=")) { - graph->bbsum = atoi (ptr + 6); + graph.bbsum = atoi (ptr + 6); } else { 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)) { - eprintf ("error: invalid arguments\n"); - return false; - } return r_sign_add_graph (core->anal, name, graph); } -static bool addHashZign(RCore *core, const char *name, int type, const char *args0, int nargs) { - if (!args0) { +static bool addHashZign(RCore *core, const char *name, int type, RList *args) { + if (r_list_length (args) != 1) { + eprintf ("error: invalid syntax\n"); return false; } - int len = strlen (args0); + const char *hash = (const char *)r_list_get_top (args); + int len = strlen (hash); if (!len) { return false; } - return r_sign_add_hash (core->anal, name, type, args0, len); + return r_sign_add_hash (core->anal, name, type, hash, len); } -static bool addBytesZign(RCore *core, const char *name, int type, const char *args0, int nargs) { - const char *hexbytes = NULL; +static bool addBytesZign(RCore *core, const char *name, int type, RList *args) { ut8 *mask = NULL, *bytes = NULL, *sep = NULL; - int size = 0, blen = 0; + int size = 0; bool retval = true; - if (nargs != 1) { + if (r_list_length (args) != 1) { eprintf ("error: invalid syntax\n"); - retval = false; - goto out; + return false; } - hexbytes = r_str_word_get0 (args0, 0); - if ((sep = (ut8*) strchr (hexbytes, ':'))) { - blen = sep - (ut8*) hexbytes; - if (!blen || (blen & 1) || strlen ((char*) ++sep) != blen) { + const char *hexbytes = (const char *)r_list_get_top (args); + if ((sep = (ut8 *)strchr (hexbytes, ':'))) { + size_t blen = sep - (ut8 *)hexbytes; + sep++; + if (!blen || (blen & 1) || strlen ((char *)sep) != blen) { eprintf ("error: cannot parse hexpairs\n"); - retval = false; - goto out; + return false; } bytes = calloc (1, blen + 1); mask = calloc (1, blen + 1); memcpy (bytes, hexbytes, blen); memcpy (mask, sep, blen); size = r_hex_str2bin ((char*) bytes, bytes); - if (size != blen / 2 || r_hex_str2bin ((char*) mask, mask) != size) { + if (size != blen / 2 || r_hex_str2bin ((char*)mask, mask) != size) { eprintf ("error: cannot parse hexpairs\n"); retval = false; goto out; } } else { - blen = strlen (hexbytes) + 4; + size_t blen = strlen (hexbytes) + 4; bytes = malloc (blen); mask = malloc (blen); @@ -292,112 +285,42 @@ out: return retval; } -static bool addOffsetZign(RCore *core, const char *name, const char *args0, int nargs) { - const char *offstr = NULL; - ut64 offset = UT64_MAX; - - if (nargs != 1) { +static bool addOffsetZign(RCore *core, const char *name, RList *args) { + if (r_list_length (args) != 1) { eprintf ("error: invalid syntax\n"); return false; } - - offstr = r_str_word_get0 (args0, 0); - offset = r_num_get (core->num, offstr); - + const char *offstr = (const char *)r_list_get_top (args); + if (!offstr) { + return false; + } + ut64 offset = r_num_get (core->num, offstr); return r_sign_add_addr (core->anal, name, offset); } -static bool addRefsZign(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_refs (core->anal, name, refs); - r_list_free (refs); - 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) { - eprintf ("error: invalid syntax\n"); - return false; - } - - RList *vars = r_list_newf ((RListFree) free); - for (i = 0; i < nargs; i++) { - r_list_append (vars, r_str_new (r_str_word_get0 (args0, i))); - } - - bool retval = r_sign_add_vars (core->anal, name, vars); - r_list_free (vars); - return retval; -} - -static bool addTypesZign(RCore *core, const char *name, const char *args0, int nargs) { - int i = 0; - if (nargs < 1) { - eprintf ("error: invalid syntax\n"); - return false; - } - - RList *types = r_list_newf ((RListFree)free); - for (i = 0; i < nargs; i++) { - r_list_append (types, strdup (r_str_word_get0 (args0, i))); - } - - bool retval = r_sign_add_types (core->anal, name, types); - r_list_free (types); - return retval; -} - -static bool addZign(RCore *core, const char *name, int type, const char *args0, int nargs) { +static bool addZign(RCore *core, const char *name, int type, RList *args) { switch (type) { case R_SIGN_BYTES: case R_SIGN_ANAL: - return addBytesZign (core, name, type, args0, nargs); + return addBytesZign (core, name, type, args); case R_SIGN_GRAPH: - return addGraphZign (core, name, args0, nargs); + return addGraphZign (core, name, args); case R_SIGN_COMMENT: - return addCommentZign (core, name, args0, nargs); + return addCommentZign (core, name, args); case R_SIGN_NAME: - return addNameZign (core, name, args0, nargs); + return addNameZign (core, name, args); case R_SIGN_OFFSET: - return addOffsetZign (core, name, args0, nargs); + return addOffsetZign (core, name, args); case R_SIGN_REFS: - return addRefsZign (core, name, args0, nargs); + return r_sign_add_refs (core->anal, name, args); case R_SIGN_XREFS: - return addXRefsZign (core, name, args0, nargs); + return r_sign_add_xrefs (core->anal, name, args); case R_SIGN_VARS: - return addVarsZign (core, name, args0, nargs); + return r_sign_add_vars (core->anal, name, args); case R_SIGN_TYPES: - return addTypesZign (core, name, args0, nargs); + return r_sign_add_types (core->anal, name, args); case R_SIGN_BBHASH: - return addHashZign (core, name, type, args0, nargs); + return addHashZign (core, name, type, args); default: eprintf ("error: unknown zignature type\n"); } @@ -411,30 +334,35 @@ static int cmdAdd(void *data, const char *input) { switch (*input) { case ' ': { - const char *zigname = NULL, *args0 = NULL; - char *args = NULL; - int type = 0, n = 0; bool retval = true; - - args = r_str_new (input + 1); - n = r_str_word_set0 (args); - - if (n < 3) { - eprintf ("usage: za zigname type params\n"); + char *args = r_str_trim_dup (input + 1); + if (!args) { + return false; + } + RList *lst = r_str_split_list (args, " ", 0); + if (!lst) { + goto out_case_manual; + } + if (r_list_length (lst) < 3) { + eprintf ("Usage: za zigname type params\n"); + retval = false; + goto out_case_manual; + } + char *zigname = r_list_pop_head (lst); + char *type_str = r_list_pop_head (lst); + if (strlen (type_str) != 1) { + eprintf ("Usage: za zigname type params\n"); retval = false; goto out_case_manual; } - zigname = r_str_word_get0 (args, 0); - type = r_str_word_get0 (args, 1)[0]; - args0 = r_str_word_get0 (args, 2); - - if (!addZign (core, zigname, type, args0, n - 2)) { + if (!addZign (core, zigname, type_str[0], lst)) { retval = false; goto out_case_manual; } out_case_manual: + r_list_free (lst); free (args); return retval; } @@ -448,11 +376,11 @@ out_case_manual: int n = 0; bool retval = true; - args = r_str_new (r_str_trim_head_ro (input + 1)); + args = r_str_trim_dup (input + 1); n = r_str_word_set0 (args); if (n > 2) { - eprintf ("usage: zaf [fcnname] [zigname]\n"); + eprintf ("Usage: zaf [fcnname] [zigname]\n"); retval = false; goto out_case_fcn; } @@ -537,7 +465,7 @@ out_case_fcn: } break; default: - eprintf ("usage: za[fF?] [args]\n"); + eprintf ("Usage: za[fF?] [args]\n"); return false; } @@ -545,32 +473,32 @@ out_case_fcn: } static int cmdOpen(void *data, const char *input) { - RCore *core = (RCore *) data; + RCore *core = (RCore *)data; switch (*input) { case ' ': if (input[1]) { return r_sign_load (core->anal, input + 1); } - eprintf ("usage: zo filename\n"); + eprintf ("Usage: zo filename\n"); return false; case 's': if (input[1] == ' ' && input[2]) { return r_sign_save (core->anal, input + 2); } - eprintf ("usage: zos filename\n"); + eprintf ("Usage: zos filename\n"); return false; case 'z': if (input[1] == ' ' && input[2]) { return r_sign_load_gz (core->anal, input + 2); } - eprintf ("usage: zoz filename\n"); + eprintf ("Usage: zoz filename\n"); return false; case '?': r_core_cmd_help (core, help_msg_zo); break; default: - eprintf ("usage: zo[zs] filename\n"); + eprintf ("Usage: zo[zs] filename\n"); return false; } @@ -584,14 +512,14 @@ static int cmdSpace(void *data, const char *input) { switch (*input) { case '+': if (!input[1]) { - eprintf ("usage: zs+zignspace\n"); + eprintf ("Usage: zs+zignspace\n"); return false; } r_spaces_push (zs, input + 1); break; case 'r': if (input[1] != ' ' || !input[2]) { - eprintf ("usage: zsr newname\n"); + eprintf ("Usage: zsr newname\n"); return false; } r_spaces_rename (zs, NULL, input + 2); @@ -612,7 +540,7 @@ static int cmdSpace(void *data, const char *input) { break; case ' ': if (!input[1]) { - eprintf ("usage: zs zignspace\n"); + eprintf ("Usage: zs zignspace\n"); return false; } r_spaces_set (zs, input + 1); @@ -621,7 +549,7 @@ static int cmdSpace(void *data, const char *input) { r_core_cmd_help (core, help_msg_zs); break; default: - eprintf ("usage: zs[+-*] [namespace]\n"); + eprintf ("Usage: zs[+-*] [namespace]\n"); return false; } @@ -629,13 +557,13 @@ static int cmdSpace(void *data, const char *input) { } static int cmdFlirt(void *data, const char *input) { - RCore *core = (RCore *) data; + RCore *core = (RCore *)data; switch (*input) { case 'd': // TODO if (input[1] != ' ') { - eprintf ("usage: zfd filename\n"); + eprintf ("Usage: zfd filename\n"); return false; } r_sign_flirt_dump (core->anal, input + 2); @@ -643,7 +571,7 @@ static int cmdFlirt(void *data, const char *input) { case 's': // TODO if (input[1] != ' ') { - eprintf ("usage: zfs filename\n"); + eprintf ("Usage: zfs filename\n"); return false; } int depth = r_config_get_i (core->config, "dir.depth"); @@ -662,7 +590,7 @@ static int cmdFlirt(void *data, const char *input) { r_core_cmd_help (core, help_msg_zf); break; default: - eprintf ("usage: zf[dsz] filename\n"); + eprintf ("Usage: zf[dsz] filename\n"); return false; } return true; @@ -687,10 +615,9 @@ static void apply_name(RCore *core, RAnalFunction *fcn, RSignItem *it, bool rad) return; } RFlagItem *flag = r_flag_get (core->flags, fcn->name); - if (!flag || !flag->space || strcmp (flag->space->name, R_FLAGS_FS_FUNCTIONS)) { - return; + if (flag && flag->space && strcmp (flag->space->name, R_FLAGS_FS_FUNCTIONS)) { + r_flag_rename (core->flags, flag, name); } - r_flag_rename (core->flags, flag, name); r_anal_function_rename (fcn, name); if (core->anal->cb.on_fcn_rename) { core->anal->cb.on_fcn_rename (core->anal, core->anal->user, fcn, name); @@ -1150,7 +1077,7 @@ static int cmdCompare(void *data, const char *input) { switch (*input) { case ' ': if (!input[1]) { - eprintf ("usage: zc other_space\n"); + eprintf ("Usage: zc other_space\n"); result = false; break; } @@ -1160,7 +1087,7 @@ static int cmdCompare(void *data, const char *input) { switch (input[1]) { case ' ': if (!input[2]) { - eprintf ("usage: zcn other_space\n"); + eprintf ("Usage: zcn other_space\n"); result = false; break; } @@ -1168,14 +1095,14 @@ static int cmdCompare(void *data, const char *input) { break; case '!': if (input[2] != ' ' || !input[3]) { - eprintf ("usage: zcn! other_space\n"); + eprintf ("Usage: zcn! other_space\n"); result = false; break; } result = r_sign_diff_by_name (core->anal, options, input + 3, true); break; default: - eprintf ("usage: zcn! other_space\n"); + eprintf ("Usage: zcn! other_space\n"); result = false; } break; @@ -1183,7 +1110,7 @@ static int cmdCompare(void *data, const char *input) { r_core_cmd_help (core, help_msg_zc); break; default: - eprintf ("usage: zc[?n!] other_space\n"); + eprintf ("Usage: zc[?n!] other_space\n"); result = false; } @@ -1299,14 +1226,14 @@ static int cmdSearch(void *data, const char *input) { case '*': return search (core, input[1] == '*', true); default: - eprintf ("usage: z/[f*]\n"); + eprintf ("Usage: z/[f*]\n"); return false; } case '?': r_core_cmd_help (core, help_msg_z_slash); break; default: - eprintf ("usage: z/[*]\n"); + eprintf ("Usage: z/[*]\n"); return false; } return true; diff --git a/test/db/cmd/cmd_zignature b/test/db/cmd/cmd_zignature index ede7a91ae2..9ff56cbeb0 100644 --- a/test/db/cmd/cmd_zignature +++ b/test/db/cmd/cmd_zignature @@ -1739,3 +1739,48 @@ sym.fourth sym.fith EOF RUN + +NAME=manually add signatures +FILE=- +CMDS=<