From 8da078247f746a08c3a4c93f8b751a25b1d118bb Mon Sep 17 00:00:00 2001 From: Sylvain Pelissier Date: Mon, 18 Nov 2024 11:26:11 +0100 Subject: [PATCH] Add /h* and make /h behave like the rest ##search --- libr/core/cmd_search.inc.c | 57 +++++++++++++++++++++++--------------- libr/crypto/hash/hash.c | 39 ++++++++++++++++++-------- test/db/cmd/hash | 37 +++++++++++++++++++------ 3 files changed, 90 insertions(+), 43 deletions(-) diff --git a/libr/core/cmd_search.inc.c b/libr/core/cmd_search.inc.c index 6a21f93d80..35d6a18ca7 100644 --- a/libr/core/cmd_search.inc.c +++ b/libr/core/cmd_search.inc.c @@ -84,7 +84,7 @@ static RCoreHelpMessage help_msg_slash_magic = { static RCoreHelpMessage help_msg_slash = { "Usage:", "/[!bf] [arg]", "Search stuff (see 'e??search' for options)\n" - "Use io.va for searching in non virtual addressing spaces", + "Use io.va for searching in non virtual addressing spaces", "/", " foo\\x00", "search for string 'foo\\0'", "/j", " foo\\x00", "search for string 'foo\\0' (json output)", "/!", " ff", "search for first occurrence not matching, command modifier", @@ -101,7 +101,7 @@ static RCoreHelpMessage help_msg_slash = { "/F", " file [off] [sz]", "search contents of file with offset and size", // TODO: add subcommands to find paths between functions and filter only function names instead of offsets, etc "/g", "[g] [from]", "find all graph paths A to B (/gg follow jumps, see search.count and anal.depth)", - "/h", "[?][algorithm] [digest] [size]", "find block of size bytes having this digest. See ph", + "/h", "[?*] [algorithm] [digest] [size]", "find block of size bytes having this digest. See ph", "/i", " foo", "search for string 'foo' ignoring case", "/k", " foo", "search for string 'foo' using Rabin Karp alg", "/m", "[?][ebm] magicfile", "search for magic, filesystems or binary headers", @@ -252,6 +252,19 @@ struct endlist_pair { int delay_size; }; +static inline void print_search_progress(ut64 at, ut64 to, int n, struct search_parameters *param) { + if ((++param->c % 64) || (param->outmode == R_MODE_JSON)) { + return; + } + if (r_cons_singleton ()->columns < 50) { + eprintf ("\r[ ] 0x%08" PFMT64x " hits = %d \r%s", + at, n, (param->c % 2)? "[ #]": "[# ]"); + } else { + eprintf ("\r[ ] 0x%08" PFMT64x " < 0x%08" PFMT64x " hits = %d \r%s", + at, to, n, (param->c % 2)? "[ #]": "[# ]"); + } +} + static int search_hash(RCore *core, const char *hashname, const char *hashstr, ut32 minlen, ut32 maxlen, struct search_parameters *param) { RIOMap *map; ut8 *buf; @@ -288,25 +301,29 @@ static int search_hash(RCore *core, const char *hashname, const char *hashstr, u } R_LOG_INFO ("Search in range 0x%08"PFMT64x " and 0x%08"PFMT64x, from, to); int blocks = (int) (to - from - len); - R_LOG_INFO ("Carving %d blocks:", blocks); + R_LOG_INFO ("Carving %d blocks", blocks); (void) r_io_read_at (core->io, from, buf, bufsz); for (i = 0; (from + i + len) < to; i++) { if (r_cons_is_breaked ()) { break; } char *s = r_hash_tostring (NULL, hashname, buf + i, len); - if (!(i % 5)) { - eprintf ("%d\r", i); - } + print_search_progress (i, to, 0, param); if (!s) { R_LOG_ERROR ("Hash fail"); break; } - // eprintf ("0x%08"PFMT64x" %s\n", from+i, s); if (!strcmp (s, hashstr)) { - R_LOG_INFO ("Found at 0x%"PFMT64x, from + i); - r_cons_printf ("f hash.%s.%s = 0x%"PFMT64x "\n", - hashname, hashstr, from + i); + if (param->searchflags) { + char hash_short[9]; + r_str_ncpy (hash_short, hashstr, sizeof (hash_short)); + r_strf_var (flag, 256, "%s.%s", hashname, hash_short); + r_cons_printf ("0x%" PFMT64x ": %s : %s\n", from + i, flag, hashstr); + r_flag_set (core->flags, flag, from + i, len); + } else { + r_cons_printf ("f hash.%s.%s = 0x%" PFMT64x "\n", hashname, hashstr, from + i); + } + free (s); free (buf); return 1; @@ -740,19 +757,6 @@ static int _cb_hit(R_NULLABLE RSearchKeyword *kw, void *user, ut64 addr) { return _cb_hit_sz (kw_used, klen, user, addr); } -static inline void print_search_progress(ut64 at, ut64 to, int n, struct search_parameters *param) { - if ((++param->c % 64) || (param->outmode == R_MODE_JSON)) { - return; - } - if (r_cons_singleton ()->columns < 50) { - eprintf ("\r[ ] 0x%08" PFMT64x " hits = %d \r%s", - at, n, (param->c % 2)? "[ #]": "[# ]"); - } else { - eprintf ("\r[ ] 0x%08" PFMT64x " < 0x%08" PFMT64x " hits = %d \r%s", - at, to, n, (param->c % 2)? "[ #]": "[# ]"); - } -} - static void append_bound(RList *list, RIO *io, RInterval search_itv, ut64 from, ut64 size, int perms) { RIOMap *map = R_NEW0 (RIOMap); if (!map) { @@ -5118,11 +5122,18 @@ reread: break; case 'h': // "/h" { + char *p, *arg = r_str_trim_dup (input + 1); if (*arg == '?') { r_core_cmd_help_match (core, help_msg_slash, "/h"); break; } + // "/h*" we do not add a flag for the search hit. + if (*arg == '*') { + param.searchflags = 0; + free (arg); + arg = r_str_trim_dup (input + 2); + } p = strchr (arg, ' '); if (p) { *p++ = 0; diff --git a/libr/crypto/hash/hash.c b/libr/crypto/hash/hash.c index 9fad24d146..fbaa1597e8 100644 --- a/libr/crypto/hash/hash.c +++ b/libr/crypto/hash/hash.c @@ -1,5 +1,6 @@ /* radare2 - LGPL - Copyright 2007-2024 pancake */ +#include #include #include #if USE_LIB_XXHASH @@ -360,19 +361,34 @@ R_API void r_hash_do_spice(RHash *ctx, ut64 algo, int loops, R_NULLABLE RHashSee R_API R_MUSTUSE char *r_hash_tostring(R_NULLABLE RHash *ctx, const char *name, const ut8 *data, int len) { R_RETURN_VAL_IF_FAIL (name && len >= 0 && data, NULL); - ut64 algo = r_hash_name_to_bits (name); char *digest_hex = NULL; - RHash *myctx = NULL; - if (!algo) { - return NULL; - } - if (!ctx) { - myctx = ctx = r_hash_new (true, algo); - } - r_hash_do_begin (ctx, algo); - int digest_size = r_hash_calculate (ctx, algo, data, len); - r_hash_do_end (ctx, algo); + int digest_size = 0; size_t digest_hex_size = 0; + + RCrypto *cry = r_crypto_new (); + RCryptoJob *cj = r_crypto_use (cry, name); + + ut64 algo = r_hash_name_to_bits (name); + if (!ctx) { + ctx = r_hash_new (true, algo); + } + + if (cj && cj->h->type == R_CRYPTO_TYPE_HASHER) { + r_crypto_job_update (cj, data, len); + ut8 *result = r_crypto_job_get_output (cj, &digest_size); + memcpy (ctx->digest, result, digest_size); + free (result); + } else { + if (!algo) { + R_LOG_ERROR ("Hash algorithm %s not found", name); + return NULL; + } + r_hash_do_begin (ctx, algo); + digest_size = r_hash_calculate (ctx, algo, data, len); + r_hash_do_end (ctx, algo); + } + r_crypto_job_free (cj); + r_crypto_free (cry); if (digest_size == 0) { digest_hex_size = 16; digest_hex = calloc (digest_hex_size, 1); @@ -393,6 +409,5 @@ R_API R_MUSTUSE char *r_hash_tostring(R_NULLABLE RHash *ctx, const char *name, c } } } - r_hash_free (myctx); return digest_hex; } diff --git a/test/db/cmd/hash b/test/db/cmd/hash index 3f9b618266..ec4ecf9c6c 100644 --- a/test/db/cmd/hash +++ b/test/db/cmd/hash @@ -104,17 +104,16 @@ ph crc32 @ $$+10 EOF EXPECT=<