Rizin
unix-like reverse engineering framework and cli tools
cmd_search.c File Reference
#include <ht_uu.h>
#include <rz_asm.h>
#include <rz_core.h>
#include <rz_io.h>
#include <rz_list.h>
#include <rz_types_base.h>
#include "../core_private.h"
#include "cmd_search_rop.c"

Go to the source code of this file.

Classes

struct  search_parameters
 
struct  endlist_pair
 

Macros

#define USE_EMULATION   0
 
#define AES_SEARCH_LENGTH   40
 
#define PRIVATE_KEY_SEARCH_LENGTH   11
 
#define USE_SKYLINE   0
 
#define MAXINSTR   8
 
#define SUMARRAY(arr, size, res)
 

Functions

static int search_hash (RzCore *core, const char *hashname, const char *hashstr, ut32 minlen, ut32 maxlen, struct search_parameters *param)
 
static void cmd_search_bin (RzCore *core, RzInterval itv)
 
static int __prelude_cb_hit (RzSearchKeyword *kw, void *user, ut64 addr)
 
RZ_API int rz_core_search_prelude (RzCore *core, ut64 from, ut64 to, const ut8 *buf, int blen, const ut8 *mask, int mlen)
 
RZ_API int rz_core_search_preludes (RzCore *core, bool log)
 
static char * getstring (char *b, int l)
 
static int _cb_hit (RzSearchKeyword *kw, void *user, ut64 addr)
 
static void print_search_progress (ut64 at, ut64 to, int n, struct search_parameters *param)
 
static void append_bound (RzList *list, RzIO *io, RzInterval search_itv, ut64 from, ut64 size, int perms)
 
static bool maskMatches (int perm, int mask, bool only)
 
RZ_API RZ_OWN RzListrz_core_get_boundaries_prot (RzCore *core, int perm, const char *mode, const char *prefix)
 
static bool is_end_gadget (const RzAnalysisOp *aop, const ut8 crop)
 
static bool insert_into (void *user, const ut64 k, const ut64 v)
 
static RzListconstruct_rop_gadget (RzCore *core, ut64 addr, ut8 *buf, int buflen, int idx, const char *grep, int regex, RzList *rx_list, struct endlist_pair *end_gadget, HtUU *badstart)
 
static void print_rop (RzCore *core, RzList *hitlist, PJ *pj, int mode)
 
static int rz_core_search_rop (RzCore *core, RzInterval search_itv, int opt, const char *grep, int regexp, struct search_parameters *param)
 
static bool esil_addrinfo (RzAnalysisEsil *esil)
 
static void do_esil_search (RzCore *core, struct search_parameters *param, const char *input)
 
static void do_syscall_search (RzCore *core, struct search_parameters *param)
 
static void do_ref_search (RzCore *core, ut64 addr, ut64 from, ut64 to, struct search_parameters *param)
 
static bool do_analysis_search (RzCore *core, struct search_parameters *param, const char *input)
 
static void do_section_search (RzCore *core, struct search_parameters *param, const char *input)
 
static void do_asm_search (RzCore *core, struct search_parameters *param, const char *input, int mode, RzInterval search_itv)
 
static void do_string_search (RzCore *core, RzInterval search_itv, struct search_parameters *param)
 
static void rop_kuery (void *data, const char *input, PJ *pj)
 
static int memcmpdiff (const ut8 *a, const ut8 *b, int len)
 
static void search_similar_pattern_in (RzCore *core, int count, ut64 from, ut64 to)
 
static void search_similar_pattern (RzCore *core, int count, struct search_parameters *param)
 
static bool isArm (RzCore *core)
 
void _CbInRangeSearchV (RzCore *core, ut64 from, ut64 to, int vsize, void *user)
 
static ut8v_writebuf (RzCore *core, RzList *nums, int len, char ch, int bsize)
 
static void incBuffer (ut8 *buf, int bufsz)
 
static void incPrintBuffer (ut8 *buf, int bufsz)
 
static void incLowerBuffer (ut8 *buf, int bufsz)
 
static void incUpperBuffer (ut8 *buf, int bufsz)
 
static void incAlphaBuffer (ut8 *buf, int bufsz)
 
static void incDigitBuffer (ut8 *buf, int bufsz)
 
static void search_collisions (RzCore *core, const char *hashName, const ut8 *hashValue, int hashLength, int mode)
 
static void __core_cmd_search_asm_infinite (RzCore *core, const char *arg)
 
static void __core_cmd_search_asm_byteswap (RzCore *core, int nth)
 
RZ_IPI int rz_cmd_search (void *data, const char *input)
 

Variables

static const char * help_msg_search_esil []
 
static const char * help_msg_slash_m []
 
static const char * help_msg_slash []
 
static const char * help_msg_slash_a []
 
static const char * help_msg_slash_c []
 
static const char * help_msg_slash_r []
 
static const char * help_msg_slash_R []
 
static const char * help_msg_slash_Rk []
 
static const char * help_msg_slash_x []
 
static int preludecnt = 0
 
static int searchflags = 0
 
static int searchshow = 0
 
static const char * searchprefix = NULL
 
static int c = 0
 

Macro Definition Documentation

◆ AES_SEARCH_LENGTH

#define AES_SEARCH_LENGTH   40

Definition at line 16 of file cmd_search.c.

◆ MAXINSTR

#define MAXINSTR   8

Definition at line 1705 of file cmd_search.c.

◆ PRIVATE_KEY_SEARCH_LENGTH

#define PRIVATE_KEY_SEARCH_LENGTH   11

Definition at line 17 of file cmd_search.c.

◆ SUMARRAY

#define SUMARRAY (   arr,
  size,
  res 
)
Value:
do \
(res) += (arr)[--(size)]; \
while ((size))
voidpf void uLong size
Definition: ioapi.h:138

Definition at line 1706 of file cmd_search.c.

◆ USE_EMULATION

#define USE_EMULATION   0

Definition at line 14 of file cmd_search.c.

◆ USE_SKYLINE

#define USE_SKYLINE   0

Function Documentation

◆ __core_cmd_search_asm_byteswap()

static void __core_cmd_search_asm_byteswap ( RzCore core,
int  nth 
)
static

Definition at line 2856 of file cmd_search.c.

2856  {
2857  RzAsmOp asmop;
2858  ut8 buf[32];
2859  int i;
2860  rz_io_read_at(core->io, 0, buf, sizeof(buf));
2861  if (nth < 0 || nth >= sizeof(buf) - 1) {
2862  return;
2863  }
2864  for (i = 0; i <= 0xff; i++) {
2865  buf[nth] = i;
2866  if (rz_asm_disassemble(core->rasm, &asmop, buf, sizeof(buf)) > 0) {
2867  const char *asmstr = rz_strbuf_get(&asmop.buf_asm);
2868  if (!strstr(asmstr, "invalid") && !strstr(asmstr, "unaligned")) {
2869  rz_cons_printf("%02x %s\n", i, asmstr);
2870  }
2871  }
2872  }
2873 }
lzma_index ** i
Definition: index.h:629
RZ_API int rz_asm_disassemble(RzAsm *a, RzAsmOp *op, const ut8 *buf, int len)
Definition: asm.c:543
RZ_API int rz_cons_printf(const char *format,...)
Definition: cons.c:1202
voidpf void * buf
Definition: ioapi.h:138
uint8_t ut8
Definition: lh5801.h:11
RZ_API bool rz_io_read_at(RzIO *io, ut64 addr, ut8 *buf, int len)
Definition: io.c:300
RZ_API char * rz_strbuf_get(RzStrBuf *sb)
Definition: strbuf.c:321
RzStrBuf buf_asm
Definition: rz_asm.h:72
RzAsm * rasm
Definition: rz_core.h:323
RzIO * io
Definition: rz_core.h:313

References rz_asm_op_t::buf_asm, search_parameters::core, i, rz_core_t::io, rz_core_t::rasm, rz_asm_disassemble(), rz_cons_printf(), rz_io_read_at(), and rz_strbuf_get().

Referenced by rz_cmd_search().

◆ __core_cmd_search_asm_infinite()

static void __core_cmd_search_asm_infinite ( RzCore core,
const char *  arg 
)
static

Definition at line 2828 of file cmd_search.c.

2828  {
2829  const char *search_in = rz_config_get(core->config, "search.in");
2830  RzList *boundaries = rz_core_get_boundaries_prot(core, -1, search_in, "search");
2831  RzListIter *iter;
2832  RzIOMap *map;
2834  ut64 at;
2835  rz_list_foreach (boundaries, iter, map) {
2836  ut64 map_begin = map->itv.addr;
2837  ut64 map_size = map->itv.size;
2838  ut64 map_end = map_begin + map_size;
2839  ut8 *buf = calloc(map_end - map_begin, 1);
2840  if (!buf) {
2841  continue;
2842  }
2843  (void)rz_io_read_at(core->io, map_begin, buf, map_size);
2844  for (at = map->itv.addr; at + 24 < map_end; at += 1) {
2845  rz_analysis_op(core->analysis, &analop, at, buf + (at - map_begin), 24, RZ_ANALYSIS_OP_MASK_HINT);
2846  if (at == analop.jump) {
2847  rz_cons_printf("0x%08" PFMT64x "\n", at);
2848  }
2849  at += analop.size;
2851  }
2852  free(buf);
2853  }
2854 }
static int analop(RzAnalysis *a, RzAnalysisOp *op, ut64 addr, const ut8 *buf, int len, RzAnalysisOpMask mask)
RZ_API RZ_OWN RzList * rz_core_get_boundaries_prot(RzCore *core, int perm, const char *mode, const char *prefix)
Definition: cmd_search.c:577
RZ_API RZ_BORROW const char * rz_config_get(RzConfig *cfg, RZ_NONNULL const char *name)
Definition: config.c:75
size_t map(int syms, int left, int len)
Definition: enough.c:237
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
void * calloc(size_t number, size_t size)
Definition: malloc.c:102
RZ_API bool rz_analysis_op_fini(RzAnalysisOp *op)
Definition: op.c:37
RZ_API int rz_analysis_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8 *data, int len, RzAnalysisOpMask mask)
Definition: op.c:96
@ RZ_ANALYSIS_OP_MASK_HINT
Definition: rz_analysis.h:443
#define PFMT64x
Definition: rz_types.h:393
RzAnalysis * analysis
Definition: rz_core.h:322
RzConfig * config
Definition: rz_core.h:300
ut64(WINAPI *w32_GetEnabledXStateFeatures)()

References analop(), rz_core_t::analysis, search_parameters::boundaries, calloc(), rz_core_t::config, search_parameters::core, free(), rz_core_t::io, map(), PFMT64x, rz_analysis_op(), rz_analysis_op_fini(), RZ_ANALYSIS_OP_MASK_HINT, rz_config_get(), rz_cons_printf(), rz_core_get_boundaries_prot(), rz_io_read_at(), and ut64().

Referenced by rz_cmd_search().

◆ __prelude_cb_hit()

static int __prelude_cb_hit ( RzSearchKeyword kw,
void *  user,
ut64  addr 
)
static

Definition at line 283 of file cmd_search.c.

283  {
284  RzCore *core = (RzCore *)user;
285  int depth = rz_config_get_i(core->config, "analysis.depth");
286  // eprintf ("ap: Found function prelude %d at 0x%08"PFMT64x"\n", preludecnt, addr);
288  preludecnt++;
289  return 1;
290 }
RZ_API int rz_core_analysis_fcn(RzCore *core, ut64 at, ut64 from, int reftype, int depth)
Definition: canalysis.c:2026
static int preludecnt
Definition: cmd_search.c:154
RZ_API ut64 rz_config_get_i(RzConfig *cfg, RZ_NONNULL const char *name)
Definition: config.c:119
@ RZ_ANALYSIS_XREF_TYPE_NULL
Definition: rz_analysis.h:899
static int addr
Definition: z80asm.c:58

References addr, rz_core_t::config, preludecnt, RZ_ANALYSIS_XREF_TYPE_NULL, rz_config_get_i(), and rz_core_analysis_fcn().

Referenced by rz_core_search_prelude().

◆ _cb_hit()

static int _cb_hit ( RzSearchKeyword kw,
void *  user,
ut64  addr 
)
static

Definition at line 403 of file cmd_search.c.

