From 3fa18414c3c904e463464d91402d479a49b38e98 Mon Sep 17 00:00:00 2001 From: Roi Martin Date: Thu, 16 Mar 2017 20:45:45 +0000 Subject: [PATCH] Implement open/save zignature file --- libr/anal/sign.c | 48 ++++++++++++++++++ libr/core/cmd_zign.c | 112 ++++++++++++++++++++++++++++-------------- libr/include/r_sign.h | 3 ++ 3 files changed, 127 insertions(+), 36 deletions(-) diff --git a/libr/anal/sign.c b/libr/anal/sign.c index c21c252fc9..483112f370 100644 --- a/libr/anal/sign.c +++ b/libr/anal/sign.c @@ -454,3 +454,51 @@ R_API void r_sign_item_free(void *_item) { free (item->mask); free (item); } + +static int zignLoadCB(void *user, const char *k, const char *v) { + RAnal *a = (RAnal *) user; + char nk[R_SIGN_KEY_MAXSZ], nv[R_SIGN_VAL_MAXSZ]; + RSignItem *it = R_NEW0 (RSignItem); + + if (!deserialize (it, k, v)) { + eprintf ("error: cannot deserialize zign\n"); + goto exit_function; + } + + it->space = a->zign_spaces.space_idx; + serialize (it, nk, nv); + sdb_set (a->sdb_zigns, nk, nv, 0); + +exit_function: + r_sign_item_free (it); + + return 1; +} + +R_API bool r_sign_load(RAnal *a, const char *file) { + if (!r_file_exists (file)) { + eprintf ("error: file %s does not exist\n", file); + return false; + } + + Sdb *db = sdb_new (NULL, file, 0); + sdb_foreach (db, zignLoadCB, a); + sdb_close (db); + sdb_free (db); + + return true; +} + +R_API bool r_sign_save(RAnal *a, const char *file) { + bool retval = true; + + // TODO(nibble): Fix sdb. If we use only one db to sync to disk, + // when executing f-* some null entries remain. + Sdb *db = sdb_new (NULL, file, 0); + sdb_merge (db, a->sdb_zigns); + retval = sdb_sync (db); + sdb_close (db); + sdb_free (db); + + return retval; +} diff --git a/libr/core/cmd_zign.c b/libr/core/cmd_zign.c index 06d4fcbd2c..9af0d68184 100644 --- a/libr/core/cmd_zign.c +++ b/libr/core/cmd_zign.c @@ -17,7 +17,7 @@ static bool zignAddFcn(RCore *core, RAnalFunction *fcn, int type, int minzlen, i eprintf ("warn: omitting %s zignature is too small. Length is %d. Check zign.min.\n", fcn->name, fcnlen); retval = false; - goto exit_func; + goto exit_function; } len = R_MIN (fcnlen, maxzlen); @@ -27,7 +27,7 @@ static bool zignAddFcn(RCore *core, RAnalFunction *fcn, int type, int minzlen, i if (r_io_read_at (core->io, fcn->addr, buf, len) != len) { eprintf ("error: cannot read at 0x%08"PFMT64x"\n", fcn->addr); retval = false; - goto exit_func; + goto exit_function; } switch (type) { @@ -41,7 +41,7 @@ static bool zignAddFcn(RCore *core, RAnalFunction *fcn, int type, int minzlen, i break; } -exit_func: +exit_function: free (buf); free (mask); @@ -60,7 +60,7 @@ static bool zignAddHex(RCore *core, const char *name, int type, const char *hexb size = r_hex_str2binmask (hexbytes, bytes, mask); if (size <= 0) { retval = false; - goto exit_func; + goto exit_function; } switch (type) { @@ -72,7 +72,7 @@ static bool zignAddHex(RCore *core, const char *name, int type, const char *hexb break; } -exit_func: +exit_function: free (bytes); free (mask); @@ -88,13 +88,15 @@ static int zignAddBytes(void *data, const char *input, int type) { const char *name = NULL, *hexbytes = NULL; char *args = NULL; int n = 0; + bool retval = true; args = r_str_new (input + 1); n = r_str_word_set0(args); if (n != 2) { eprintf ("usage: za%s name bytes\n", type == R_SIGN_ANAL? "a": "e"); - return false; + retval = false; + goto exit_case; } name = r_str_word_get0(args, 0); @@ -102,9 +104,13 @@ static int zignAddBytes(void *data, const char *input, int type) { if (!zignAddHex (core, name, type, hexbytes)) { eprintf ("error: cannot add zignature\n"); + retval = false; + goto exit_case; } +exit_case: free (args); + return retval; } break; case 'f': @@ -179,6 +185,7 @@ static int zignAddBytes(void *data, const char *input, int type) { break; default: eprintf ("usage: za%s[f] [args]\n", type == R_SIGN_ANAL? "a": "e"); + return false; } return true; @@ -205,28 +212,55 @@ static int zignAdd(void *data, const char *input) { break; default: eprintf ("usage: za[aemg] [args]\n"); + return false; } return true; } -static int zignLoad(void *data, const char *input) { +static int zignFile(void *data, const char *input) { RCore *core = (RCore *) data; switch (*input) { + case ' ': + { + const char *filename; + + if (input[1] != '\x00') { + filename = input + 1; + return r_sign_load (core->anal, filename); + } else { + eprintf ("Usage: zo filename\n"); + return false; + } + } + break; + case 's': + { + const char *filename; + + if (input[1] == ' ' && input[2] != '\x00') { + filename = input + 2; + return r_sign_save (core->anal, filename); + } else { + eprintf ("Usage: zos filename\n"); + return false; + } + } + break; case '?': - { - const char *help_msg[] = { - "Usage:", "zo[dz] [args] ", "# Load zignatures from file", - "zo ", "filename", "load zignatures from file", - "zod ", "filename", "load zinatures from sdb file", - "zoz ", "filename", "load zinagures from gzip file", - NULL}; - r_core_cmd_help (core, help_msg); - } - break; + { + const char *help_msg[] = { + "Usage:", "zo[s] filename ", "# Manage zignature files", + "zo ", "filename", "load zinatures from sdb file", + "zos ", "filename", "save zignatures to sdb file", + NULL}; + r_core_cmd_help (core, help_msg); + } + break; default: - eprintf ("usage: zo[dz] [args]\n"); + eprintf ("usage: zo[s] filename\n"); + return false; } return true; @@ -237,27 +271,12 @@ static int zignSpace(void *data, const char *input) { RSpaces *zs = &core->anal->zign_spaces; switch (*input) { - case '?': - { - const char *help_msg[] = { - "Usage:", "zs[+-*] [namespace] ", "# Manage zignspaces", - "zs", "", "display zignspaces", - "zs ", "zignspace", "select zignspace", - "zs ", "*", "select all zignspaces", - "zs-", "zignspace", "delete zignspace", - "zs-", "*", "delete all zignspaces", - "zs+", "zignspace", "push previous zignspace and set", - "zs-", "", "pop to the previous zignspace", - "zsr ", "newname", "rename selected zignspace", - NULL}; - r_core_cmd_help (core, help_msg); - } - break; case '+': if (input[1] != '\x00') { r_space_push (zs, input + 1); } else { eprintf ("Usage: zs+zignspace\n"); + return false; } break; case 'r': @@ -265,6 +284,7 @@ static int zignSpace(void *data, const char *input) { r_space_rename (zs, NULL, input + 2); } else { eprintf ("Usage: zsr newname\n"); + return false; } break; case '-': @@ -286,6 +306,23 @@ static int zignSpace(void *data, const char *input) { r_space_set (zs, input + 1); } else { eprintf ("Usage: zs zignspace\n"); + return false; + } + break; + case '?': + { + const char *help_msg[] = { + "Usage:", "zs[+-*] [namespace] ", "# Manage zignspaces", + "zs", "", "display zignspaces", + "zs ", "zignspace", "select zignspace", + "zs ", "*", "select all zignspaces", + "zs-", "zignspace", "delete zignspace", + "zs-", "*", "delete all zignspaces", + "zs+", "zignspace", "push previous zignspace and set", + "zs-", "", "pop to the previous zignspace", + "zsr ", "newname", "rename selected zignspace", + NULL}; + r_core_cmd_help (core, help_msg); } break; default: @@ -341,6 +378,7 @@ static int zignFlirt(void *data, const char *input) { break; default: eprintf ("usage: zf[dsz] filename\n"); + return false; } return true; @@ -474,6 +512,7 @@ static int zignSearch(void *data, const char *input) { break; default: eprintf ("usage: z/[*]\n"); + return false; } return true; @@ -510,7 +549,7 @@ static int cmd_zign(void *data, const char *input) { r_sign_delete (core->anal, input + 1); break; case 'o': - return zignLoad (data, input + 1); + return zignFile (data, input + 1); case 'a': return zignAdd (data, input + 1); case 'f': @@ -531,7 +570,7 @@ static int cmd_zign(void *data, const char *input) { "z-", "zignature", "delete zignature", "z-", "*", "delete all zignatures", "za", "[?]", "add zignature", - "zo", "[?]", "load zignatures from file", + "zo", "[?]", "Manage zignature files", "zf", "[?]", "manage FLIRT signatures", "z/", "[?]", "search zignatures", "zc", "", "check zignatures at address", @@ -544,6 +583,7 @@ static int cmd_zign(void *data, const char *input) { break; default: eprintf ("usage: z[*j-aof/cs] [args]\n"); + return false; } return true; diff --git a/libr/include/r_sign.h b/libr/include/r_sign.h index aa5c6f19c9..85f168f92d 100644 --- a/libr/include/r_sign.h +++ b/libr/include/r_sign.h @@ -55,6 +55,9 @@ R_API void r_sign_search_free(RSignSearch *ss); R_API void r_sign_search_init(RAnal *a, RSignSearch *ss, RSignSearchCallback cb, void *user); R_API int r_sign_search_update(RAnal *a, RSignSearch *ss, ut64 *at, const ut8 *buf, int len); +R_API bool r_sign_load(RAnal *a, const char *file); +R_API bool r_sign_save(RAnal *a, const char *file); + R_API RSignItem *r_sign_item_dup(RSignItem *it); R_API void r_sign_item_free(void *_item);