Rizin
unix-like reverse engineering framework and cli tools
analysis.c
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2009-2020 pancake <pancake@nopcode.org>
2 // SPDX-FileCopyrightText: 2009-2020 nibble <nibble.ds@gmail.com>
3 // SPDX-License-Identifier: LGPL-3.0-only
4 
5 #include <rz_analysis.h>
6 #include <rz_util.h>
7 #include <rz_list.h>
8 #include <rz_util/rz_path.h>
9 #include <config.h>
10 
11 RZ_LIB_VERSION(rz_analysis);
12 
14 
16  free(analysis->limit);
17  analysis->limit = RZ_NEW0(RzAnalysisRange);
18  if (analysis->limit) {
19  analysis->limit->from = from;
20  analysis->limit->to = to;
21  }
22 }
23 
25  RZ_FREE(analysis->limit);
26 }
27 
28 static void meta_unset_for(RzEvent *ev, int type, void *user, void *data) {
29  RzSpaces *s = (RzSpaces *)ev->user;
30  RzAnalysis *analysis = container_of(s, RzAnalysis, meta_spaces);
31  RzSpaceEvent *se = (RzSpaceEvent *)data;
32  rz_meta_space_unset_for(analysis, se->data.unset.space);
33 }
34 
35 static void meta_count_for(RzEvent *ev, int type, void *user, void *data) {
36  RzSpaces *s = (RzSpaces *)ev->user;
37  RzAnalysis *analysis = container_of(s, RzAnalysis, meta_spaces);
38  RzSpaceEvent *se = (RzSpaceEvent *)data;
39  se->res = rz_meta_space_count_for(analysis, se->data.count.space);
40 }
41 
43 
45 
47  free(item->str);
48 }
49 
50 static void rz_meta_item_free(void *_item) {
51  if (_item) {
52  RzAnalysisMetaItem *item = _item;
53  rz_meta_item_fini(item);
54  free(item);
55  }
56 }
57 
58 static void global_kv_free(HtPPKv *kv) {
59  free(kv->key);
60  rz_analysis_var_global_free(kv->value);
61 }
62 
64  int i;
65  RzAnalysis *analysis = RZ_NEW0(RzAnalysis);
66  if (!analysis) {
67  return NULL;
68  }
69  if (!rz_str_constpool_init(&analysis->constpool)) {
70  free(analysis);
71  return NULL;
72  }
73  analysis->bb_tree = NULL;
74  analysis->ht_addr_fun = ht_up_new0();
75  analysis->ht_name_fun = ht_pp_new0();
76  analysis->os = strdup(RZ_SYS_OS);
78  analysis->opt.nopskip = true; // skip nops in code analysis
79  analysis->opt.hpskip = false; // skip `mov reg,reg` and `lea reg,[reg]`
80  analysis->gp = 0LL;
81  analysis->sdb = sdb_new0();
83  analysis->opt.depth = 32;
84  analysis->opt.noncode = false; // do not analyze data by default
85  rz_spaces_init(&analysis->meta_spaces, "CS");
88 
91  analysis->typedb = rz_type_db_new();
92  analysis->type_links = ht_up_new0();
93  analysis->sdb_fmts = sdb_ns(analysis->sdb, "spec", 1);
94  analysis->sdb_cc = sdb_ns(analysis->sdb, "cc", 1);
95  analysis->sdb_classes = sdb_ns(analysis->sdb, "classes", 1);
96  analysis->sdb_classes_attrs = sdb_ns(analysis->sdb_classes, "attrs", 1);
97  analysis->sdb_noret = sdb_ns(analysis->sdb, "noreturn", 1);
98  (void)rz_analysis_xrefs_init(analysis);
99  analysis->diff_thbb = RZ_ANALYSIS_THRESHOLDBB;
100  analysis->diff_thfcn = RZ_ANALYSIS_THRESHOLDFCN;
101  analysis->syscall = rz_syscall_new();
102  analysis->arch_target = rz_platform_target_new();
104  rz_io_bind_init(analysis->iob);
105  rz_flag_bind_init(analysis->flb);
106  analysis->reg = rz_reg_new();
107  analysis->last_disasm_reg = NULL;
108  analysis->stackptr = 0;
109  analysis->lineswidth = 0;
111  analysis->leaddrs = NULL;
112  analysis->imports = rz_list_newf(free);
113  rz_analysis_set_bits(analysis, 32);
114  analysis->plugins = rz_list_newf(NULL);
115  if (analysis->plugins) {
116  for (i = 0; i < RZ_ARRAY_SIZE(analysis_static_plugins); i++) {
118  }
119  }
120  analysis->ht_global_var = ht_pp_new(NULL, global_kv_free, NULL);
121  analysis->global_var_tree = NULL;
122  analysis->il_vm = NULL;
123  analysis->hash = rz_hash_new();
124  return analysis;
125 }
126 
127 RZ_API void plugin_fini(RzAnalysis *analysis) {
128  RzAnalysisPlugin *p = analysis->cur;
129  if (p && p->fini && !p->fini(analysis->plugin_data)) {
130  RZ_LOG_ERROR("analysis plugin '%s' failed to terminate.\n", p->name);
131  }
132  analysis->plugin_data = NULL;
133 }
134 
135 void __block_free_rb(RBNode *node, void *user);
136 
138  if (!a) {
139  return NULL;
140  }
141 
142  plugin_fini(a);
143 
144  rz_hash_free(a->hash);
146  rz_list_free(a->fcns);
147  ht_up_free(a->ht_addr_fun);
148  ht_pp_free(a->ht_name_fun);
149  set_u_free(a->visited);
151  rz_interval_tree_fini(&a->meta);
152  free(a->cpu);
153  free(a->os);
154  rz_list_free(a->plugins);
155  rz_rbtree_free(a->bb_tree, __block_free_rb, NULL);
156  rz_spaces_fini(&a->meta_spaces);
157  rz_syscall_free(a->syscall);
158  rz_platform_target_free(a->arch_target);
159  rz_platform_target_index_free(a->platform_target);
160  rz_reg_free(a->reg);
161  ht_up_free(a->ht_xrefs_from);
162  ht_up_free(a->ht_xrefs_to);
163  ht_up_free(a->type_links);
164  rz_list_free(a->leaddrs);
165  rz_type_db_free(a->typedb);
166  sdb_free(a->sdb);
167  if (a->esil) {
168  rz_analysis_esil_free(a->esil);
169  a->esil = NULL;
170  }
171  free(a->last_disasm_reg);
172  rz_list_free(a->imports);
173  rz_str_constpool_fini(&a->constpool);
174  ht_pp_free(a->ht_global_var);
175  free(a);
176  return NULL;
177 }
178 
180  rz_list_append(analysis->plugins, p);
181  return true;
182 }
183 
184 RZ_API bool rz_analysis_use(RzAnalysis *analysis, const char *name) {
185  RzListIter *it;
187 
188  if (analysis) {
189  if (analysis->cur && !strcmp(analysis->cur->name, name)) {
190  return true;
191  }
192  rz_list_foreach (analysis->plugins, it, h) {
193  if (!h || !h->name || strcmp(h->name, name)) {
194  continue;
195  }
196  plugin_fini(analysis);
197  analysis->cur = h;
198  if (h->init && !h->init(&analysis->plugin_data)) {
199  RZ_LOG_ERROR("analysis plugin '%s' failed to initialize.\n", h->name);
200  return false;
201  }
202  rz_analysis_set_reg_profile(analysis);
203  if (analysis->il_vm) {
204  rz_analysis_il_vm_setup(analysis);
205  }
206  return true;
207  }
208  }
209  return false;
210 }
211 
213  return (analysis && analysis->cur && analysis->cur->get_reg_profile)
214  ? analysis->cur->get_reg_profile(analysis)
215  : NULL;
216 }
217 
219  bool ret = false;
220  char *p = rz_analysis_get_reg_profile(analysis);
221  if (p) {
222  rz_reg_set_profile_string(analysis->reg, p);
223  ret = true;
224  }
225  free(p);
226  return ret;
227 }
228 
229 static bool analysis_set_os(RzAnalysis *analysis, const char *os) {
230  rz_return_val_if_fail(analysis, false);
231  if (!os || !*os) {
232  os = RZ_SYS_OS;
233  }
234  free(analysis->os);
235  analysis->os = strdup(os);
236  char *types_dir = rz_path_system(RZ_SDB_TYPES);
237  rz_type_db_set_os(analysis->typedb, os);
238  rz_type_db_reload(analysis->typedb, types_dir);
239  free(types_dir);
240  return true;
241 }
242 
243 RZ_API bool rz_analysis_set_triplet(RzAnalysis *analysis, const char *os, const char *arch, int bits) {
244  rz_return_val_if_fail(analysis, false);
245  if (!arch || !*arch) {
246  arch = analysis->cur ? analysis->cur->arch : RZ_SYS_ARCH;
247  }
248  if (bits < 1) {
249  bits = analysis->bits;
250  }
251  analysis_set_os(analysis, os);
252  rz_analysis_set_bits(analysis, bits);
253  return rz_analysis_use(analysis, arch);
254 }
255 
256 RZ_API bool rz_analysis_set_os(RzAnalysis *analysis, const char *os) {
257  return rz_analysis_set_triplet(analysis, os, NULL, -1);
258 }
259 
260 static bool is_arm_thumb_hack(RzAnalysis *analysis, int bits) {
261  if (!analysis || !analysis->cpu) {
262  return false;
263  }
264  if ((analysis->bits != bits) && !strcmp(analysis->cpu, "arm")) {
265  return (analysis->bits == 16 && bits == 32) || (analysis->bits == 32 && bits == 16);
266  }
267  return false;
268 }
269 
271  switch (bits) {
272  case 8:
273  case 16:
274  case 27:
275  case 32:
276  case 64:
277  if (analysis->bits != bits) {
278  bool is_hack = is_arm_thumb_hack(analysis, bits);
279  analysis->bits = bits;
281  analysis->pcalign = RZ_MAX(0, v);
282  rz_type_db_set_bits(analysis->typedb, bits);
284  if (!is_hack) {
285  char *types_dir = rz_path_system(RZ_SDB_TYPES);
286  rz_type_db_reload(analysis->typedb, types_dir);
287  free(types_dir);
288  }
289  rz_analysis_set_reg_profile(analysis);
290  }
291  return true;
292  }
293  return false;
294 }
295 
304  if (!analysis->cur || !analysis->cur->address_bits) {
305  return analysis->bits;
306  }
307  int r = analysis->cur->address_bits(analysis, analysis->bits);
308  return r > 0 ? r : analysis->bits;
309 }
310 
311 RZ_API void rz_analysis_set_cpu(RzAnalysis *analysis, const char *cpu) {
312  free(analysis->cpu);
313  analysis->cpu = cpu ? strdup(cpu) : NULL;
315  if (v != -1) {
316  analysis->pcalign = v;
317  }
318  rz_analysis_set_reg_profile(analysis);
319  rz_type_db_set_cpu(analysis->typedb, cpu);
320  char *types_dir = rz_path_system(RZ_SDB_TYPES);
321  rz_type_db_reload(analysis->typedb, types_dir);
322  free(types_dir);
323 }
324 
325 RZ_API int rz_analysis_set_big_endian(RzAnalysis *analysis, int bigend) {
326  analysis->big_endian = bigend;
327  if (analysis->reg) {
328  analysis->reg->big_endian = bigend;
329  }
330  rz_type_db_set_endian(analysis->typedb, bigend);
331  return true;
332 }
333 
334 RZ_API ut8 *rz_analysis_mask(RzAnalysis *analysis, ut32 size, const ut8 *data, ut64 at) {
335  RzAnalysisOp *op = NULL;
336  ut8 *ret = NULL;
337  int oplen = 0;
338  ut32 idx = 0;
339 
340  if (!data) {
341  return NULL;
342  }
343 
344  if (analysis->cur && analysis->cur->analysis_mask) {
345  return analysis->cur->analysis_mask(analysis, size, data, at);
346  }
347 
348  if (!(op = rz_analysis_op_new())) {
349  return NULL;
350  }
351 
352  if (!(ret = malloc(size))) {
354  return NULL;
355  }
356 
357  memset(ret, 0xff, size);
358 
359  while (idx < size) {
360  if ((oplen = rz_analysis_op(analysis, op, at, data + idx, size - idx, RZ_ANALYSIS_OP_MASK_BASIC)) < 1) {
361  break;
362  }
363  if ((op->ptr != UT64_MAX || op->jump != UT64_MAX) && op->nopcode != 0) {
364  memset(ret + idx + op->nopcode, 0, oplen - op->nopcode);
365  }
366  idx += oplen;
367  at += oplen;
370  }
371 
373 
374  return ret;
375 }
376 
378  RzAnalysisBlock *bbi;
379  RzAnalysisFunction *fcni;
380  RzListIter *iter2;
381  fcni = rz_analysis_get_fcn_in(analysis, addr, 0);
382  if (fcni) {
383  rz_list_foreach (fcni->bbs, iter2, bbi) {
384  if (addr >= bbi->addr && addr < (bbi->addr + bbi->size)) {
385  bbi->traced = true;
386  break;
387  }
388  }
389  }
390 }
391 
392 RZ_API RzList /*<RzAnalysisFunction *>*/ *rz_analysis_get_fcns(RzAnalysis *analysis) {
393  // avoid received to free this thing
394  analysis->fcns->free = NULL;
395  return analysis->fcns;
396 }
397 
400  if (!op) {
401  return NULL;
402  }
403  ut8 *buf = calloc(1, strlen(str) + 1);
404  if (!buf) {
405  free(op);
406  return NULL;
407  }
408  int len = rz_hex_str2bin(str, buf);
410  free(buf);
411  return op;
412 }
413 
415  if (op->eob) {
416  return true;
417  }
418  switch (op->type) {
427  return true;
428  default:
429  return false;
430  }
431 }
432 
434  rz_analysis_hint_clear(analysis);
435  rz_interval_tree_fini(&analysis->meta);
437  rz_type_db_purge(analysis->typedb);
438  ht_up_free(analysis->type_links);
439  analysis->type_links = ht_up_new0();
440  sdb_reset(analysis->sdb_classes);
441  sdb_reset(analysis->sdb_classes_attrs);
442  sdb_reset(analysis->sdb_cc);
443  sdb_reset(analysis->sdb_noret);
444  rz_list_free(analysis->fcns);
446  rz_analysis_purge_imports(analysis);
447 }
448 
449 RZ_API int rz_analysis_archinfo(RzAnalysis *analysis, int query) {
450  rz_return_val_if_fail(analysis, -1);
451  switch (query) {
455  if (analysis->cur && analysis->cur->archinfo) {
456  return analysis->cur->archinfo(analysis, query);
457  }
458  break;
459  }
460  return -1;
461 }
462 
463 #define K_NORET_ADDR(x) sdb_fmt("addr.%" PFMT64x ".noreturn", x)
464 #define K_NORET_FUNC(x) sdb_fmt("func.%s.noreturn", x)
465 
466 RZ_API bool rz_analysis_noreturn_add(RzAnalysis *analysis, const char *name, ut64 addr) {
467  const char *tmp_name = NULL;
468  Sdb *NDB = analysis->sdb_noret;
469  char *fnl_name = NULL;
470  if (addr != UT64_MAX) {
471  if (sdb_bool_set(NDB, K_NORET_ADDR(addr), true, 0)) {
473  if (fcn) {
474  fcn->is_noreturn = true;
475  }
476  return true;
477  }
478  }
479  if (name && *name) {
480  tmp_name = name;
481  } else {
482  RzAnalysisFunction *fcn = rz_analysis_get_fcn_in(analysis, addr, -1);
483  RzFlagItem *fi = analysis->flb.get_at(analysis->flb.f, addr, false);
484  if (!fcn && !fi) {
485  RZ_LOG_ERROR("Cannot find function and flag at address 0x%" PFMT64x "\n", addr);
486  return false;
487  }
488  tmp_name = fcn ? fcn->name : fi->name;
489  if (fcn) {
490  fcn->is_noreturn = true;
491  }
492  }
493  if (rz_type_func_exist(analysis->typedb, tmp_name)) {
494  fnl_name = strdup(tmp_name);
495  } else if (!(fnl_name = rz_analysis_function_name_guess(analysis->typedb, (char *)tmp_name))) {
496  if (addr == UT64_MAX) {
497  if (name) {
498  sdb_bool_set(NDB, K_NORET_FUNC(name), true, 0);
499  } else {
500  RZ_LOG_ERROR("Cannot find prototype for: %s\n", tmp_name);
501  }
502  } else {
503  RZ_LOG_ERROR("Cannot find prototype for: %s\n", tmp_name);
504  }
505  // return false;
506  }
507  if (fnl_name) {
508  sdb_bool_set(NDB, K_NORET_FUNC(fnl_name), true, 0);
509  free(fnl_name);
510  }
511  return true;
512 }
513 
514 RZ_API bool rz_analysis_noreturn_drop(RzAnalysis *analysis, const char *expr) {
515  Sdb *NDB = analysis->sdb_noret;
517  const char *fcnname = NULL;
518  if (!strncmp(expr, "0x", 2)) {
519  ut64 n = rz_num_math(NULL, expr);
520  sdb_unset(NDB, K_NORET_ADDR(n), 0);
521  RzAnalysisFunction *fcn = rz_analysis_get_fcn_in(analysis, n, -1);
522  if (!fcn) {
523  // eprintf ("can't find function at 0x%"PFMT64x"\n", n);
524  return false;
525  }
526  fcnname = fcn->name;
527  } else {
528  fcnname = expr;
529  }
530  sdb_unset(NDB, K_NORET_FUNC(fcnname), 0);
531  return false;
532 }
533 
534 static bool rz_analysis_is_noreturn(RzAnalysis *analysis, const char *name) {
535  return rz_type_func_is_noreturn(analysis->typedb, name) ||
537 }
538 
539 static bool rz_analysis_noreturn_at_name(RzAnalysis *analysis, const char *name) {
540  if (rz_analysis_is_noreturn(analysis, name)) {
541  return true;
542  }
543  char *tmp = rz_analysis_function_name_guess(analysis->typedb, (char *)name);
544  if (tmp) {
545  if (rz_analysis_is_noreturn(analysis, tmp)) {
546  free(tmp);
547  return true;
548  }
549  free(tmp);
550  }
551  if (rz_str_startswith(name, "reloc.")) {
552  return rz_analysis_noreturn_at_name(analysis, name + 6);
553  }
554  return false;
555 }
556 
558  return sdb_bool_get(analysis->sdb_noret, K_NORET_ADDR(addr), NULL);
559 }
560 
561 static bool noreturn_recurse(RzAnalysis *analysis, ut64 addr) {
562  RzAnalysisOp op = { 0 };
563  ut8 bbuf[0x10] = { 0 };
564  ut64 recurse_addr = UT64_MAX;
565  if (!analysis->iob.read_at(analysis->iob.io, addr, bbuf, sizeof(bbuf))) {
566  RZ_LOG_ERROR("Cannot read buffer at 0x%" PFMT64x "\n", addr);
567  return false;
568  }
569  if (rz_analysis_op(analysis, &op, addr, bbuf, sizeof(bbuf), RZ_ANALYSIS_OP_MASK_BASIC | RZ_ANALYSIS_OP_MASK_VAL) < 1) {
570  return false;
571  }
572  switch (op.type & RZ_ANALYSIS_OP_TYPE_MASK) {
574  if (op.jump == UT64_MAX) {
575  recurse_addr = op.ptr;
576  } else {
577  recurse_addr = op.jump;
578  }
579  break;
584  recurse_addr = op.ptr;
585  break;
588  recurse_addr = op.jump;
589  break;
590  }
591  if (recurse_addr == UT64_MAX || recurse_addr == addr) {
592  return false;
593  }
594  return rz_analysis_noreturn_at(analysis, recurse_addr);
595 }
596 
598  if (!addr || addr == UT64_MAX) {
599  return false;
600  }
601  if (rz_analysis_noreturn_at_addr(analysis, addr)) {
602  return true;
603  }
604  /* XXX this is very slow */
606  if (f) {
607  if (rz_analysis_noreturn_at_name(analysis, f->name)) {
608  return true;
609  }
610  }
611  RzFlagItem *fi = analysis->flag_get(analysis->flb.f, addr);
612  if (fi) {
613  if (rz_analysis_noreturn_at_name(analysis, fi->realname ? fi->realname : fi->name)) {
614  return true;
615  }
616  }
617  if (analysis->recursive_noreturn) {
618  return noreturn_recurse(analysis, addr);
619  }
620  return false;
621 }
622 
624  rz_return_val_if_fail(analysis, NULL);
625  // At first we read all noreturn functions from the Types DB
626  RzList *noretl = rz_type_noreturn_function_names(analysis->typedb);
627  // Then we propagate all noreturn functions that were inferred by
628  // the analysis process
629  SdbKv *kv;
630  SdbListIter *iter;
631  SdbList *l = sdb_foreach_list(analysis->sdb_noret, true);
632  ls_foreach (l, iter, kv) {
633  const char *k = sdbkv_key(kv);
634  if (!strncmp(k, "func.", 5) && strstr(k, ".noreturn")) {
635  char *s = strdup(k + 5);
636  char *d = strchr(s, '.');
637  if (d) {
638  *d = 0;
639  }
640  rz_list_append(noretl, strdup(s));
641  free(s);
642  }
643  if (!strncmp(k, "addr.", 5)) {
644  char *off;
645  if (!(off = strdup(k + 5))) {
646  break;
647  }
648  char *ptr = strstr(off, ".noreturn");
649  if (ptr) {
650  *ptr = 0;
651  char *addr = rz_str_newf("0x%s", off);
652  rz_list_append(noretl, addr);
653  }
654  free(off);
655  }
656  }
657  ls_free(l);
658  return noretl;
659 }
660 
662  if (b) {
663  b->analysis = analysis;
664  b->get_fcn_in = rz_analysis_get_fcn_in;
665  b->get_hint = rz_analysis_hint_get;
666  }
667 }
668 
669 RZ_API RzList /*<RzSearchKeyword *>*/ *rz_analysis_preludes(RzAnalysis *analysis) {
670  if (analysis->cur && analysis->cur->preludes) {
671  return analysis->cur->preludes(analysis);
672  }
673  return NULL;
674 }
675 
676 RZ_API bool rz_analysis_is_prelude(RzAnalysis *analysis, const ut8 *data, int len) {
677  RzList *l = rz_analysis_preludes(analysis);
678  if (l) {
679  RzSearchKeyword *kw;
680  RzListIter *iter;
681  rz_list_foreach (l, iter, kw) {
682  int ks = kw->keyword_length;
683  if (len >= ks && !memcmp(data, kw->bin_keyword, ks)) {
684  rz_list_free(l);
685  return true;
686  }
687  }
688  rz_list_free(l);
689  }
690  return false;
691 }
692 
693 RZ_API void rz_analysis_add_import(RzAnalysis *analysis, const char *imp) {
694  RzListIter *it;
695  const char *eimp;
696  rz_list_foreach (analysis->imports, it, eimp) {
697  if (!strcmp(eimp, imp)) {
698  return;
699  }
700  }
701  char *cimp = strdup(imp);
702  if (!cimp) {
703  return;
704  }
705  rz_list_push(analysis->imports, cimp);
706 }
707 
708 RZ_API void rz_analysis_remove_import(RzAnalysis *analysis, const char *imp) {
709  RzListIter *it;
710  const char *eimp;
711  rz_list_foreach (analysis->imports, it, eimp) {
712  if (!strcmp(eimp, imp)) {
713  rz_list_delete(analysis->imports, it);
714  return;
715  }
716  }
717 }
718 
720  rz_list_purge(analysis->imports);
721 }
size_t len
Definition: 6502dis.c:15
ut8 op
Definition: 6502dis.c:13
RZ_API RZ_OWN char * rz_analysis_function_name_guess(RzTypeDB *typedb, RZ_NONNULL char *name)
Checks if varions function name variations present in the database.
Definition: function.c:458
RZ_API RzAnalysisFunction * rz_analysis_get_function_at(RzAnalysis *analysis, ut64 addr)
Definition: function.c:184
RZ_API void rz_analysis_function_free(void *_fcn)
Definition: function.c:92
static bool rz_analysis_noreturn_at_name(RzAnalysis *analysis, const char *name)
Definition: analysis.c:539
RZ_API bool rz_analysis_noreturn_at_addr(RzAnalysis *analysis, ut64 addr)
Definition: analysis.c:557
RZ_API RzList * rz_analysis_noreturn_functions(RzAnalysis *analysis)
Definition: analysis.c:623
RZ_API void rz_analysis_unset_limits(RzAnalysis *analysis)
Definition: analysis.c:24
static void meta_count_for(RzEvent *ev, int type, void *user, void *data)
Definition: analysis.c:35
RZ_API void rz_analysis_set_cpu(RzAnalysis *analysis, const char *cpu)
Definition: analysis.c:311
RZ_API int rz_analysis_add(RzAnalysis *analysis, RzAnalysisPlugin *p)
Definition: analysis.c:179
#define K_NORET_FUNC(x)
Definition: analysis.c:464
static void rz_meta_item_free(void *_item)
Definition: analysis.c:50
RZ_API ut8 * rz_analysis_mask(RzAnalysis *analysis, ut32 size, const ut8 *data, ut64 at)
Definition: analysis.c:334
static bool is_arm_thumb_hack(RzAnalysis *analysis, int bits)
Definition: analysis.c:260
static bool analysis_set_os(RzAnalysis *analysis, const char *os)
Definition: analysis.c:229
RZ_API RzAnalysis * rz_analysis_free(RzAnalysis *a)
Definition: analysis.c:137
RZ_API bool rz_analysis_set_triplet(RzAnalysis *analysis, const char *os, const char *arch, int bits)
Definition: analysis.c:243
RZ_API RzList * rz_analysis_preludes(RzAnalysis *analysis)
Definition: analysis.c:669
RZ_API void rz_analysis_add_import(RzAnalysis *analysis, const char *imp)
Definition: analysis.c:693
void rz_analysis_hint_storage_fini(RzAnalysis *a)
Definition: hint.c:79
static void global_kv_free(HtPPKv *kv)
Definition: analysis.c:58
RZ_API void rz_analysis_bind(RzAnalysis *analysis, RzAnalysisBind *b)
Definition: analysis.c:661
RZ_API bool rz_analysis_is_prelude(RzAnalysis *analysis, const ut8 *data, int len)
Definition: analysis.c:676
RZ_API void rz_analysis_purge_imports(RzAnalysis *analysis)
Definition: analysis.c:719
static void meta_unset_for(RzEvent *ev, int type, void *user, void *data)
Definition: analysis.c:28
RZ_API bool rz_analysis_set_bits(RzAnalysis *analysis, int bits)
Definition: analysis.c:270
RZ_API RzAnalysis * rz_analysis_new(void)
Definition: analysis.c:63
static bool rz_analysis_is_noreturn(RzAnalysis *analysis, const char *name)
Definition: analysis.c:534
RZ_API void rz_analysis_trace_bb(RzAnalysis *analysis, ut64 addr)
Definition: analysis.c:377
RZ_API void rz_analysis_purge(RzAnalysis *analysis)
Definition: analysis.c:433
RZ_API int rz_analysis_archinfo(RzAnalysis *analysis, int query)
Definition: analysis.c:449
RZ_API int rz_analysis_get_address_bits(RzAnalysis *analysis)
The actual size of an address in bits.
Definition: analysis.c:303
RZ_API RzAnalysisOp * rz_analysis_op_hexstr(RzAnalysis *analysis, ut64 addr, const char *str)
Definition: analysis.c:398
RZ_API bool rz_analysis_noreturn_add(RzAnalysis *analysis, const char *name, ut64 addr)
Definition: analysis.c:466
RZ_API void rz_analysis_set_limits(RzAnalysis *analysis, ut64 from, ut64 to)
Definition: analysis.c:15
RZ_API bool rz_analysis_set_reg_profile(RzAnalysis *analysis)
Definition: analysis.c:218
#define K_NORET_ADDR(x)
Definition: analysis.c:463
static void rz_meta_item_fini(RzAnalysisMetaItem *item)
Definition: analysis.c:46
static RzAnalysisPlugin * analysis_static_plugins[]
Definition: analysis.c:13
RZ_API bool rz_analysis_noreturn_drop(RzAnalysis *analysis, const char *expr)
Definition: analysis.c:514
RZ_API RzList * rz_analysis_get_fcns(RzAnalysis *analysis)
Definition: analysis.c:392
RZ_API void rz_analysis_remove_import(RzAnalysis *analysis, const char *imp)
Definition: analysis.c:708
RZ_API int rz_analysis_set_big_endian(RzAnalysis *analysis, int bigend)
Definition: analysis.c:325
RZ_API bool rz_analysis_use(RzAnalysis *analysis, const char *name)
Definition: analysis.c:184
void rz_analysis_hint_storage_init(RzAnalysis *a)
Definition: hint.c:72
RZ_API bool rz_analysis_op_is_eob(RzAnalysisOp *op)
Definition: analysis.c:414
RZ_API char * rz_analysis_get_reg_profile(RzAnalysis *analysis)
Definition: analysis.c:212
RZ_LIB_VERSION(rz_analysis)
RZ_API bool rz_analysis_noreturn_at(RzAnalysis *analysis, ut64 addr)
Definition: analysis.c:597
void __block_free_rb(RBNode *node, void *user)
Definition: block.c:85
RZ_API bool rz_analysis_set_os(RzAnalysis *analysis, const char *os)
Definition: analysis.c:256
static bool noreturn_recurse(RzAnalysis *analysis, ut64 addr)
Definition: analysis.c:561
RZ_API void plugin_fini(RzAnalysis *analysis)
Definition: analysis.c:127
RZ_API void rz_analysis_il_vm_cleanup(RzAnalysis *analysis)
Definition: analysis_il.c:303
RZ_API bool rz_analysis_il_vm_setup(RzAnalysis *analysis)
Definition: analysis_il.c:285
static ut32 cpu[32]
Definition: analysis_or1k.c:21
lzma_index ** i
Definition: index.h:629
int bits(struct state *s, int need)
Definition: blast.c:72
#define RZ_ANALYSIS_STATIC_PLUGINS
Definition: config.h:22
static RzNumCalcValue expr(RzNum *, RzNumCalc *, int)
Definition: calc.c:167
#define RZ_API
#define NULL
Definition: cris-opc.c:27
#define r
Definition: crypto_rc6.c:12
cs_arch arch
Definition: cstool.c:13
uint32_t ut32
const char * k
Definition: dsignal.c:11
const char * v
Definition: dsignal.c:12
RZ_API void rz_analysis_esil_free(RzAnalysisEsil *esil)
Definition: esil.c:163
RZ_DEPRECATE RZ_API RzAnalysisFunction * rz_analysis_get_fcn_in(RzAnalysis *analysis, ut64 addr, int type)
Definition: fcn.c:1687
RZ_API void rz_hash_free(RzHash *rh)
Definition: hash.c:597
RZ_API RzHash * rz_hash_new(void)
Definition: hash.c:585
RZ_API RzAnalysisHint * rz_analysis_hint_get(RzAnalysis *a, ut64 addr)
Definition: hint.c:506
RZ_API void rz_analysis_hint_clear(RzAnalysis *a)
Definition: hint.c:85
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
voidpf void uLong size
Definition: ioapi.h:138
voidpf void * buf
Definition: ioapi.h:138
uint8_t ut8
Definition: lh5801.h:11
return memset(p, 0, total)
void * p
Definition: libc.cpp:67
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 void rz_list_delete(RZ_NONNULL RzList *list, RZ_NONNULL RzListIter *iter)
Removes an entry in the list by using the RzListIter pointer.
Definition: list.c:162
RZ_API RZ_BORROW RzListIter * rz_list_push(RZ_NONNULL RzList *list, void *item)
Alias for rz_list_append.
Definition: list.c:60
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 void rz_list_free(RZ_NONNULL RzList *list)
Empties the list and frees the list pointer.
Definition: list.c:137
RZ_API void rz_list_purge(RZ_NONNULL RzList *list)
Empties the list without freeing the list pointer.
Definition: list.c:120
void * malloc(size_t size)
Definition: malloc.c:123
void * calloc(size_t number, size_t size)
Definition: malloc.c:102
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")
RZ_API void ls_free(SdbList *list)
Definition: ls.c:191
#define ls_foreach(list, it, pos)
Definition: ls.h:31
RZ_API void rz_meta_space_unset_for(RzAnalysis *a, const RzSpace *space)
Definition: meta.c:274
RZ_API int rz_meta_space_count_for(RzAnalysis *a, const RzSpace *space)
Definition: meta.c:295
int n
Definition: mipsasm.c:19
int type
Definition: mipsasm.c:17
int idx
Definition: setup.py:197
RZ_API Sdb * sdb_ns(Sdb *s, const char *name, int create)
Definition: ns.c:186
RZ_API bool sdb_bool_get(Sdb *db, const char *str, ut32 *cas)
Definition: num.c:76
RZ_API int sdb_bool_set(Sdb *db, const char *str, bool v, ut32 cas)
Definition: num.c:72
const char * name
Definition: op.c:541
RZ_API void rz_analysis_op_free(void *op)
Definition: op.c:61
RZ_API bool rz_analysis_op_fini(RzAnalysisOp *op)
Definition: op.c:37
RZ_API RzAnalysisOp * rz_analysis_op_new(void)
Definition: op.c:9
RZ_API void rz_analysis_op_init(RzAnalysisOp *op)
Definition: op.c:23
RZ_API int rz_analysis_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8 *data, int len, RzAnalysisOpMask mask)
Definition: op.c:96
int off
Definition: pal.c:13
RZ_API void rz_platform_target_free(RzPlatformTarget *t)
Frees an RzPlatformTarget type.
RZ_API RZ_OWN RzPlatformTarget * rz_platform_target_new()
Creates a new RzPlatformTarget type.
RZ_API void rz_platform_target_index_free(RzPlatformTargetIndex *target)
Frees an RzPlatformTargetIndex type.
RZ_API RZ_OWN RzPlatformTargetIndex * rz_platform_target_index_new()
Creates a new RzPlatformTargetIndex type.
RZ_API bool rz_reg_set_profile_string(RZ_NONNULL RzReg *reg, RZ_NONNULL const char *profile_str)
Parses a register profile string and sets up all registers accordingly in reg.
Definition: profile.c:431
RZ_API void rz_reg_free(RzReg *reg)
Definition: reg.c:279
RZ_API RzReg * rz_reg_new(void)
Definition: reg.c:286
static RzSocket * s
Definition: rtr.c:28
#define RZ_ANALYSIS_ARCHINFO_ALIGN
Definition: rz_analysis.h:100
#define RZ_ANALYSIS_ESIL_GOTO_LIMIT
Definition: rz_analysis.h:504
@ RZ_ANALYSIS_CPP_ABI_ITANIUM
Definition: rz_analysis.h:542
#define RZ_ANALYSIS_ARCHINFO_MAX_OP_SIZE
Definition: rz_analysis.h:99
@ RZ_ANALYSIS_OP_MASK_BASIC
Definition: rz_analysis.h:440
@ RZ_ANALYSIS_OP_MASK_VAL
Definition: rz_analysis.h:442
#define RZ_ANALYSIS_OP_TYPE_MASK
Definition: rz_analysis.h:358
#define RZ_ANALYSIS_ARCHINFO_MIN_OP_SIZE
Definition: rz_analysis.h:98
@ 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_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_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_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
#define rz_return_val_if_fail(expr, val)
Definition: rz_assert.h:108
RZ_API RzEventCallbackHandle rz_event_hook(RzEvent *ev, int type, RzEventCallback cb, void *user)
Definition: event.c:58
#define rz_flag_bind_init(x)
Definition: rz_flag.h:94
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 void rz_interval_tree_init(RzIntervalTree *tree, RzIntervalNodeFree free)
Definition: intervaltree.c:101
RZ_API void rz_interval_tree_fini(RzIntervalTree *tree)
Definition: intervaltree.c:114
#define rz_io_bind_init(x)
Definition: rz_io.h:344
#define RZ_LOG_ERROR(fmtstr,...)
Definition: rz_log.h:58
RZ_API ut64 rz_num_math(RzNum *num, const char *str)
Definition: unum.c:456
RZ_API RZ_OWN char * rz_path_system(RZ_NULLABLE const char *path)
Return the full system path of the given subpath path.
Definition: path.c:162
RZ_API void rz_rbtree_free(RZ_NULLABLE RBNode *root, RBNodeFree freefn, void *user)
Definition: rbtree.c:281
RZ_API void rz_spaces_fini(RzSpaces *sp)
Definition: spaces.c:59
@ RZ_SPACE_EVENT_COUNT
Definition: rz_spaces.h:34
@ RZ_SPACE_EVENT_UNSET
Definition: rz_spaces.h:36
RZ_API bool rz_spaces_init(RzSpaces *sp, const char *name)
Definition: spaces.c:16
RZ_API char * rz_str_newf(const char *fmt,...) RZ_PRINTF_CHECK(1
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
RZ_API void rz_str_constpool_fini(RzStrConstPool *pool)
Definition: str_constpool.c:15
RZ_API bool rz_str_constpool_init(RzStrConstPool *pool)
Definition: str_constpool.c:10
#define RZ_NEW0(x)
Definition: rz_types.h:284
#define RZ_SYS_ARCH
Definition: rz_types.h:519
#define RZ_SYS_OS
Definition: rz_types.h:587
#define RZ_ARRAY_SIZE(x)
Definition: rz_types.h:300
#define RZ_FREE(x)
Definition: rz_types.h:369
#define PFMT64x
Definition: rz_types.h:393
#define container_of(ptr, type, member)
Definition: rz_types.h:650
#define RZ_MAX(x, y)
#define UT64_MAX
Definition: rz_types_base.h:86
#define RZ_SDB_TYPES
Definition: rz_userconf.h:83
RZ_API Sdb * sdb_new0(void)
Definition: sdb.c:43
RZ_API bool sdb_free(Sdb *s)
Definition: sdb.c:206
RZ_API void sdb_reset(Sdb *s)
Definition: sdb.c:433
RZ_API int sdb_unset(Sdb *s, const char *key, ut32 cas)
Definition: sdb.c:294
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
RZ_API void set_u_free(SetU *s)
Definition: set.c:46
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
#define d(i)
Definition: sha256.c:44
#define b(i)
Definition: sha256.c:42
#define f(i)
Definition: sha256.c:46
#define a(i)
Definition: sha256.c:41
#define h(i)
Definition: sha256.c:48
Definition: ls.h:17
Definition: ls.h:22
Definition: z80asm.h:102
RzAnalysisRegProfGetCallback get_reg_profile
Definition: rz_analysis.h:1259
int(* address_bits)(RzAnalysis *analysis, int bits)
Definition: rz_analysis.h:1254
RzList *(* preludes)(RzAnalysis *analysis)
Definition: rz_analysis.h:1248
ut8 *(* analysis_mask)(RzAnalysis *analysis, int size, const ut8 *data, ut64 at)
Definition: rz_analysis.h:1247
int(* archinfo)(RzAnalysis *analysis, int query)
Definition: rz_analysis.h:1246
RzAnalysisRange * limit
Definition: rz_analysis.h:587
RBTree bb_tree
Definition: rz_analysis.h:564
RzPlatformTarget * arch_target
Definition: rz_analysis.h:622
RzAnalysisCPPABI cpp_abi
Definition: rz_analysis.h:560
RzFlagGetAtAddr flag_get
Definition: rz_analysis.h:616
RzStrConstPool constpool
Definition: rz_analysis.h:620
RzList * leaddrs
Definition: rz_analysis.h:621
double diff_thfcn
Definition: rz_analysis.h:573
void * plugin_data
Definition: rz_analysis.h:561
RzList * fcns
Definition: rz_analysis.h:565
HtUP * ht_addr_fun
Definition: rz_analysis.h:566
HtPP * ht_name_fun
Definition: rz_analysis.h:567
HtPP * ht_global_var
Definition: rz_analysis.h:624
bool recursive_noreturn
Definition: rz_analysis.h:593
struct rz_analysis_plugin_t * cur
Definition: rz_analysis.h:586
RzIntervalTree meta
Definition: rz_analysis.h:600
HtUP * type_links
Definition: rz_analysis.h:603
RzSpaces meta_spaces
Definition: rz_analysis.h:601
ut8 * last_disasm_reg
Definition: rz_analysis.h:569
Sdb * sdb_classes_attrs
Definition: rz_analysis.h:606
RzHash * hash
Definition: rz_analysis.h:626
RzSyscall * syscall
Definition: rz_analysis.h:570
RzFlagBind flb
Definition: rz_analysis.h:575
RzPlatformTargetIndex * platform_target
Definition: rz_analysis.h:623
double diff_thbb
Definition: rz_analysis.h:572
RzAnalysisOptions opt
Definition: rz_analysis.h:608
RzAnalysisILVM * il_vm
user-faced VM, NEVER use this for any analysis passes!
Definition: rz_analysis.h:585
RzList * imports
Definition: rz_analysis.h:618
RzList * plugins
Definition: rz_analysis.h:588
Sdb * sdb_classes
Definition: rz_analysis.h:605
RzIOBind iob
Definition: rz_analysis.h:574
RzTypeDB * typedb
Definition: rz_analysis.h:602
RBTree global_var_tree
Definition: rz_analysis.h:625
void * user
Definition: rz_event.h:15
RzFlagGetAt get_at
Definition: rz_flag.h:81
RzFlag * f
Definition: rz_flag.h:78
char * realname
Definition: rz_flag.h:36
char * name
Definition: rz_flag.h:35
RzIOReadAt read_at
Definition: rz_io.h:240
RzIO * io
Definition: rz_io.h:232
RzListFree free
Definition: rz_list.h:21
bool big_endian
Definition: rz_reg.h:158
struct rz_space_event_t::@311::@313 unset
struct rz_space_event_t::@311::@312 count
union rz_space_event_t::@311 data
RzEvent * event
Definition: rz_spaces.h:61
Definition: sdbht.h:14
Definition: sdb.h:63
RZ_API RzSyscall * rz_syscall_new(void)
Creates a new RzSyscall type.
Definition: syscall.c:67
RZ_API void rz_syscall_free(RzSyscall *s)
Frees an RzSyscall type.
Definition: syscall.c:79
RZ_API bool rz_type_func_is_noreturn(RzTypeDB *typedb, RZ_NONNULL const char *name)
Checks if the RzCallable type is defined as "noreturn".
Definition: function.c:503
RZ_API bool rz_type_func_exist(RzTypeDB *typedb, RZ_NONNULL const char *name)
Checks if the RzCallable type exists in the database given the name.
Definition: function.c:203
RZ_API RZ_OWN RzList * rz_type_noreturn_function_names(RzTypeDB *typedb)
Returns the list of all noreturn function type names.
Definition: function.c:588
RZ_API void rz_type_db_set_address_bits(RzTypeDB *typedb, int addr_bits)
Set the RzType target adress size.
Definition: type.c:161
RZ_API void rz_type_db_reload(RzTypeDB *typedb, const char *types_dir)
Re-initializes the types database for current target.
Definition: type.c:357
RZ_API void rz_type_db_set_os(RzTypeDB *typedb, const char *os)
Set the RzType target architecture operating system.
Definition: type.c:175
RZ_API void rz_type_db_set_bits(RzTypeDB *typedb, int bits)
Set the RzType target architecture bits.
Definition: type.c:145
RZ_API void rz_type_db_free(RzTypeDB *typedb)
Frees the instance of the RzTypeDB.
Definition: type.c:79
RZ_API void rz_type_db_purge(RzTypeDB *typedb)
Purges the instance of the RzTypeDB.
Definition: type.c:96
RZ_API void rz_type_db_set_endian(RzTypeDB *typedb, bool big_endian)
Set the RzType target architecture CPU.
Definition: type.c:202
RZ_API RzTypeDB * rz_type_db_new()
Creates a new instance of the RzTypeDB.
Definition: type.c:34
RZ_API void rz_type_db_set_cpu(RzTypeDB *typedb, const char *cpu)
Set the RzType target architecture CPU.
Definition: type.c:189
Definition: dis.c:32
RZ_API void rz_analysis_var_global_free(RzAnalysisVarGlobal *glob)
Free the global variable instance.
Definition: var_global.c:79
ut64(WINAPI *w32_GetEnabledXStateFeatures)()
RZ_API bool rz_analysis_xrefs_init(RzAnalysis *analysis)
Definition: xrefs.c:245
static int addr
Definition: z80asm.c:58