403  {
404  struct search_parameters *param = user;
405  RzCore *core = param->core;
406  const RzSearch *search = core->search;
407  ut64 base_addr = 0;
408  bool use_color = core->print->flags & RZ_PRINT_FLAGS_COLOR;
409  int keyword_len = kw ? kw->keyword_length + (search->mode == RZ_SEARCH_DELTAKEY) : 0;
410 
411  if (searchshow && kw && kw->keyword_length > 0) {
412  int len, i, extra, mallocsize;
413  char *s = NULL, *str = NULL, *p = NULL;
414  extra = (param->outmode == RZ_MODE_JSON) ? 3 : 1;
415  const char *type = "hexpair";
416  ut8 *buf = malloc(keyword_len);
417  if (!buf) {
418  return 0;
419  }
420  switch (kw->type) {
422  const int ctx = 16;
423  const int prectx = addr > 16 ? ctx : addr;
424  char *pre, *pos, *wrd;
425  const int len = keyword_len;
426  char *buf = calloc(1, len + 32 + ctx * 2);
427  type = "string";
428  rz_io_read_at(core->io, addr - prectx, (ut8 *)buf, len + (ctx * 2));
429  pre = getstring(buf, prectx);
430  pos = getstring(buf + prectx + len, ctx);
431  if (!pos) {
432  pos = strdup("");
433  }
434  if (param->outmode == RZ_MODE_JSON) {
435  wrd = getstring(buf + prectx, len);
436  s = rz_str_newf("%s%s%s", pre, wrd, pos);
437  } else {
438  wrd = rz_str_utf16_encode(buf + prectx, len);
439  s = rz_str_newf(use_color ? ".%s" Color_YELLOW "%s" Color_RESET "%s."
440  : "\"%s%s%s\"",
441  pre, wrd, pos);
442  }
443  free(buf);
444  free(pre);
445  free(wrd);
446  free(pos);
447  }
448  free(p);
449  break;
450  default:
451  len = keyword_len; // 8 byte context
452  mallocsize = (len * 2) + extra;
453  str = (len > 0xffff) ? NULL : malloc(mallocsize);
454  if (str) {
455  p = str;
456  memset(str, 0, len);
457  rz_io_read_at(core->io, base_addr + addr, buf, keyword_len);
458  if (param->outmode == RZ_MODE_JSON) {
459  p = str;
460  }
461  const int bytes = (len > 40) ? 40 : len;
462  for (i = 0; i < bytes; i++) {
463  sprintf(p, "%02x", buf[i]);
464  p += 2;
465  }
466  if (bytes != len) {
467  strcpy(p, "...");
468  p += 3;
469  }
470  *p = 0;
471  } else {
472  eprintf("Cannot allocate %d\n", mallocsize);
473  }
474  s = str;
475  str = NULL;
476  break;
477  }
478 
479  if (param->outmode == RZ_MODE_JSON) {
480  pj_o(param->pj);
481  pj_kN(param->pj, "offset", base_addr + addr);
482  pj_ks(param->pj, "type", type);
483  pj_ks(param->pj, "data", s);
484  pj_end(param->pj);
485  } else {
486  rz_cons_printf("0x%08" PFMT64x " %s%d_%d %s\n",
487  base_addr + addr, searchprefix, kw->kwidx, kw->count, s);
488  }
489  free(s);
490  free(buf);
491  free(str);
492  } else if (kw) {
493  if (param->outmode == RZ_MODE_JSON) {
494  pj_o(param->pj);
495  pj_kN(param->pj, "offset", base_addr + addr);
496  pj_ki(param->pj, "len", keyword_len);
497  pj_end(param->pj);
498  } else {
499  if (searchflags) {
500  rz_cons_printf("%s%d_%d\n", searchprefix, kw->kwidx, kw->count);
501  } else {
502  rz_cons_printf("f %s%d_%d %d @ 0x%08" PFMT64x "\n", searchprefix,
503  kw->kwidx, kw->count, keyword_len, base_addr + addr);
504  }
505  }
506  }
507  if (searchflags && kw) {
508  const char *flag = sdb_fmt("%s%d_%d", searchprefix, kw->kwidx, kw->count);
509  rz_flag_set(core->flags, flag, base_addr + addr, keyword_len);
510  }
511  if (*param->cmd_hit) {
512  ut64 here = core->offset;
513  rz_core_seek(core, base_addr + addr, true);
514  rz_core_cmd(core, param->cmd_hit, 0);
515  rz_core_seek(core, here, true);
516  }
517  return true;
518 }
size_t len
Definition: 6502dis.c:15
static ut8 bytes[32]
Definition: asm_arc.c:23
void search()
Definition: cabinfo.c:91
RZ_API int rz_core_cmd(RzCore *core, const char *cstr, int log)
Definition: cmd.c:5328
static char * getstring(char *b, int l)
Definition: cmd_search.c:388
static const char * searchprefix
Definition: cmd_search.c:157
static int searchshow
Definition: cmd_search.c:156
static int searchflags
Definition: cmd_search.c:155
#define NULL
Definition: cris-opc.c:27
RZ_API RzFlagItem * rz_flag_set(RzFlag *f, const char *name, ut64 off, ut32 size)
Definition: flag.c:521
RZ_API char * sdb_fmt(const char *fmt,...)
Definition: fmt.c:26
sprintf
Definition: kernel.h:365
return memset(p, 0, total)
void * p
Definition: libc.cpp:67
void * malloc(size_t size)
Definition: malloc.c:123
return strdup("=SP r13\n" "=LR r14\n" "=PC r15\n" "=A0 r0\n" "=A1 r1\n" "=A2 r2\n" "=A3 r3\n" "=ZF zf\n" "=SF nf\n" "=OF vf\n" "=CF cf\n" "=SN or0\n" "gpr lr .32 56 0\n" "gpr pc .32 60 0\n" "gpr cpsr .32 64 0 ____tfiae_________________qvczn\n" "gpr or0 .32 68 0\n" "gpr tf .1 64.5 0 thumb\n" "gpr ef .1 64.9 0 endian\n" "gpr jf .1 64.24 0 java\n" "gpr qf .1 64.27 0 sticky_overflow\n" "gpr vf .1 64.28 0 overflow\n" "gpr cf .1 64.29 0 carry\n" "gpr zf .1 64.30 0 zero\n" "gpr nf .1 64.31 0 negative\n" "gpr itc .4 64.10 0 if_then_count\n" "gpr gef .4 64.16 0 great_or_equal\n" "gpr r0 .32 0 0\n" "gpr r1 .32 4 0\n" "gpr r2 .32 8 0\n" "gpr r3 .32 12 0\n" "gpr r4 .32 16 0\n" "gpr r5 .32 20 0\n" "gpr r6 .32 24 0\n" "gpr r7 .32 28 0\n" "gpr r8 .32 32 0\n" "gpr r9 .32 36 0\n" "gpr r10 .32 40 0\n" "gpr r11 .32 44 0\n" "gpr r12 .32 48 0\n" "gpr r13 .32 52 0\n" "gpr r14 .32 56 0\n" "gpr r15 .32 60 0\n" "gpr r16 .32 64 0\n" "gpr r17 .32 68 0\n")
int type
Definition: mipsasm.c:17
#define eprintf(x, y...)
Definition: rlcc.c:7
static RzSocket * s
Definition: rtr.c:28
#define Color_RESET
Definition: rz_cons.h:617
#define Color_YELLOW
Definition: rz_cons.h:631
RZ_API PJ * pj_ki(PJ *j, const char *k, int d)
Definition: pj.c:149
RZ_API PJ * pj_end(PJ *j)
Definition: pj.c:87
RZ_API PJ * pj_o(PJ *j)
Definition: pj.c:75
RZ_API PJ * pj_ks(PJ *j, const char *k, const char *v)
Definition: pj.c:170
RZ_API PJ * pj_kN(PJ *j, const char *k, st64 n)
Definition: pj.c:128
#define RZ_PRINT_FLAGS_COLOR
Definition: rz_print.h:15
#define RZ_SEARCH_KEYWORD_TYPE_STRING
Definition: rz_search.h:32
@ RZ_SEARCH_DELTAKEY
Definition: rz_search.h:24
RZ_API char * rz_str_newf(const char *fmt,...) RZ_PRINTF_CHECK(1
RZ_API char * rz_str_utf16_encode(const char *s, int len)
Definition: str.c:2993
#define RZ_MODE_JSON
Definition: rz_types.h:29
RZ_API bool rz_core_seek(RzCore *core, ut64 addr, bool rb)
Seek to addr.
Definition: seek.c:116
RzSearch * search
Definition: rz_core.h:331
ut64 offset
Definition: rz_core.h:301
RzFlag * flags
Definition: rz_core.h:330
RzPrint * print
Definition: rz_core.h:327
int flags
Definition: rz_print.h:137
const char * cmd_hit
Definition: cmd_search.c:163
int pos
Definition: main.c:11

References addr, bytes, calloc(), search_parameters::cmd_hit, Color_RESET, Color_YELLOW, search_parameters::core, rz_search_keyword_t::count, eprintf, rz_core_t::flags, rz_print_t::flags, free(), getstring(), i, rz_core_t::io, rz_search_keyword_t::keyword_length, rz_search_keyword_t::kwidx, len, malloc(), memset(), NULL, rz_core_t::offset, search_parameters::outmode, p, PFMT64x, search_parameters::pj, pj_end(), pj_ki(), pj_kN(), pj_ks(), pj_o(), pos, rz_core_t::print, rz_cons_printf(), rz_core_cmd(), rz_core_seek(), rz_flag_set(), rz_io_read_at(), RZ_MODE_JSON, RZ_PRINT_FLAGS_COLOR, RZ_SEARCH_DELTAKEY, RZ_SEARCH_KEYWORD_TYPE_STRING, rz_str_newf(), rz_str_utf16_encode(), s, sdb_fmt(), rz_core_t::search, search(), searchflags, searchprefix, searchshow, sprintf, cmd_descs_generate::str, strdup(), type, rz_search_keyword_t::type, and ut64().

Referenced by do_esil_search(), and do_string_search().

◆ _CbInRangeSearchV()

void _CbInRangeSearchV ( RzCore core,
ut64  from,
ut64  to,
int  vsize,
void *  user 
)

Definition at line 2578 of file cmd_search.c.

2578  {
2579  struct search_parameters *param = user;
2580  bool isarm = isArm(core);
2581  // this is expensive operation that could be cached but is a callback
2582  // and for not messing adding a new param
2583  const char *prefix = rz_config_get(core->config, "search.prefix");
2584  if (isarm) {
2585  if (to & 1) {
2586  to--;
2587  }
2588  }
2589  if (param->outmode != RZ_MODE_JSON) {
2590  rz_cons_printf("0x%" PFMT64x ": 0x%" PFMT64x "\n", from, to);
2591  } else {
2592  pj_o(param->pj);
2593  pj_kN(param->pj, "offset", from);
2594  pj_kN(param->pj, "value", to);
2595  pj_end(param->pj);
2596  }
2597  rz_core_cmdf(core, "f %s.value.0x%08" PFMT64x " %d @ 0x%08" PFMT64x " \n", prefix, to, vsize, to); // flag at value of hit
2598  rz_core_cmdf(core, "f %s.offset.0x%08" PFMT64x " %d @ 0x%08" PFMT64x " \n", prefix, from, vsize, from); // flag at offset of hit
2599  const char *cmdHit = rz_config_get(core->config, "cmd.hit");
2600  if (cmdHit && *cmdHit) {
2601  ut64 addr = core->offset;
2602  rz_core_seek(core, from, true);
2603  rz_core_cmd(core, cmdHit, 0);
2604  rz_core_seek(core, addr, true);
2605  }
2606 }
RZ_API int rz_core_cmdf(RzCore *core, const char *fmt,...)
Definition: cmd.c:5413
static bool isArm(RzCore *core)
Definition: cmd_search.c:2566
unsigned short prefix[65536]
Definition: gun.c:163
static struct sockaddr static addrlen static backlog const void static flags void struct sockaddr from
Definition: sfsocketcall.h:123
static struct sockaddr static addrlen static backlog const void static flags void struct sockaddr socklen_t static fromlen const void const struct sockaddr to
Definition: sfsocketcall.h:125

References addr, rz_core_t::config, search_parameters::core, from, isArm(), rz_core_t::offset, search_parameters::outmode, PFMT64x, search_parameters::pj, pj_end(), pj_kN(), pj_o(), prefix, rz_config_get(), rz_cons_printf(), rz_core_cmd(), rz_core_cmdf(), rz_core_seek(), RZ_MODE_JSON, to, and ut64().

Referenced by rz_cmd_search().

◆ append_bound()

static void append_bound ( RzList list,
RzIO io,
RzInterval  search_itv,
ut64  from,
ut64  size,
int  perms 
)
static

Definition at line 535 of file cmd_search.c.

535  {
537  if (!map) {
538  return;
539  }
540  if (io && io->desc) {
541  map->fd = rz_io_fd_get_current(io);
542  }
543 
544  map->perm = perms;
545  RzInterval itv = { from, size };
546  if (size == -1) {
547  eprintf("Warning: Invalid range. Use different search.in=? or analysis.in=dbg.maps.x\n");
548  free(map);
549  return;
550  }
551  // TODO UT64_MAX is a valid address. search.from and search.to are not specified
552  if (search_itv.addr == UT64_MAX && !search_itv.size) {
553  map->itv = itv;
555  } else if (rz_itv_overlap(itv, search_itv)) {
556  map->itv = rz_itv_intersect(itv, search_itv);
557  if (map->itv.size) {
559  } else {
560  free(map);
561  }
562  } else {
563  free(map);
564  }
565 }
static void list(RzEgg *egg)
Definition: rz-gg.c:52
RZ_API RZ_BORROW RzListIter * rz_list_append(RZ_NONNULL RzList *list, void *data)
Appends at the end of the list a new element.
Definition: list.c:288
RZ_API int rz_io_fd_get_current(RzIO *io)
Definition: io_fd.c:135
static bool rz_itv_overlap(RzInterval itv, RzInterval x)
Definition: rz_itv.h:64
static RzInterval rz_itv_intersect(RzInterval itv, RzInterval x)
Definition: rz_itv.h:76
#define RZ_NEW0(x)
Definition: rz_types.h:284
#define UT64_MAX
Definition: rz_types_base.h:86
ut64 addr
Definition: rz_itv.h:15
ut64 size
Definition: rz_itv.h:16
struct rz_io_desc_t * desc
Definition: rz_io.h:60

References rz_interval_t::addr, rz_io_t::desc, eprintf, free(), from, list(), map(), rz_io_fd_get_current(), rz_itv_intersect(), rz_itv_overlap(), rz_list_append(), RZ_NEW0, rz_interval_t::size, and UT64_MAX.

Referenced by rz_core_get_boundaries_prot().

◆ cmd_search_bin()

static void cmd_search_bin ( RzCore core,
RzInterval  itv 
)
static

Definition at line 246 of file cmd_search.c.

246  {
247  ut64 from = itv.addr, to = rz_itv_end(itv);
248  int size; // , sz = sizeof (buf);
249 
250  int fd = core->file->fd;
253  while (from < to) {
254  if (rz_cons_is_breaked()) {
255  break;
256  }
257  RzBuffer *ref = rz_buf_new_slice(b, from, to);
258  RzBinPlugin *plug = rz_bin_get_binplugin_by_buffer(core->bin, ref);
259  if (plug) {
260  rz_cons_printf("0x%08" PFMT64x " %s\n", from, plug->name);
261  if (plug->size) {
262  RzBinOptions opt = {
263  .pluginname = plug->name,
264  .obj_opts = { 0 },
265  .sz = 4096,
266  .xtr_idx = 0,
267  .fd = fd,
268  };
269  rz_bin_open_io(core->bin, &opt);
270  size = plug->size(core->bin->cur);
271  if (size > 0) {
272  rz_cons_printf("size %d\n", size);
273  }
274  }
275  }
276  rz_buf_free(ref);
277  from++;
278  }
279  rz_buf_free(b);
281 }
RZ_API RzBinPlugin * rz_bin_get_binplugin_by_buffer(RzBin *bin, RzBuffer *buf)
Definition: bin.c:349
RZ_API RzBinFile * rz_bin_open_io(RzBin *bin, RzBinOptions *opt)
Definition: bin.c:283
RZ_API void rz_cons_break_pop(void)
Definition: cons.c:361
RZ_API void rz_cons_break_push(RzConsBreak cb, void *user)
Definition: cons.c:357
RZ_API bool rz_cons_is_breaked(void)
Definition: cons.c:373
RZ_API RZ_OWN RzBuffer * rz_buf_new_with_io_fd(RZ_NONNULL void *iob, int fd)
Creates a new buffer wrapping a file descriptor accessed through RzIOBind.
Definition: buf.c:490
RZ_API void rz_buf_free(RzBuffer *b)
Free all internal data hold by the buffer and the buffer.
Definition: buf.c:1253
RZ_API RZ_OWN RzBuffer * rz_buf_new_slice(RzBuffer *b, ut64 offset, ut64 size)
Creates a new buffer from a slice of another buffer.
Definition: buf.c:364
static ut64 rz_itv_end(RzInterval itv)
Definition: rz_itv.h:42
#define b(i)
Definition: sha256.c:42
RzIOBind iob
Definition: rz_analysis.h:574
char * name
Definition: rz_bin.h:509
ut64(* size)(RzBinFile *bin)
Definition: rz_bin.h:516
RZ_DEPRECATE RzBinFile * cur
never use this in new code! Get a file from the binfiles list or track it yourself.
Definition: rz_bin.h:330
RzBin * bin
Definition: rz_core.h:298
RzCoreFile * file
Definition: rz_core.h:314
static const z80_opcode fd[]
Definition: z80_tab.h:997

References rz_interval_t::addr, rz_core_t::analysis, b, rz_core_t::bin, rz_bin_t::cur, fd, rz_core_file_t::fd, rz_core_t::file, from, rz_analysis_t::iob, rz_bin_plugin_t::name, NULL, PFMT64x, rz_bin_get_binplugin_by_buffer(), rz_bin_open_io(), rz_buf_free(), rz_buf_new_slice(), rz_buf_new_with_io_fd(), rz_cons_break_pop(), rz_cons_break_push(), rz_cons_is_breaked(), rz_cons_printf(), rz_itv_end(), rz_bin_plugin_t::size, to, and ut64().

Referenced by rz_cmd_search().

◆ construct_rop_gadget()

static RzList* construct_rop_gadget ( RzCore core,
ut64  addr,
ut8 buf,
int  buflen,
int  idx,
const char *  grep,
int  regex,
RzList rx_list,
struct endlist_pair end_gadget,
HtUU *  badstart 
)
static

Definition at line 990 of file cmd_search.c.

990  {
991  int endaddr = end_gadget->instr_offset;
992  int branch_delay = end_gadget->delay_size;
993  RzAnalysisOp aop = { 0 };
994  const char *start = NULL, *end = NULL;
995  char *grep_str = NULL;
996  RzCoreAsmHit *hit = NULL;
997  RzList *hitlist = rz_core_asm_hit_list_new();
998  ut8 nb_instr = 0;
999  const ut8 max_instr = rz_config_get_i(core->config, "rop.len");
1000  bool valid = false;
1001  int grep_find;
1002  int search_hit;
1003  char *rx = NULL;
1004  HtUUOptions opt = { 0 };
1005  HtUU *localbadstart = ht_uu_new_opt(&opt);
1006  int count = 0;
1007 
1008  if (grep) {
1009  start = grep;
1010  end = strchr(grep, ';');
1011  if (!end) { // We filter on a single opcode, so no ";"
1012  end = start + strlen(grep);
1013  }
1014  grep_str = calloc(1, end - start + 1);
1015  strncpy(grep_str, start, end - start);
1016  if (regex) {
1017  // get the first regexp.
1018  if (rz_list_length(rx_list) > 0) {
1019  rx = rz_list_get_n(rx_list, count++);
1020  }
1021  }
1022  }
1023 
1024  bool found;
1025  ht_uu_find(badstart, idx, &found);
1026  if (found) {
1027  valid = false;
1028  goto ret;
1029  }
1030  while (nb_instr < max_instr) {
1031  ht_uu_insert(localbadstart, idx, 1);
1032 
1034  if (error < 0 || (nb_instr == 0 && (is_end_gadget(&aop, 0) || aop.type == RZ_ANALYSIS_OP_TYPE_NOP))) {
1035  valid = false;
1036  goto ret;
1037  }
1038 
1039  const int opsz = aop.size;
1040  // opsz = rz_strbuf_length (asmop.buf);
1041  char *opst = aop.mnemonic;
1042  if (!opst) {
1043  RZ_LOG_WARN("Analysis plugin %s did not return disassembly\n", core->analysis->cur->name);
1044  RzAsmOp asmop;
1045  rz_asm_set_pc(core->rasm, addr);
1046  if (rz_asm_disassemble(core->rasm, &asmop, buf + idx, buflen - idx) < 0) {
1047  valid = false;
1048  goto ret;
1049  }
1050  opst = strdup(rz_asm_op_get_asm(&asmop));
1051  rz_asm_op_fini(&asmop);
1052  }
1053  if (!rz_str_ncasecmp(opst, "invalid", strlen("invalid")) ||
1054  !rz_str_ncasecmp(opst, ".byte", strlen(".byte"))) {
1055  valid = false;
1056  goto ret;
1057  }
1058 
1060  if (hit) {
1061  hit->addr = addr;
1062  hit->len = opsz;
1063  rz_list_append(hitlist, hit);
1064  }
1065 
1066  // Move on to the next instruction
1067  idx += opsz;
1068  addr += opsz;
1069  if (rx) {
1070  grep_find = !rz_regex_match(rx, "e", opst);
1071  search_hit = (end && grep && (grep_find < 1));
1072  } else {
1073  search_hit = (end && grep && strstr(opst, grep_str));
1074  }
1075 
1076  // Handle (possible) grep
1077  if (search_hit) {
1078  if (end[0] == ';') { // fields are semicolon-separated
1079  start = end + 1; // skip the ;
1080  end = strchr(start, ';');
1081  end = end ? end : start + strlen(start); // latest field?
1082  free(grep_str);
1083  grep_str = calloc(1, end - start + 1);
1084  if (grep_str) {
1085  strncpy(grep_str, start, end - start);
1086  }
1087  } else {
1088  end = NULL;
1089  }
1090  if (regex) {
1091  rx = rz_list_get_n(rx_list, count++);
1092  }
1093  }
1094  if (endaddr <= (idx - opsz)) {
1095  valid = (endaddr == idx - opsz);
1096  goto ret;
1097  }
1098  rz_analysis_op_fini(&aop);
1099  nb_instr++;
1100  }
1101 ret:
1102  rz_analysis_op_fini(&aop);
1103  free(grep_str);
1104  if (regex && rx) {
1105  rz_list_free(hitlist);
1106  ht_uu_free(localbadstart);
1107  return NULL;
1108  }
1109  if (!valid || (grep && end)) {
1110  rz_list_free(hitlist);
1111  ht_uu_free(localbadstart);
1112  return NULL;
1113  }
1114  ht_uu_foreach(localbadstart, insert_into, badstart);
1115  ht_uu_free(localbadstart);
1116  // If our arch has bds then we better be including them
1117  if (branch_delay && rz_list_length(hitlist) < (1 + branch_delay)) {
1118  rz_list_free(hitlist);
1119  return NULL;
1120  }
1121  return hitlist;
1122 }
RZ_API void rz_asm_op_fini(RzAsmOp *op)
Definition: aop.c:21
RZ_API char * rz_asm_op_get_asm(RzAsmOp *op)
Definition: aop.c:37
RZ_API int rz_asm_set_pc(RzAsm *a, ut64 pc)
Definition: asm.c:533
RZ_API RzCoreAsmHit * rz_core_asm_hit_new(void)
Definition: casm.c:28
RZ_API RzList * rz_core_asm_hit_list_new(void)
Definition: casm.c:38
static bool is_end_gadget(const RzAnalysisOp *aop, const ut8 crop)
Definition: cmd_search.c:951
static bool insert_into(void *user, const ut64 k, const ut64 v)
Definition: cmd_search.c:983
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void count
Definition: sflib.h:98
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void static offset struct stat static buf void long static basep static whence static length const void static len static semflg const void static shmflg const struct timespec struct timespec static rem const char static group const void start
Definition: sflib.h:133
RZ_API const KEY_TYPE bool * found
Definition: ht_inc.h:130
static int hit(RzSearchKeyword *kw, void *user, ut64 addr)
Definition: rz-find.c:58
RZ_API RZ_BORROW void * rz_list_get_n(RZ_NONNULL const RzList *list, ut32 n)
Returns the N-th element of the list.
Definition: list.c:574
RZ_API ut32 rz_list_length(RZ_NONNULL const RzList *list)
Returns the length of the list.
Definition: list.c:109
RZ_API void rz_list_free(RZ_NONNULL RzList *list)
Empties the list and frees the list pointer.
Definition: list.c:137
int idx
Definition: setup.py:197
@ RZ_ANALYSIS_OP_MASK_DISASM
Definition: rz_analysis.h:445
@ RZ_ANALYSIS_OP_TYPE_NOP
Definition: rz_analysis.h:389
#define RZ_LOG_WARN(fmtstr,...)
Definition: rz_log.h:56
RZ_API int rz_regex_match(const char *pattern, const char *flags, const char *text)
Definition: regcomp.c:142
RZ_API int rz_str_ncasecmp(const char *dst, const char *orig, size_t n)
Definition: str.c:129
int instr_offset
Definition: cmd_search.c:172
struct rz_analysis_plugin_t * cur
Definition: rz_analysis.h:586
bool valid
Definition: core.c:77
ut64 buflen
Definition: core.c:76
void error(const char *msg)
Definition: untgz.c:593

References addr, rz_core_t::analysis, buflen, calloc(), rz_core_t::config, search_parameters::core, count, rz_analysis_t::cur, endlist_pair::delay_size, test_evm::end, error(), found, free(), hit(), setup::idx, insert_into(), endlist_pair::instr_offset, is_end_gadget(), rz_analysis_op_t::mnemonic, rz_analysis_plugin_t::name, NULL, rz_core_t::rasm, rz_analysis_op(), rz_analysis_op_fini(), RZ_ANALYSIS_OP_MASK_DISASM, RZ_ANALYSIS_OP_TYPE_NOP, rz_asm_disassemble(), rz_asm_op_fini(), rz_asm_op_get_asm(), rz_asm_set_pc(), rz_config_get_i(), rz_core_asm_hit_list_new(), rz_core_asm_hit_new(), rz_list_append(), rz_list_free(), rz_list_get_n(), rz_list_length(), RZ_LOG_WARN, rz_regex_match(), rz_str_ncasecmp(), rz_analysis_op_t::size, start, strdup(), rz_analysis_op_t::type, and valid.

Referenced by rz_core_search_rop().

◆ do_analysis_search()

static bool do_analysis_search ( RzCore core,
struct search_parameters param,
const char *  input 
)
static

Definition at line 1949 of file cmd_search.c.

1949  {
1950  RzSearch *search = core->search;
1951  ut64 at;
1952  RzAnalysisOp aop;
1953  int type = 0;
1954  int mode = 0;
1955  int kwidx = core->search->n_kws;
1956  int i, ret, count = 0;
1957 
1958  while (*input && *input != ' ') {
1959  switch (*input) {
1960  case 'j':
1961  case 'q':
1962  mode = *input;
1963  break;
1964  case 'l': // "/alt" "/alf"
1965  switch (type) {
1966  case 't': // "/alt"
1967  case 'f': // "/alf"
1968  for (i = 0; i < 64; i++) {
1969  const char *str = type == 'f'
1972  if (!str || !*str) {
1973  break;
1974  }
1975  if (!strcmp(str, "undefined")) {
1976  continue;
1977  }
1979  }
1980  break;
1981  case 's': { // "/als"
1982  RzListIter *iter;
1983  RzSyscallItem *si;
1985  rz_list_foreach (list, iter, si) {
1986  rz_cons_printf("%s = 0x%02x.%s\n",
1987  si->name, si->swi, syscallNumber(si->num));
1988  }
1989  rz_list_free(list);
1990  break;
1991  }
1992  case 0:
1993  rz_core_cmd0(core, "aoml");
1994  break;
1995  default:
1996  RZ_LOG_ERROR("/al%c - unknown command\n", type);
1997  break;
1998  }
1999  return false;
2000  case 'f': // "/af"
2001  case 's': // "/as"
2002  case 't': // "/at"
2003  case 'm': // "/am"
2004  case ' ':
2005  type = *input;
2006  break;
2007  case 0:
2008  case '?':
2009  default:
2011  return false;
2012  }
2013  input++;
2014  }
2015  if (type == 's') {
2017  return true;
2018  }
2019  if (mode == 'j') {
2020  pj_a(param->pj);
2021  }
2024  RzIOMap *map;
2025  RzListIter *iter;
2026  rz_list_foreach (param->boundaries, iter, map) {
2027  ut64 from = map->itv.addr;
2028  ut64 to = rz_itv_end(map->itv);
2029  for (i = 0, at = from; at < to; i++, at++) {
2030  if (rz_cons_is_breaked()) {
2031  break;
2032  }
2033  at = from + i;
2034  ut8 bufop[32];
2035  rz_io_read_at(core->io, at, bufop, sizeof(bufop));
2036  ret = rz_analysis_op(core->analysis, &aop, at, bufop, sizeof(bufop), RZ_ANALYSIS_OP_MASK_BASIC | RZ_ANALYSIS_OP_MASK_DISASM);
2037  if (ret > 0) {
2038  bool match = false;
2039  if (type == 'm') {
2040  const char *fam = aop.mnemonic;
2041  if (fam && (!*input || rz_str_startswith(fam, input))) {
2042  match = true;
2043  }
2044  } else if (type == 'f') {
2045  const char *fam = rz_analysis_op_family_to_string(aop.family);
2046  if (fam && (!*input || !strcmp(input, fam))) {
2047  match = true;
2048  }
2049  } else {
2050  const char *type = rz_analysis_optype_to_string(aop.type);
2051  if (type) {
2052  bool isCandidate = !*input;
2053  if (!strcmp(input, "cswi")) {
2054  if (!strcmp(input + 1, type)) {
2055  isCandidate = true;
2056  }
2057  } else {
2058  if (!strcmp(input, type)) {
2059  isCandidate = true;
2060  }
2061  }
2062  if (isCandidate) {
2063  if (strstr(input, "swi")) {
2064  if (*input == 'c') {
2065  match = true; // aop.cond;
2066  } else {
2067  match = !aop.cond;
2068  }
2069  } else {
2070  match = true;
2071  }
2072  }
2073  }
2074  }
2075  if (match) {
2076  // char *opstr = rz_core_disassemble_instr (core, at, 1);
2077  char *opstr = rz_core_op_str(core, at);
2078  switch (mode) {
2079  case 'j':
2080  pj_o(param->pj);
2081  pj_kN(param->pj, "addr", at);
2082  pj_ki(param->pj, "size", ret);
2083  pj_ks(param->pj, "opstr", opstr);
2084  pj_end(param->pj);
2085  break;
2086  case 'q':
2087  rz_cons_printf("0x%08" PFMT64x "\n", at);
2088  break;
2089  default:
2090  if (type == 'f') {
2091  const char *fam = rz_analysis_op_family_to_string(aop.family);
2092  rz_cons_printf("0x%08" PFMT64x " %d %s %s\n", at, ret, fam, opstr);
2093  } else {
2094  rz_cons_printf("0x%08" PFMT64x " %d %s\n", at, ret, opstr);
2095  }
2096  break;
2097  }
2098  RZ_FREE(opstr);
2099  if (*input && searchflags) {
2100  char flag[64];
2101  snprintf(flag, sizeof(flag), "%s%d_%d",
2102  searchprefix, kwidx, count);
2103  rz_flag_set(core->flags, flag, at, ret);
2104  }
2105  if (*param->cmd_hit) {
2106  ut64 here = core->offset;
2107  rz_core_seek(core, at, true);
2108  rz_core_cmd(core, param->cmd_hit, 0);
2109  rz_core_seek(core, here, true);
2110  }
2111  count++;
2112  if (search->maxhits && count >= search->maxhits) {
2113  goto done;
2114  }
2115  }
2116  int inc = (core->search->align > 0) ? core->search->align - 1 : ret - 1;
2117  if (inc < 0) {
2118  inc = 0;
2119  }
2120  i += inc;
2121  at += inc;
2122  }
2123  }
2124  }
2125 done:
2126  if (mode == 'j') {
2127  pj_end(param->pj);
2128  }
2130  return false;
2131 }
si
static int opstr(RzAsm *a, ut8 *data, const Opcode *op)
Definition: asm_x86_nz.c:4054
RZ_API int rz_core_cmd0(RzCore *core, const char *cmd)
Definition: cmd.c:5428
RZ_API void rz_core_cmd_help(const RzCore *core, const char *help[])
Definition: cmd.c:163
static const char * syscallNumber(int n)
static const char * help_msg_slash_a[]
Definition: cmd_search.c:86
RZ_API void rz_cons_println(const char *str)
Definition: cons.c:233
struct tab * done
Definition: enough.c:233
const char int mode
Definition: ioapi.h:137
snprintf
Definition: kernel.h:364
RZ_API char * rz_core_op_str(RzCore *core, ut64 addr)
Definition: core.c:2869
RZ_API const char * rz_analysis_optype_to_string(int type)
Definition: op.c:310
RZ_API const char * rz_analysis_op_family_to_string(int id)
Definition: op.c:560
@ RZ_ANALYSIS_OP_MASK_BASIC
Definition: rz_analysis.h:440
#define rz_warn_if_reached()
Definition: rz_assert.h:29
#define RZ_LOG_ERROR(fmtstr,...)
Definition: rz_log.h:58
RZ_API PJ * pj_a(PJ *j)
Definition: pj.c:81
RZ_API const char * rz_str_trim_head_ro(const char *str)
Definition: str_trim.c:86
RZ_API bool rz_str_startswith(RZ_NONNULL const char *str, RZ_NONNULL const char *needle)
Checks if a string starts with a specifc sequence of characters (case sensitive)
Definition: str.c:3286
#define RZ_FREE(x)
Definition: rz_types.h:369
Definition: engine.c:71
RzAnalysisOpFamily family
Definition: rz_analysis.h:823
RzTypeCond cond
Definition: rz_analysis.h:818
RzSyscall * syscall
Definition: rz_analysis.h:570
RzList * boundaries
Definition: cmd_search.c:161
RZ_API RzList * rz_syscall_list(RzSyscall *s)
Definition: syscall.c:415
if(dbg->bits==RZ_SYS_BITS_64)
Definition: windows-arm64.h:4
static bool input(void *ud, zip_uint8_t *data, zip_uint64_t length)

References rz_search_t::align, rz_core_t::analysis, search_parameters::boundaries, search_parameters::cmd_hit, rz_analysis_op_t::cond, count, done, rz_analysis_op_t::family, rz_core_t::flags, from, help_msg_slash_a, i, if(), input(), rz_core_t::io, list(), map(), rz_analysis_op_t::mnemonic, rz_search_t::n_kws, NULL, rz_core_t::offset, opstr(), PFMT64x, search_parameters::pj, pj_a(), pj_end(), pj_ki(), pj_kN(), pj_ks(), pj_o(), rz_analysis_op(), rz_analysis_op_family_to_string(), RZ_ANALYSIS_OP_MASK_BASIC, RZ_ANALYSIS_OP_MASK_DISASM, rz_analysis_optype_to_string(), rz_cons_break_pop(), rz_cons_break_push(), rz_cons_is_breaked(), rz_cons_printf(), rz_cons_println(), rz_core_cmd(), rz_core_cmd0(), rz_core_cmd_help(), rz_core_op_str(), rz_core_seek(), rz_flag_set(), RZ_FREE, rz_io_read_at(), rz_itv_end(), rz_list_free(), RZ_LOG_ERROR, rz_str_startswith(), rz_str_trim_head_ro(), rz_syscall_list(), rz_warn_if_reached, rz_core_t::search, search(), searchflags, searchprefix, si, snprintf, cmd_descs_generate::str, rz_analysis_t::syscall, syscallNumber(), to, type, rz_analysis_op_t::type, and ut64().

Referenced by rz_cmd_search().

◆ do_asm_search()

static void do_asm_search ( RzCore core,
struct search_parameters param,
const char *  input,
int  mode,
RzInterval  search_itv 
)
static

Definition at line 2201 of file cmd_search.c.

2201  {
2202  RzCoreAsmHit *hit;
2203  RzListIter *iter, *itermap;
2204  int count = 0, maxhits = 0, filter = 0;
2205  int kwidx = core->search->n_kws; // (int)rz_config_get_i (core->config, "search.kwidx")-1;
2206  RzList *hits;
2207  RzIOMap *map;
2208  bool regexp = input[0] == '/'; // "/c/"
2209  bool everyByte = regexp && input[1] == 'a';
2210  char *end_cmd = strchr(input, ' ');
2211  switch ((end_cmd ? *(end_cmd - 1) : input[0])) {
2212  case 'j':
2213  param->outmode = RZ_MODE_JSON;
2214  break;
2215  case '*':
2216  param->outmode = RZ_MODE_RIZINCMD;
2217  break;
2218  default:
2219  break;
2220  }
2221  if (mode == 'o') {
2222  everyByte = true;
2223  }
2224 
2225  maxhits = (int)rz_config_get_i(core->config, "search.maxhits");
2226  filter = (int)rz_config_get_i(core->config, "asm.sub.names");
2227  if (param->outmode == RZ_MODE_JSON) {
2228  pj_a(param->pj);
2229  }
2231  if (everyByte) {
2232  input++;
2233  }
2234  rz_list_foreach (param->boundaries, itermap, map) {
2235  if (!rz_itv_overlap(search_itv, map->itv)) {
2236  continue;
2237  }
2238  ut64 from = map->itv.addr;
2239  ut64 to = rz_itv_end(map->itv);
2240  if (rz_cons_is_breaked()) {
2241  break;
2242  }
2243  if (maxhits && count >= maxhits) {
2244  break;
2245  }
2246  hits = rz_core_asm_strsearch(core, end_cmd,
2247  from, to, maxhits, regexp, everyByte, mode);
2248  if (hits) {
2249  const char *cmdhit = rz_config_get(core->config, "cmd.hit");
2250  rz_list_foreach (hits, iter, hit) {
2251  if (rz_cons_is_breaked()) {
2252  break;
2253  }
2254  if (cmdhit && *cmdhit) {
2255  rz_core_cmdf(core, "%s @ 0x%" PFMT64x, cmdhit, hit->addr);
2256  }
2257  switch (param->outmode) {
2258  case RZ_MODE_JSON:
2259  pj_o(param->pj);
2260  pj_kN(param->pj, "offset", hit->addr);
2261  pj_ki(param->pj, "len", hit->len);
2262  pj_ks(param->pj, "code", hit->code);
2263  pj_end(param->pj);
2264  break;
2265  case RZ_MODE_RIZINCMD:
2266  rz_cons_printf("f %s%d_%i @ 0x%08" PFMT64x "\n",
2267  searchprefix, kwidx, count, hit->addr);
2268  break;
2269  default:
2270  if (filter) {
2271  char tmp[128] = {
2272  0
2273  };
2274  RzAnalysisHint *hint = rz_analysis_hint_get(core->analysis, hit->addr);
2275  rz_parse_filter(core->parser, hit->addr, core->flags, hint, hit->code, tmp, sizeof(tmp),
2276  core->print->big_endian);
2277  rz_analysis_hint_free(hint);
2278  rz_cons_printf("0x%08" PFMT64x " # %i: %s\n",
2279  hit->addr, hit->len, tmp);
2280  } else {
2281  rz_cons_printf("0x%08" PFMT64x " # %i: %s\n",
2282  hit->addr, hit->len, hit->code);
2283  }
2284  break;
2285  }
2286  if (searchflags) {
2287  const char *flagname = sdb_fmt("%s%d_%d", searchprefix, kwidx, count);
2288  if (flagname) {
2289  rz_flag_set(core->flags, flagname, hit->addr, hit->len);
2290  }
2291  }
2292  count++;
2293  }
2294  rz_list_purge(hits);
2295  free(hits);
2296  }
2297  }
2298  if (param->outmode == RZ_MODE_JSON) {
2299  pj_end(param->pj);
2300  }
2302 }
RZ_API RzList * rz_core_asm_strsearch(RzCore *core, const char *input, ut64 from, ut64 to, int maxhits, int regexp, int everyByte, int mode)
Definition: casm.c:185
RZ_API RzAnalysisHint * rz_analysis_hint_get(RzAnalysis *a, ut64 addr)
Definition: hint.c:506
RZ_API void rz_analysis_hint_free(RzAnalysisHint *h)
Definition: hint.c:371
RZ_API void rz_list_purge(RZ_NONNULL RzList *list)
Empties the list without freeing the list pointer.
Definition: list.c:120
RZ_API bool rz_parse_filter(RzParse *p, ut64 addr, RzFlag *f, RzAnalysisHint *hint, char *data, char *str, int len, bool big_endian)
filter the opcode in data into str by following the flags and hints information
Definition: filter.c:592
#define RZ_MODE_RIZINCMD
Definition: rz_types.h:26
static int
Definition: sfsocketcall.h:114
RzParse * parser
Definition: rz_core.h:326
int big_endian
Definition: rz_print.h:124

References rz_core_t::analysis, rz_print_t::big_endian, search_parameters::boundaries, rz_core_t::config, count, rz_core_t::flags, free(), from, hit(), input(), int, map(), rz_search_t::n_kws, NULL, search_parameters::outmode, rz_core_t::parser, PFMT64x, search_parameters::pj, pj_a(), pj_end(), pj_ki(), pj_kN(), pj_ks(), pj_o(), rz_core_t::print, rz_analysis_hint_free(), rz_analysis_hint_get(), rz_config_get(), rz_config_get_i(), rz_cons_break_pop(), rz_cons_break_push(), rz_cons_is_breaked(), rz_cons_printf(), rz_core_asm_strsearch(), rz_core_cmdf(), rz_flag_set(), rz_itv_end(), rz_itv_overlap(), rz_list_purge(), RZ_MODE_JSON, RZ_MODE_RIZINCMD, rz_parse_filter(), sdb_fmt(), rz_core_t::search, searchflags, searchprefix, autogen_x86imm::tmp, to, and ut64().

Referenced by rz_cmd_search().

◆ do_esil_search()

static void do_esil_search ( RzCore core,
struct search_parameters param,
const char *  input 
)
static

Definition at line 1573 of file cmd_search.c.

1573  {
1574  const int hit_combo_limit = rz_config_get_i(core->config, "search.esilcombo");
1575  const bool cfgDebug = rz_config_get_b(core->config, "cfg.debug");
1576  RzSearch *search = core->search;
1578  if (input[0] != 'E') {
1579  return;
1580  }
1581  if (input[1] == 'j') { // "/Ej"
1582  pj_a(param->pj);
1583  param->outmode = RZ_MODE_JSON;
1584  input++;
1585  }
1586  if (input[1] != ' ') { // "/E?"
1588  return;
1589  }
1590  if (!core->analysis->esil) {
1591  // initialize esil vm
1593  if (!core->analysis->esil) {
1594  eprintf("Cannot initialize the ESIL vm\n");
1595  return;
1596  }
1597  }
1598  RzIOMap *map;
1599  RzListIter *iter;
1600  rz_list_foreach (param->boundaries, iter, map) {
1601  const int iotrap = rz_config_get_i(core->config, "esil.iotrap");
1602  const int stacksize = rz_config_get_i(core->config, "esil.stacksize");
1603  int nonull = rz_config_get_i(core->config, "esil.nonull");
1604  bool hit_happens = false;
1605  size_t hit_combo = 0;
1606  char *res;
1607  ut64 nres, addr;
1608  ut64 from = map->itv.addr;
1609  ut64 to = rz_itv_end(map->itv);
1610  unsigned int addrsize = rz_config_get_i(core->config, "esil.addr.size");
1611  if (!core->analysis->esil) {
1612  core->analysis->esil = rz_analysis_esil_new(stacksize, iotrap, addrsize);
1613  }
1614  /* hook addrinfo */
1615  core->analysis->esil->cb.user = core;
1617  /* hook addrinfo */
1618  rz_analysis_esil_setup(core->analysis->esil, core->analysis, 1, 0, nonull);
1620  core->analysis->esil->verbose = 0;
1621 
1623  for (addr = from; addr < to; addr++) {
1624  if (core->search->align) {
1625  if ((addr % core->search->align)) {
1626  continue;
1627  }
1628  }
1629 #if 0
1630  // we need a way to retrieve info from a speicif address, and make it accessible from the esil search
1631  // maybe we can just do it like this: 0x804840,AddressType,3,&, ... bitmask
1632  // executable = 1
1633  // writable = 2
1634  // inprogram
1635  // instack
1636  // inlibrary
1637  // inheap
1638  rz_analysis_esil_set_op (core->analysis->esil, "AddressInfo", esil_search_address_info);
1639 #endif
1640  if (rz_cons_is_breaked()) {
1641  eprintf("Breaked at 0x%08" PFMT64x "\n", addr);
1642  break;
1643  }
1645  if (!rz_analysis_esil_parse(core->analysis->esil, input + 2)) {
1646  // XXX: return value doesnt seems to be correct here
1647  eprintf("Cannot parse esil (%s)\n", input + 2);
1648  break;
1649  }
1650  hit_happens = false;
1651  res = rz_analysis_esil_pop(core->analysis->esil);
1652  if (rz_analysis_esil_get_parm(core->analysis->esil, res, &nres)) {
1653  if (cfgDebug) {
1654  eprintf("RES 0x%08" PFMT64x " %" PFMT64d "\n", addr, nres);
1655  }
1656  if (nres) {
1657  eprintf("hits: %d\r", kw.count);
1658  hit_happens = true;
1659  if (param->outmode != RZ_MODE_JSON) {
1660  if (!_cb_hit(&kw, param, addr)) {
1661  free(res);
1662  break;
1663  }
1664  // eprintf (" HIT AT 0x%"PFMT64x"\n", addr);
1665  kw.type = 0; // RZ_SEARCH_TYPE_ESIL;
1666  kw.kwidx = search->n_kws;
1667  kw.count++;
1668  kw.keyword_length = 0;
1669  }
1670  }
1671  } else {
1672  eprintf("Cannot parse esil (%s)\n", input + 2);
1674  free(res);
1675  break;
1676  }
1678  free(res);
1679 
1680  if (hit_happens) {
1681  if (param->outmode == RZ_MODE_JSON) {
1682  pj_o(param->pj);
1683  pj_kn(param->pj, "addr", addr);
1684  pj_kn(param->pj, "value", nres);
1685  pj_end(param->pj);
1686  }
1687  hit_combo++;
1688  if (hit_combo > hit_combo_limit) {
1689  eprintf("Hit search.esilcombo reached (%d). Stopping search. Use f-\n", hit_combo_limit);
1690  break;
1691  }
1692  } else {
1693  hit_combo = 0;
1694  }
1695  }
1696  rz_config_set_i(core->config, "search.kwidx", search->n_kws); // TODO remove
1698  }
1699  rz_cons_clear_line(1);
1700  if (param->outmode == RZ_MODE_JSON) {
1701  pj_end(param->pj);
1702  }
1703 }
RZ_API void rz_core_analysis_esil_reinit(RZ_NONNULL RzCore *core)
Reinitialize ESIL.
Definition: cil.c:54
static int _cb_hit(RzSearchKeyword *kw, void *user, ut64 addr)
Definition: cmd_search.c:403
static bool esil_addrinfo(RzAnalysisEsil *esil)
Definition: cmd_search.c:1558
static const char * help_msg_search_esil[]
Definition: cmd_search.c:19
RZ_API bool rz_config_get_b(RzConfig *cfg, RZ_NONNULL const char *name)
Definition: config.c:142
RZ_API RzConfigNode * rz_config_set_i(RzConfig *cfg, RZ_NONNULL const char *name, const ut64 i)
Definition: config.c:419
RZ_API void rz_cons_clear_line(int std_err)
Definition: cons.c:756
RZ_API void rz_analysis_esil_stack_free(RzAnalysisEsil *esil)
Definition: esil.c:3103
RZ_API RzAnalysisEsil * rz_analysis_esil_new(int stacksize, int iotrap, unsigned int addrsize)
Definition: esil.c:85
RZ_API int rz_analysis_esil_get_parm(RzAnalysisEsil *esil, const char *str, ut64 *num)
Definition: esil.c:483
RZ_API bool rz_analysis_esil_set_pc(RzAnalysisEsil *esil, ut64 addr)
Definition: esil.c:155
RZ_API bool rz_analysis_esil_set_op(RzAnalysisEsil *esil, const char *op, RzAnalysisEsilOpCb code, ut32 push, ut32 pop, ut32 type)
Definition: esil.c:110
RZ_API char * rz_analysis_esil_pop(RzAnalysisEsil *esil)
Definition: esil.c:422
RZ_API bool rz_analysis_esil_setup(RzAnalysisEsil *esil, RzAnalysis *analysis, int romem, int stats, int nonull)
Definition: esil.c:3298
RZ_API bool rz_analysis_esil_parse(RzAnalysisEsil *esil, const char *str)
Definition: esil.c:2998
@ RZ_ANALYSIS_ESIL_OP_TYPE_UNKNOWN
Definition: rz_analysis.h:1178
RZ_API PJ * pj_kn(PJ *j, const char *k, ut64 n)
Definition: pj.c:121
#define PFMT64d
Definition: rz_types.h:394
#define RZ_EMPTY
Definition: rz_types_base.h:68
RzAnalysisEsilCallbacks cb
Definition: rz_analysis.h:1078
struct rz_analysis_esil_t * esil
Definition: rz_analysis.h:584

References _cb_hit(), addr, rz_search_t::align, rz_core_t::analysis, search_parameters::boundaries, rz_analysis_esil_t::cb, rz_core_t::config, rz_search_keyword_t::count, eprintf, rz_analysis_t::esil, esil_addrinfo(), free(), from, help_msg_search_esil, input(), rz_search_keyword_t::keyword_length, rz_search_keyword_t::kwidx, map(), NULL, search_parameters::outmode, PFMT64d, PFMT64x, search_parameters::pj, pj_a(), pj_end(), pj_kn(), pj_o(), rz_analysis_esil_get_parm(), rz_analysis_esil_new(), RZ_ANALYSIS_ESIL_OP_TYPE_UNKNOWN, rz_analysis_esil_parse(), rz_analysis_esil_pop(), rz_analysis_esil_set_op(), rz_analysis_esil_set_pc(), rz_analysis_esil_setup(), rz_analysis_esil_stack_free(), rz_config_get_b(), rz_config_get_i(), rz_config_set_i(), rz_cons_break_pop(), rz_cons_break_push(), rz_cons_clear_line(), rz_cons_is_breaked(), rz_core_analysis_esil_reinit(), rz_core_cmd_help(), RZ_EMPTY, rz_itv_end(), RZ_MODE_JSON, rz_core_t::search, search(), to, rz_search_keyword_t::type, rz_analysis_esil_callbacks_t::user, ut64(), and rz_analysis_esil_t::verbose.

Referenced by rz_cmd_search().

◆ do_ref_search()

static void do_ref_search ( RzCore core,
ut64  addr,
ut64  from,
ut64  to,
struct search_parameters param 
)
static

Definition at line 1904 of file cmd_search.c.

1904  {
1905  const int size = 12;
1906  char str[512];
1907  RzAnalysisFunction *fcn;
1908  RzAnalysisXRef *xref;
1909  RzListIter *iter;
1910  ut8 buf[12];
1911  RzAsmOp asmop;
1913  if (list) {
1914  rz_list_foreach (list, iter, xref) {
1915  rz_io_read_at(core->io, xref->from, buf, size);
1916  rz_asm_set_pc(core->rasm, xref->from);
1917  rz_asm_disassemble(core->rasm, &asmop, buf, size);
1918  fcn = rz_analysis_get_fcn_in(core->analysis, xref->from, 0);
1919  RzAnalysisHint *hint = rz_analysis_hint_get(core->analysis, xref->from);
1920  rz_parse_filter(core->parser, xref->from, core->flags, hint, rz_strbuf_get(&asmop.buf_asm),
1921  str, sizeof(str), core->print->big_endian);
1922  rz_analysis_hint_free(hint);
1923  const char *comment = rz_meta_get_string(core->analysis, RZ_META_TYPE_COMMENT, xref->from);
1924  char *print_comment = NULL;
1925  const char *nl = comment ? strchr(comment, '\n') : NULL;
1926  if (nl) { // display only until the first newline
1927  comment = print_comment = rz_str_ndup(comment, nl - comment);
1928  }
1929  char *buf_fcn = comment
1930  ? rz_str_newf("%s; %s", fcn ? fcn->name : "(nofunc)", comment)
1931  : rz_str_newf("%s", fcn ? fcn->name : "(nofunc)");
1933  if (from <= xref->from && to >= xref->from) {
1934  rz_cons_printf("%s 0x%" PFMT64x " [%s] %s\n",
1935  buf_fcn, xref->from, rz_analysis_xrefs_type_tostring(xref->type), str);
1936  if (*param->cmd_hit) {
1937  ut64 here = core->offset;
1938  rz_core_seek(core, xref->from, true);
1939  rz_core_cmd(core, param->cmd_hit, 0);
1940  rz_core_seek(core, here, true);
1941  }
1942  }
1943  free(buf_fcn);
1944  }
1945  }
1946  rz_list_free(list);
1947 }
static void print_comment(const aarch64_inst *inst, struct disassemble_info *info)
Definition: aarch64-dis.c:3074
RZ_DEPRECATE RZ_API RzAnalysisFunction * rz_analysis_get_fcn_in(RzAnalysis *analysis, ut64 addr, int type)
Definition: fcn.c:1687
RZ_API const char * rz_meta_get_string(RzAnalysis *a, RzAnalysisMetaType type, ut64 addr)
Definition: meta.c:146
@ RZ_META_TYPE_COMMENT
Definition: rz_analysis.h:295
RZ_API char * rz_str_ndup(RZ_NULLABLE const char *ptr, int len)
Create new copy of string ptr limited to size len.
Definition: str.c:1006
Definition: z80asm.h:102
RzAnalysisXRefType type
Definition: rz_analysis.h:909
RZ_API RzList * rz_analysis_xrefs_get_to(RzAnalysis *analysis, ut64 addr)
Definition: xrefs.c:173
RZ_API const char * rz_analysis_xrefs_type_tostring(RzAnalysisXRefType type)
Definition: xrefs.c:216

References addr, rz_core_t::analysis, rz_print_t::big_endian, rz_asm_op_t::buf_asm, search_parameters::cmd_hit, rz_core_t::flags, free(), rz_analysis_ref_t::from, from, rz_core_t::io, list(), rz_analysis_function_t::name, NULL, rz_core_t::offset, rz_core_t::parser, PFMT64x, rz_core_t::print, print_comment(), rz_core_t::rasm, rz_analysis_get_fcn_in(), rz_analysis_hint_free(), rz_analysis_hint_get(), rz_analysis_xrefs_get_to(), rz_analysis_xrefs_type_tostring(), rz_asm_disassemble(), rz_asm_set_pc(), rz_cons_printf(), rz_core_cmd(), rz_core_seek(), rz_io_read_at(), rz_list_free(), rz_meta_get_string(), RZ_META_TYPE_COMMENT, rz_parse_filter(), rz_str_ndup(), rz_str_newf(), rz_strbuf_get(), cmd_descs_generate::str, to, rz_analysis_ref_t::type, and ut64().

Referenced by rz_cmd_search().

◆ do_section_search()

static void do_section_search ( RzCore core,
struct search_parameters param,
const char *  input 
)
static

Definition at line 2133 of file cmd_search.c.

2133  {
2134  double threshold = 1;
2135  bool r2mode = false;
2136  if (input && *input) {
2137  if (*input == '*') {
2138  r2mode = true;
2139  }
2140  sscanf(input, "%lf", &threshold);
2141  if (threshold < 1) {
2142  threshold = 1;
2143  }
2144  }
2145  int buf_size = core->blocksize;
2146  ut8 *buf = malloc(buf_size);
2147  if (!buf) {
2148  return;
2149  }
2150  double oe = 0;
2151  RzListIter *iter;
2152  RzIOMap *map;
2153  ut64 begin = UT64_MAX;
2154  ut64 at, end = 0;
2155  int index = 0;
2156  bool lastBlock = true;
2158  rz_list_foreach (param->boundaries, iter, map) {
2159  ut64 from = map->itv.addr;
2160  ut64 to = rz_itv_end(map->itv);
2161  if (rz_cons_is_breaked()) {
2162  break;
2163  }
2164  for (at = from; at < to; at += buf_size) {
2165  if (begin == UT64_MAX) {
2166  begin = at;
2167  }
2168  rz_io_read_at(core->io, at, buf, buf_size);
2169  double e = rz_hash_entropy(core->hash, buf, buf_size);
2170  double diff = oe - e;
2171  diff = RZ_ABS(diff);
2172  end = at + buf_size;
2173  if (diff > threshold) {
2174  if (r2mode) {
2175  rz_cons_printf("f entropy_section_%d 0x%08" PFMT64x " @ 0x%08" PFMT64x "\n", index, end - begin, begin);
2176  } else {
2177  rz_cons_printf("0x%08" PFMT64x " - 0x%08" PFMT64x " ~ %lf\n", begin, end, e);
2178  }
2179  begin = UT64_MAX;
2180  index++;
2181  lastBlock = false;
2182  } else {
2183  lastBlock = true;
2184  }
2185  oe = e;
2186  }
2187  begin = UT64_MAX;
2188  }
2189  if (begin != UT64_MAX && lastBlock) {
2190  if (r2mode) {
2191  rz_cons_printf("f entropy_section_%d 0x%08" PFMT64x " @ 0x%08" PFMT64x "\n", index, end - begin, begin);
2192  } else {
2193  rz_cons_printf("0x%08" PFMT64x " - 0x%08" PFMT64x " ~ %d .. last\n", begin, end, 0);
2194  }
2195  index++;
2196  }
2198  free(buf);
2199 }
#define e(frag)
static int buf_size
Definition: debug_qnx.c:35
RZ_API double rz_hash_entropy(RZ_NONNULL RzHash *rh, RZ_NONNULL const ut8 *data, ut64 len)
Definition: hash.c:32
@ RZ_ABS
RzHash * hash
Definition: rz_core.h:389
ut32 blocksize
Definition: rz_core.h:303

References rz_core_t::blocksize, search_parameters::boundaries, buf_size, e, test_evm::end, free(), from, rz_core_t::hash, input(), rz_core_t::io, malloc(), map(), NULL, PFMT64x, RZ_ABS, rz_cons_break_pop(), rz_cons_break_push(), rz_cons_is_breaked(), rz_cons_printf(), rz_hash_entropy(), rz_io_read_at(), rz_itv_end(), to, ut64(), and UT64_MAX.

Referenced by rz_cmd_search().

◆ do_string_search()

static void do_string_search ( RzCore core,
RzInterval  search_itv,
struct search_parameters param 
)
static

Definition at line 2304 of file cmd_search.c.

2304  {
2305  ut64 at;
2306  ut8 *buf;
2307  RzSearch *search = core->search;
2308 
2309  if (param->outmode == RZ_MODE_JSON) {
2310  pj_a(param->pj);
2311  }
2312  RzListIter *iter;
2313  RzIOMap *map;
2314  if (!searchflags && param->outmode != RZ_MODE_JSON) {
2315  rz_cons_printf("fs hits\n");
2316  }
2317  core->search->inverse = param->inverse;
2318  // TODO Bad but is to be compatible with the legacy behavior
2319  if (param->inverse) {
2320  core->search->maxhits = 1;
2321  }
2322  if (core->search->n_kws > 0) {
2323  /* set callback */
2324  /* TODO: handle last block of data */
2325  /* TODO: handle ^C */
2326  /* TODO: launch search in background support */
2327  // REMOVE OLD FLAGS rz_core_cmdf (core, "f-%s*", rz_config_get (core->config, "search.prefix"));
2328  rz_search_set_callback(core->search, &_cb_hit, param);
2329  if (!(buf = malloc(core->blocksize))) {
2330  return;
2331  }
2332  if (search->bckwrds) {
2334  }
2336  // TODO search cross boundary
2337  rz_list_foreach (param->boundaries, iter, map) {
2338  if (!rz_itv_overlap(search_itv, map->itv)) {
2339  continue;
2340  }
2341  const ut64 saved_nhits = search->nhits;
2342  RzInterval itv = rz_itv_intersect(search_itv, map->itv);
2343  if (rz_cons_is_breaked()) {
2344  break;
2345  }
2346  if (param->outmode != RZ_MODE_JSON) {
2347  RzSearchKeyword *kw = rz_list_first(core->search->kws);
2348  int lenstr = kw ? kw->keyword_length : 0;
2349  const char *bytestr = lenstr > 1 ? "bytes" : "byte";
2350  eprintf("Searching %d %s in [0x%" PFMT64x "-0x%" PFMT64x "]\n",
2351  kw ? kw->keyword_length : 0, bytestr, itv.addr, rz_itv_end(itv));
2352  }
2353  if (!core->search->bckwrds) {
2354  RzListIter *it;
2355  RzSearchKeyword *kw;
2356  rz_list_foreach (core->search->kws, it, kw) {
2357  kw->last = 0;
2358  }
2359  }
2360 
2361  const ut64 from = itv.addr, to = rz_itv_end(itv),
2362  from1 = search->bckwrds ? to : from,
2363  to1 = search->bckwrds ? from : to;
2364  ut64 len;
2365  for (at = from1; at != to1; at = search->bckwrds ? at - len : at + len) {
2366  print_search_progress(at, to1, search->nhits, param);
2367  if (rz_cons_is_breaked()) {
2368  eprintf("\n\n");
2369  break;
2370  }
2371  if (search->bckwrds) {
2372  len = RZ_MIN(core->blocksize, at - from);
2373  // TODO prefix_read_at
2374  if (!rz_io_is_valid_offset(core->io, at - len, 0)) {
2375  break;
2376  }
2377  (void)rz_io_read_at(core->io, at - len, buf, len);
2378  } else {
2379  len = RZ_MIN(core->blocksize, to - at);
2380  if (!rz_io_is_valid_offset(core->io, at, 0)) {
2381  break;
2382  }
2383  (void)rz_io_read_at(core->io, at, buf, len);
2384  }
2385  rz_search_update(core->search, at, buf, len);
2386  if (param->aes_search) {
2387  // Adjust length to search between blocks.
2388  if (len == core->blocksize) {
2389  len -= AES_SEARCH_LENGTH - 1;
2390  }
2391  } else if (param->privkey_search) {
2392  // Adjust length to search between blocks.
2393  if (len == core->blocksize) {
2395  }
2396  }
2397  if (core->search->maxhits > 0 && core->search->nhits >= core->search->maxhits) {
2398  goto done;
2399  }
2400  }
2401  print_search_progress(at, to1, search->nhits, param);
2402  rz_cons_clear_line(1);
2403  core->num->value = search->nhits;
2404  if (param->outmode != RZ_MODE_JSON) {
2405  eprintf("hits: %" PFMT64d "\n", search->nhits - saved_nhits);
2406  }
2407  }
2408  done:
2410  free(buf);
2411  } else {
2412  eprintf("No keywords defined\n");
2413  }
2414 
2415  if (param->outmode == RZ_MODE_JSON) {
2416  pj_end(param->pj);
2417  }
2418 }
static void print_search_progress(ut64 at, ut64 to, int n, struct search_parameters *param)
Definition: cmd_search.c:522
#define AES_SEARCH_LENGTH
Definition: cmd_search.c:16
#define PRIVATE_KEY_SEARCH_LENGTH
Definition: cmd_search.c:17
RZ_API RZ_BORROW void * rz_list_first(RZ_NONNULL const RzList *list)
Returns the first element of the list.
Definition: list.c:77
RZ_API bool rz_io_is_valid_offset(RzIO *io, ut64 offset, int hasperm)
Definition: ioutils.c:20
#define RZ_MIN(x, y)
RZ_API void rz_search_string_prepare_backward(RzSearch *s)
Definition: search.c:516
RZ_API int rz_search_update(RzSearch *s, ut64 from, const ut8 *buf, long len)
Definition: search.c:470
RZ_API void rz_search_set_callback(RzSearch *s, RzSearchCallback(callback), void *user)
Definition: search.c:463
RzNum * num
Definition: rz_core.h:316
ut64 value
Definition: rz_num.h:63
char bckwrds
Definition: rz_search.h:74
ut64 maxhits
Definition: rz_search.h:64
RzList * kws
Definition: rz_search.h:72
int inverse
Definition: rz_search.h:67
ut64 nhits
Definition: rz_search.h:63

References _cb_hit(), rz_interval_t::addr, search_parameters::aes_search, AES_SEARCH_LENGTH, rz_search_t::bckwrds, rz_core_t::blocksize, search_parameters::boundaries, done, eprintf, free(), from, search_parameters::inverse, rz_search_t::inverse, rz_core_t::io, rz_search_keyword_t::keyword_length, rz_search_t::kws, rz_search_keyword_t::last, len, malloc(), map(), rz_search_t::maxhits, rz_search_t::n_kws, rz_search_t::nhits, NULL, rz_core_t::num, search_parameters::outmode, PFMT64d, PFMT64x, search_parameters::pj, pj_a(), pj_end(), print_search_progress(), PRIVATE_KEY_SEARCH_LENGTH, search_parameters::privkey_search, rz_cons_break_pop(), rz_cons_break_push(), rz_cons_clear_line(), rz_cons_is_breaked(), rz_cons_printf(), rz_io_is_valid_offset(), rz_io_read_at(), rz_itv_end(), rz_itv_intersect(), rz_itv_overlap(), rz_list_first(), RZ_MIN, RZ_MODE_JSON, rz_search_set_callback(), rz_search_string_prepare_backward(), rz_search_update(), rz_core_t::search, search(), searchflags, to, ut64(), and rz_num_t::value.

Referenced by rz_cmd_search().

◆ do_syscall_search()

static void do_syscall_search ( RzCore core,
struct search_parameters param 
)
static

Definition at line 1760 of file cmd_search.c.

1760  {
1761  RzSearch *search = core->search;
1762  ut64 at;
1763 #if USE_EMULATION
1764  ut64 curpc;
1765 #endif
1766  ut8 *buf;
1767  int curpos, idx = 0, count = 0;
1768  RzAnalysisOp aop = { 0 };
1769  int i, ret, bsize = RZ_MAX(64, core->blocksize);
1770  int kwidx = core->search->n_kws;
1771  RzIOMap *map;
1772  RzListIter *iter;
1773  const int mininstrsz = rz_analysis_archinfo(core->analysis, RZ_ANALYSIS_ARCHINFO_MIN_OP_SIZE);
1774  const int minopcode = RZ_MAX(1, mininstrsz);
1775  RzAnalysisEsil *esil;
1776  int align = core->search->align;
1777  int stacksize = rz_config_get_i(core->config, "esil.stack.depth");
1778  int iotrap = rz_config_get_i(core->config, "esil.iotrap");
1779  unsigned int addrsize = rz_config_get_i(core->config, "esil.addr.size");
1780 
1781  if (!(esil = rz_analysis_esil_new(stacksize, iotrap, addrsize))) {
1782  return;
1783  }
1784  int *previnstr = calloc(MAXINSTR + 1, sizeof(int));
1785  if (!previnstr) {
1786  rz_analysis_esil_free(esil);
1787  return;
1788  }
1789  buf = malloc(bsize);
1790  if (!buf) {
1791  eprintf("Cannot allocate %d byte(s)\n", bsize);
1792  rz_analysis_esil_free(esil);
1793  free(previnstr);
1794  return;
1795  }
1796  ut64 oldoff = core->offset;
1797  int syscallNumber = 0;
1799  const char *a0 = rz_reg_get_name(core->analysis->reg, RZ_REG_NAME_SN);
1800  char *esp = rz_str_newf("%s,=", a0);
1801  char *esp32 = NULL;
1802  if (core->analysis->bits == 64) {
1803  const char *reg = rz_reg_64_to_32(core->analysis->reg, a0);
1804  if (reg) {
1805  esp32 = rz_str_newf("%s,=", reg);
1806  }
1807  }
1808  rz_list_foreach (param->boundaries, iter, map) {
1809  ut64 from = map->itv.addr;
1810  ut64 to = rz_itv_end(map->itv);
1811  if (from >= to) {
1812  eprintf("Error: from must be lower than to\n");
1813  goto beach;
1814  }
1815  if (to == UT64_MAX) {
1816  eprintf("Error: Invalid destination boundary\n");
1817  goto beach;
1818  }
1819  for (i = 0, at = from; at < to; at++, i++) {
1820  if (rz_cons_is_breaked()) {
1821  break;
1822  }
1823  if (i >= (bsize - 32)) {
1824  i = 0;
1825  }
1826  if (align && (at % align)) {
1827  continue;
1828  }
1829  if (!i) {
1830  rz_io_read_at(core->io, at, buf, bsize);
1831  }
1832  ret = rz_analysis_op(core->analysis, &aop, at, buf + i, bsize - i, RZ_ANALYSIS_OP_MASK_ESIL);
1833  curpos = idx++ % (MAXINSTR + 1);
1834  previnstr[curpos] = ret; // This array holds prev n instr size + cur instr size
1835  if (aop.type == RZ_ANALYSIS_OP_TYPE_MOV) {
1836  const char *es = RZ_STRBUF_SAFEGET(&aop.esil);
1837  if (strstr(es, esp)) {
1838  if (aop.val != -1) {
1839  syscallNumber = aop.val;
1840  }
1841  } else if (esp32 && strstr(es, esp32)) {
1842  if (aop.val != -1) {
1843  syscallNumber = aop.val;
1844  }
1845  }
1846  }
1847  if ((aop.type == RZ_ANALYSIS_OP_TYPE_SWI) && ret) { // && (aop.val > 10)) {
1848  int scVector = -1; // int 0x80, svc 0x70, ...
1849  int scNumber = 0; // r0/eax/...
1850 #if USE_EMULATION
1851  // This for calculating no of bytes to be subtracted , to get n instr above syscall
1852  int nbytes = 0;
1853  int nb_opcodes = MAXINSTR;
1854  SUMARRAY(previnstr, nb_opcodes, nbytes);
1855  curpc = at - (nbytes - previnstr[curpos]);
1856  scNumber = emulateSyscallPrelude(core, at, curpc);
1857 #else
1858  scNumber = syscallNumber;
1859 #endif
1860  scVector = (aop.val > 0) ? aop.val : -1; // int 0x80 (aop.val = 0x80)
1861  RzSyscallItem *item = rz_syscall_get(core->analysis->syscall, scNumber, scVector);
1862  if (item) {
1863  rz_cons_printf("0x%08" PFMT64x " %s\n", at, item->name);
1864  }
1865  memset(previnstr, 0, (MAXINSTR + 1) * sizeof(*previnstr)); // clearing the buffer
1866  if (searchflags) {
1867  char *flag = rz_str_newf("%s%d_%d.%s", searchprefix, kwidx, count, item ? item->name : "syscall");
1868  rz_flag_set(core->flags, flag, at, ret);
1869  free(flag);
1870  }
1871  rz_syscall_item_free(item);
1872  if (*param->cmd_hit) {
1873  ut64 here = core->offset;
1874  rz_core_seek(core, at, true);
1875  rz_core_cmd(core, param->cmd_hit, 0);
1876  rz_core_seek(core, here, true);
1877  }
1878  count++;
1879  if (search->maxhits > 0 && count >= search->maxhits) {
1880  rz_analysis_op_fini(&aop);
1881  break;
1882  }
1883  syscallNumber = 0;
1884  }
1885  int inc = (core->search->align > 0) ? core->search->align - 1 : ret - 1;
1886  if (inc < 0) {
1887  inc = minopcode;
1888  }
1889  i += inc;
1890  at += inc;
1891  rz_analysis_op_fini(&aop);
1892  }
1893  }
1894 beach:
1895  rz_core_seek(core, oldoff, true);
1896  rz_analysis_esil_free(esil);
1898  free(buf);
1899  free(esp32);
1900  free(esp);
1901  free(previnstr);
1902 }
RZ_API int rz_analysis_archinfo(RzAnalysis *analysis, int query)
Definition: analysis.c:449
#define MAXINSTR
Definition: cmd_search.c:1705
#define SUMARRAY(arr, size, res)
Definition: cmd_search.c:1706
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void static offset struct stat static buf void nbytes
Definition: sflib.h:113
RZ_API void rz_analysis_esil_free(RzAnalysisEsil *esil)
Definition: esil.c:163
a0
Definition: insn-good.s.cs:704
#define reg(n)
RZ_API const char * rz_reg_64_to_32(RzReg *reg, const char *rreg64)
Definition: reg.c:44
RZ_API const char * rz_reg_get_name(RzReg *reg, int role)
Definition: reg.c:147
@ RZ_ANALYSIS_OP_MASK_ESIL
Definition: rz_analysis.h:441
#define RZ_ANALYSIS_ARCHINFO_MIN_OP_SIZE
Definition: rz_analysis.h:98
@ RZ_ANALYSIS_OP_TYPE_SWI
Definition: rz_analysis.h:393
@ RZ_ANALYSIS_OP_TYPE_MOV
Definition: rz_analysis.h:390
@ RZ_REG_NAME_SN
Definition: rz_reg.h:70
#define RZ_STRBUF_SAFEGET(sb)
Definition: rz_strbuf.h:18
#define RZ_MAX(x, y)
const char * name
Definition: sparc-opc.c:1838
RZ_API void rz_syscall_item_free(RzSyscallItem *si)
Definition: syscall.c:325
RZ_API RzSyscallItem * rz_syscall_get(RzSyscall *s, int num, int swi)
Definition: syscall.c:345

References a0, rz_search_t::align, rz_core_t::analysis, rz_analysis_t::bits, rz_core_t::blocksize, search_parameters::boundaries, calloc(), search_parameters::cmd_hit, rz_core_t::config, count, eprintf, rz_analysis_op_t::esil, rz_core_t::flags, free(), from, i, setup::idx, if(), rz_core_t::io, malloc(), map(), MAXINSTR, memset(), rz_search_t::n_kws, arg::name, nbytes, NULL, rz_core_t::offset, PFMT64x, reg, rz_analysis_t::reg, rz_analysis_archinfo(), RZ_ANALYSIS_ARCHINFO_MIN_OP_SIZE, rz_analysis_esil_free(), rz_analysis_esil_new(), rz_analysis_op(), rz_analysis_op_fini(), RZ_ANALYSIS_OP_MASK_ESIL, RZ_ANALYSIS_OP_TYPE_MOV, RZ_ANALYSIS_OP_TYPE_SWI, rz_config_get_i(), rz_cons_break_pop(), rz_cons_break_push(), rz_cons_is_breaked(), rz_cons_printf(), rz_core_cmd(), rz_core_seek(), rz_flag_set(), rz_io_read_at(), rz_itv_end(), RZ_MAX, rz_reg_64_to_32(), rz_reg_get_name(), RZ_REG_NAME_SN, rz_str_newf(), RZ_STRBUF_SAFEGET, rz_syscall_get(), rz_syscall_item_free(), rz_core_t::search, search(), searchflags, searchprefix, SUMARRAY, rz_analysis_t::syscall, syscallNumber(), to, rz_analysis_op_t::type, ut64(), UT64_MAX, and rz_analysis_op_t::val.

Referenced by rz_cmd_search().

◆ esil_addrinfo()

static bool esil_addrinfo ( RzAnalysisEsil esil)
static

Definition at line 1558 of file cmd_search.c.

1558  {
1559  RzCore *core = (RzCore *)esil->cb.user;
1560  ut64 num = 0;
1561  char *src = rz_analysis_esil_pop(esil);
1562  if (src && *src && rz_analysis_esil_get_parm(esil, src, &num)) {
1563  num = rz_core_analysis_address(core, num);
1565  } else {
1566  // error. empty stack?
1567  return false;
1568  }
1569  free(src);
1570  return true;
1571 }
lzma_index * src
Definition: index.h:567
RZ_API ut64 rz_core_analysis_address(RzCore *core, ut64 addr)
Definition: canalysis.c:168
RZ_API bool rz_analysis_esil_pushnum(RzAnalysisEsil *esil, ut64 num)
Definition: esil.c:408
static static fork const void static count static fd const char const char static newpath char char char static envp time_t static t const char static mode static whence const char static dir time_t static t unsigned static seconds const char struct utimbuf static buf static inc static sig const char static mode static oldfd struct tms static buf static getgid static geteuid const char static filename static arg static mask struct ustat static ubuf static getppid static setsid static egid sigset_t static set struct timeval struct timezone static tz fd_set fd_set fd_set struct timeval static timeout const char char static bufsiz const char static swapflags void static offset const char static length static mode static who const char struct statfs static buf unsigned unsigned num
Definition: sflib.h:126

References rz_analysis_esil_t::cb, free(), num, rz_analysis_esil_get_parm(), rz_analysis_esil_pop(), rz_analysis_esil_pushnum(), rz_core_analysis_address(), src, rz_analysis_esil_callbacks_t::user, and ut64().

Referenced by do_esil_search().

◆ getstring()

static char* getstring ( char *  b,
int  l 
)
static

Definition at line 388 of file cmd_search.c.

388  {
389  char *r, *res = malloc(l + 1);
390  int i;
391  if (!res) {
392  return NULL;
393  }
394  for (i = 0, r = res; i < l; b++, i++) {
395  if (IS_PRINTABLE(*b)) {
396  *r++ = *b;
397  }
398  }
399  *r = 0;
400  return res;
401 }
#define r
Definition: crypto_rc6.c:12
#define IS_PRINTABLE(x)
Definition: rz_str_util.h:10

References b, i, IS_PRINTABLE, malloc(), NULL, and r.

Referenced by _cb_hit().

◆ incAlphaBuffer()

static void incAlphaBuffer ( ut8 buf,
int  bufsz 
)
static

Definition at line 2710 of file cmd_search.c.

2710  {
2711  int i = 0;
2712  while (i < bufsz) {
2713  buf[i]++;
2714  if (buf[i] && isalpha(buf[i])) {
2715  break;
2716  }
2717  if (!buf[i]) {
2718  i++;
2719  continue;
2720  }
2721  }
2722  // may overflow/hang/end/stop/whatever here
2723 }
#define isalpha(c)
Definition: safe-ctype.h:125

References i, and isalpha.

Referenced by __printPattern(), and search_collisions().

◆ incBuffer()

static void incBuffer ( ut8 buf,
int  bufsz 
)
static

Definition at line 2655 of file cmd_search.c.

2655  {
2656  int i = 0;
2657  while (i < bufsz) {
2658  buf[i]++;
2659  if (!buf[i]) {
2660  i++;
2661  continue;
2662  }
2663  break;
2664  }
2665  // may overflow/hang/end/stop/whatever here
2666 }

References i.

Referenced by search_collisions().

◆ incDigitBuffer()

static void incDigitBuffer ( ut8 buf,
int  bufsz 
)
static

Definition at line 2725 of file cmd_search.c.

2725  {
2726  int i = 0;
2727  while (i < bufsz) {
2728  buf[i]++;
2729  if (buf[i] && isdigit(buf[i])) {
2730  break;
2731  }
2732  if (!buf[i]) {
2733  i++;
2734  continue;
2735  }
2736  }
2737  // may overflow/hang/end/stop/whatever here
2738 }
#define isdigit(c)
Definition: safe-ctype.h:131

References i, and isdigit.

Referenced by __printPattern(), and search_collisions().

◆ incLowerBuffer()

static void incLowerBuffer ( ut8 buf,
int  bufsz 
)
static

Definition at line 2682 of file cmd_search.c.

2682  {
2683  int i = 0;
2684  while (i < bufsz) {
2685  buf[i]++;
2686  if (buf[i] && isalpha(buf[i]) && islower(buf[i])) {
2687  break;
2688  }
2689  if (!buf[i]) {
2690  i++;
2691  continue;
2692  }
2693  }
2694 }
#define islower(c)
Definition: safe-ctype.h:135

References i, isalpha, and islower.

Referenced by search_collisions().

◆ incPrintBuffer()

static void incPrintBuffer ( ut8 buf,
int  bufsz 
)
static

Definition at line 2668 of file cmd_search.c.

2668  {
2669  int i = 0;
2670  while (i < bufsz) {
2671  buf[i]++;
2672  if (!buf[i]) {
2673  i++;
2674  continue;
2675  }
2676  if (IS_PRINTABLE(buf[i])) {
2677  break;
2678  }
2679  }
2680 }

References i, and IS_PRINTABLE.

Referenced by search_collisions().

◆ incUpperBuffer()

static void incUpperBuffer ( ut8 buf,
int  bufsz 
)
static

Definition at line 2696 of file cmd_search.c.

2696  {
2697  int i = 0;
2698  while (i < bufsz) {
2699  buf[i]++;
2700  if (buf[i] && isalpha(buf[i]) && isupper(buf[i])) {
2701  break;
2702  }
2703  if (!buf[i]) {
2704  i++;
2705  continue;
2706  }
2707  }
2708 }
#define isupper(c)
Definition: safe-ctype.h:143

References i, isalpha, and isupper.

Referenced by search_collisions().

◆ insert_into()

static bool insert_into ( void *  user,
const ut64  k,
const ut64  v 
)
static

Definition at line 983 of file cmd_search.c.

983  {
984  HtUU *ht = (HtUU *)user;
985  ht_uu_insert(ht, k, v);
986  return true;
987 }
const char * k
Definition: dsignal.c:11
const char * v
Definition: dsignal.c:12

References k, and v.

Referenced by construct_rop_gadget().

◆ is_end_gadget()

static bool is_end_gadget ( const RzAnalysisOp aop,
const ut8  crop 
)
static

Definition at line 951 of file cmd_search.c.

951  {
953  return false;
954  }
955  switch (aop->type) {
968  return true;
969  }
970  if (crop) { // if conditional jumps, calls and returns should be used for the gadget-search too
971  switch (aop->type) {
977  return true;
978  }
979  }
980  return false;
981 }
@ RZ_ANALYSIS_OP_FAMILY_SECURITY
Definition: rz_analysis.h:320
@ RZ_ANALYSIS_OP_TYPE_ICALL
Definition: rz_analysis.h:381
@ RZ_ANALYSIS_OP_TYPE_JMP
Definition: rz_analysis.h:368
@ RZ_ANALYSIS_OP_TYPE_UJMP
Definition: rz_analysis.h:369
@ RZ_ANALYSIS_OP_TYPE_IJMP
Definition: rz_analysis.h:371
@ RZ_ANALYSIS_OP_TYPE_UCCALL
Definition: rz_analysis.h:384
@ RZ_ANALYSIS_OP_TYPE_TRAP
Definition: rz_analysis.h:392
@ RZ_ANALYSIS_OP_TYPE_CCALL
Definition: rz_analysis.h:383
@ RZ_ANALYSIS_OP_TYPE_CALL
Definition: rz_analysis.h:378
@ RZ_ANALYSIS_OP_TYPE_CRET
Definition: rz_analysis.h:386
@ RZ_ANALYSIS_OP_TYPE_IRJMP
Definition: rz_analysis.h:372
@ RZ_ANALYSIS_OP_TYPE_RJMP
Definition: rz_analysis.h:370
@ RZ_ANALYSIS_OP_TYPE_CJMP
Definition: rz_analysis.h:373
@ RZ_ANALYSIS_OP_TYPE_UCJMP
Definition: rz_analysis.h:377
@ RZ_ANALYSIS_OP_TYPE_UCALL
Definition: rz_analysis.h:379
@ RZ_ANALYSIS_OP_TYPE_RET
Definition: rz_analysis.h:385
@ RZ_ANALYSIS_OP_TYPE_RCALL
Definition: rz_analysis.h:380
@ RZ_ANALYSIS_OP_TYPE_IRCALL
Definition: rz_analysis.h:382

