Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add / (search) commands to newshell + rewrite of rz_search #4742

Draft
wants to merge 11 commits into
base: dev
Choose a base branch
from
23 changes: 9 additions & 14 deletions librz/arch/analysis.c
Original file line number Diff line number Diff line change
Expand Up @@ -795,28 +795,23 @@ RZ_API void rz_analysis_bind(RzAnalysis *analysis, RzAnalysisBind *b) {
}
}

RZ_API RzList /*<RzSearchKeyword *>*/ *rz_analysis_preludes(RzAnalysis *analysis) {
RZ_API RzSearchCollection *rz_analysis_preludes(RzAnalysis *analysis) {
if (analysis->cur && analysis->cur->preludes) {
return analysis->cur->preludes(analysis);
}
return NULL;
}

RZ_API bool rz_analysis_is_prelude(RzAnalysis *analysis, const ut8 *data, int len) {
RzList *l = rz_analysis_preludes(analysis);
if (l) {
RzSearchKeyword *kw;
RzListIter *iter;
rz_list_foreach (l, iter, kw) {
int ks = kw->keyword_length;
if (len >= ks && !memcmp(data, kw->bin_keyword, ks)) {
rz_list_free(l);
return true;
}
}
rz_list_free(l);
RzSearchCollection *col = rz_analysis_preludes(analysis);
if (!col || len < 1) {
rz_search_collection_free(col);
return false;
}
return false;

bool any = rz_search_collection_match_any(col, data, len);
rz_search_collection_free(col);
return any;
}

RZ_API void rz_analysis_add_import(RzAnalysis *analysis, const char *imp) {
Expand Down
31 changes: 17 additions & 14 deletions librz/arch/p/analysis/analysis_arm_cs.c
Original file line number Diff line number Diff line change
Expand Up @@ -2701,29 +2701,32 @@ static ut8 *analysis_mask(RzAnalysis *analysis, int size, const ut8 *data, ut64
return ret;
}

static RzList /*<RzSearchKeyword *>*/ *analysis_preludes(RzAnalysis *analysis) {
#define KW(d, ds, m, ms) rz_list_append(l, rz_search_keyword_new((const ut8 *)d, ds, (const ut8 *)m, ms, NULL))
RzList *l = rz_list_newf((RzListFree)rz_search_keyword_free);
static RzSearchCollection *analysis_preludes(RzAnalysis *analysis) {
RzSearchCollection *sc = rz_search_collection_bytes();
if (!sc) {
return NULL;
}
#define ADD_PRELUDE(d, m, l) rz_search_collection_bytes_add(sc, NULL, (const ut8 *)d, (const ut8 *)m, l)
switch (analysis->bits) {
case 16:
KW("\x00\xb5", 2, "\x0f\xff", 2);
KW("\x08\xb5", 2, "\x0f\xff", 2);
ADD_PRELUDE("\x00\xb5", "\x0f\xff", 2);
ADD_PRELUDE("\x08\xb5", "\x0f\xff", 2);
break;
case 32:
KW("\x00\x00\x2d\xe9", 4, "\x0f\x0f\xff\xff", 4);
ADD_PRELUDE("\x00\x00\x2d\xe9", "\x0f\x0f\xff\xff", 4);
break;
case 64:
KW("\x7f\x23\x03\xd5", 4, "\xff\xff\xff\xff", 4); // pacibsp - Pointer auth
KW("\xf0\x0f\x00\xf8", 4, "\xf0\x0f\x00\xff", 4);
KW("\xf0\x00\x00\xd1", 4, "\xf0\x00\x00\xff", 4);
KW("\xf0\x00\x00\xa9", 4, "\xf0\x00\x00\xff", 4);
KW("\x7f\x23\x03\xd5\xff", 5, NULL, 0);
ADD_PRELUDE("\x7f\x23\x03\xd5", "\xff\xff\xff\xff", 4); // pacibsp - Pointer auth
ADD_PRELUDE("\xf0\x0f\x00\xf8", "\xf0\x0f\x00\xff", 4);
ADD_PRELUDE("\xf0\x00\x00\xd1", "\xf0\x00\x00\xff", 4);
ADD_PRELUDE("\xf0\x00\x00\xa9", "\xf0\x00\x00\xff", 4);
ADD_PRELUDE("\x7f\x23\x03\xd5\xff", NULL, 5);
break;
default:
rz_list_free(l);
l = NULL;
rz_search_collection_free(sc);
sc = NULL;
}
return l;
return sc;
}

static int address_bits(RzAnalysis *analysis, int bits) {
Expand Down
13 changes: 8 additions & 5 deletions librz/arch/p/analysis/analysis_mips_cs.c
Original file line number Diff line number Diff line change
Expand Up @@ -1234,11 +1234,14 @@ static int archinfo(RzAnalysis *a, RzAnalysisInfoType query) {
}
}

static RzList /*<RzSearchKeyword *>*/ *analysis_preludes(RzAnalysis *analysis) {
#define KW(d, ds, m, ms) rz_list_append(l, rz_search_keyword_new((const ut8 *)d, ds, (const ut8 *)m, ms, NULL))
RzList *l = rz_list_newf((RzListFree)rz_search_keyword_free);
KW("\x27\xbd\x00", 3, NULL, 0);
return l;
static RzSearchCollection *analysis_preludes(RzAnalysis *analysis) {
RzSearchCollection *sc = rz_search_collection_bytes();
if (!sc) {
return NULL;
}
#define ADD_PRELUDE(d, m, l) rz_search_collection_bytes_add(sc, NULL, (const ut8 *)d, (const ut8 *)m, l)
ADD_PRELUDE("\x27\xbd\x00", NULL, 3);
return sc;
}

static bool mips_fini(void *user) {
Expand Down
13 changes: 8 additions & 5 deletions librz/arch/p/analysis/analysis_ppc_cs.c
Original file line number Diff line number Diff line change
Expand Up @@ -1763,11 +1763,14 @@ static int archinfo(RzAnalysis *a, RzAnalysisInfoType query) {
}
}

static RzList /*<RzSearchKeyword *>*/ *analysis_preludes(RzAnalysis *analysis) {
#define KW(d, ds, m, ms) rz_list_append(l, rz_search_keyword_new((const ut8 *)d, ds, (const ut8 *)m, ms, NULL))
RzList *l = rz_list_newf((RzListFree)rz_search_keyword_free);
KW("\x7c\x08\x02\xa6", 4, NULL, 0);
return l;
static RzSearchCollection *analysis_preludes(RzAnalysis *analysis) {
RzSearchCollection *sc = rz_search_collection_bytes();
if (!sc) {
return NULL;
}
#define ADD_PRELUDE(d, m, l) rz_search_collection_bytes_add(sc, NULL, (const ut8 *)d, (const ut8 *)m, l)
ADD_PRELUDE("\x7c\x08\x02\xa6", NULL, 4);
return sc;
}

static RzAnalysisILConfig *il_config(RzAnalysis *analysis) {
Expand Down
34 changes: 19 additions & 15 deletions librz/arch/p/analysis/analysis_v850.c
Original file line number Diff line number Diff line change
Expand Up @@ -421,38 +421,42 @@ static char *get_reg_profile(RzAnalysis *analysis) {
/**
* All preludes are guessed by looking at the instruction at the beginning of the function
*/
static RzList /*<RzSearchKeyword *>*/ *analysis_preludes(RzAnalysis *analysis) {
#define KW(d, ds, m, ms) rz_list_append(l, rz_search_keyword_new((const ut8 *)d, ds, (const ut8 *)m, ms, NULL))
RzList *l = rz_list_newf((RzListFree)rz_search_keyword_free);

static RzSearchCollection *analysis_preludes(RzAnalysis *analysis) {
RzSearchCollection *sc = rz_search_collection_bytes();
if (!sc) {
return NULL;
}
#define ADD_PRELUDE(d, m, l) rz_search_collection_bytes_add(sc, NULL, (const ut8 *)d, (const ut8 *)m, l)

// movea 0xff, r0, r20
KW("\x20\xa6\xff\x00", 4, "\xff\xff\xff\xff", 4);
ADD_PRELUDE("\x20\xa6\xff\x00", "\xff\xff\xff\xff", 4);

// mov r6, r7
// ld.w ?[gp], r6
// prepare {lp}, 0
KW("\x06\x38\x24\x37\x01\x00\x80\x07\x21\x00", 10, "\xff\xff\xff\xff\x01\x00\xff\xff\xff\xff", 10);
ADD_PRELUDE("\x06\x38\x24\x37\x01\x00\x80\x07\x21\x00", "\xff\xff\xff\xff\x01\x00\xff\xff\xff\xff", 10);

// ld.w ?[gp], r6
// prepare {lp}, 0
KW("\x24\x37\x01\x00\x80\x07\x21\x00", 8, "\xff\xff\x01\x00\xff\xff\xff\xff", 8);
ADD_PRELUDE("\x24\x37\x01\x00\x80\x07\x21\x00", "\xff\xff\x01\x00\xff\xff\xff\xff", 8);

// prepare
KW("\x80\x07\x01\x00", 4, "\xc0\xff\x1f\x00", 4);
KW("\x80\x07\x03\x00", 4, "\xc0\xff\x1f\x00", 4);
KW("\x80\x07\x0b\x00\x00\x00", 6, "\xc0\xff\x1f\x00\x00\x00", 6);
KW("\x80\x07\x13\x00\x00\x00", 6, "\xc0\xff\x1f\x00\x00\x00", 6);
KW("\x80\x07\x1b\x00\x00\x00\x00\x00", 8, "\xc0\xff\x1f\x00\x00\x00\x00\x00", 8);
ADD_PRELUDE("\x80\x07\x01\x00", "\xc0\xff\x1f\x00", 4);
ADD_PRELUDE("\x80\x07\x03\x00", "\xc0\xff\x1f\x00", 4);
ADD_PRELUDE("\x80\x07\x0b\x00\x00\x00", "\xc0\xff\x1f\x00\x00\x00", 6);
ADD_PRELUDE("\x80\x07\x13\x00\x00\x00", "\xc0\xff\x1f\x00\x00\x00", 6);
ADD_PRELUDE("\x80\x07\x1b\x00\x00\x00\x00\x00", "\xc0\xff\x1f\x00\x00\x00\x00\x00", 8);

// trap
KW("\xe0\x07\x00\x01", 4, "\xe0\xff\xff\xff", 4);
ADD_PRELUDE("\xe0\x07\x00\x01", "\xe0\xff\xff\xff", 4);

// addi ?, sp, sp
KW("\x03\x1e\xd0\xff", 4, "\xff\xff\xff\xff", 4);
ADD_PRELUDE("\x03\x1e\xd0\xff", "\xff\xff\xff\xff", 4);

// add ?, sp
KW("\x50\x1a", 2, "\xf0\xff", 2);
return l;
ADD_PRELUDE("\x50\x1a", "\xf0\xff", 2);
return sc;
}

static int archinfo(RzAnalysis *a, RzAnalysisInfoType query) {
Expand Down
30 changes: 16 additions & 14 deletions librz/arch/p/analysis/analysis_x86_cs.c
Original file line number Diff line number Diff line change
Expand Up @@ -3702,27 +3702,29 @@ static int archinfo(RzAnalysis *a, RzAnalysisInfoType query) {
}
}

static RzList /*<RzSearchKeyword *>*/ *analysis_preludes(RzAnalysis *analysis) {
#define KW(d, ds, m, ms) rz_list_append(l, rz_search_keyword_new((const ut8 *)d, ds, (const ut8 *)m, ms, NULL))
RzList *l = rz_list_newf((RzListFree)rz_search_keyword_free);
static RzSearchCollection *analysis_preludes(RzAnalysis *analysis) {
RzSearchCollection *sc = rz_search_collection_bytes();
if (!sc) {
return NULL;
}
#define ADD_PRELUDE(d, m, l) rz_search_collection_bytes_add(sc, NULL, (const ut8 *)d, (const ut8 *)m, l)
switch (analysis->bits) {
case 32:
KW("\x8b\xff\x55\x8b\xec", 5, NULL, 0);
KW("\x55\x89\xe5", 3, NULL, 0);
KW("\x55\x8b\xec", 3, NULL, 0);
KW("\xf3\x0f\x1e\xfb", 4, NULL, 0); // endbr32
ADD_PRELUDE("\x8b\xff\x55\x8b\xec", NULL, 5);
ADD_PRELUDE("\x55\x89\xe5", NULL, 3);
ADD_PRELUDE("\x55\x8b\xec", NULL, 3);
ADD_PRELUDE("\xf3\x0f\x1e\xfb", NULL, 4); // endbr32
break;
case 64:
KW("\x55\x48\x89\xe5", 4, NULL, 0);
KW("\x55\x48\x8b\xec", 4, NULL, 0);
KW("\xf3\x0f\x1e\xfa", 4, NULL, 0); // endbr64
ADD_PRELUDE("\x55\x48\x89\xe5", NULL, 4);
ADD_PRELUDE("\x55\x48\x8b\xec", NULL, 4);
ADD_PRELUDE("\xf3\x0f\x1e\xfa", NULL, 4); // endbr64
break;
default:
rz_list_free(l);
l = NULL;
break;
rz_search_collection_free(sc);
sc = NULL;
}
return l;
return sc;
}

RzAnalysisPlugin rz_analysis_plugin_x86_cs = {
Expand Down
4 changes: 2 additions & 2 deletions librz/core/canalysis.c
Original file line number Diff line number Diff line change
Expand Up @@ -1505,7 +1505,7 @@ static bool is_skippable_addr(RzCore *core, ut64 addr) {
RZ_API int rz_core_analysis_fcn(RzCore *core, ut64 at, ut64 from, int reftype, int depth) {
if (from == UT64_MAX && is_skippable_addr(core, at)) {
RZ_LOG_DEBUG("invalid address for function 0x%08" PFMT64x "\n", at);
return 0;
return false;
}

const bool use_esil = rz_config_get_i(core->config, "analysis.esil");
Expand Down Expand Up @@ -1885,7 +1885,7 @@ RZ_API int rz_core_analysis_search(RzCore *core, ut64 from, ut64 to, ut64 ref, i
// TODO: get current section range here
// ???
// XXX must read bytes correctly
do_bckwrd_srch = bckwrds = core->search->bckwrds;
do_bckwrd_srch = bckwrds = core->search->backwards;
if (core->file) {
rz_io_use_fd(core->io, core->file->fd);
}
Expand Down
78 changes: 63 additions & 15 deletions librz/core/cconfig.c
Original file line number Diff line number Diff line change
Expand Up @@ -2415,19 +2415,66 @@ static bool cb_scrrows(void *user, void *data) {
return true;
}

static bool cb_contiguous(void *user, void *data) {
static bool cb_search_contiguous(void *user, void *data) {
RzCore *core = (RzCore *)user;
RzConfigNode *node = (RzConfigNode *)data;
core->search->contiguous = node->i_value;
core->search->contiguous = node->i_value ? true : false;
return true;
}

static bool cb_searchalign(void *user, void *data) {
static bool cb_search_align(void *user, void *data) {
RzCore *core = (RzCore *)user;
RzConfigNode *node = (RzConfigNode *)data;
core->search->align = node->i_value;
core->print->addrmod = node->i_value;
return true;
return rz_search_set_align(core->search, node->i_value);
}

static bool cb_search_distance(void *user, void *data) {
RzCore *core = (RzCore *)user;
RzConfigNode *node = (RzConfigNode *)data;
return rz_search_set_distance(core->search, node->i_value);
}

static bool cb_search_flags(void *user, void *data) {
RzCore *core = (RzCore *)user;
RzConfigNode *node = (RzConfigNode *)data;
return rz_search_set_flags(core->search, node->i_value ? true : false);
}

static bool cb_search_overlap(void *user, void *data) {
RzCore *core = (RzCore *)user;
RzConfigNode *node = (RzConfigNode *)data;
return rz_search_set_overlap(core->search, node->i_value ? true : false);
}

static bool cb_search_inverse(void *user, void *data) {
RzCore *core = (RzCore *)user;
RzConfigNode *node = (RzConfigNode *)data;
return rz_search_set_inverse(core->search, node->i_value ? true : false);
}

static bool cb_search_maxhits(void *user, void *data) {
RzCore *core = (RzCore *)user;
RzConfigNode *node = (RzConfigNode *)data;
return rz_search_set_maxhits(core->search, node->i_value);
}

static bool cb_search_from(void *user, void *data) {
RzCore *core = (RzCore *)user;
RzConfigNode *node = (RzConfigNode *)data;
return rz_search_set_from_addr(core->search, node->i_value);
}

static bool cb_search_to(void *user, void *data) {
RzCore *core = (RzCore *)user;
RzConfigNode *node = (RzConfigNode *)data;
return rz_search_set_to_addr(core->search, node->i_value);
}

static bool cb_search_prefix(void *user, void *data) {
RzCore *core = (RzCore *)user;
RzConfigNode *node = (RzConfigNode *)data;
return rz_search_set_prefix(core->search, node->value);
}

static bool cb_segoff(void *user, void *data) {
Expand Down Expand Up @@ -3745,16 +3792,18 @@ RZ_API int rz_core_config_init(RzCore *core) {
SETOPTIONS(n, "auto", "rosections", "raw", NULL);

/* search */
SETCB("search.contiguous", "true", &cb_contiguous, "Accept contiguous/adjacent search hits");
SETICB("search.align", 0, &cb_searchalign, "Only catch aligned search hits");
SETB("search.progress", false, "Shows search progress (true: enable, false: disable)");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❤️

SETICB("search.contiguous", true, &cb_search_contiguous, "Accept contiguous/adjacent search hits");
SETICB("search.align", 0, &cb_search_align, "Only catch aligned search hits");
SETI("search.chunk", 0, "Chunk size for /+ (default size is asm.bits/8");
SETI("search.esilcombo", 8, "Stop search after N consecutive hits");
SETI("search.distance", 0, "Search string distance");
SETBPREF("search.flags", "true", "All search results are flagged, otherwise only printed");
SETBPREF("search.overlap", "false", "Look for overlapped search hits");
SETI("search.maxhits", 0, "Maximum number of hits (0: no limit)");
SETI("search.from", 0, "Search start address");
SETI("search.to", UT64_MAX, "Search end address");
SETICB("search.distance", 0, &cb_search_distance, "Search string distance");
SETICB("search.flags", true, &cb_search_flags, "All search results are flagged, otherwise only printed");
SETICB("search.overlap", false, &cb_search_overlap, "Look for overlapped search hits");
SETICB("search.inverse", false, &cb_search_inverse, "Shows search progress (true: enable, false: disable)");
SETICB("search.maxhits", 0, &cb_search_maxhits, "Maximum number of hits (0: no limit)");
SETICB("search.from", 0, &cb_search_from, "Search start address");
SETICB("search.to", UT64_MAX, &cb_search_to, "Search end address");
n = NODECB("search.in", "io.maps", &cb_search_in);
SETDESC(n, "Specify search boundaries");
SETOPTIONS(n, "raw", "block",
Expand All @@ -3765,9 +3814,8 @@ RZ_API int rz_core_config_init(RzCore *core) {
"analysis.fcn", "analysis.bb",
NULL);
SETICB("search.kwidx", 0, &cb_search_kwidx, "Store last search index count");
SETPREF("search.prefix", "hit", "Prefix name in search hits label");
SETCB("search.prefix", "hit", &cb_search_prefix, "Prefix name in search hits label");
SETBPREF("search.show", "true", "Show search results");
SETI("search.to", -1, "Search end address");
n = NODECB("search.case_sensitive", "smart", &cb_search_case_sensitive);
SETDESC(n, "Set grep(~) as case smart/sensitive/insensitive");
SETOPTIONS(n, "smart", "sensitive", "insensitive", NULL);
Expand Down
4 changes: 0 additions & 4 deletions librz/core/cmd/cmd_magic.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,6 @@ static RzMagic *ck = NULL; // XXX: Use RzCore->magic
static char *ofile = NULL;
static int kw_count = 0;

static void rz_core_magic_reset(RzCore *core) {
kw_count = 0;
}

static int rz_core_magic_at(RzCore *core, const char *file, ut64 addr, int depth, int v, PJ *pj, int *hits) {
const char *fmt;
char *q, *p;
Expand Down
Loading
Loading