References rz_analysis_op_t::family, RZ_ANALYSIS_OP_FAMILY_SECURITY, RZ_ANALYSIS_OP_TYPE_CALL, RZ_ANALYSIS_OP_TYPE_CCALL, RZ_ANALYSIS_OP_TYPE_CJMP, RZ_ANALYSIS_OP_TYPE_CRET, RZ_ANALYSIS_OP_TYPE_ICALL, RZ_ANALYSIS_OP_TYPE_IJMP, RZ_ANALYSIS_OP_TYPE_IRCALL, RZ_ANALYSIS_OP_TYPE_IRJMP, RZ_ANALYSIS_OP_TYPE_JMP, RZ_ANALYSIS_OP_TYPE_RCALL, RZ_ANALYSIS_OP_TYPE_RET, RZ_ANALYSIS_OP_TYPE_RJMP, RZ_ANALYSIS_OP_TYPE_TRAP, RZ_ANALYSIS_OP_TYPE_UCALL, RZ_ANALYSIS_OP_TYPE_UCCALL, RZ_ANALYSIS_OP_TYPE_UCJMP, RZ_ANALYSIS_OP_TYPE_UJMP, and rz_analysis_op_t::type.

Referenced by construct_rop_gadget(), and rz_core_search_rop().

◆ isArm()

static bool isArm ( RzCore core)
static

Definition at line 2566 of file cmd_search.c.

2566  {
2567  RzAsm *as = core ? core->rasm : NULL;
2568  if (as && as->cur && as->cur->arch) {
2569  if (rz_str_startswith(as->cur->arch, "arm")) {
2570  if (as->cur->bits < 64) {
2571  return true;
2572  }
2573  }
2574  }
2575  return false;
2576 }
_RzAsmPlugin * cur
Definition: rz_asm.h:106

References rz_asm_t::cur, NULL, rz_core_t::rasm, and rz_str_startswith().

Referenced by _CbInRangeSearchV().

◆ maskMatches()

static bool maskMatches ( int  perm,
int  mask,
bool  only 
)
static

Definition at line 567 of file cmd_search.c.

567  {
568  if (mask) {
569  if (only) {
570  return ((perm & 7) != mask);
571  }
572  return (perm & mask) != mask;
573  }
574  return false;
575 }
#define mask()

References mask.

Referenced by rz_core_get_boundaries_prot().

◆ memcmpdiff()

static int memcmpdiff ( const ut8 a,
const ut8 b,
int  len 
)
static

Definition at line 2517 of file cmd_search.c.

2517  {
2518  int i, diff = 0;
2519  for (i = 0; i < len; i++) {
2520  if (a[i] == b[i] && a[i] == 0x00) {
2521  /* ignore nulls */
2522  } else if (a[i] != b[i]) {
2523  diff++;
2524  }
2525  }
2526  return diff;
2527 }
#define a(i)
Definition: sha256.c:41

References a, b, i, and len.

Referenced by search_similar_pattern_in().

◆ print_rop()

static void print_rop ( RzCore core,
RzList hitlist,
PJ pj,
int  mode 
)
static

Definition at line 1124 of file cmd_search.c.

1124  {
1125  RzCoreAsmHit *hit = NULL;
1126  RzListIter *iter;
1127  RzList *ropList = NULL;
1128  unsigned int size = 0;
1130  RzAsmOp asmop;
1131  Sdb *db = NULL;
1132  const bool colorize = rz_config_get_i(core->config, "scr.color");
1133  const bool rop_comments = rz_config_get_i(core->config, "rop.comments");
1134  const bool esil = rz_config_get_i(core->config, "asm.esil");
1135  const bool rop_db = rz_config_get_i(core->config, "rop.db");
1136 
1137  if (rop_db) {
1138  db = sdb_ns(core->sdb, "rop", true);
1139  ropList = rz_list_newf(free);
1140  if (!db) {
1141  eprintf("Error: Could not create SDB 'rop' namespace\n");
1142  rz_list_free(ropList);
1143  return;
1144  }
1145  }
1146 
1147  switch (mode) {
1148  case 'j':
1149  pj_o(pj);
1150  pj_ka(pj, "opcodes");
1151  rz_list_foreach (hitlist, iter, hit) {
1152  ut8 *buf = malloc(hit->len);
1153  if (!buf) {
1154  return;
1155  }
1156  rz_io_read_at(core->io, hit->addr, buf, hit->len);
1157  rz_asm_set_pc(core->rasm, hit->addr);
1158  rz_asm_disassemble(core->rasm, &asmop, buf, hit->len);
1160  size += hit->len;
1161  if (analop.type != RZ_ANALYSIS_OP_TYPE_RET) {
1162  char *opstr_n = rz_str_newf(" %s", RZ_STRBUF_SAFEGET(&analop.esil));
1163  rz_list_append(ropList, (void *)opstr_n);
1164  }
1165  pj_o(pj);
1166  pj_kN(pj, "offset", hit->addr);
1167  pj_ki(pj, "size", hit->len);
1168  pj_ks(pj, "opcode", rz_asm_op_get_asm(&asmop));
1169  pj_ks(pj, "type", rz_analysis_optype_to_string(analop.type));
1170  pj_end(pj);
1171  free(buf);
1173  }
1174  pj_end(pj);
1175  if (db && hit) {
1176  const ut64 addr = ((RzCoreAsmHit *)hitlist->head->data)->addr;
1177  // rz_cons_printf ("Gadget size: %d\n", (int)size);
1178  const char *key = sdb_fmt("0x%08" PFMT64x, addr);
1179  rop_classify(core, db, ropList, key, size);
1180  }
1181  if (hit) {
1182  pj_kN(pj, "retaddr", hit->addr);
1183  pj_ki(pj, "size", size);
1184  }
1185  pj_end(pj);
1186  break;
1187  case 'q':
1188  // Print gadgets in a 'linear manner', each sequence
1189  // on one line.
1190  rz_cons_printf("0x%08" PFMT64x ":",
1191  ((RzCoreAsmHit *)hitlist->head->data)->addr);
1192  rz_list_foreach (hitlist, iter, hit) {
1193  ut8 *buf = malloc(hit->len);
1194  rz_io_read_at(core->io, hit->addr, buf, hit->len);
1195  rz_asm_set_pc(core->rasm, hit->addr);
1196  rz_asm_disassemble(core->rasm, &asmop, buf, hit->len);
1198  size += hit->len;
1199  const char *opstr = RZ_STRBUF_SAFEGET(&analop.esil);
1200  if (analop.type != RZ_ANALYSIS_OP_TYPE_RET) {
1201  rz_list_append(ropList, rz_str_newf(" %s", opstr));
1202  }
1203  if (esil) {
1204  rz_cons_printf("%s\n", opstr);
1205  } else if (colorize) {
1206  RzStrBuf *colored_asm, *bw_str = rz_strbuf_new(rz_asm_op_get_asm(&asmop));
1207  colored_asm = rz_asm_colorize_asm_str(bw_str, core->print, rz_asm_get_parse_param(core->analysis->reg, analop.type), asmop.asm_toks);
1208  rz_cons_printf(" %s%s;", rz_strbuf_get(colored_asm), Color_RESET);
1209  rz_strbuf_free(colored_asm);
1210  } else {
1211  rz_cons_printf(" %s;", rz_asm_op_get_asm(&asmop));
1212  }
1213  free(buf);
1215  }
1216  if (db && hit) {
1217  const ut64 addr = ((RzCoreAsmHit *)hitlist->head->data)->addr;
1218  // rz_cons_printf ("Gadget size: %d\n", (int)size);
1219  const char *key = sdb_fmt("0x%08" PFMT64x, addr);
1220  rop_classify(core, db, ropList, key, size);
1221  }
1222  break;
1223  default:
1224  // Print gadgets with new instruction on a new line.
1225  rz_list_foreach (hitlist, iter, hit) {
1226  const char *comment = rop_comments ? rz_meta_get_string(core->analysis, RZ_META_TYPE_COMMENT, hit->addr) : NULL;
1227  if (hit->len < 0) {
1228  eprintf("Invalid hit length here\n");
1229  continue;
1230  }
1231  ut8 *buf = malloc(1 + hit->len);
1232  if (!buf) {
1233  break;
1234  }
1235  buf[hit->len] = 0;
1236  rz_io_read_at(core->io, hit->addr, buf, hit->len);
1237  rz_asm_set_pc(core->rasm, hit->addr);
1238  rz_asm_disassemble(core->rasm, &asmop, buf, hit->len);
1240  size += hit->len;
1241  if (analop.type != RZ_ANALYSIS_OP_TYPE_RET) {
1242  char *opstr_n = rz_str_newf(" %s", RZ_STRBUF_SAFEGET(&analop.esil));
1243  rz_list_append(ropList, (void *)opstr_n);
1244  }
1245  char *asm_op_hex = rz_asm_op_get_hex(&asmop);
1246  if (colorize) {
1247  RzStrBuf *colored_asm, *bw_str = rz_strbuf_new(rz_asm_op_get_asm(&asmop));
1248  colored_asm = rz_asm_colorize_asm_str(bw_str, core->print, rz_asm_get_parse_param(core->analysis->reg, analop.type), asmop.asm_toks);
1249  if (comment) {
1250  rz_cons_printf(" 0x%08" PFMT64x " %18s %s%s ; %s\n",
1251  hit->addr, asm_op_hex, rz_strbuf_get(colored_asm), Color_RESET, comment);
1252  } else {
1253  rz_cons_printf(" 0x%08" PFMT64x " %18s %s%s\n",
1254  hit->addr, asm_op_hex, rz_strbuf_get(colored_asm), Color_RESET);
1255  }
1256  rz_strbuf_free(colored_asm);
1257  } else {
1258  if (comment) {
1259  rz_cons_printf(" 0x%08" PFMT64x " %18s %s ; %s\n",
1260  hit->addr, asm_op_hex, rz_asm_op_get_asm(&asmop), comment);
1261  } else {
1262  rz_cons_printf(" 0x%08" PFMT64x " %18s %s\n",
1263  hit->addr, asm_op_hex, rz_asm_op_get_asm(&asmop));
1264  }
1265  }
1266  free(asm_op_hex);
1267  free(buf);
1269  }
1270  if (db && hit) {
1271  const ut64 addr = ((RzCoreAsmHit *)hitlist->head->data)->addr;
1272  // rz_cons_printf ("Gadget size: %d\n", (int)size);
1273  const char *key = sdb_fmt("0x%08" PFMT64x, addr);
1274  rop_classify(core, db, ropList, key, size);
1275  }
1276  }
1277  if (mode != 'j') {
1278  rz_cons_newline();
1279  }
1280  rz_list_free(ropList);
1281 }
RZ_API char * rz_asm_op_get_hex(RzAsmOp *op)
Definition: aop.c:28
RZ_API RZ_OWN RzAsmParseParam * rz_asm_get_parse_param(RZ_NULLABLE const RzReg *reg, ut32 ana_op_type)
Does all kinds of NULL checks on the parameters and returns an initialized RzAsmParseParam or NULL on...
Definition: asm.c:1763
RZ_DEPRECATE RZ_API RZ_OWN RzStrBuf * rz_asm_colorize_asm_str(RZ_BORROW RzStrBuf *asm_str, RZ_BORROW RzPrint *p, RZ_NULLABLE const RzAsmParseParam *param, RZ_NULLABLE const RzAsmTokenString *toks)
Colors a given asm string and returns it. If toks is not NULL it uses the tokens to color the asm str...
Definition: asm.c:1741
static void rop_classify(RzCore *core, Sdb *db, RzList *ropList, const char *key, unsigned int size)
RZ_API void rz_cons_newline(void)
Definition: cons.c:1274
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void static offset struct stat static buf void long static basep static whence static length const void static len key
Definition: sflib.h:118
RZ_API RZ_OWN RzList * rz_list_newf(RzListFree f)
Returns a new initialized RzList pointer and sets the free method.
Definition: list.c:248
RZ_API Sdb * sdb_ns(Sdb *s, const char *name, int create)
Definition: ns.c:186
RZ_API PJ * pj_ka(PJ *j, const char *k)
Definition: pj.c:163
RZ_API RzStrBuf * rz_strbuf_new(const char *s)
Definition: strbuf.c:8
RZ_API void rz_strbuf_free(RzStrBuf *sb)
Definition: strbuf.c:358
RzAsmTokenString * asm_toks
Tokenized asm string.
Definition: rz_asm.h:74
Sdb * sdb
Definition: rz_core.h:365
void * data
Definition: rz_list.h:14
RzListIter * head
Definition: rz_list.h:19
Definition: sdb.h:63

References addr, analop(), rz_core_t::analysis, rz_asm_op_t::asm_toks, Color_RESET, rz_core_t::config, search_parameters::core, rz_list_iter_t::data, eprintf, free(), rz_list_t::head, hit(), rz_core_t::io, key, malloc(), NULL, opstr(), PFMT64x, search_parameters::pj, pj_end(), pj_ka(), pj_ki(), pj_kN(), pj_ks(), pj_o(), rz_core_t::print, rz_core_t::rasm, rz_analysis_t::reg, rop_classify(), rz_analysis_op(), rz_analysis_op_fini(), RZ_ANALYSIS_OP_MASK_BASIC, RZ_ANALYSIS_OP_MASK_ESIL, RZ_ANALYSIS_OP_TYPE_RET, rz_analysis_optype_to_string(), rz_asm_colorize_asm_str(), rz_asm_disassemble(), rz_asm_get_parse_param(), rz_asm_op_get_asm(), rz_asm_op_get_hex(), rz_asm_set_pc(), rz_config_get_i(), rz_cons_newline(), rz_cons_printf(), RZ_EMPTY, rz_io_read_at(), rz_list_append(), rz_list_free(), rz_list_newf(), rz_meta_get_string(), RZ_META_TYPE_COMMENT, rz_str_newf(), rz_strbuf_free(), rz_strbuf_get(), rz_strbuf_new(), RZ_STRBUF_SAFEGET, rz_core_t::sdb, sdb_fmt(), sdb_ns(), and ut64().

Referenced by rz_cmd_search(), and rz_core_search_rop().

◆ print_search_progress()

static void print_search_progress ( ut64  at,
ut64  to,
int  n,
struct search_parameters param 
)
inlinestatic

Definition at line 522 of file cmd_search.c.

522  {
523  if ((++c % 64) || (param->outmode == RZ_MODE_JSON)) {
524  return;
525  }
526  if (rz_cons_singleton()->columns < 50) {
527  eprintf("\r[ ] 0x%08" PFMT64x " hits = %d \r%s",
528  at, n, (c % 2) ? "[ #]" : "[# ]");
529  } else {
530  eprintf("\r[ ] 0x%08" PFMT64x " < 0x%08" PFMT64x " hits = %d \r%s",
531  at, to, n, (c % 2) ? "[ #]" : "[# ]");
532  }
533 }
static int c
Definition: cmd_search.c:520
RZ_API RzCons * rz_cons_singleton(void)
Definition: cons.c:300
int n
Definition: mipsasm.c:19

References c, eprintf, n, search_parameters::outmode, PFMT64x, rz_cons_singleton(), RZ_MODE_JSON, and to.

Referenced by do_string_search().

◆ rop_kuery()

static void rop_kuery ( void *  data,
const char *  input,
PJ pj 
)
static

Definition at line 2420 of file cmd_search.c.

2420  {
2421  RzCore *core = (RzCore *)data;
2422  Sdb *db_rop = sdb_ns(core->sdb, "rop", false);
2423  SdbListIter *sdb_iter, *it;
2424  SdbList *sdb_list;
2425  SdbNs *ns;
2426  SdbKv *kv;
2427  char *out;
2428 
2429  if (!db_rop) {
2430  eprintf("Error: could not find SDB 'rop' namespace\n");
2431  return;
2432  }
2433 
2434  switch (*input) {
2435  case 'q':
2436  ls_foreach (db_rop->ns, it, ns) {
2437  sdb_list = sdb_foreach_list(ns->sdb, false);
2438  ls_foreach (sdb_list, sdb_iter, kv) {
2439  rz_cons_printf("%s ", sdbkv_key(kv));
2440  }
2441  }
2442  break;
2443  case 'j':
2444  pj_o(pj);
2445  pj_ka(pj, "gadgets");
2446  ls_foreach (db_rop->ns, it, ns) {
2447  sdb_list = sdb_foreach_list(ns->sdb, false);
2448  ls_foreach (sdb_list, sdb_iter, kv) {
2449  char *dup = strdup(sdbkv_value(kv));
2450  bool flag = false; // to free tok when doing strdup
2451  char *size = strtok(dup, " ");
2452  char *tok = strtok(NULL, "{}");
2453  if (!tok) {
2454  tok = strdup("NOP");
2455  flag = true;
2456  }
2457  pj_o(pj);
2458  pj_ks(pj, "address", sdbkv_key(kv));
2459  pj_ks(pj, "size", size);
2460  pj_ks(pj, "type", ns->name);
2461  pj_ks(pj, "effect", tok);
2462  pj_end(pj);
2463  free(dup);
2464  if (flag) {
2465  free(tok);
2466  }
2467  }
2468  }
2469  pj_end(pj);
2470  pj_end(pj);
2471  break;
2472  case ' ':
2473  if (!strcmp(input + 1, "nop")) {
2474  out = sdb_querys(core->sdb, NULL, 0, "rop/nop/*");
2475  if (out) {
2477  free(out);
2478  }
2479  } else if (!strcmp(input + 1, "mov")) {
2480  out = sdb_querys(core->sdb, NULL, 0, "rop/mov/*");
2481  if (out) {
2483  free(out);
2484  }
2485  } else if (!strcmp(input + 1, "const")) {
2486  out = sdb_querys(core->sdb, NULL, 0, "rop/const/*");
2487  if (out) {
2489  free(out);
2490  }
2491  } else if (!strcmp(input + 1, "arithm")) {
2492  out = sdb_querys(core->sdb, NULL, 0, "rop/arithm/*");
2493  if (out) {
2495  free(out);
2496  }
2497  } else if (!strcmp(input + 1, "arithm_ct")) {
2498  out = sdb_querys(core->sdb, NULL, 0, "rop/arithm_ct/*");
2499  if (out) {
2501  free(out);
2502  }
2503  } else {
2504  eprintf("Invalid ROP class\n");
2505  }
2506  break;
2507  default:
2508  out = sdb_querys(core->sdb, NULL, 0, "rop/***");
2509  if (out) {
2511  free(out);
2512  }
2513  break;
2514  }
2515 }
const lzma_allocator const uint8_t size_t uint8_t * out
Definition: block.h:528
RZ_API char * sdb_querys(Sdb *r, char *buf, size_t len, const char *_cmd)
Definition: query.c:164
static static fork const void static count static fd const char const char static newpath char char char static envp time_t static t const char static mode static whence const char static dir time_t static t unsigned static seconds const char struct utimbuf static buf static inc static sig const char static mode dup
Definition: sflib.h:68
#define ls_foreach(list, it, pos)
Definition: ls.h:31
RZ_API SdbList * sdb_foreach_list(Sdb *s, bool sorted)
Definition: sdb.c:630
static char * sdbkv_key(const SdbKv *kv)
Definition: sdbht.h:21
static char * sdbkv_value(const SdbKv *kv)
Definition: sdbht.h:25
Definition: ls.h:17
Definition: ls.h:22
Definition: sdbht.h:14
Definition: sdb.h:88
char * name
Definition: sdb.h:89
Sdb * sdb
Definition: sdb.h:91
SdbList * ns
Definition: sdb.h:82

References dup, eprintf, free(), input(), ls_foreach, sdb_ns_t::name, sdb_t::ns, NULL, out, pj_end(), pj_ka(), pj_ks(), pj_o(), rz_cons_printf(), rz_cons_println(), rz_core_t::sdb, sdb_ns_t::sdb, sdb_foreach_list(), sdb_ns(), sdb_querys(), sdbkv_key(), sdbkv_value(), and strdup().

Referenced by rz_cmd_search().

◆ rz_cmd_search()

RZ_IPI int rz_cmd_search ( void *  data,
const char *  input 
)

Definition at line 2875 of file cmd_search.c.

2875  {
2876  bool dosearch = false;
2877  int ret = true;
2878  RzCore *core = (RzCore *)data;
2879  struct search_parameters param = {
2880  .core = core,
2881  .cmd_hit = rz_config_get(core->config, "cmd.hit"),
2882  .outmode = 0,
2883  .inverse = false,
2884  .aes_search = false,
2885  .privkey_search = false,
2886  };
2887  if (!param.cmd_hit) {
2888  param.cmd_hit = "";
2889  }
2890  RzSearch *search = core->search;
2891  int ignorecase = false;
2892  int param_offset = 2;
2893  char *inp;
2894  if (!core || !core->io) {
2895  eprintf("Can't search if we don't have an open file.\n");
2896  return false;
2897  }
2898  if (core->in_search) {
2899  eprintf("Can't search from within a search.\n");
2900  return false;
2901  }
2902  if (input[0] == '/') {
2903  if (core->lastsearch) {
2904  input = core->lastsearch;
2905  } else {
2906  eprintf("No previous search done\n");
2907  return false;
2908  }
2909  } else {
2910  free(core->lastsearch);
2912  }
2913 
2914  core->in_search = true;
2915  rz_flag_space_push(core->flags, "search");
2916  const ut64 search_from = rz_config_get_i(core->config, "search.from"),
2917  search_to = rz_config_get_i(core->config, "search.to");
2918  if (search_from > search_to && search_to) {
2919  eprintf("search.from > search.to is not supported\n");
2920  ret = false;
2921  goto beach;
2922  }
2923  // {.addr = UT64_MAX, .size = 0} means search range is unspecified
2924  RzInterval search_itv = { search_from, search_to - search_from };
2925  bool empty_search_itv = search_from == search_to && search_from != UT64_MAX;
2926  if (empty_search_itv) {
2927  eprintf("WARNING from == to?\n");
2928  ret = false;
2929  goto beach;
2930  }
2931  // TODO full address cannot be represented, shrink 1 byte to [0, UT64_MAX)
2932  if (search_from == UT64_MAX && search_to == UT64_MAX) {
2933  search_itv.addr = 0;
2934  search_itv.size = UT64_MAX;
2935  }
2936 
2937  c = 0;
2938 
2939  searchshow = rz_config_get_i(core->config, "search.show");
2940  param.mode = rz_config_get(core->config, "search.in");
2941  param.boundaries = rz_core_get_boundaries_prot(core, -1, param.mode, "search");
2942 
2943  /*
2944  this introduces a bug until we implement backwards search
2945  for all search types
2946  if (__to < __from) {
2947  eprintf ("Invalid search range. Check 'e search.{from|to}'\n");
2948  return false;
2949  }
2950  since the backward search will be implemented soon I'm not gonna stick
2951  checks for every case in switch // jjdredd
2952  remove when everything is done
2953  */
2954 
2955  core->search->align = rz_config_get_i(core->config, "search.align");
2956  searchflags = rz_config_get_i(core->config, "search.flags");
2957  core->search->maxhits = rz_config_get_i(core->config, "search.maxhits");
2958  searchprefix = rz_config_get(core->config, "search.prefix");
2959  core->search->overlap = rz_config_get_i(core->config, "search.overlap");
2960  core->search->bckwrds = false;
2961 
2962  /* Quick & dirty check for json output */
2963  if (input[0] && (input[1] == 'j') && (input[0] != ' ')) {
2964  param.outmode = RZ_MODE_JSON;
2965  param_offset++;
2966  }
2967  param.pj = pj_new();
2968 
2969 reread:
2970  switch (*input) {
2971  case '!':
2972  input++;
2973  param.inverse = true;
2974  goto reread;
2975  case 'b': // "/b" backward search
2976  if (*(++input) == '?') {
2977  eprintf("Usage: /b<command> [value] backward search, see '/?'\n");
2978  goto beach;
2979  }
2980  search->bckwrds = true;
2981  if (core->offset) {
2982  RzInterval itv = { 0, core->offset };
2983  if (!rz_itv_overlap(search_itv, itv)) {
2984  ret = false;
2985  goto beach;
2986  } else {
2987  search_itv = rz_itv_intersect(search_itv, itv);
2988  }
2989  }
2990  goto reread;
2991  case 'o': { // "/o" print the offset of the Previous opcode
2992  ut64 addr, n = input[param_offset - 1] ? rz_num_math(core->num, input + param_offset) : 1;
2993  n = RZ_ABS((st64)n);
2994  if (((st64)n) < 1) {
2995  n = 1;
2996  }
2997  if (!rz_core_prevop_addr(core, core->offset, n, &addr)) {
2998  addr = UT64_MAX;
2999  (void)rz_core_asm_bwdis_len(core, NULL, &addr, n);
3000  }
3001  if (param.outmode == RZ_MODE_JSON) {
3002  rz_cons_printf("[%" PFMT64u "]", addr);
3003  } else {
3004  rz_cons_printf("0x%08" PFMT64x "\n", addr);
3005  }
3006  break;
3007  }
3008  case 'O': { // "/O" alternative to "/o"
3009  ut64 addr, n = input[param_offset - 1] ? rz_num_math(core->num, input + param_offset) : 1;
3010  if (!n) {
3011  n = 1;
3012  }
3014  if (param.outmode == RZ_MODE_JSON) {
3015  rz_cons_printf("[%" PFMT64u "]", addr);
3016  } else {
3017  rz_cons_printf("0x%08" PFMT64x "\n", addr);
3018  }
3019  break;
3020  }
3021  case 'R': // "/R"
3022  if (input[1] == '?') {
3024  } else if (input[1] == '/') {
3025  rz_core_search_rop(core, search_itv, 0, input + 1, 1, &param);
3026  } else if (input[1] == 'k') {
3027  if (input[2] == '?') {
3029  } else {
3030  rop_kuery(core, input + 2, param.pj);
3031  }
3032  } else {
3033  Sdb *gadgetSdb = sdb_ns(core->sdb, "gadget_sdb", false);
3034 
3035  if (!gadgetSdb) {
3036  rz_core_search_rop(core, search_itv, 0, input + 1, 0, &param);
3037  } else {
3038  SdbKv *kv;
3039  SdbListIter *sdb_iter;
3040  SdbList *sdb_list = sdb_foreach_list(gadgetSdb, true);
3041 
3042  ls_foreach (sdb_list, sdb_iter, kv) {
3043  RzList *hitlist = rz_core_asm_hit_list_new();
3044  if (!hitlist) {
3045  goto beach;
3046  }
3047 
3048  char *s = sdbkv_value(kv);
3049  ut64 addr;
3050  int opsz;
3051  int mode = 0;
3052 
3053  // Options, like JSON, linear, ...
3054  if (input + 1) {
3055  mode = *(input + 1);
3056  }
3057 
3058  do {
3059  RzCoreAsmHit *hit = rz_core_asm_hit_new();
3060  if (!hit) {
3061  rz_list_free(hitlist);
3062  goto beach;
3063  }
3064  sscanf(s, "%" PFMT64x "(%" PFMT32d ")", &addr, &opsz);
3065  hit->addr = addr;
3066  hit->len = opsz;
3067  rz_list_append(hitlist, hit);
3068  } while (*(s = strchr(s, ')') + 1) != '\0');
3069 
3070  print_rop(core, hitlist, param.pj, mode);
3071  rz_list_free(hitlist);
3072  }
3073  }
3074  }
3075  goto beach;
3076  case 'r': // "/r"
3077  {
3078  ut64 n = (input[1] == ' ' || (input[1] && input[2] == ' '))
3079  ? rz_num_math(core->num, input + 2)
3080  : UT64_MAX;
3081  if (n == 0LL) {
3082  eprintf("Cannot find null references.\n");
3083  break;
3084  }
3085  switch (input[1]) {
3086  case 'c': // "/rc"
3087  {
3088  RzListIter *iter;
3089  RzIOMap *map;
3090  rz_list_foreach (param.boundaries, iter, map) {
3091  eprintf("-- 0x%" PFMT64x " 0x%" PFMT64x "\n", map->itv.addr, rz_itv_end(map->itv));
3092  rz_core_analysis_search(core, map->itv.addr, rz_itv_end(map->itv), n, 'c');
3093  }
3094  } break;
3095  case 'a': // "/ra"
3096  {
3097  RzListIter *iter;
3098  RzIOMap *map;
3099  rz_list_foreach (param.boundaries, iter, map) {
3100  eprintf("-- 0x%" PFMT64x " 0x%" PFMT64x "\n", map->itv.addr, rz_itv_end(map->itv));
3101  rz_core_analysis_search(core, map->itv.addr, rz_itv_end(map->itv), n, 0);
3102  }
3103  } break;
3104  case 'r': // "/rr" - read refs
3105  {
3106  RzListIter *iter;
3107  RzIOMap *map;
3108  rz_list_foreach (param.boundaries, iter, map) {
3109  eprintf("-- 0x%" PFMT64x " 0x%" PFMT64x "\n", map->itv.addr, rz_itv_end(map->itv));
3110  rz_core_analysis_search(core, map->itv.addr, rz_itv_end(map->itv), n, 'r');
3111  }
3112  } break;
3113  case 'w': // "/rw" - write refs
3114  {
3115  RzListIter *iter;
3116  RzIOMap *map;
3117  rz_list_foreach (param.boundaries, iter, map) {
3118  eprintf("-- 0x%" PFMT64x " 0x%" PFMT64x "\n", map->itv.addr, rz_itv_end(map->itv));
3119  rz_core_analysis_search(core, map->itv.addr, rz_itv_end(map->itv), n, 'w');
3120  }
3121  } break;
3122  case ' ': // "/r $$"
3123  case 0: // "/r"
3124  {
3125  RzListIter *iter;
3126  RzIOMap *map;
3127  rz_list_foreach (param.boundaries, iter, map) {
3128  ut64 from = map->itv.addr;
3129  ut64 to = rz_itv_end(map->itv);
3130  if (input[param_offset - 1] == ' ') {
3132  rz_num_math(core->num, input + 2), 0);
3133  do_ref_search(core, rz_num_math(core->num, input + 2), from, to, &param);
3134  } else {
3136  do_ref_search(core, core->offset, from, to, &param);
3137  }
3138  if (rz_cons_is_breaked()) {
3139  break;
3140  }
3141  }
3142  } break;
3143  case '?':
3145  break;
3146  }
3147  } break;
3148  case 'a': // "/a"
3149  if (input[1] == '?') {
3151  } else if (input[1] == 'd') { // "ad"
3152  dosearch = 0;
3153  do_asm_search(core, &param, input + 2, 0, search_itv);
3154  } else if (input[1] == 'e') { // "ae"
3155  dosearch = 0;
3156  do_asm_search(core, &param, input + 2, 'e', search_itv);
3157  } else if (input[1] == 'c') { // "/ac"
3158  dosearch = 0;
3159  do_asm_search(core, &param, input + 2, 'c', search_itv);
3160  } else if (input[1] == 'o') { // "/ao"
3161  dosearch = 0;
3162  do_asm_search(core, &param, input + 2, 'o', search_itv);
3163  } else if (input[1] == 'a') { // "/aa"
3164  dosearch = 0;
3165  do_asm_search(core, &param, input + 2, 'a', search_itv);
3166  } else if (input[1] == 'i') { // "/ai"
3167  do_asm_search(core, &param, input + 2, 'i', search_itv);
3168  } else if (input[1] == '1') { // "a1"
3170  } else if (input[1] == 'I') { // "/aI" - infinite
3172  } else if (input[1] == ' ') {
3173  if (input[param_offset - 1]) {
3174  char *kwd = rz_core_asm_search(core, input + param_offset);
3175  if (!kwd) {
3176  ret = false;
3177  goto beach;
3178  }
3179  dosearch = true;
3181  rz_search_set_distance(core->search, (int)rz_config_get_i(core->config, "search.distance"));
3184  free(kwd);
3185  }
3186  } else if (input[1] == 's') {
3187  if (input[2] == 'l') { // "asl"
3188  rz_core_cmd0(core, "asl");
3189  } else { // "as"
3190  do_syscall_search(core, &param);
3191  }
3192  dosearch = false;
3193  } else {
3194  dosearch = do_analysis_search(core, &param, input + 1);
3195  }
3196  break;
3197  case 'c': { // "/c"
3198  dosearch = true;
3199  switch (input[1]) {
3200  case 'c': // "/cc"
3201  {
3202  ret = false;
3203  char *space = strchr(input, ' ');
3204  const char *arg = space ? rz_str_trim_head_ro(space + 1) : NULL;
3205  if (!arg || input[2] == '?') {
3206  eprintf("Usage: /cc[aAdlpb] [hashname] [hexpairhashvalue]\n");
3207  eprintf(" /cca - lowercase alphabet chars only\n");
3208  eprintf(" /ccA - uppercase alphabet chars only\n");
3209  eprintf(" /ccl - letters (lower + upper alphabet chars)\n");
3210  eprintf(" /ccd - digits (only numbers)\n");
3211  eprintf(" /ccp - printable (alpha + digit)\n");
3212  eprintf(" /ccb - binary (any number is valid)\n");
3213  goto beach;
3214  }
3215  char *s = strdup(arg);
3216  char *sp = strchr(s, ' ');
3217  int mode = input[2];
3218  if (sp) {
3219  *sp = 0;
3220  sp++;
3221  char *hashName = s;
3222  ut8 *hashValue = (ut8 *)strdup(sp);
3223  if (hashValue) {
3224  if (!rz_str_startswith((const char *)hashValue, "0x")) {
3225  // TODO: support bigger hashes
3226  int hashLength = 4;
3227  ut32 n = (ut32)rz_num_get(NULL, (const char *)hashValue);
3228  memcpy(hashValue, (const ut8 *)&n, sizeof(ut32));
3229  search_collisions(core, hashName, hashValue, hashLength, mode);
3230  } else {
3231  int hashLength = rz_hex_str2bin(sp, hashValue);
3232  if (hashLength > 0) {
3233  search_collisions(core, hashName, hashValue, hashLength, mode);
3234  } else {
3235  eprintf("Invalid expected hash hexpairs.\n");
3236  }
3237  }
3238  free(hashValue);
3239  } else {
3240  eprintf("Cannot allocate memory.\n");
3241  }
3242  ret = true;
3243  } else {
3244  eprintf("Usage: /cc [hashname] [hexpairhashvalue]\n");
3245  eprintf("Usage: /CC to search ascii collisions\n");
3246  }
3247  free(s);
3248  goto beach;
3249  } break;
3250  case 'd': // "cd"
3251  {
3252  RzSearchKeyword *kw;
3253  kw = rz_search_keyword_new_hex("308200003082", "ffff0000ffff", NULL);
3255  if (kw) {
3257  // eprintf ("Searching %d byte(s)...\n", kw->keyword_length);
3259  } else {
3260  eprintf("bad pointer\n");
3261  dosearch = false;
3262  }
3263  } break;
3264  case 'a': // "ca"
3265  {
3266  RzSearchKeyword *kw;
3267  kw = rz_search_keyword_new_hexmask("00", NULL);
3268  // AES search is done over 40 bytes
3271  rz_search_kw_add(search, kw);
3273  param.aes_search = true;
3274  break;
3275  }
3276  case 'r': // "cr"
3277  {
3278  RzSearchKeyword *kw;
3279  kw = rz_search_keyword_new_hexmask("00", NULL);
3280  // Private key search is at least 11 bytes
3283  rz_search_kw_add(search, kw);
3285  param.privkey_search = true;
3286  break;
3287  }
3288  default: {
3289  dosearch = false;
3291  }
3292  }
3293  } break;
3294  case 'm': // "/m"
3295  dosearch = false;
3296  if (input[1] == '?') { // "/m?"
3298  } else if (input[1] == 'b') { // "/mb"
3299  bool bin_verbose = rz_config_get_i(core->config, "bin.verbose");
3300  rz_config_set_i(core->config, "bin.verbose", false);
3301  // TODO : iter maps?
3302  cmd_search_bin(core, search_itv);
3303  rz_config_set_i(core->config, "bin.verbose", bin_verbose);
3304  } else if (input[1] == ' ' || input[1] == '\0' || param.outmode == RZ_MODE_JSON) {
3305  int ret;
3306  const char *file = input[param_offset - 1] ? input + param_offset : NULL;
3307  ut64 addr = search_itv.addr;
3308  RzListIter *iter;
3309  RzIOMap *map;
3310  if (param.outmode == RZ_MODE_JSON) {
3311  pj_a(param.pj);
3312  }
3314  int maxHits = rz_config_get_i(core->config, "search.maxhits");
3315  int hits = 0;
3316  rz_list_foreach (param.boundaries, iter, map) {
3317  if (param.outmode != RZ_MODE_JSON) {
3318  eprintf("-- %llx %llx\n", map->itv.addr, rz_itv_end(map->itv));
3319  }
3321  for (addr = map->itv.addr; addr < rz_itv_end(map->itv); addr++) {
3322  if (rz_cons_is_breaked()) {
3323  break;
3324  }
3325  ret = rz_core_magic_at(core, file, addr, 99, false, param.outmode == RZ_MODE_JSON ? param.pj : NULL, &hits);
3326  if (ret == -1) {
3327  // something went terribly wrong.
3328  break;
3329  }
3330  if (maxHits && hits >= maxHits) {
3331  break;
3332  }
3333  addr += ret - 1;
3334  }
3335  rz_cons_clear_line(1);
3337  }
3338  if (param.outmode == RZ_MODE_JSON) {
3339  pj_end(param.pj);
3340  }
3341  } else {
3342  eprintf("Usage: /m [file]\n");
3343  }
3344  rz_cons_clear_line(1);
3345  break;
3346  case 'p': // "/p"
3347  {
3348  if (input[param_offset - 1]) {
3349  int ps = atoi(input + param_offset);
3350  if (ps > 1) {
3351  RzListIter *iter;
3352  RzIOMap *map;
3353  rz_list_foreach (param.boundaries, iter, map) {
3354  eprintf("-- %llx %llx\n", map->itv.addr, rz_itv_end(map->itv));
3357  rz_search_pattern(core->search, map->itv.addr, rz_itv_end(map->itv));
3359  }
3360  break;
3361  }
3362  }
3363  eprintf("Invalid pattern size (must be > 0)\n");
3364  } break;
3365  case 'P': // "/P"
3366  search_similar_pattern(core, atoi(input + 1), &param);
3367  break;
3368  case 'V': // "/V"
3369  {
3370  if (input[2] == 'j') {
3371  param.outmode = RZ_MODE_JSON;
3372  param_offset++;
3373  } else if (strchr(input + 1, '*')) {
3374  param.outmode = RZ_MODE_RIZINCMD;
3375  }
3376  int err = 1, vsize = atoi(input + 1);
3377  const char *num_str = input + param_offset + 1;
3378  if (vsize && input[2] && num_str) {
3379  if (param.outmode == RZ_MODE_JSON) {
3380  pj_a(param.pj);
3381  }
3382  char *w = strchr(num_str, ' ');
3383  if (w) {
3384  *w++ = 0;
3385  ut64 vmin = rz_num_math(core->num, num_str);
3386  ut64 vmax = rz_num_math(core->num, w);
3387  if (vsize > 0) {
3388  RzIOMap *map;
3389  RzListIter *iter;
3390  rz_list_foreach (param.boundaries, iter, map) {
3391  err = 0;
3392  int hits = rz_core_search_value_in_range(core, map->itv,
3393  vmin, vmax, vsize,
3394  _CbInRangeSearchV, &param);
3395  if (param.outmode != RZ_MODE_JSON) {
3396  eprintf("hits: %d\n", hits);
3397  }
3398  }
3399  }
3400  }
3401  if (param.outmode == RZ_MODE_JSON) {
3402  pj_end(param.pj);
3403  }
3404  }
3405  if (err) {
3406  eprintf("Usage: /V[1|2|4|8] [minval] [maxval]\n");
3407  }
3408  }
3409  dosearch = false;
3410  break;
3411  case 'v': // "/v"
3412  if (input[1]) {
3413  if (input[1] == '?') {
3414  rz_cons_print("Usage: /v[1|2|4|8] [value]\n");
3415  break;
3416  }
3417  if (input[2] == 'j') {
3418  param.outmode = RZ_MODE_JSON;
3419  param_offset++;
3420  }
3421  }
3423  rz_search_set_distance(core->search, (int)rz_config_get_i(core->config, "search.distance"));
3424  char *v_str = (char *)rz_str_trim_head_ro(input + param_offset);
3425  RzList *nums = rz_num_str_split_list(v_str);
3426  int len = rz_list_length(nums);
3427  int bsize = 0;
3428  ut8 *v_buf = NULL;
3429  switch (input[1]) {
3430  case '8':
3431  if (input[param_offset]) {
3432  bsize = sizeof(ut64) * len;
3433  v_buf = v_writebuf(core, nums, len, '8', bsize);
3434  } else {
3435  eprintf("Usage: /v8 value\n");
3436  }
3437  break;
3438  case '1':
3439  if (input[param_offset]) {
3440  bsize = sizeof(ut8) * len;
3441  v_buf = v_writebuf(core, nums, len, '1', bsize);
3442  } else {
3443  eprintf("Usage: /v1 value\n");
3444  }
3445  break;
3446  case '2':
3447  if (input[param_offset]) {
3448  bsize = sizeof(ut16) * len;
3449  v_buf = v_writebuf(core, nums, len, '2', bsize);
3450  } else {
3451  eprintf("Usage: /v2 value\n");
3452  }
3453  break;
3454  default: // default size
3455  case '4':
3456  if (input[param_offset - 1]) {
3457  if (input[param_offset]) {
3458  bsize = sizeof(ut32) * len;
3459  v_buf = v_writebuf(core, nums, len, '4', bsize);
3460  }
3461  } else {
3462  eprintf("Usage: /v4 value\n");
3463  }
3464  break;
3465  }
3466  if (v_buf) {
3468  rz_search_keyword_new((const ut8 *)v_buf, bsize, NULL, 0, NULL));
3469  free(v_buf);
3470  }
3472  dosearch = true;
3473  break;
3474  case 'w': // "/w" search wide string, includes ignorecase search functionality (/wi cmd)!
3475  if (input[2]) {
3476  if (input[1] == 'j' || input[2] == 'j') {
3477  param.outmode = RZ_MODE_JSON;
3478  }
3479  if (input[1] == 'i' || input[2] == 'i') {
3480  ignorecase = true;
3481  }
3482  } else {
3483  param.outmode = RZ_MODE_RIZINCMD;
3484  }
3485 
3486  size_t shift = 1 + ignorecase;
3487  if (param.outmode == RZ_MODE_JSON) {
3488  shift++;
3489  }
3490  size_t strstart;
3491  const char *p2;
3492  char *p;
3493  strstart = shift + 1;
3494  len = strlen(input + strstart);
3495  inp = calloc((len + 1), 2);
3496  for (p2 = input + strstart, p = inp; *p2; p += 2, p2++) {
3497  if (ignorecase) {
3498  p[0] = tolower((const ut8)*p2);
3499  } else {
3500  p[0] = *p2;
3501  }
3502  p[1] = 0;
3503  }
3505  rz_search_set_distance(core->search, (int)rz_config_get_i(core->config, "search.distance"));
3506  RzSearchKeyword *skw;
3507  skw = rz_search_keyword_new((const ut8 *)inp, len * 2, NULL, 0, NULL);
3508  free(inp);
3509  if (skw) {
3510  skw->icase = ignorecase;
3511  rz_search_kw_add(core->search, skw);
3513  dosearch = true;
3514  } else {
3515  eprintf("Invalid keyword\n");
3516  break;
3517  }
3518  // fallthrough
3519  case 'i': // "/i"
3520  if (input[param_offset - 1] != ' ') {
3521  eprintf("Missing ' ' after /i\n");
3522  ret = false;
3523  goto beach;
3524  }
3525  ignorecase = true;
3526  // fallthrough
3527  case 'j': // "/j"
3528  if (input[0] == 'j' && input[1] == ' ') {
3529  param.outmode = RZ_MODE_JSON;
3530  }
3531  // fallthrough
3532  case ' ': // "/ " search string
3533  inp = strdup(input + 1 + ignorecase + (param.outmode == RZ_MODE_JSON ? 1 : 0));
3534  len = rz_str_unescape(inp);
3535 #if 0
3536  if (!json) {
3537  eprintf ("Searching %d byte(s) from 0x%08"PFMT64x " to 0x%08"PFMT64x ": ",
3538  len, search_itv.addr, rz_itv_end (search_itv));
3539  for (i = 0; i < len; i++) {
3540  eprintf ("%02x ", (ut8) inp[i]);
3541  }
3542  eprintf ("\n");
3543  }
3544 #endif
3546  rz_search_set_distance(core->search, (int)rz_config_get_i(core->config, "search.distance"));
3547  {
3548  RzSearchKeyword *skw;
3549  skw = rz_search_keyword_new((const ut8 *)inp, len, NULL, 0, NULL);
3550  free(inp);
3551  if (skw) {
3552  skw->icase = ignorecase;
3554  rz_search_kw_add(core->search, skw);
3555  } else {
3556  eprintf("Invalid keyword\n");
3557  break;
3558  }
3559  }
3561  dosearch = true;
3562  break;
3563  case 'e': // "/e" match regexp
3564  if (input[1] == '?') {
3565  eprintf("Usage: /e /foo/i or /e/foo/i\n");
3566  } else if (input[1]) {
3567  RzSearchKeyword *kw;
3569  if (!kw) {
3570  eprintf("Invalid regexp specified\n");
3571  break;
3572  }
3574  // TODO distance is unused
3575  rz_search_set_distance(core->search, (int)rz_config_get_i(core->config, "search.distance"));
3578  dosearch = true;
3579  } else {
3580  eprintf("Missing regex\n");
3581  }
3582  break;
3583  case 'E': // "/E"
3584  if (core->bin && core->bin->is_debugger) {
3586  }
3587  do_esil_search(core, &param, input);
3588  goto beach;
3589  case 'd': // "/d" search delta key
3590  if (input[1]) {
3593  rz_search_keyword_new_hexmask(input + param_offset, NULL));
3595  dosearch = true;
3596  } else {
3597  eprintf("Missing delta\n");
3598  }
3599  break;
3600  case 'h': // "/h"
3601  {
3602  char *p, *arg = rz_str_trim_dup(input + 1);
3603  p = strchr(arg, ' ');
3604  if (p) {
3605  *p++ = 0;
3606  if (*arg == '?') {
3607  eprintf("Usage: /h md5 [hash] [datalen]\n");
3608  } else {
3609  ut32 min = UT32_MAX;
3610  ut32 max = UT32_MAX;
3611  char *pmax, *pmin = strchr(p, ' ');
3612  if (pmin) {
3613  *pmin++ = 0;
3614  pmax = strchr(pmin, ' ');
3615  if (pmax) {
3616  *pmax++ = 0;
3617  max = rz_num_math(core->num, pmax);
3618  }
3619  min = rz_num_math(core->num, pmin);
3620  }
3621  search_hash(core, arg, p, min, max, &param);
3622  }
3623  } else {
3624  eprintf("Missing hash. See ph?\n");
3625  }
3626  free(arg);
3627  } break;
3628  case 'f': // "/f" forward search
3629  if (core->offset) {
3630  RzInterval itv = { core->offset, -core->offset };
3631  if (!rz_itv_overlap(search_itv, itv)) {
3632  ret = false;
3633  goto beach;
3634  } else {
3635  search_itv = rz_itv_intersect(search_itv, itv);
3636  }
3637  }
3638  break;
3639  case 'g': // "/g" graph search
3640  if (input[1] == '?') {
3641  rz_cons_printf("Usage: /g[g] [fromaddr] @ [toaddr]\n");
3642  rz_cons_printf("(find all graph paths A to B (/gg follow jumps, see search.count and analysis.depth)");
3643  } else {
3644  ut64 addr = UT64_MAX;
3645  if (input[1]) {
3646  addr = rz_num_math(core->num, input + 2);
3647  } else {
3649  if (fcn) {
3650  addr = fcn->addr;
3651  } else {
3652  addr = core->offset;
3653  }
3654  }
3655  const int depth = rz_config_get_i(core->config, "analysis.depth");
3656  // Va;ifate input length
3657  if (input[1] != '\0') {
3658  rz_core_analysis_paths(core, addr, core->offset, input[1] == 'g', depth, (input[1] == 'j' || input[2] == 'j'));
3659  }
3660  }
3661  break;
3662  case 'F': // "/F" search file /F [file] ([offset] ([sz]))
3663  if (input[param_offset - 1] == ' ') {
3664  int n_args;
3665  char **args = rz_str_argv(input + param_offset, &n_args);
3666  ut8 *buf = NULL;
3667  ut64 offset = 0;
3668  size_t size;
3669  buf = (ut8 *)rz_file_slurp(args[0], &size);
3670  if (!buf) {
3671  eprintf("Cannot open '%s'\n", args[0]);
3673  break;
3674  }
3675  if (n_args > 1) {
3676  offset = rz_num_math(core->num, args[1]);
3677  if (size <= offset) {
3678  eprintf("size <= offset\n");
3680  free(buf);
3681  break;
3682  }
3683  }
3684  if (n_args > 2) {
3685  len = rz_num_math(core->num, args[2]);
3686  if (len > size - offset) {
3687  eprintf("len too large\n");
3689  free(buf);
3690  break;
3691  }
3692  } else {
3693  len = size - offset;
3694  }
3695  RzSearchKeyword *kw;
3697  rz_search_set_distance(core->search, (int)rz_config_get_i(core->config, "search.distance"));
3698  kw = rz_search_keyword_new(buf + offset, len, NULL, 0, NULL);
3699  if (kw) {
3701  // eprintf ("Searching %d byte(s)...\n", kw->keyword_length);
3703  dosearch = true;
3704  } else {
3705  eprintf("no keyword\n");
3706  }
3707 
3709  free(buf);
3710  } else {
3711  eprintf("Usage: /F[j] [file] ([offset] ([sz]))\n");
3712  }
3713  break;
3714  case 'x': // "/x" search hex
3715  if (input[1] == '?') {
3717  } else {
3718  RzSearchKeyword *kw;
3719  char *s, *p = strdup(input + param_offset);
3721  rz_search_set_distance(core->search, (int)rz_config_get_i(core->config, "search.distance"));
3722  s = strchr(p, ':');
3723  if (s) {
3724  *s++ = 0;
3726  } else {
3728  }
3729  if (kw) {
3731  // eprintf ("Searching %d byte(s)...\n", kw->keyword_length);
3733  dosearch = true;
3734  } else {
3735  eprintf("no keyword\n");
3736  }
3737  free(p);
3738  }
3739  break;
3740  case 's': // "/s"
3741  do_section_search(core, &param, input + 1);
3742  break;
3743  case '+': // "/+"
3744  if (input[1] == ' ') {
3745  // TODO: support /+j
3746  char *buf = malloc(strlen(input) * 2);
3747  char *str = strdup(input + 2);
3748  int ochunksize;
3749  int i, len, chunksize = rz_config_get_i(core->config, "search.chunk");
3750  if (chunksize < 1) {
3751  chunksize = core->rasm->bits / 8;
3752  }
3753  len = rz_str_unescape(str);
3754  ochunksize = chunksize = RZ_MIN(len, chunksize);
3755  eprintf("Using chunksize: %d\n", chunksize);
3756  core->in_search = false;
3757  for (i = 0; i < len; i += chunksize) {
3758  chunksize = ochunksize;
3759  again:
3760  rz_hex_bin2str((ut8 *)str + i, RZ_MIN(chunksize, len - i), buf);
3761  eprintf("/x %s\n", buf);
3762  rz_core_cmdf(core, "/x %s", buf);
3763  if (core->num->value == 0) {
3764  chunksize--;
3765  if (chunksize < 1) {
3766  eprintf("Oops\n");
3767  free(buf);
3768  free(str);
3769  goto beach;
3770  }
3771  eprintf("Repeat with chunk size %d\n", chunksize);
3772  goto again;
3773  }
3774  }
3775  free(str);
3776  free(buf);
3777  } else {
3778  eprintf("Usage: /+ [string]\n");
3779  }
3780  break;
3781  case 'z': // "/z" search strings of min-max range
3782  {
3783  char *p;
3784  ut32 min, max;
3785  if (!input[1]) {
3786  eprintf("Usage: /z min max\n");
3787  break;
3788  }
3789  if ((p = strchr(input + 2, ' '))) {
3790  *p = 0;
3791  max = rz_num_math(core->num, p + 1);
3792  } else {
3793  eprintf("Usage: /z min max\n");
3794  break;
3795  }
3796  min = rz_num_math(core->num, input + 2);
3798  eprintf("Error: min must be lower than max\n");
3799  break;
3800  }
3802  rz_search_set_distance(core->search, (int)rz_config_get_i(core->config, "search.distance"));
3803  {
3806  rz_search_kw_add(search, kw);
3807  }
3809  dosearch = true;
3810  } break;
3811  case '?': // "/?"
3813  break;
3814  default:
3815  eprintf("See /? for help.\n");
3816  break;
3817  }
3818  rz_config_set_i(core->config, "search.kwidx", search->n_kws);
3819  if (dosearch) {
3820  do_string_search(core, search_itv, &param);
3821  }
3822 beach:
3823  core->num->value = search->nhits;
3824  core->in_search = false;
3825  rz_flag_space_pop(core->flags);
3826  if (param.outmode == RZ_MODE_JSON) {
3827  rz_cons_println(pj_string(param.pj));
3828  }
3829  pj_free(param.pj);
3830  rz_list_free(param.boundaries);
3832  return ret;
3833 }
RZ_API RzAnalysisFunction * rz_analysis_get_function_at(RzAnalysis *analysis, ut64 addr)
Definition: function.c:184
static RZ_NULLABLE RzILOpBitVector * shift(RzILOpBitVector *val, RZ_NULLABLE RzILOpBool **carry_out, arm_shifter type, RZ_OWN RzILOpBitVector *dist)
Definition: arm_il32.c:190
static bool err
Definition: armass.c:435
RZ_API int rz_search_pattern(RzSearch *s, ut64 from, ut64 to)
Definition: bytepat.c:61
RZ_API int rz_core_analysis_search(RzCore *core, ut64 from, ut64 to, ut64 ref, int mode)
Definition: canalysis.c:3071
RZ_API void rz_core_analysis_paths(RzCore *core, ut64 from, ut64 to, bool followCalls, int followDepth, bool is_json)
Definition: canalysis.c:5121
RZ_API int rz_core_search_value_in_range(RzCore *core, RzInterval search_itv, ut64 vmin, ut64 vmax, int vsize, inRangeCb cb, void *cb_user)
Definition: canalysis.c:4895
RZ_API char * rz_core_asm_search(RzCore *core, const char *input)
Definition: casm.c:56
RZ_API ut32 rz_core_asm_bwdis_len(RzCore *core, int *instr_len, ut64 *start_addr, ut32 nb)
Definition: casm.c:890
static int rz_core_magic_at(RzCore *core, const char *file, ut64 addr, int depth, int v, PJ *pj, int *hits)
Definition: cmd_magic.c:16
static void rz_core_magic_reset(RzCore *core)
Definition: cmd_magic.c:12
static void do_string_search(RzCore *core, RzInterval search_itv, struct search_parameters *param)
Definition: cmd_search.c:2304
static const char * help_msg_slash[]
Definition: cmd_search.c:35
static void __core_cmd_search_asm_infinite(RzCore *core, const char *arg)
Definition: cmd_search.c:2828
static const char * help_msg_slash_m[]
Definition: cmd_search.c:28
static void do_asm_search(RzCore *core, struct search_parameters *param, const char *input, int mode, RzInterval search_itv)
Definition: cmd_search.c:2201
static int search_hash(RzCore *core, const char *hashname, const char *hashstr, ut32 minlen, ut32 maxlen, struct search_parameters *param)
Definition: cmd_search.c:176
static ut8 * v_writebuf(RzCore *core, RzList *nums, int len, char ch, int bsize)
Definition: cmd_search.c:2608
static void do_esil_search(RzCore *core, struct search_parameters *param, const char *input)
Definition: cmd_search.c:1573
static void do_syscall_search(RzCore *core, struct search_parameters *param)
Definition: cmd_search.c:1760
static void print_rop(RzCore *core, RzList *hitlist, PJ *pj, int mode)
Definition: cmd_search.c:1124
static void search_similar_pattern(RzCore *core, int count, struct search_parameters *param)
Definition: cmd_search.c:2555
static const char * help_msg_slash_x[]
Definition: cmd_search.c:147
static const char * help_msg_slash_c[]
Definition: cmd_search.c:107
static void do_section_search(RzCore *core, struct search_parameters *param, const char *input)
Definition: cmd_search.c:2133
static const char * help_msg_slash_r[]
Definition: cmd_search.c:116
static const char * help_msg_slash_Rk[]
Definition: cmd_search.c:139
void _CbInRangeSearchV(RzCore *core, ut64 from, ut64 to, int vsize, void *user)
Definition: cmd_search.c:2578
static bool do_analysis_search(RzCore *core, struct search_parameters *param, const char *input)
Definition: cmd_search.c:1949
static void __core_cmd_search_asm_byteswap(RzCore *core, int nth)
Definition: cmd_search.c:2856
static void do_ref_search(RzCore *core, ut64 addr, ut64 from, ut64 to, struct search_parameters *param)
Definition: cmd_search.c:1904
static const char * help_msg_slash_R[]
Definition: cmd_search.c:127
static void cmd_search_bin(RzCore *core, RzInterval itv)
Definition: cmd_search.c:246
static void search_collisions(RzCore *core, const char *hashName, const ut8 *hashValue, int hashLength, int mode)
Definition: cmd_search.c:2740
static void rop_kuery(void *data, const char *input, PJ *pj)
Definition: cmd_search.c:2420
static int rz_core_search_rop(RzCore *core, RzInterval search_itv, int opt, const char *grep, int regexp, struct search_parameters *param)
Definition: cmd_search.c:1283
#define w
Definition: crypto_rc6.c:13
#define ut8
Definition: dcpu16.h:8
uint16_t ut16
uint32_t ut32
RZ_API bool rz_debug_map_sync(RzDebug *dbg)
Definition: dmap.c:33
int max
Definition: enough.c:225
voidpf uLong offset
Definition: ioapi.h:144
RZ_API RzSearchKeyword * rz_search_keyword_new_hex(const char *kwstr, const char *bmstr, const char *data)
Definition: keyword.c:132
RZ_API RzSearchKeyword * rz_search_keyword_new_regexp(const char *str, const char *data)
Definition: keyword.c:196
RZ_API RzSearchKeyword * rz_search_keyword_new(const ut8 *kwbuf, int kwlen, const ut8 *bmbuf, int bmlen, const char *data)
Definition: keyword.c:16
RZ_API RzSearchKeyword * rz_search_keyword_new_hexmask(const char *kwstr, const char *data)
Definition: keyword.c:173
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
int args
Definition: mipsasm.c:18
#define chunksize
#define min(a, b)
Definition: qsort.h:83
RZ_API RZ_OWN char * rz_file_slurp(const char *str, RZ_NULLABLE size_t *usz)
Definition: file.c:454
RZ_API int rz_hex_str2bin(const char *in, ut8 *out)
Convert an input string in into the binary form in out.
Definition: hex.c:444
RZ_API int rz_hex_bin2str(const ut8 *in, int len, char *out)
Definition: hex.c:382
RZ_API RzList * rz_num_str_split_list(char *str)
Definition: unum.c:905
RZ_API ut64 rz_num_get(RzNum *num, const char *str)
Definition: unum.c:172
RZ_API ut64 rz_num_math(RzNum *num, const char *str)
Definition: unum.c:456
RZ_API PJ * pj_new(void)
Definition: pj.c:25
RZ_API const char * pj_string(PJ *pj)
Definition: pj.c:57
RZ_API void pj_free(PJ *j)
Definition: pj.c:34
@ RZ_SEARCH_REGEXP
Definition: rz_search.h:18
@ RZ_SEARCH_STRING
Definition: rz_search.h:20
@ RZ_SEARCH_AES
Definition: rz_search.h:22
@ RZ_SEARCH_KEYWORD
Definition: rz_search.h:17
@ RZ_SEARCH_PRIV_KEY
Definition: rz_search.h:23
RZ_API char * rz_str_trim_dup(const char *str)
Definition: str_trim.c:78
RZ_API char ** rz_str_argv(const char *str, int *_argc)
Definition: str.c:2509
RZ_API int rz_str_unescape(char *buf)
Definition: str.c:1300
RZ_API void rz_str_argv_free(char **argv)
Definition: str.c:2633
#define PFMT64u
Definition: rz_types.h:395
#define PFMT32d
Definition: rz_types.h:408
#define st64
Definition: rz_types_base.h:10
#define UT32_MAX
Definition: rz_types_base.h:99
#define tolower(c)
Definition: safe-ctype.h:149
RZ_API int rz_search_begin(RzSearch *s)
Definition: search.c:96
RZ_API void rz_search_kw_reset(RzSearch *s)
Definition: search.c:544
RZ_API int rz_search_set_string_limits(RzSearch *s, ut32 min, ut32 max)
Definition: search.c:64
RZ_API void rz_search_reset(RzSearch *s, int mode)
Definition: search.c:537
RZ_API void rz_search_pattern_size(RzSearch *s, int size)
Definition: search.c:459
RZ_API int rz_search_kw_add(RzSearch *s, RzSearchKeyword *kw)
Definition: search.c:506
RZ_API void rz_search_set_distance(RzSearch *s, int dist)
Definition: search.c:449
Definition: gzappend.c:170
int bits
Definition: rz_asm.h:100
int is_debugger
Definition: rz_bin.h:350
RzDebug * dbg
Definition: rz_core.h:329
bool in_search
Definition: rz_core.h:359
char * lastsearch
Definition: rz_core.h:370
bool overlap
Definition: rz_search.h:68
const char * mode
Definition: cmd_search.c:162
RZ_API bool rz_core_prevop_addr(RzCore *core, ut64 start_addr, int numinstrs, ut64 *prev_addr)
Definition: visual.c:1173
RZ_API ut64 rz_core_prevop_addr_force(RzCore *core, ut64 start_addr, int numinstrs)
Definition: visual.c:1195
static int sp
Definition: z80asm.c:91

References __core_cmd_search_asm_byteswap(), __core_cmd_search_asm_infinite(), _CbInRangeSearchV(), addr, rz_analysis_function_t::addr, rz_interval_t::addr, search_parameters::aes_search, AES_SEARCH_LENGTH, rz_search_t::align, rz_core_t::analysis, args, rz_search_t::bckwrds, rz_core_t::bin, rz_asm_t::bits, search_parameters::boundaries, c, calloc(), chunksize, search_parameters::cmd_hit, cmd_search_bin(), rz_core_t::config, search_parameters::core, rz_core_t::dbg, do_analysis_search(), do_asm_search(), do_esil_search(), do_ref_search(), do_section_search(), do_string_search(), do_syscall_search(), eprintf, err, rz_core_t::flags, free(), from, help_msg_slash, help_msg_slash_a, help_msg_slash_c, help_msg_slash_m, help_msg_slash_r, help_msg_slash_R, help_msg_slash_Rk, help_msg_slash_x, hit(), i, rz_search_keyword_t::icase, rz_core_t::in_search, input(), search_parameters::inverse, rz_core_t::io, rz_bin_t::is_debugger, rz_search_keyword_t::keyword_length, rz_core_t::lastsearch, len, ls_foreach, malloc(), map(), max, rz_search_t::maxhits, memcpy(), min, search_parameters::mode, n, NULL, rz_core_t::num, rz_core_t::offset, search_parameters::outmode, rz_search_t::overlap, p, PFMT32d, PFMT64u, PFMT64x, search_parameters::pj, pj_a(), pj_end(), pj_free(), pj_new(), pj_string(), print_rop(), PRIVATE_KEY_SEARCH_LENGTH, search_parameters::privkey_search, rz_core_t::rasm, rop_kuery(), RZ_ABS, rz_analysis_get_function_at(), rz_config_get(), rz_config_get_i(), rz_config_set_i(), rz_cons_break_pop(), rz_cons_break_push(), rz_cons_clear_line(), rz_cons_is_breaked(), rz_cons_printf(), rz_cons_println(), rz_core_analysis_paths(), rz_core_analysis_search(), rz_core_asm_bwdis_len(), rz_core_asm_hit_list_new(), rz_core_asm_hit_new(), rz_core_asm_search(), rz_core_cmd0(), rz_core_cmd_help(), rz_core_cmdf(), rz_core_get_boundaries_prot(), rz_core_magic_at(), rz_core_magic_reset(), rz_core_prevop_addr(), rz_core_prevop_addr_force(), rz_core_search_rop(), rz_core_search_value_in_range(), rz_debug_map_sync(), rz_file_slurp(), rz_hex_bin2str(), rz_hex_str2bin(), rz_itv_end(), rz_itv_intersect(), rz_itv_overlap(), rz_list_append(), rz_list_free(), rz_list_length(), RZ_MIN, RZ_MODE_JSON, RZ_MODE_RIZINCMD, rz_num_get(), rz_num_math(), rz_num_str_split_list(), RZ_SEARCH_AES, rz_search_begin(), RZ_SEARCH_DELTAKEY, RZ_SEARCH_KEYWORD, rz_search_keyword_new(), rz_search_keyword_new_hex(), rz_search_keyword_new_hexmask(), rz_search_keyword_new_regexp(), RZ_SEARCH_KEYWORD_TYPE_STRING, rz_search_kw_add(), rz_search_kw_reset(), rz_search_pattern(), rz_search_pattern_size(), RZ_SEARCH_PRIV_KEY, RZ_SEARCH_REGEXP, rz_search_reset(), rz_search_set_distance(), rz_search_set_string_limits(), RZ_SEARCH_STRING, rz_str_argv(), rz_str_argv_free(), rz_str_startswith(), rz_str_trim_dup(), rz_str_trim_head_ro(), rz_str_unescape(), s, rz_core_t::sdb, sdb_foreach_list(), sdb_ns(), sdbkv_value(), rz_core_t::search, search(), search_collisions(), search_hash(), search_similar_pattern(), searchflags, searchprefix, searchshow, shift(), rz_interval_t::size, sp, st64, cmd_descs_generate::str, strdup(), to, tolower, rz_search_keyword_t::type, UT32_MAX, ut64(), UT64_MAX, ut8, v_writebuf(), rz_num_t::value, and w.

Referenced by rz_core_cmd_init(), and rzshell_cmddescs_init().

◆ rz_core_get_boundaries_prot()

RZ_API RZ_OWN RzList* rz_core_get_boundaries_prot ( RzCore core,
int  perm,
const char *  mode,
const char *  prefix 
)

Definition at line 577 of file cmd_search.c.

577  {
579 
580  RzList *list = rz_list_newf(free); // XXX rz_io_map_free);
581  if (!list) {
582  return NULL;
583  }
584 
585  char bound_in[32];
586  char bound_from[32];
587  char bound_to[32];
588  snprintf(bound_in, sizeof(bound_in), "%s.%s", prefix, "in");
589  snprintf(bound_from, sizeof(bound_from), "%s.%s", prefix, "from");
590  snprintf(bound_to, sizeof(bound_to), "%s.%s", prefix, "to");
591  const ut64 search_from = rz_config_get_i(core->config, bound_from),
592  search_to = rz_config_get_i(core->config, bound_to);
593  const RzInterval search_itv = { search_from, search_to - search_from };
594  if (!mode) {
595  mode = rz_config_get(core->config, bound_in);
596  }
597  if (!rz_config_get_b(core->config, "cfg.debug") && !core->io->va) {
598  append_bound(list, core->io, search_itv, 0, rz_io_size(core->io), 7);
599  } else if (!strcmp(mode, "file")) {
600  append_bound(list, core->io, search_itv, 0, rz_io_size(core->io), 7);
601  } else if (!strcmp(mode, "block")) {
602  append_bound(list, core->io, search_itv, core->offset, core->blocksize, 7);
603  } else if (!strcmp(mode, "io.map")) {
604  RzIOMap *m = rz_io_map_get(core->io, core->offset);
605  if (m) {
606  append_bound(list, core->io, search_itv, m->itv.addr, m->itv.size, m->perm);
607  }
608  } else if (!strcmp(mode, "io.maps")) { // Non-overlapping RzIOMap parts not overridden by others (skyline)
609  ut64 begin = UT64_MAX;
610  ut64 end = UT64_MAX;
611 #define USE_SKYLINE 0
612 #if USE_SKYLINE
613  const RzPVector *skyline = &core->io->map_skyline;
614  size_t i;
615  for (i = 0; i < rz_pvector_len(skyline); i++) {
616  const RzIOMapSkyline *part = rz_pvector_at(skyline, i);
617  ut64 from = rz_itv_begin(part->itv);
618  ut64 to = rz_itv_end(part->itv);
619  // XXX skyline's fake map perms are wrong
620  RzIOMap *m = rz_io_map_get(core->io, from);
621  int rwx = m ? m->perm : part->map->perm;
622 #else
623  void **it;
624  RzPVector *maps = rz_io_maps(core->io);
625  rz_pvector_foreach (maps, it) {
626  RzIOMap *map = *it;
627  ut64 from = rz_itv_begin(map->itv);
628  ut64 to = rz_itv_end(map->itv);
629  int rwx = map->perm;
630 #endif
631  // eprintf ("--------- %llx %llx (%llx %llx)\n", from, to, begin, end);
632  if (begin == UT64_MAX) {
633  begin = from;
634  }
635  if (end == UT64_MAX) {
636  end = to;
637  } else {
638  if (end == from) {
639  end = to;
640  } else {
641  append_bound(list, NULL, search_itv,
642  begin, end - begin, rwx);
643  begin = from;
644  end = to;
645  }
646  }
647  }
648  if (end != UT64_MAX) {
649  append_bound(list, NULL, search_itv, begin, end - begin, 7);
650  }
651  } else if (rz_str_startswith(mode, "io.maps.")) {
652  int len = strlen("io.maps.");
653  int mask = (mode[len - 1] == '.') ? rz_str_rwx(mode + len) : 0;
654  // bool only = (bool)(size_t)strstr (mode, ".only");
655 
656  void **it;
657  RzPVector *maps = rz_io_maps(core->io);
658  rz_pvector_foreach (maps, it) {
659  RzIOMap *map = *it;
660  ut64 from = rz_itv_begin(map->itv);
661  // ut64 to = rz_itv_end (map->itv);
662  int rwx = map->perm;
663  if ((rwx & mask) != mask) {
664  continue;
665  }
666  append_bound(list, core->io, search_itv, from, rz_itv_size(map->itv), rwx);
667  }
668  } else if (rz_str_startswith(mode, "io.sky.")) {
669  int len = strlen("io.sky.");
670  int mask = (mode[len - 1] == '.') ? rz_str_rwx(mode + len) : 0;
671  bool only = (bool)(size_t)strstr(mode, ".only");
672  RzVector *skyline = &core->io->map_skyline.v;
673  ut64 begin = UT64_MAX;
674  ut64 end = UT64_MAX;
675  size_t i;
676  for (i = 0; i < rz_vector_len(skyline); i++) {
677  const RzSkylineItem *part = rz_vector_index_ptr(skyline, i);
678  ut64 from = part->itv.addr;
679  ut64 to = part->itv.addr + part->itv.size;
680  int perm = ((RzIOMap *)part->user)->perm;
681  if (maskMatches(perm, mask, only)) {
682  continue;
683  }
684  // eprintf ("--------- %llx %llx (%llx %llx)\n", from, to, begin, end);
685  if (begin == UT64_MAX) {
686  begin = from;
687  }
688  if (end == UT64_MAX) {
689  end = to;
690  } else {
691  if (end == from) {
692  end = to;
693  } else {
694  // eprintf ("[%llx - %llx]\n", begin, end);
695  append_bound(list, NULL, search_itv, begin, end - begin, perm);
696  begin = from;
697  end = to;
698  }
699  }
700  }
701  if (end != UT64_MAX) {
702  append_bound(list, NULL, search_itv, begin, end - begin, 7);
703  }
704  } else if (rz_str_startswith(mode, "bin.segments")) {
705  int len = strlen("bin.segments.");
706  int mask = (mode[len - 1] == '.') ? rz_str_rwx(mode + len) : 0;
707  bool only = (bool)(size_t)strstr(mode, ".only");
708  RzBinObject *obj = rz_bin_cur_object(core->bin);
709  if (obj) {
710  RzBinSection *s;
711  RzListIter *iter;
712  rz_list_foreach (obj->sections, iter, s) {
713  if (!s->is_segment) {
714  continue;
715  }
716  if (maskMatches(s->perm, mask, only)) {
717  continue;
718  }
719  ut64 addr = core->io->va ? s->vaddr : s->paddr;
720  ut64 size = core->io->va ? s->vsize : s->size;
721  append_bound(list, core->io, search_itv, addr, size, s->perm);
722  }
723  }
724  } else if (rz_str_startswith(mode, "code")) {
725  RzBinObject *obj = rz_bin_cur_object(core->bin);
726  if (obj) {
727  ut64 from = UT64_MAX;
728  ut64 to = 0;
729  RzBinSection *s;
730  RzListIter *iter;
731  rz_list_foreach (obj->sections, iter, s) {
732  if (s->is_segment) {
733  continue;
734  }
735  if (maskMatches(s->perm, 1, false)) {
736  continue;
737  }
738  ut64 addr = core->io->va ? s->vaddr : s->paddr;
739  ut64 size = core->io->va ? s->vsize : s->size;
740  from = RZ_MIN(addr, from);
741  to = RZ_MAX(to, addr + size);
742  }
743  if (from == UT64_MAX) {
744  int mask = 1;
745  void **it;
746  RzPVector *maps = rz_io_maps(core->io);
747  rz_pvector_foreach (maps, it) {
748  RzIOMap *map = *it;
749  ut64 from = rz_itv_begin(map->itv);
750  ut64 size = rz_itv_size(map->itv);
751  int rwx = map->perm;
752  if ((rwx & mask) != mask) {
753  continue;
754  }
755  append_bound(list, core->io, search_itv, from, size, rwx);
756  }
757  }
758  append_bound(list, core->io, search_itv, from, to - from, 1);
759  }
760  } else if (rz_str_startswith(mode, "bin.sections")) {
761  int len = strlen("bin.sections.");
762  int mask = (mode[len - 1] == '.') ? rz_str_rwx(mode + len) : 0;
763  bool only = (bool)(size_t)strstr(mode, ".only");
764  RzBinObject *obj = rz_bin_cur_object(core->bin);
765  if (obj) {
766  RzBinSection *s;
767  RzListIter *iter;
768  rz_list_foreach (obj->sections, iter, s) {
769  if (s->is_segment) {
770  continue;
771  }
772  if (maskMatches(s->perm, mask, only)) {
773  continue;
774  }
775  ut64 addr = core->io->va ? s->vaddr : s->paddr;
776  ut64 size = core->io->va ? s->vsize : s->size;
777  append_bound(list, core->io, search_itv, addr, size, s->perm);
778  }
779  }
780  } else if (!strcmp(mode, "bin.segment")) {
781  RzBinObject *obj = rz_bin_cur_object(core->bin);
782  if (obj) {
783  RzBinSection *s;
784  RzListIter *iter;
785  rz_list_foreach (obj->sections, iter, s) {
786  if (!s->is_segment) {
787  continue;
788  }
789  ut64 addr = core->io->va ? s->vaddr : s->paddr;
790  ut64 size = core->io->va ? s->vsize : s->size;
791  if (RZ_BETWEEN(addr, core->offset, addr + size)) {
792  append_bound(list, core->io, search_itv, addr, size, s->perm);
793  }
794  }
795  }
796  } else if (!strcmp(mode, "bin.section")) {
797  RzBinObject *obj = rz_bin_cur_object(core->bin);
798  if (obj) {
799  RzBinSection *s;
800  RzListIter *iter;
801  rz_list_foreach (obj->sections, iter, s) {
802  if (s->is_segment) {
803  continue;
804  }
805  ut64 addr = core->io->va ? s->vaddr : s->paddr;
806  ut64 size = core->io->va ? s->vsize : s->size;
807  if (RZ_BETWEEN(addr, core->offset, addr + size)) {
808  append_bound(list, core->io, search_itv, addr, size, s->perm);
809  }
810  }
811  }
812  } else if (!strcmp(mode, "analysis.fcn") || !strcmp(mode, "analysis.bb")) {
815  if (f) {
817 
818  /* Search only inside the basic block */
819  if (!strcmp(mode, "analysis.bb")) {
820  RzListIter *iter;
821  RzAnalysisBlock *bb;
822 
823  rz_list_foreach (f->bbs, iter, bb) {
824  ut64 at = core->offset;
825  if ((at >= bb->addr) && (at < (bb->addr + bb->size))) {
826  from = bb->addr;
827  size = bb->size;
828  break;
829  }
830  }
831  }
832  append_bound(list, core->io, search_itv, from, size, 5);
833  } else {
834  eprintf("WARNING: search.in = ( analysis.bb | analysis.fcn )"
835  "requires to seek into a valid function\n");
836  append_bound(list, core->io, search_itv, core->offset, 1, 5);
837  }
838  } else if (!strncmp(mode, "dbg.", 4)) {
839  if (core->bin->is_debugger) {
840  int mask = 0;
841  int add = 0;
842  bool heap = false;
843  bool stack = false;
844  bool all = false;
845  bool first = false;
846  RzListIter *iter;
847  RzDebugMap *map;
848 
849  rz_debug_map_sync(core->dbg);
850 
851  if (!strcmp(mode, "dbg.map")) {
852  int perm = 0;
853  ut64 from = core->offset;
854  ut64 to = core->offset;
855  rz_list_foreach (core->dbg->maps, iter, map) {
856  if (from >= map->addr && from < map->addr_end) {
857  from = map->addr;
858  to = map->addr_end;
859  perm = map->perm;
860  break;
861  }
862  }
863  if (perm) {
864  RzIOMap *nmap = RZ_NEW0(RzIOMap);
865  if (nmap) {
866  // nmap->fd = core->io->desc->fd;
867  nmap->itv.addr = from;
868  nmap->itv.size = to - from;
869  nmap->perm = perm;
870  nmap->delta = 0;
871  rz_list_append(list, nmap);
872  }
873  }
874  } else {
875  bool only = false;
876  mask = 0;
877  if (!strcmp(mode, "dbg.program")) {
878  first = true;
879  mask = RZ_PERM_X;
880  } else if (!strcmp(mode, "dbg.maps")) {
881  all = true;
882  } else if (rz_str_startswith(mode, "dbg.maps.")) {
883  mask = rz_str_rwx(mode + 9);
884  only = (bool)(size_t)strstr(mode, ".only");
885  } else if (!strcmp(mode, "dbg.heap")) {
886  heap = true;
887  } else if (!strcmp(mode, "dbg.stack")) {
888  stack = true;
889  }
890 
891  ut64 from = UT64_MAX;
892  ut64 to = 0;
893  rz_list_foreach (core->dbg->maps, iter, map) {
894  if (!all && maskMatches(map->perm, mask, only)) {
895  continue;
896  }
897  add = (stack && strstr(map->name, "stack")) ? 1 : 0;
898  if (!add && (heap && (map->perm & RZ_PERM_W)) && strstr(map->name, "heap")) {
899  add = 1;
900  }
901  if ((mask && (map->perm & mask)) || add || all) {
902  if (!list) {
904  }
905  RzIOMap *nmap = RZ_NEW0(RzIOMap);
906  if (!nmap) {
907  break;
908  }
909  nmap->itv.addr = map->addr;
910  nmap->itv.size = map->addr_end - map->addr;
911  if (nmap->itv.addr) {
912  from = RZ_MIN(from, nmap->itv.addr);
913  to = RZ_MAX(to - 1, rz_itv_end(nmap->itv) - 1) + 1;
914  }
915  nmap->perm = map->perm;
916  nmap->delta = 0;
917  rz_list_append(list, nmap);
918  if (first) {
919  break;
920  }
921  }
922  }
923  }
924  }
925  } else {
926  /* obey temporary seek if defined '/x 8080 @ addr:len' */
927  if (core->tmpseek) {
928  append_bound(list, core->io, search_itv, core->offset, core->blocksize, 5);
929  } else {
930  // TODO: repeat last search doesnt works for /a
931  ut64 from = rz_config_get_i(core->config, bound_from);
932  if (from == UT64_MAX) {
933  from = core->offset;
934  }
935  ut64 to = rz_config_get_i(core->config, bound_to);
936  if (to == UT64_MAX) {
937  if (core->io->va) {
938  /* TODO: section size? */
939  } else {
940  if (core->file) {
941  to = rz_io_fd_size(core->io, core->file->fd);
942  }
943  }
944  }
945  append_bound(list, core->io, search_itv, from, to - from, 5);
946  }
947  }
948  return list;
949 }
RZ_API ut64 rz_analysis_function_size_from_entry(RzAnalysisFunction *fcn)
Definition: function.c:333
RZ_API RzBinObject * rz_bin_cur_object(RzBin *bin)
Definition: bin.c:900
static RzList * maps(RzBinFile *bf)
Definition: bin_bf.c:116
static bool maskMatches(int perm, int mask, bool only)
Definition: cmd_search.c:567
static void append_bound(RzList *list, RzIO *io, RzInterval search_itv, ut64 from, ut64 size, int perms)
Definition: cmd_search.c:535
@ RZ_ANALYSIS_FCN_TYPE_SYM
Definition: rz_analysis.h:195
@ RZ_ANALYSIS_FCN_TYPE_FCN
Definition: rz_analysis.h:193
#define rz_return_val_if_fail(expr, val)
Definition: rz_assert.h:108
RZ_API ut64 rz_io_fd_size(RzIO *io, int fd)
Definition: io_fd.c:42
RZ_API ut64 rz_io_size(RzIO *io)
Definition: io.c:399
RZ_API RzIOMap * rz_io_map_get(RzIO *io, ut64 addr)
Definition: io_map.c:176
RZ_API RZ_BORROW RzPVector * rz_io_maps(RzIO *io)
Returns the pointer to vector containing maps list.
Definition: io_map.c:435
static ut64 rz_itv_begin(RzInterval itv)
Definition: rz_itv.h:34
static ut64 rz_itv_size(RzInterval itv)
Definition: rz_itv.h:38
RZ_API int rz_str_rwx(const char *str)
Definition: str.c:318
#define RZ_PERM_W
Definition: rz_types.h:94
#define RZ_PERM_X
Definition: rz_types.h:95
#define RZ_BETWEEN(x, y, z)
static void * rz_vector_index_ptr(RzVector *vec, size_t index)
Definition: rz_vector.h:88
static size_t rz_pvector_len(const RzPVector *vec)
Definition: rz_vector.h:231
static size_t rz_vector_len(const RzVector *vec)
Definition: rz_vector.h:82
static void * rz_pvector_at(const RzPVector *vec, size_t index)
Definition: rz_vector.h:236
#define rz_pvector_foreach(vec, it)
Definition: rz_vector.h:334
#define f(i)
Definition: sha256.c:46
Definition: heap-inl.h:40
RzList * sections
Definition: rz_bin.h:267
bool tmpseek
Definition: rz_core.h:308
RzList * maps
Definition: rz_debug.h:306
int perm
Definition: rz_io.h:147
ut64 delta
Definition: rz_io.h:150
RzInterval itv
Definition: rz_io.h:149
RzSkyline map_skyline
Definition: rz_io.h:74
int va
Definition: rz_io.h:63
RzInterval itv
Definition: rz_skyline.h:8
RzVector v
Definition: rz_skyline.h:13
Definition: z80asm.h:140
#define bool
Definition: sysdefs.h:146
static int add(char *argv[])
Definition: ziptool.c:84

References add(), addr, rz_analysis_bb_t::addr, rz_interval_t::addr, test_group_name::all, rz_core_t::analysis, append_bound(), rz_core_t::bin, rz_core_t::blocksize, bool, rz_core_t::config, search_parameters::core, rz_core_t::dbg, rz_io_map_t::delta, test_evm::end, eprintf, f, rz_core_file_t::fd, rz_core_t::file, free(), from, i, rz_core_t::io, rz_bin_t::is_debugger, rz_io_map_t::itv, rz_skyline_item_t::itv, len, list(), regress::m, map(), rz_io_t::map_skyline, maps(), rz_debug_t::maps, mask, maskMatches(), NULL, rz_core_t::offset, rz_io_map_t::perm, prefix, RZ_ANALYSIS_FCN_TYPE_FCN, RZ_ANALYSIS_FCN_TYPE_SYM, rz_analysis_function_size_from_entry(), rz_analysis_get_fcn_in(), RZ_BETWEEN, rz_bin_cur_object(), rz_config_get(), rz_config_get_b(), rz_config_get_i(), rz_debug_map_sync(), rz_io_fd_size(), rz_io_map_get(), rz_io_maps(), rz_io_size(), rz_itv_begin(), rz_itv_end(), rz_itv_size(), rz_list_append(), rz_list_newf(), RZ_MAX, RZ_MIN, RZ_NEW0, RZ_PERM_W, RZ_PERM_X, rz_pvector_at(), rz_pvector_foreach, rz_pvector_len(), rz_return_val_if_fail, rz_str_rwx(), rz_str_startswith(), rz_vector_index_ptr(), rz_vector_len(), s, rz_bin_object_t::sections, rz_analysis_bb_t::size, rz_interval_t::size, snprintf, rz_core_t::tmpseek, to, rz_skyline_item_t::user, ut64(), UT64_MAX, rz_skyline_t::v, and rz_io_t::va.

Referenced by __core_cmd_search_asm_infinite(), cmd_print_bars(), cmd_print_blocks(), do_debug_trace_calls(), rz_analyze_all_consecutive_functions_in_section_handler(), rz_cmd_help(), rz_cmd_search(), rz_core_analysis_calls(), rz_core_analysis_esil_default(), rz_core_analysis_refs(), rz_core_analysis_value_pointers(), and rz_core_search_preludes().

◆ rz_core_search_prelude()

RZ_API int rz_core_search_prelude ( RzCore core,
ut64  from,
ut64  to,
const ut8 buf,
int  blen,
const ut8 mask,
int  mlen 
)

Definition at line 292 of file cmd_search.c.

292  {
293  ut64 at;
294  ut8 *b = (ut8 *)malloc(core->blocksize);
295  if (!b) {
296  return 0;
297  }
298  // TODO: handle sections ?
299  if (from >= to) {
300  eprintf("aap: Invalid search range 0x%08" PFMT64x " - 0x%08" PFMT64x "\n", from, to);
301  free(b);
302  return 0;
303  }
305  rz_search_kw_add(core->search, rz_search_keyword_new(buf, blen, mask, mlen, NULL));
306  rz_search_begin(core->search);
308  preludecnt = 0;
309  for (at = from; at < to; at += core->blocksize) {
310  if (rz_cons_is_breaked()) {
311  break;
312  }
313  if (!rz_io_is_valid_offset(core->io, at, 0)) {
314  break;
315  }
316  (void)rz_io_read_at(core->io, at, b, core->blocksize);
317  if (rz_search_update(core->search, at, b, core->blocksize) == -1) {
318  eprintf("search: update read error at 0x%08" PFMT64x "\n", at);
319  break;
320  }
321  }
322  // rz_search_reset might also benifet from having an if(s->data) RZ_FREE(s->data), but im not sure.
323  // add a commit that puts it in there to this PR if it wouldn't break anything. (don't have to worry about this happening again, since all searches start by resetting core->search)
324  // For now we will just use rz_search_kw_reset
325  rz_search_kw_reset(core->search);
326  free(b);
327  return preludecnt;
328 }
static int __prelude_cb_hit(RzSearchKeyword *kw, void *user, ut64 addr)
Definition: cmd_search.c:283

References __prelude_cb_hit(), b, rz_core_t::blocksize, eprintf, free(), from, rz_core_t::io, malloc(), mask, NULL, PFMT64x, preludecnt, rz_cons_is_breaked(), rz_io_is_valid_offset(), rz_io_read_at(), rz_search_begin(), RZ_SEARCH_KEYWORD, rz_search_keyword_new(), rz_search_kw_add(), rz_search_kw_reset(), rz_search_reset(), rz_search_set_callback(), rz_search_update(), rz_core_t::search, to, and ut64().

Referenced by rz_core_search_preludes().

◆ rz_core_search_preludes()

RZ_API int rz_core_search_preludes ( RzCore core,
bool  log 
)

Definition at line 330 of file cmd_search.c.

330  {
331  int ret = -1;
332  ut64 from = UT64_MAX;
333  ut64 to = UT64_MAX;
334  int keyword_length = 0;
335  ut8 *keyword = NULL;
336  const char *prelude = rz_config_get(core->config, "analysis.prelude");
337  const char *where = rz_config_get(core->config, "analysis.in");
338 
339  RzList *list = rz_core_get_boundaries_prot(core, RZ_PERM_X, where, "search");
340  RzList *arch_preludes = NULL;
341  RzListIter *iter = NULL, *iter2 = NULL;
342  RzIOMap *p = NULL;
343  RzSearchKeyword *kw = NULL;
344 
345  if (!list) {
346  return -1;
347  }
348 
349  if (RZ_STR_ISNOTEMPTY(prelude)) {
350  keyword = malloc(strlen(prelude) + 1);
351  if (!keyword) {
352  RZ_LOG_ERROR("aap: cannot allocate 'analysis.prelude' buffer\n");
354  return -1;
355  }
356  keyword_length = rz_hex_str2bin(prelude, keyword);
357  } else {
358  arch_preludes = rz_analysis_preludes(core->analysis);
359  if (!arch_preludes) {
361  return -1;
362  }
363  }
364 
365  rz_list_foreach (list, iter, p) {
366  if (!(p->perm & RZ_PERM_X)) {
367  continue;
368  }
369  from = p->itv.addr;
370  to = rz_itv_end(p->itv);
371  if (keyword && keyword_length > 0) {
372  ret = rz_core_search_prelude(core, from, to, keyword, keyword_length, NULL, 0);
373  } else {
374  rz_list_foreach (arch_preludes, iter2, kw) {
375  ret = rz_core_search_prelude(core, from, to,
376  kw->bin_keyword, kw->keyword_length,
377  kw->bin_binmask, kw->binmask_length);
378  }
379  }
380  }
381  free(keyword);
383  rz_list_free(arch_preludes);
384  return ret;
385 }
RZ_API RzList * rz_analysis_preludes(RzAnalysis *analysis)
Definition: analysis.c:669
RZ_API int rz_core_search_prelude(RzCore *core, ut64 from, ut64 to, const ut8 *buf, int blen, const ut8 *mask, int mlen)
Definition: cmd_search.c:292
#define RZ_STR_ISNOTEMPTY(x)
Definition: rz_str.h:68

References rz_core_t::analysis, rz_search_keyword_t::bin_binmask, rz_search_keyword_t::bin_keyword, rz_search_keyword_t::binmask_length, rz_core_t::config, free(), from, rz_search_keyword_t::keyword_length, list(), malloc(), NULL, p, rz_analysis_preludes(), rz_config_get(), rz_core_get_boundaries_prot(), rz_core_search_prelude(), rz_hex_str2bin(), rz_itv_end(), rz_list_free(), RZ_LOG_ERROR, RZ_PERM_X, RZ_STR_ISNOTEMPTY, to, ut64(), and UT64_MAX.

Referenced by rz_analyze_all_preludes_handler(), and rz_core_analysis_everything().

◆ rz_core_search_rop()

static int rz_core_search_rop ( RzCore core,
RzInterval  search_itv,
int  opt,
const char *  grep,
int  regexp,
struct search_parameters param 
)
static

Definition at line 1283 of file cmd_search.c.

1283  {
1284  const ut8 crop = rz_config_get_i(core->config, "rop.conditional"); // decide if cjmp, cret, and ccall should be used too for the gadget-search
1285  const ut8 subchain = rz_config_get_i(core->config, "rop.subchains");
1286  const ut8 max_instr = rz_config_get_i(core->config, "rop.len");
1287  const char *arch = rz_config_get(core->config, "asm.arch");
1288  int max_count = rz_config_get_i(core->config, "search.maxhits");
1289  int i = 0, end = 0, mode = 0, increment = 1, ret, result = true;
1290  RzList /*<endlist_pair>*/ *end_list = rz_list_newf(free);
1291  RzList /*<RzRegex>*/ *rx_list = NULL;
1292  int align = core->search->align;
1293  RzListIter *itermap = NULL;
1294  char *tok, *gregexp = NULL;
1295  char *grep_arg = NULL;
1296  char *rx = NULL;
1297  int delta = 0;
1298  ut8 *buf;
1299  RzIOMap *map;
1300  RzAsmOp asmop;
1301 
1302  Sdb *gadgetSdb = NULL;
1303  if (rz_config_get_i(core->config, "rop.sdb")) {
1304  if (!(gadgetSdb = sdb_ns(core->sdb, "gadget_sdb", false))) {
1305  gadgetSdb = sdb_ns(core->sdb, "gadget_sdb", true);
1306  }
1307  }
1308  if (max_count == 0) {
1309  max_count = -1;
1310  }
1311  if (max_instr <= 1) {
1312  rz_list_free(end_list);
1313  eprintf("ROP length (rop.len) must be greater than 1.\n");
1314  if (max_instr == 1) {
1315  eprintf("For rop.len = 1, use /c to search for single "
1316  "instructions. See /c? for help.\n");
1317  }
1318  return false;
1319  }
1320 
1321  if (!strcmp(arch, "mips")) { // MIPS has no jump-in-the-middle
1322  increment = 4;
1323  } else if (!strcmp(arch, "arm")) { // ARM has no jump-in-the-middle
1324  increment = rz_config_get_i(core->config, "asm.bits") == 16 ? 2 : 4;
1325  } else if (!strcmp(arch, "avr")) { // AVR is halfword aligned.
1326  increment = 2;
1327  }
1328 
1329  // Options, like JSON, linear, ...
1330  grep_arg = strchr(grep, ' ');
1331  if (*grep) {
1332  if (grep_arg) {
1333  mode = *(grep_arg - 1);
1334  } else {
1335  mode = *grep;
1336  ++grep;
1337  }
1338  }
1339  if (grep_arg) {
1340  grep_arg = strdup(grep_arg);
1341  grep_arg = rz_str_replace(grep_arg, ",,", ";", true);
1342  grep = grep_arg;
1343  }
1344 
1345  if (*grep == ' ') { // grep mode
1346  for (++grep; *grep == ' '; grep++) {
1347  ;
1348  }
1349  } else {
1350  grep = NULL;
1351  }
1352 
1353  // Deal with the grep guy.
1354  if (grep && regexp) {
1355  if (!rx_list) {
1356  rx_list = rz_list_newf(free);
1357  }
1358  gregexp = strdup(grep);
1359  tok = strtok(gregexp, ";");
1360  while (tok) {
1361  rx = strdup(tok);
1362  rz_list_append(rx_list, rx);
1363  tok = strtok(NULL, ";");
1364  }
1365  }
1366  if (param->outmode == RZ_MODE_JSON) {
1367  pj_a(param->pj);
1368  }
1370 
1371  rz_list_foreach (param->boundaries, itermap, map) {
1372  HtUUOptions opt = { 0 };
1373  HtUU *badstart = ht_uu_new_opt(&opt);
1374  if (!rz_itv_overlap(search_itv, map->itv)) {
1375  continue;
1376  }
1377  RzInterval itv = rz_itv_intersect(search_itv, map->itv);
1378  ut64 from = itv.addr, to = rz_itv_end(itv);
1379  if (rz_cons_is_breaked()) {
1380  break;
1381  }
1382  delta = to - from;
1383  buf = calloc(1, delta);
1384  if (!buf) {
1385  result = false;
1386  goto bad;
1387  }
1388  (void)rz_io_read_at(core->io, from, buf, delta);
1389 
1390  // Find the end gadgets.
1391  for (i = 0; i + 32 < delta; i += increment) {
1392  RzAnalysisOp end_gadget = RZ_EMPTY;
1393  // Disassemble one.
1394  if (rz_analysis_op(core->analysis, &end_gadget, from + i, buf + i,
1395  delta - i, RZ_ANALYSIS_OP_MASK_BASIC) < 1) {
1396  rz_analysis_op_fini(&end_gadget);
1397  continue;
1398  }
1399  if (is_end_gadget(&end_gadget, crop)) {
1400 #if 0
1401  if (search->maxhits && rz_list_length (end_list) >= search->maxhits) {
1402  // limit number of high level rop gadget results
1403  rz_analysis_op_fini (&end_gadget);
1404  break;
1405  }
1406 #endif
1407  struct endlist_pair *epair = RZ_NEW0(struct endlist_pair);
1408  if (epair) {
1409  // If this arch has branch delay slots, add the next instr as well
1410  if (end_gadget.delay) {
1411  epair->instr_offset = i + increment;
1412  epair->delay_size = end_gadget.delay;
1413  } else {
1414  epair->instr_offset = (intptr_t)i;
1415  epair->delay_size = end_gadget.delay;
1416  }
1417  rz_list_append(end_list, (void *)(intptr_t)epair);
1418  }
1419  }
1420  rz_analysis_op_fini(&end_gadget);
1421  if (rz_cons_is_breaked()) {
1422  break;
1423  }
1424  // Right now we have a list of all of the end/stop gadgets.
1425  // We can just construct gadgets from a little bit before them.
1426  }
1427  rz_list_reverse(end_list);
1428  // If we have no end gadgets, just skip all of this search nonsense.
1429  if (!rz_list_empty(end_list)) {
1430  int prev, next, ropdepth;
1431  const int max_inst_size_x86 = 15;
1432  // Get the depth of rop search, should just be max_instr
1433  // instructions, x86 and friends are weird length instructions, so
1434  // we'll just assume 15 byte instructions.
1435  ropdepth = increment == 1 ? max_instr * max_inst_size_x86 /* wow, x86 is long */ : max_instr * increment;
1436  if (rz_cons_is_breaked()) {
1437  break;
1438  }
1439  struct endlist_pair *end_gadget = (struct endlist_pair *)rz_list_pop(end_list);
1440  next = end_gadget->instr_offset;
1441  prev = 0;
1442  // Start at just before the first end gadget.
1443  for (i = next - ropdepth; i < (delta - max_inst_size_x86) && max_count; i += increment) {
1444  if (increment == 1) {
1445  // give in-boundary instructions a shot
1446  if (i < prev - max_inst_size_x86) {
1447  i = prev - max_inst_size_x86;
1448  }
1449  } else {
1450  if (i < prev) {
1451  i = prev;
1452  }
1453  }
1454  if (i < 0) {
1455  i = 0;
1456  }
1457  if (rz_cons_is_breaked()) {
1458  break;
1459  }
1460  if (i >= next) {
1461  // We've exhausted the first end-gadget section,
1462  // move to the next one.
1463  free(end_gadget);
1464  if (rz_list_get_n(end_list, 0)) {
1465  prev = i;
1466  end_gadget = (struct endlist_pair *)rz_list_pop(end_list);
1467  next = end_gadget->instr_offset;
1468  i = next - ropdepth;
1469  if (i < 0) {
1470  i = 0;
1471  }
1472  } else {
1473  break;
1474  }
1475  }
1476  if (i >= end) { // read by chunk of 4k
1477  rz_io_read_at(core->io, from + i, buf + i,
1478  RZ_MIN((delta - i), 4096));
1479  end = i + 2048;
1480  }
1481  ret = rz_asm_disassemble(core->rasm, &asmop, buf + i, delta - i);
1482  if (ret) {
1483  rz_asm_set_pc(core->rasm, from + i);
1484  RzList *hitlist = construct_rop_gadget(core,
1485  from + i, buf, delta, i, grep, regexp,
1486  rx_list, end_gadget, badstart);
1487  if (!hitlist) {
1488  continue;
1489  }
1490  if (align && (0 != ((from + i) % align))) {
1491  continue;
1492  }
1493  if (gadgetSdb) {
1494  RzListIter *iter;
1495 
1496  RzCoreAsmHit *hit = (RzCoreAsmHit *)hitlist->head->data;
1497  char *headAddr = rz_str_newf("%" PFMT64x, hit->addr);
1498  if (!headAddr) {
1499  result = false;
1500  goto bad;
1501  }
1502 
1503  rz_list_foreach (hitlist, iter, hit) {
1504  char *addr = rz_str_newf("%" PFMT64x "(%" PFMT32d ")", hit->addr, hit->len);
1505  if (!addr) {
1506  free(headAddr);
1507  result = false;
1508  goto bad;
1509  }
1510  sdb_concat(gadgetSdb, headAddr, addr, 0);
1511  free(addr);
1512  }
1513  free(headAddr);
1514  }
1515 
1516  if (param->outmode == RZ_MODE_JSON) {
1517  mode = 'j';
1518  }
1519  if ((mode == 'q') && subchain) {
1520  do {
1521  print_rop(core, hitlist, NULL, mode);
1522  hitlist->head = hitlist->head->n;
1523  } while (hitlist->head->n);
1524  } else {
1525  print_rop(core, hitlist, param->pj, mode);
1526  }
1527  rz_list_free(hitlist);
1528  if (max_count > 0) {
1529  max_count--;
1530  if (max_count < 1) {
1531  break;
1532  }
1533  }
1534  }
1535  if (increment != 1) {
1536  i = next;
1537  }
1538  }
1539  }
1540  free(buf);
1541  }
1542  if (rz_cons_is_breaked()) {
1543  eprintf("\n");
1544  }
1546 
1547  if (param->outmode == RZ_MODE_JSON) {
1548  pj_end(param->pj);
1549  }
1550 bad:
1551  rz_list_free(rx_list);
1552  rz_list_free(end_list);
1553  free(grep_arg);
1554  free(gregexp);
1555  return result;
1556 }
static RzList * construct_rop_gadget(RzCore *core, ut64 addr, ut8 *buf, int buflen, int idx, const char *grep, int regex, RzList *rx_list, struct endlist_pair *end_gadget, HtUU *badstart)
Definition: cmd_search.c:990
cs_arch arch
Definition: cstool.c:13
RZ_API void rz_list_reverse(RZ_NONNULL RzList *list)
Reverses the list.
Definition: list.c:477
RZ_API RZ_OWN void * rz_list_pop(RZ_NONNULL RzList *list)
Removes and returns the last element of the list.
Definition: list.c:376
static size_t max_count
Definition: malloc.c:67
RZ_API char * rz_str_replace(char *str, const char *key, const char *val, int g)
Definition: str.c:1110
RZ_API int sdb_concat(Sdb *s, const char *key, const char *value, ut32 cas)
Definition: sdb.c:329
_W64 signed int intptr_t
struct rz_list_iter_t * n
Definition: rz_list.h:15
static st64 delta
Definition: vmenus.c:2425

References addr, rz_interval_t::addr, rz_search_t::align, rz_core_t::analysis, arch, search_parameters::boundaries, calloc(), rz_core_t::config, construct_rop_gadget(), search_parameters::core, rz_list_iter_t::data, rz_analysis_op_t::delay, endlist_pair::delay_size, delta, test_evm::end, eprintf, free(), from, rz_list_t::head, hit(), i, endlist_pair::instr_offset, rz_core_t::io, is_end_gadget(), map(), max_count, rz_list_iter_t::n, NULL, search_parameters::outmode, PFMT32d, PFMT64x, search_parameters::pj, pj_a(), pj_end(), print_rop(), rz_core_t::rasm, rz_analysis_op(), rz_analysis_op_fini(), RZ_ANALYSIS_OP_MASK_BASIC, rz_asm_disassemble(), rz_asm_set_pc(), rz_config_get(), rz_config_get_i(), rz_cons_break_pop(), rz_cons_break_push(), rz_cons_is_breaked(), RZ_EMPTY, rz_io_read_at(), rz_itv_end(), rz_itv_intersect(), rz_itv_overlap(), rz_list_append(), rz_list_free(), rz_list_get_n(), rz_list_length(), rz_list_newf(), rz_list_pop(), rz_list_reverse(), RZ_MIN, RZ_MODE_JSON, RZ_NEW0, rz_str_newf(), rz_str_replace(), rz_core_t::sdb, sdb_concat(), sdb_ns(), rz_core_t::search, search(), strdup(), to, and ut64().

Referenced by rz_cmd_search().

◆ search_collisions()

static void search_collisions ( RzCore core,
const char *  hashName,
const ut8 hashValue,
int  hashLength,
int  mode 
)
static

Definition at line 2740 of file cmd_search.c.

2740  {
2741  ut8 RZ_ALIGNED(8) cmphash[128];
2743  ut8 *digest = NULL;
2744 
2745  int i = 0;
2746  int bufsz = core->blocksize;
2747  ut8 *buf = calloc(1, bufsz);
2748  if (!buf) {
2749  return;
2750  }
2751  memcpy(buf, core->block, bufsz);
2752  if (hashLength > sizeof(cmphash)) {
2753  eprintf("Hashlength mismatch %d %d\n", hashLength, (int)sizeof(cmphash));
2754  free(buf);
2755  return;
2756  }
2757  memcpy(cmphash, hashValue, hashLength);
2758 
2759  if (hashLength != 4) {
2760  eprintf("Invalid hash size %d (expected 4)\n", hashLength);
2761  free(buf);
2762  return;
2763  }
2764 
2766  ut64 prev = rz_time_now_mono();
2767  ut64 inc = 0;
2768  int amount = 0;
2769  int mount = 0;
2770  while (!rz_cons_is_breaked()) {
2771  ut64 now = rz_time_now_mono();
2772  if (now < (prev + 1000000)) {
2773  amount++;
2774  } else {
2775  mount += amount;
2776  mount /= 2;
2777  amount = 0;
2778  prev = now;
2779  }
2780  switch (mode) {
2781  case 'p': // digits+alpha
2782  incPrintBuffer(buf, bufsz);
2783  break;
2784  case 'a': // lowercase alpha
2785  incLowerBuffer(buf, bufsz);
2786  break;
2787  case 'A': // uppercase alpha
2788  incUpperBuffer(buf, bufsz);
2789  break;
2790  case 'l': // letters
2791  incAlphaBuffer(buf, bufsz);
2792  break;
2793  case 'd': // digits
2794  incDigitBuffer(buf, bufsz);
2795  break;
2796  default: // binary
2797  incBuffer(buf, bufsz);
2798  break;
2799  }
2800 
2801  eprintf("0x%08" PFMT64x " input:", inc);
2802  for (i = 0; i < bufsz; i++) {
2803  eprintf("%02x", buf[i]);
2804  }
2805  if (mode) {
2806  eprintf(" \"%s\"", buf);
2807  }
2808 
2809  crc32->small_block(buf, bufsz, &digest, NULL);
2810 
2811  eprintf(" digest:");
2812  for (i = 0; i < hashLength; i++) {
2813  eprintf("%02x", digest[i]);
2814  }
2815  eprintf(" (%d h/s) \r", mount);
2816  if (!memcmp(hashValue, digest, hashLength)) {
2817  eprintf("\nCOLLISION FOUND!\n");
2818  rz_core_print_hexdump(core, core->offset, buf, bufsz, 0, 16, 0);
2819  rz_cons_flush();
2820  }
2821  RZ_FREE(digest);
2822  inc++;
2823  }
2825  free(buf);
2826 }
static void incDigitBuffer(ut8 *buf, int bufsz)
Definition: cmd_search.c:2725
static void incAlphaBuffer(ut8 *buf, int bufsz)
Definition: cmd_search.c:2710
static void incLowerBuffer(ut8 *buf, int bufsz)
Definition: cmd_search.c:2682
static void incUpperBuffer(ut8 *buf, int bufsz)
Definition: cmd_search.c:2696
static void incBuffer(ut8 *buf, int bufsz)
Definition: cmd_search.c:2655
static void incPrintBuffer(ut8 *buf, int bufsz)
Definition: cmd_search.c:2668
RZ_API void rz_cons_flush(void)
Definition: cons.c:959
RZ_IPI void rz_core_print_hexdump(RZ_NONNULL RzCore *core, ut64 addr, RZ_NONNULL const ut8 *buf, int len, int base, int step, size_t zoomsz)
Definition: cprint.c:161
RZ_API RZ_BORROW const RzHashPlugin * rz_hash_plugin_by_name(RZ_NONNULL RzHash *rh, RZ_NONNULL const char *name)
Definition: hash.c:120
#define const
Definition: ansidecl.h:240
RZ_API ut64 rz_time_now_mono(void)
Returns the current time in microseconds, using the monotonic clock.
Definition: time.c:102
typedef RZ_ALIGNED(1) ut16 uut16
ut8 * block
Definition: rz_core.h:305
static int blocksize
Definition: visual.c:15
unsigned long ZEXPORT crc32(unsigned long crc, const unsigned char FAR *buf, uInt len)
Definition: crc32.c:1063

References rz_core_t::block, rz_core_t::blocksize, calloc(), search_parameters::core, crc32(), eprintf, free(), rz_core_t::hash, i, incAlphaBuffer(), incBuffer(), incDigitBuffer(), incLowerBuffer(), incPrintBuffer(), incUpperBuffer(), memcpy(), NULL, rz_core_t::offset, PFMT64x, RZ_ALIGNED(), rz_cons_break_pop(), rz_cons_break_push(), rz_cons_flush(), rz_cons_is_breaked(), rz_core_print_hexdump(), RZ_FREE, rz_hash_plugin_by_name(), rz_time_now_mono(), and ut64().

Referenced by rz_cmd_search().

◆ search_hash()

static int search_hash ( RzCore core,
const char *  hashname,
const char *  hashstr,
ut32  minlen,
ut32  maxlen,
struct search_parameters param 
)
static

Definition at line 176 of file cmd_search.c.

176  {
177  RzIOMap *map;
178  ut8 *buf;
179  int i, j;
180  RzListIter *iter;
181 
182  if (!minlen || minlen == UT32_MAX) {
183  minlen = core->blocksize;
184  }
185  if (!maxlen || maxlen == UT32_MAX) {
186  maxlen = minlen;
187  }
188 
190  for (j = minlen; j <= maxlen; j++) {
191  ut32 len = j;
192  eprintf("Searching %s for %d byte length.\n", hashname, j);
193  rz_list_foreach (param->boundaries, iter, map) {
194  if (rz_cons_is_breaked()) {
195  break;
196  }
197  ut64 from = map->itv.addr, to = rz_itv_end(map->itv);
198  st64 bufsz;
199  bufsz = to - from;
200  if (len > bufsz) {
201  eprintf("Hash length is bigger than range 0x%" PFMT64x "\n", from);
202  continue;
203  }
204  buf = malloc(bufsz);
205  if (!buf) {
206  eprintf("Cannot allocate %" PFMT64d " bytes\n", bufsz);
207  goto fail;
208  }
209  eprintf("Search in range 0x%08" PFMT64x " and 0x%08" PFMT64x "\n", from, to);
210  int blocks = (int)(to - from - len);
211  eprintf("Carving %d blocks...\n", blocks);
212  (void)rz_io_read_at(core->io, from, buf, bufsz);
213  for (i = 0; (from + i + len) < to; i++) {
214  if (rz_cons_is_breaked()) {
215  break;
216  }
217  char *s = rz_hash_cfg_calculate_small_block_string(core->hash, hashname, buf + i, len, NULL, false);
218  if (!s) {
219  eprintf("Hash fail\n");
220  break;
221  }
222  if (!(i % 5)) {
223  eprintf("%d\r", i);
224  }
225  // eprintf ("0x%08"PFMT64x" %s\n", from+i, s);
226  if (!strcmp(s, hashstr)) {
227  eprintf("Found at 0x%" PFMT64x "\n", from + i);
228  rz_cons_printf("f hash.%s.%s @ 0x%" PFMT64x "\n",
229  hashname, hashstr, from + i);
230  free(s);
231  free(buf);
232  return 1;
233  }
234  free(s);
235  }
236  free(buf);
237  }
238  }
240  eprintf("No hashes found\n");
241  return 0;
242 fail:
243  return -1;
244 }
RZ_API RZ_OWN char * rz_hash_cfg_calculate_small_block_string(RZ_NONNULL RzHash *rh, RZ_NONNULL const char *name, RZ_NONNULL const ut8 *buffer, ut64 bsize, RZ_NULLABLE ut32 *size, bool invert)
Definition: hash.c:545
ut64 maxlen
Definition: core.c:76
uint64_t blocks
Definition: list.c:104
#define fail(test)
Definition: tests.h:29

References blocks, rz_core_t::blocksize, search_parameters::boundaries, eprintf, fail, free(), from, rz_core_t::hash, i, int, rz_core_t::io, len, malloc(), map(), maxlen, NULL, PFMT64d, PFMT64x, rz_cons_break_pop(), rz_cons_break_push(), rz_cons_is_breaked(), rz_cons_printf(), rz_hash_cfg_calculate_small_block_string(), rz_io_read_at(), rz_itv_end(), s, st64, to, UT32_MAX, and ut64().

Referenced by rz_cmd_search().

◆ search_similar_pattern()

static void search_similar_pattern ( RzCore core,
int  count,
struct search_parameters param 
)
static

Definition at line 2555 of file cmd_search.c.

2555  {
2556  RzIOMap *p;
2557  RzListIter *iter;
2558 
2560  rz_list_foreach (param->boundaries, iter, p) {
2561  search_similar_pattern_in(core, count, p->itv.addr, rz_itv_end(p->itv));
2562  }
2564 }
static void search_similar_pattern_in(RzCore *core, int count, ut64 from, ut64 to)
Definition: cmd_search.c:2529

References search_parameters::boundaries, count, NULL, p, rz_cons_break_pop(), rz_cons_break_push(), rz_itv_end(), and search_similar_pattern_in().

Referenced by rz_cmd_search().

◆ search_similar_pattern_in()

static void search_similar_pattern_in ( RzCore core,
int  count,
ut64  from,
ut64  to 
)
static

Definition at line 2529 of file cmd_search.c.

2529  {
2530  ut64 addr = from;
2531  ut8 *block = calloc(core->blocksize, 1);
2532  if (!block) {
2533  return;
2534  }
2535  while (addr < to) {
2536  (void)rz_io_read_at(core->io, addr, block, core->blocksize);
2537  if (rz_cons_is_breaked()) {
2538  break;
2539  }
2540  int diff = memcmpdiff(core->block, block, core->blocksize);
2541  int equal = core->blocksize - diff;
2542  if (equal >= count) {
2543  int pc = (equal * 100) / core->blocksize;
2544  rz_cons_printf("0x%08" PFMT64x " %4d/%d %3d%% ", addr, equal, core->blocksize, pc);
2545  ut8 ptr[2] = {
2546  (ut8)(pc * 2.5), 0
2547  };
2548  rz_print_fill(core->print, ptr, 1, UT64_MAX, core->blocksize);
2549  }
2550  addr += core->blocksize;
2551  }
2552  free(block);
2553 }
static int memcmpdiff(const ut8 *a, const ut8 *b, int len)
Definition: cmd_search.c:2517
RZ_API void rz_print_fill(RzPrint *p, const ut8 *arr, int size, ut64 addr, int step)
Definition: print.c:1346

References addr, rz_core_t::block, rz_core_t::blocksize, calloc(), count, free(), from, rz_core_t::io, memcmpdiff(), pc, PFMT64x, rz_core_t::print, rz_cons_is_breaked(), rz_cons_printf(), rz_io_read_at(), rz_print_fill(), to, ut64(), UT64_MAX, and ut8.

Referenced by search_similar_pattern().

◆ v_writebuf()

static ut8* v_writebuf ( RzCore core,
RzList nums,
int  len,
char  ch,
int  bsize 
)
static

Definition at line 2608 of file cmd_search.c.

2608  {
2609  ut8 *ptr;
2610  ut64 n64;
2611  ut32 n32;
2612  ut16 n16;
2613  ut8 n8;
2614  int i = 0;
2615  ut8 *buf = calloc(1, bsize);
2616  if (!buf) {
2617  eprintf("Cannot allocate %d byte(s)\n", bsize);
2618  free(buf);
2619  return NULL;
2620  }
2621  ptr = buf;
2622  for (i = 0; i < len; i++) {
2623  switch (ch) {
2624  case '1':
2625  n8 = rz_num_math(core->num, rz_list_pop_head(nums));
2626  rz_write_le8(ptr, n8);
2627  ptr = (ut8 *)ptr + sizeof(ut8);
2628  break;
2629  case '2':
2630  n16 = rz_num_math(core->num, rz_list_pop_head(nums));
2631  rz_write_le16(ptr, n16);
2632  ptr = (ut8 *)ptr + sizeof(ut16);
2633  break;
2634  case '4':
2635  n32 = (ut32)rz_num_math(core->num, rz_list_pop_head(nums));
2636  rz_write_le32(ptr, n32);
2637  ptr = (ut8 *)ptr + sizeof(ut32);
2638  break;
2639  default:
2640  case '8':
2641  n64 = rz_num_math(core->num, rz_list_pop_head(nums));
2642  rz_write_le64(ptr, n64);
2643  ptr = (ut8 *)ptr + sizeof(ut64);
2644  break;
2645  }
2646  if (ptr > ptr + bsize) {
2647  free(buf);
2648  return NULL;
2649  }
2650  }
2651  return buf;
2652 }
RZ_API RZ_OWN void * rz_list_pop_head(RZ_NONNULL RzList *list)
Removes and returns the first element of the list.
Definition: list.c:401
static void rz_write_le32(void *dest, ut32 val)
Definition: rz_endian.h:256
static void rz_write_le16(void *dest, ut16 val)
Definition: rz_endian.h:222
static void rz_write_le64(void *dest, ut64 val)
Definition: rz_endian.h:277
static void rz_write_le8(void *dest, ut8 val)
Definition: rz_endian.h:198

References calloc(), search_parameters::core, eprintf, free(), i, len, NULL, rz_core_t::num, rz_list_pop_head(), rz_num_math(), rz_write_le16(), rz_write_le32(), rz_write_le64(), rz_write_le8(), and ut64().

Referenced by rz_cmd_search().

Variable Documentation

◆ c

int c = 0
static

Definition at line 520 of file cmd_search.c.

Referenced by print_search_progress(), and rz_cmd_search().

◆ help_msg_search_esil

const char* help_msg_search_esil[]
static
Initial value:
= {
"/E", " [esil-expr]", "search offsets matching a specific esil expression",
"/Ej", " [esil-expr]", "same as above but using the given magic file",
"/E?", " ", "show this help",
"\nExamples:", "", "",
"", "/E $$,0x100001060,-,!", "hit when address is 0x100001060",
}

Definition at line 19 of file cmd_search.c.

Referenced by do_esil_search().

◆ help_msg_slash

const char* help_msg_slash[]
static

Definition at line 35 of file cmd_search.c.

Referenced by rz_cmd_search().

◆ help_msg_slash_a

const char* help_msg_slash_a[]
static
Initial value:
= {
"Usage:", "/a[?] [arg]", "Search for assembly instructions matching given properties",
"/a", " push rbp", "Assemble given instruction and search the bytes",
"/a1", " [number]", "Find valid assembly generated by changing only the nth byte",
"/aI", "", "Search for infinite loop instructions (jmp $$)",
"/aa", " mov eax", "Linearly find aproximated assembly (case insensitive strstr)",
"/ac", " mov eax", "Same as /aa, but case-sensitive",
"/ad", "[/*j] push;mov", "Match ins1 followed by ins2 in linear disasm",
"/ad/", " ins1;ins2", "Search for regex instruction 'ins1' followed by regex 'ins2'",
"/ad/a", " instr", "Search for every byte instruction that matches regexp 'instr'",
"/ae", " esil", "Search for esil expressions matching substring",
"/af", "[l] family", "Search for instruction of specific family (afl=list",
"/ai", "[j] 0x300 [0x500]", "Find all the instructions using that immediate (in range)",
"/al", "", "Same as aoml, list all opcodes",
"/am", " opcode", "Search for specific instructions of specific mnemonic",
"/ao", " instr", "Search for instruction 'instr' (in all offsets)",
"/as", "[l] ([type])", "Search for syscalls (See /at swi and /af priv)",
"/at", "[l] ([type])", "Search for instructions of given type",
}

Definition at line 86 of file cmd_search.c.

Referenced by do_analysis_search(), and rz_cmd_search().

◆ help_msg_slash_c

const char* help_msg_slash_c[]
static
Initial value:
= {
"Usage: /c", "", "Search for crypto materials",
"/ca", "", "Search for AES keys expanded in memory",
"/cc", "[algo] [digest]", "Find collisions (bruteforce block length values until given checksum is found)",
"/cd", "", "Search for ASN1/DER certificates",
"/cr", "", "Search for ASN1/DER private keys (RSA and ECC)",
}

Definition at line 107 of file cmd_search.c.

Referenced by rz_cmd_search().

◆ help_msg_slash_m

const char* help_msg_slash_m[]
static
Initial value:
= {
"/m", "", "search for known magic patterns",
"/m", " [file]", "same as above but using the given magic file",
"/mb", "", "search recognized RzBin headers",
}

Definition at line 28 of file cmd_search.c.

Referenced by rz_cmd_search().

◆ help_msg_slash_r

const char* help_msg_slash_r[]
static
Initial value:
= {
"Usage:", "/r[acerwx] [address]", " search references to this specific address",
"/r", " [addr]", "search references to this specific address",
"/ra", "", "search all references",
"/rc", "", "search for call references",
"/rr", "", "Find read references",
"/rw", "", "Find write references",
"/rx", "", "Find exec references",
}

Definition at line 116 of file cmd_search.c.

Referenced by rz_cmd_search().

◆ help_msg_slash_R

const char* help_msg_slash_R[]
static
Initial value:
= {
"Usage: /R", "", "Search for ROP gadgets",
"/R", " [filter-by-string]", "Show gadgets",
"/R/", " [filter-by-regexp]", "Show gadgets [regular expression]",
"/R/j", " [filter-by-regexp]", "JSON output [regular expression]",
"/R/q", " [filter-by-regexp]", "Show gadgets in a quiet manner [regular expression]",
"/Rj", " [filter-by-string]", "JSON output",
"/Rk", " [select-by-class]", "Query stored ROP gadgets",
"/Rq", " [filter-by-string]", "Show gadgets in a quiet manner",
}

Definition at line 127 of file cmd_search.c.

Referenced by rz_cmd_search().

◆ help_msg_slash_Rk

const char* help_msg_slash_Rk[]
static
Initial value:
= {
"Usage: /Rk", "", "Query stored ROP gadgets",
"/Rk", " [nop|mov|const|arithm|arithm_ct]", "Show gadgets",
"/Rkj", "", "JSON output",
"/Rkq", "", "List Gadgets offsets",
}

Definition at line 139 of file cmd_search.c.

Referenced by rz_cmd_search().

◆ help_msg_slash_x

const char* help_msg_slash_x[]
static
Initial value:
= {
"Usage:", "/x [hexpairs]:[binmask]", "Search in memory",
"/x ", "9090cd80", "search for those bytes",
"/x ", "9090cd80:ffff7ff0", "search with binary mask",
}

Definition at line 147 of file cmd_search.c.

Referenced by rz_cmd_search().

◆ preludecnt

int preludecnt = 0
static

Definition at line 154 of file cmd_search.c.

Referenced by __prelude_cb_hit(), and rz_core_search_prelude().

◆ searchflags

int searchflags = 0
static

◆ searchprefix

const char* searchprefix = NULL
static

◆ searchshow

int searchshow = 0
static

Definition at line 156 of file cmd_search.c.

Referenced by _cb_hit(), and rz_cmd_search().