Rizin
unix-like reverse engineering framework and cli tools
cmd_analysis.c
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2009-2021 pancake <pancake@nopcode.org>
2 // SPDX-FileCopyrightText: 2009-2021 maijin <maijin21@gmail.com>
3 // SPDX-License-Identifier: LGPL-3.0-only
4 
5 #include <rz_core.h>
7 
8 #include "../core_private.h"
9 
10 #define MAX_SCAN_SIZE 0x7ffffff
11 
13 
14 static const char *help_msg_a[] = {
15  "Usage:", "a", "[abdefFghoprxstc] [...]",
16  "a*", "", "same as afl*;ah*;ax*",
17  "aa", "[?]", "analyze all (fcns + bbs) (aa0 to avoid sub renaming)",
18  "a8", " [hexpairs]", "analyze bytes",
19  "ab", "[?] [addr]", "analyze block",
20  "ad", "[?]", "analyze data trampoline (wip)",
21  "ad", " [from] [to]", "analyze data pointers to (from-to)",
22  "ae", "[?] [expr]", "analyze opcode eval expression (see ao)",
23  "af", "[?]", "analyze Functions",
24  "aF", "", "same as above, but using analysis.depth=1",
25  "ag", "[?] [options]", "draw graphs in various formats",
26  "ah", "[?]", "analysis hints (force opcode size, ...)",
27  "ai", " [addr]", "address information (show perms, stack, heap, ...)",
28  "aj", "", "same as a* but in json (aflj)",
29  "aL", "", "list all asm/analysis plugins (e asm.arch=?)",
30  "an", " [name] [@addr]", "show/rename/create whatever flag/function is used at addr",
31  "ao", "[?] [len]", "analyze Opcodes (or emulate it)",
32  "aO", "[?] [len]", "Analyze N instructions in M bytes",
33  "ap", "", "find prelude for current offset",
34  "ar", "[?]", "like 'dr' but for the esil vm. (registers)",
35  "as", "[?] [num]", "analyze syscall using dbg.reg",
36  "av", "[?] [.]", "show vtables",
37  "ax", "[?]", "manage refs/xrefs (see also afx?)",
38  NULL
39 };
40 
41 static const char *help_msg_ad[] = {
42  "Usage:", "ad", "[kt] [...]",
43  "ad", " [N] [D]", "analyze N data words at D depth",
44  "ad4", " [N] [D]", "analyze N data words at D depth (asm.bits=32)",
45  "ad8", " [N] [D]", "analyze N data words at D depth (asm.bits=64)",
46  "adf", "", "analyze data in function (use like .adf @@=`afl~[0]`",
47  "adfg", "", "analyze data in function gaps",
48  "adt", "", "analyze data trampolines (wip)",
49  "adk", "", "analyze data kind (code, text, data, invalid, ...)",
50  NULL
51 };
52 
53 static const char *help_msg_ae[] = {
54  "Usage:", "ae[idesr?] [arg]", "ESIL code emulation",
55  "ae", " [expr]", "evaluate ESIL expression",
56  "ae?", "", "show this help",
57  "ae??", "", "show ESIL help",
58  "ae[aA]", "[f] [count]", "analyse esil accesses (regs, mem..)",
59  "aeC", "[arg0 arg1..] @ addr", "appcall in esil",
60  "aec", "[?]", "continue until ^C",
61  "aecb", "", "continue back until breakpoint",
62  "aecs", "", "continue until syscall",
63  "aecc", "", "continue until call",
64  "aecu", " [addr]", "continue until address",
65  "aecue", " [esil]", "continue until esil expression match",
66  "aef", " [addr]", "emulate function",
67  "aefa", " [addr]", "emulate function to find out args in given or current offset",
68  "aei", "", "initialize ESIL VM state (aei- to deinitialize)",
69  "aeim", " [addr] [size] [name]", "initialize ESIL VM stack (aeim- remove)",
70  "aeip", "", "initialize ESIL program counter to curseek",
71  "aek", " [query]", "perform sdb query on ESIL.info",
72  "aek-", "", "resets the ESIL.info sdb instance",
73  "aeli", "", "list loaded ESIL interrupts",
74  "aeli", " [file]", "load ESIL interrupts from shared object",
75  "aelir", " [interrupt number]", "remove ESIL interrupt and free it if needed",
76  "aepc", " [addr]", "change esil PC to this address",
77  "aes", "", "perform emulated debugger step",
78  "aesp", " [X] [N]", "evaluate N instr from offset X",
79  "aesb", "", "step back",
80  "aeso", " ", "step over",
81  "aesou", " [addr]", "step over until given address",
82  "aess", " ", "step skip (in case of CALL, just skip, instead of step into)",
83  "aesu", " [addr]", "step until given address",
84  "aesue", " [esil]", "step until esil expression match",
85  "aesuo", " [optype]", "step until given opcode type",
86  "aets", "[?]", "ESIL Trace session",
87  "aex", " [hex]", "evaluate opcode expression",
88  "aez", "[?]", "RzIL Emulation",
89  NULL
90 };
91 
92 static const char *help_detail_ae[] = {
93  "Examples:", "ESIL", " examples and documentation",
94  "=", "", "assign updating internal flags",
95  ":=", "", "assign without updating internal flags",
96  "+=", "", "A+=B => B,A,+=",
97  "+", "", "A=A+B => B,A,+,A,=",
98  "++", "", "increment, 2,A,++ == 3 (see rsi,--=[1], ... )",
99  "--", "", "decrement, 2,A,-- == 1",
100  "*=", "", "A*=B => B,A,*=",
101  "/=", "", "A/=B => B,A,/=",
102  "%=", "", "A%=B => B,A,%=",
103  "&=", "", "and ax, bx => bx,ax,&=",
104  "|", "", "or r0, r1, r2 => r2,r1,|,r0,=",
105  "!=", "", "negate all bits",
106  "^=", "", "xor ax, bx => bx,ax,^=",
107  "", "[]", "mov eax,[eax] => eax,[],eax,=",
108  "=", "[]", "mov [eax+3], 1 => 1,3,eax,+,=[]",
109  "=", "[1]", "mov byte[eax],1 => 1,eax,=[1]",
110  "=", "[8]", "mov [rax],1 => 1,rax,=[8]",
111  "[]", "", "peek from random position",
112  "[N]", "", "peek word of N bytes from popped address",
113  "[*]", "", "peek some from random position",
114  "=", "[*]", "poke some at random position",
115  "$", "", "int 0x80 => 0x80,$",
116  "$$", "", "simulate a hardware trap",
117  "==", "", "pops twice, compare and update esil flags",
118  "<", "", "compare for smaller",
119  "<=", "", "compare for smaller or equal",
120  ">", "", "compare for bigger",
121  ">=", "", "compare bigger for or equal",
122  ">>=", "", "shr ax, bx => bx,ax,>>= # shift right",
123  "<<=", "", "shl ax, bx => bx,ax,<<= # shift left",
124  ">>>=", "", "ror ax, bx => bx,ax,>>>= # rotate right",
125  "<<<=", "", "rol ax, bx => bx,ax,<<<= # rotate left",
126  "?{", "", "if popped value != 0 run the block until }",
127  "POP", "", "drops last element in the esil stack",
128  "DUP", "", "duplicate last value in stack",
129  "NUM", "", "evaluate last item in stack to number",
130  "SWAP", "", "swap last two values in stack",
131  "TRAP", "", "stop execution",
132  "BITS", "", "16,BITS # change bits, useful for arm/thumb",
133  "TODO", "", "the instruction is not yet esilized",
134  "STACK", "", "show contents of stack",
135  "CLEAR", "", "clears the esil stack",
136  "REPEAT", "", "repeat n times",
137  "BREAK", "", "terminates the string parsing",
138  "SETJT", "", "set jump target",
139  "SETJTS", "", "set jump target set",
140  "SETD", "", "set delay slot",
141  "GOTO", "", "jump to the Nth word popped from the stack",
142  "$", "", "esil interrupt",
143  "$z", "", "internal flag: zero",
144  "$c", "", "internal flag: carry",
145  "$b", "", "internal flag: borrow",
146  "$p", "", "internal flag: parity",
147  "$s", "", "internal flag: sign",
148  "$o", "", "internal flag: overflow",
149  "$ds", "", "internal flag: delay-slot",
150  "$jt", "", "internal flag: jump-target",
151  "$js", "", "internal flag: jump-target-set",
152  // DEPRECATED "$r", "", "internal flag: jump-sign",
153  "$$", "", "internal flag: pc address",
154  NULL
155 };
156 
157 static const char *help_msg_aea[] = {
158  "Examples:", "aea", " show regs and memory accesses used in a range",
159  "aea", " [ops]", "Show regs/memory accesses used in N instructions ",
160  "aea*", " [ops]", "Create mem.* flags for memory accesses",
161  "aeab", "", "Show regs used in current basic block",
162  "aeaf", "", "Show regs used in current function",
163  "aear", " [ops]", "Show regs read in N instructions",
164  "aeaw", " [ops]", "Show regs written in N instructions",
165  "aean", " [ops]", "Show regs not written in N instructions",
166  "aeaj", " [ops]", "Show aea output in JSON format",
167  "aeA", " [len]", "Show regs used in N bytes (subcommands are the same)",
168  "Legend:", "", "",
169  "I", "", "input registers (read before being set)",
170  "A", "", "all regs accessed",
171  "R", "", "register values read",
172  "W", "", "registers written",
173  "N", "", "read but never written",
174  "V", "", "values",
175  "@R", "", "memreads",
176  "@W", "", "memwrites",
177  "NOTE:", "", "mem{reads,writes} with PIC only fetch the offset",
178  NULL
179 };
180 
181 static const char *help_msg_ag[] = {
182  "Usage:", "ag<graphtype><format> [addr]", "",
183  "Graph commands:", "", "",
184  "aga", "[format]", "Data references graph",
185  "agA", "[format]", "Global data references graph",
186  "agc", "[format]", "Function callgraph",
187  "agC", "[format]", "Global callgraph",
188  "agd", "[format] [fcn addr]", "Diff graph",
189  "agf", "[format]", "Basic blocks function graph",
190  "agi", "[format]", "Imports graph",
191  "agr", "[format]", "References graph",
192  "agR", "[format]", "Global references graph",
193  "agx", "[format]", "Cross references graph",
194  "agg", "[format]", "Custom graph",
195  "ag-", "", "Clear the custom graph",
196  "agn", "[?] title body", "Add a node to the custom graph",
197  "age", "[?] title1 title2", "Add an edge to the custom graph",
198  "", "", "",
199  "Output formats:", "", "",
200  "<blank>", "", "Ascii art",
201  "*", "", "rizin commands",
202  "d", "", "Graphviz dot",
203  "g", "", "Graph Modelling Language (gml)",
204  "j", "", "json ('J' for formatted disassembly)",
205  "k", "", "SDB key-value",
206  "t", "", "Tiny ascii art",
207  "v", "", "Interactive ascii art",
208  "w", " [path]", "Write to path or display graph image (see graph.gv.format)",
209  NULL
210 };
211 
212 static const char *help_msg_age[] = {
213  "Usage:", "age [title1] [title2]", "",
214  "Examples:", "", "",
215  "age", " title1 title2", "Add an edge from the node with \"title1\" as title to the one with title \"title2\"",
216  "age", " \"title1 with spaces\" title2", "Add an edge from node \"title1 with spaces\" to node \"title2\"",
217  "age-", " title1 title2", "Remove an edge from the node with \"title1\" as title to the one with title \"title2\"",
218  "age?", "", "Show this help",
219  NULL
220 };
221 
222 static const char *help_msg_agn[] = {
223  "Usage:", "agn [title] [body]", "",
224  "Examples:", "", "",
225  "agn", " title1 body1", "Add a node with title \"title1\" and body \"body1\"",
226  "agn", " \"title with space\" \"body with space\"", "Add a node with spaces in the title and in the body",
227  "agn", " title1 base64:Ym9keTE=", "Add a node with the body specified as base64",
228  "agn-", " title1", "Remove a node with title \"title1\"",
229  "agn?", "", "Show this help",
230  NULL
231 };
232 
241  if (fcn) {
242  return fcn;
243  }
245  if (rz_list_empty(list)) {
246  RZ_LOG_ERROR("No function found in 0x%08" PFMT64x ".\n", offset);
247  goto exit;
248  }
249  if (rz_list_length(list) > 1) {
250  RZ_LOG_ERROR("Multiple overlapping functions found at 0x%08" PFMT64x ". "
251  "Re-run this command at the entrypoint of one of them to disambiguate.\n",
252  offset);
253  goto exit;
254  }
255  fcn = rz_list_first(list);
256  if (!fcn) {
258  }
259 exit:
261  return fcn;
262 }
263 
264 static int cmpaddr(const void *_a, const void *_b) {
265  const RzAnalysisFunction *a = _a, *b = _b;
266  return (a->addr > b->addr) ? 1 : (a->addr < b->addr) ? -1
267  : 0;
268 }
269 
270 static bool listOpDescriptions(void *_core, const char *k, const char *v) {
271  rz_cons_printf("%s=%s\n", k, v);
272  return true;
273 }
274 
275 static void var_accesses_list(RzAnalysisFunction *fcn, RzAnalysisVar *var, PJ *pj, int access_type, const char *name) {
276  RzAnalysisVarAccess *acc;
277  bool first = true;
278  if (pj) {
279  pj_o(pj);
280  pj_ks(pj, "name", name);
281  pj_ka(pj, "addrs");
282  } else {
283  rz_cons_printf("%10s", name);
284  }
285  rz_vector_foreach(&var->accesses, acc) {
286  if (!(acc->type & access_type)) {
287  continue;
288  }
289  ut64 addr = fcn->addr + acc->offset;
290  if (pj) {
291  pj_n(pj, addr);
292  } else {
293  rz_cons_printf("%s0x%" PFMT64x, first ? " " : ",", addr);
294  }
295  first = false;
296  }
297  if (pj) {
298  pj_end(pj);
299  pj_end(pj);
300  } else {
301  rz_cons_newline();
302  }
303 }
304 
305 typedef enum {
306  IS_VAR = 0,
310 
311 static void list_vars(RzCore *core, RzAnalysisFunction *fcn, PJ *pj, int type, const char *name, RzVarListType vlt) {
312  RzAnalysisVar *var = NULL;
313  RzListIter *iter;
315  if (type == '=') {
316  ut64 oaddr = core->offset;
317  rz_list_foreach (list, iter, var) {
318  rz_cons_printf("* %s\n", var->name);
319  RzAnalysisVarAccess *acc;
320  rz_vector_foreach(&var->accesses, acc) {
321  if (!(acc->type & RZ_ANALYSIS_VAR_ACCESS_TYPE_READ)) {
322  continue;
323  }
324  rz_cons_printf("R 0x%" PFMT64x " ", fcn->addr + acc->offset);
325  rz_core_seek(core, fcn->addr + acc->offset, 1);
327  }
328  rz_vector_foreach(&var->accesses, acc) {
329  if (!(acc->type & RZ_ANALYSIS_VAR_ACCESS_TYPE_WRITE)) {
330  continue;
331  }
332  rz_cons_printf("W 0x%" PFMT64x " ", fcn->addr + acc->offset);
333  rz_core_seek(core, fcn->addr + acc->offset, 1);
335  }
336  }
337  rz_core_seek(core, oaddr, 0);
338  return;
339  }
340  if (type == '*') {
341  const char *bp = rz_reg_get_name(core->analysis->reg, RZ_REG_NAME_BP);
342  rz_cons_printf("f-fcnvar*\n");
343  rz_list_foreach (list, iter, var) {
344  rz_cons_printf("f fcnvar.%s @ %s%s%d\n", var->name, bp,
345  var->delta >= 0 ? "+" : "", var->delta);
346  }
347  return;
348  }
349  if (type != 'W' && type != 'R') {
350  return;
351  }
353  if (pj) {
354  pj_a(pj);
355  }
356  if (name && *name) {
358  if (var) {
359  if (var->isarg == vlt || vlt == IS_ARG_AND_VAR) {
360  var_accesses_list(fcn, var, pj, access_type, var->name);
361  }
362  }
363  } else {
364  rz_list_foreach (list, iter, var) {
365  if (var->isarg == vlt || vlt == IS_ARG_AND_VAR) {
366  var_accesses_list(fcn, var, pj, access_type, var->name);
367  }
368  }
369  }
370  if (pj) {
371  pj_end(pj);
372  }
373 }
374 
375 #define PJ_KS(pj, key, value) \
376  { \
377  const char *value_tmp = (value); \
378  if (RZ_STR_ISNOTEMPTY(value_tmp)) { \
379  pj_ks(pj, key, value_tmp); \
380  } \
381  }
382 #define PJ_KN(pj, key, value) \
383  { \
384  const ut64 value_tmp = (value); \
385  if (value_tmp != UT64_MAX) { \
386  pj_kn(pj, key, value_tmp); \
387  } \
388  }
389 
391  RzCoreAnalysisName *p = rz_core_analysis_name(core, core->offset);
392  if (!p) {
393  return false;
394  }
395  PJ *pj = state->d.pj;
396  switch (state->mode) {
397  case RZ_OUTPUT_MODE_JSON: {
398  pj_a(pj);
399 
400  pj_o(pj);
401  PJ_KS(pj, "name", p->name);
402  PJ_KS(pj, "realname", p->realname);
403  pj_ks(pj, "type", rz_core_analysis_name_type_to_str(p->type));
404  pj_kn(pj, "offset", p->offset);
405  pj_end(pj);
406 
407  pj_end(pj);
408  break;
409  }
411  if (p->type == RZ_CORE_ANALYSIS_NAME_TYPE_ADDRESS) {
412  rz_cons_printf("0x%" PFMT64x "\n", p->offset);
413  } else {
414  rz_cons_println(p->name);
415  }
416  break;
417  }
418  default:
420  return false;
421  }
422 
424  return true;
425 }
426 
427 static void print_trampolines(RzCore *core, ut64 a, ut64 b, size_t element_size) {
428  int i;
429  for (i = 0; i < core->blocksize; i += element_size) {
430  ut32 n;
431  memcpy(&n, core->block + i, sizeof(ut32));
432  if (n >= a && n <= b) {
433  if (element_size == 4) {
434  rz_cons_printf("f trampoline.%x @ 0x%" PFMT64x "\n", n, core->offset + i);
435  } else {
436  rz_cons_printf("f trampoline.%" PFMT32x " @ 0x%" PFMT64x "\n", n, core->offset + i);
437  }
438  rz_cons_printf("Cd %zu @ 0x%" PFMT64x ":%zu\n", element_size, core->offset + i, element_size);
439  // TODO: add data xrefs
440  }
441  }
442 }
443 
444 static void cmd_analysis_trampoline(RzCore *core, const char *input) {
445  int bits = rz_config_get_i(core->config, "asm.bits");
446  char *p, *inp = strdup(input);
447  p = strchr(inp, ' ');
448  if (p) {
449  *p = 0;
450  }
451  ut64 a = rz_num_math(core->num, inp);
452  ut64 b = p ? rz_num_math(core->num, p + 1) : 0;
453  free(inp);
454 
455  switch (bits) {
456  case 32:
457  print_trampolines(core, a, b, 4);
458  break;
459  case 64:
460  print_trampolines(core, a, b, 8);
461  break;
462  }
463 }
464 
465 static int mw(RzAnalysisEsil *esil, ut64 addr, const ut8 *buf, int len) {
466  int *ec = (int *)esil->user;
467  *ec += (len * 2);
468  return 1;
469 }
470 
471 static int mr(RzAnalysisEsil *esil, ut64 addr, ut8 *buf, int len) {
472  int *ec = (int *)esil->user;
473  *ec += len;
474  return 1;
475 }
476 
477 static int esil_cost(RzCore *core, ut64 addr, const char *expr) {
478  if (RZ_STR_ISEMPTY(expr)) {
479  return 0;
480  }
481  int ec = 0;
482  RzAnalysisEsil *e = rz_analysis_esil_new(256, 0, 0);
483  rz_analysis_esil_setup(e, core->analysis, false, false, false);
484  e->user = &ec;
485  e->cb.mem_read = mr;
486  e->cb.mem_write = mw;
489  return ec;
490 }
491 
492 static void core_analysis_bytes_size(RzCore *core, const ut8 *buf, int len, int nops) {
493  core->parser->subrel = rz_config_get_i(core->config, "asm.sub.rel");
494  int ret, i, idx;
495  RzAnalysisOp op = { 0 };
496  ut64 addr;
497  int totalsize = 0;
498 
499  for (i = idx = 0; idx < len && (!nops || (nops && i < nops)); i++, idx += ret) {
500  addr = core->offset + idx;
501  rz_asm_set_pc(core->rasm, addr);
502  ret = rz_analysis_op(core->analysis, &op, addr, buf + idx, len - idx,
504 
505  if (ret < 1) {
506  RZ_LOG_ERROR("Invalid instruction at 0x%08" PFMT64x "...\n", core->offset + idx);
507  break;
508  }
509  totalsize += op.size;
511  }
513  rz_cons_printf("%d\n", totalsize);
514 }
515 
516 static void core_analysis_bytes_desc(RzCore *core, const ut8 *buf, int len, int nops) {
517  core->parser->subrel = rz_config_get_i(core->config, "asm.sub.rel");
518  int ret, i, idx;
519  RzAsmOp asmop;
520  RzAnalysisOp op = { 0 };
521  ut64 addr;
522 
523  for (i = idx = 0; idx < len && (!nops || (nops && i < nops)); i++, idx += ret) {
524  addr = core->offset + idx;
525  rz_asm_set_pc(core->rasm, addr);
526  ret = rz_analysis_op(core->analysis, &op, addr, buf + idx, len - idx,
528  (void)rz_asm_disassemble(core->rasm, &asmop, buf + idx, len - idx);
529 
530  if (ret < 1) {
531  RZ_LOG_ERROR("Invalid instruction at 0x%08" PFMT64x "...\n", core->offset + idx);
532  break;
533  }
534 
535  char *opname = strdup(rz_asm_op_get_asm(&asmop));
536  if (opname) {
537  rz_str_split(opname, ' ');
538  char *d = rz_asm_describe(core->rasm, opname);
539  if (d && *d) {
540  rz_cons_printf("%s: %s\n", opname, d);
541  free(d);
542  } else {
543  RZ_LOG_ERROR("mnemonic %s has no description\n", opname);
544  }
545  free(opname);
546  }
548  }
550 }
551 
552 static void core_analysis_bytes_esil(RzCore *core, const ut8 *buf, int len, int nops) {
553  bool use_color = core->print->flags & RZ_PRINT_FLAGS_COLOR;
554  core->parser->subrel = rz_config_get_i(core->config, "asm.sub.rel");
555  int ret, i, idx;
556  const char *color = "";
557  const char *esilstr;
558  RzAnalysisEsil *esil = NULL;
559  RzAnalysisOp op = { 0 };
560  ut64 addr;
561 
562  if (use_color) {
563  color = core->cons->context->pal.label;
564  }
565  for (i = idx = 0; idx < len && (!nops || (nops && i < nops)); i++, idx += ret) {
566  addr = core->offset + idx;
567  rz_asm_set_pc(core->rasm, addr);
568  ret = rz_analysis_op(core->analysis, &op, addr, buf + idx, len - idx,
570  esilstr = RZ_STRBUF_SAFEGET(&op.esil);
571 
572  if (ret < 1) {
573  RZ_LOG_ERROR("Invalid instruction at 0x%08" PFMT64x "...\n", core->offset + idx);
574  break;
575  }
576 
577  if (RZ_STR_ISNOTEMPTY(esilstr)) {
578  if (use_color) {
579  rz_cons_printf("%s0x%" PFMT64x Color_RESET " %s\n", color, core->offset + idx, esilstr);
580  } else {
581  rz_cons_printf("0x%" PFMT64x " %s\n", core->offset + idx, esilstr);
582  }
583  }
585  }
587  rz_analysis_esil_free(esil);
588 }
589 
590 static void core_analysis_bytes_json(RzCore *core, const ut8 *buf, int len, int nops, PJ *pj) {
591  RzPVector *vec = rz_core_analysis_bytes(core, buf, len, nops);
592  if (!vec) {
593  return;
594  }
595 
596  void **iter;
597  RzAnalysisBytes *ab;
598 
599  pj_a(pj);
600  rz_pvector_foreach (vec, iter) {
601  if (!iter) {
602  break;
603  }
604  ab = *iter;
605  if (!ab || !ab->op) {
606  break;
607  }
608  RzAnalysisOp *op = ab->op;
609  const char *esilstr = RZ_STRBUF_SAFEGET(&op->esil);
610  const char *opexstr = RZ_STRBUF_SAFEGET(&op->opex);
611  RzAnalysisHint *hint = ab->hint;
612 
613  pj_o(pj);
614  PJ_KS(pj, "opcode", ab->opcode);
615  PJ_KS(pj, "disasm", ab->disasm);
616  PJ_KS(pj, "pseudo", ab->pseudo);
617  PJ_KS(pj, "description", ab->description);
618  PJ_KS(pj, "mnemonic", op->mnemonic);
619  PJ_KS(pj, "mask", ab->mask);
620 
621  if (hint) {
622  PJ_KS(pj, "ophint", hint->opcode);
623  }
624  PJ_KN(pj, "jump", op->jump);
625  PJ_KN(pj, "fail", op->fail);
626  PJ_KS(pj, "esil", (hint && hint->esil) ? hint->esil : esilstr);
627 
628  if (op->il_op) {
629  pj_k(pj, "rzil");
630  rz_il_op_effect_json(op->il_op, pj);
631  }
632  pj_kb(pj, "sign", op->sign);
633  pj_kn(pj, "prefix", op->prefix);
634  pj_ki(pj, "id", op->id);
635  if (RZ_STR_ISNOTEMPTY(opexstr)) {
636  pj_k(pj, "opex");
637  pj_j(pj, opexstr);
638  }
639  PJ_KN(pj, "addr", op->addr);
640  PJ_KS(pj, "bytes", ab->bytes);
641  PJ_KN(pj, "val", op->val);
642  PJ_KN(pj, "disp", op->disp);
643  PJ_KN(pj, "ptr", op->ptr);
644  pj_ki(pj, "size", op->size);
645  PJ_KS(pj, "type", rz_analysis_optype_to_string((int)op->type));
646  PJ_KS(pj, "datatype", rz_analysis_datatype_to_string(op->datatype));
647  if (esilstr) {
648  pj_ki(pj, "esilcost", esil_cost(core, op->addr, esilstr));
649  }
650  PJ_KS(pj, "reg", op->reg);
651  PJ_KS(pj, "ireg", op->ireg);
652  pj_ki(pj, "scale", op->scale);
653  if (op->refptr != -1) {
654  pj_ki(pj, "refptr", op->refptr);
655  }
656  pj_ki(pj, "cycles", op->cycles);
657  pj_ki(pj, "failcycles", op->failcycles);
658  pj_ki(pj, "delay", op->delay);
659  const char *p1 = rz_analysis_stackop_tostring(op->stackop);
660  if (strcmp(p1, "null") != 0) {
661  PJ_KS(pj, "stack", p1);
662  }
663  pj_kn(pj, "stackptr", op->stackptr);
664  PJ_KS(pj, "cond", (op->type & RZ_ANALYSIS_OP_TYPE_COND) ? rz_type_cond_tostring(op->cond) : NULL);
665  PJ_KS(pj, "family", rz_analysis_op_family_to_string(op->family));
666  pj_end(pj);
667  }
668 
669  pj_end(pj);
670  rz_pvector_free(vec);
671 }
672 
673 #define PRINTF_LN(k, fmt, arg) \
674  { \
675  if (use_color) \
676  rz_cons_printf("%s%s: " Color_RESET, color, k); \
677  else \
678  rz_cons_printf("%s: ", k); \
679  if (fmt) \
680  rz_cons_printf(fmt, arg); \
681  }
682 
683 #define PRINTF_LN_NOT(k, fmt, arg, notv) \
684  if ((arg) != (notv)) { \
685  PRINTF_LN(k, fmt, arg) \
686  }
687 
688 #define PRINTF_LN_STR(k, arg) \
689  { \
690  const char *value = (arg); \
691  if (RZ_STR_ISNOTEMPTY(value)) { \
692  if (use_color) \
693  rz_cons_printf("%s%s: %s\n" Color_RESET, color, k, value); \
694  else \
695  rz_cons_printf("%s: %s\n", k, value); \
696  } \
697  }
698 
699 static void core_analysis_bytes_standard(RzCore *core, const ut8 *buf, int len, int nops) {
700  RzPVector *vec = rz_core_analysis_bytes(core, buf, len, nops);
701  if (!vec) {
702  return;
703  }
704 
705  bool use_color = core->print->flags & RZ_PRINT_FLAGS_COLOR;
706  const char *color = use_color ? core->cons->context->pal.label : "";
707 
708  void **iter;
709  RzAnalysisBytes *ab;
710  rz_pvector_foreach (vec, iter) {
711  if (!(iter && *iter && ((RzAnalysisBytes *)*iter)->op)) {
712  break;
713  }
714  ab = *iter;
715  RzAnalysisOp *op = ab->op;
716  const char *esilstr = RZ_STRBUF_SAFEGET(&op->esil);
717  RzAnalysisHint *hint = ab->hint;
718 
719  PRINTF_LN("address", "0x%" PFMT64x "\n", op->addr);
720  PRINTF_LN("opcode", "%s\n", ab->opcode);
721  if (esilstr) {
722  PRINTF_LN("esilcost", "%d\n", esil_cost(core, op->addr, esilstr));
723  }
724  PRINTF_LN("disasm", "%s\n", ab->disasm);
725  PRINTF_LN_STR("pseudo", ab->pseudo);
726  PRINTF_LN("mnemonic", "%s\n", op->mnemonic);
727  PRINTF_LN_STR("description", ab->description);
728  PRINTF_LN("mask", "%s\n", ab->mask);
729  PRINTF_LN_STR("ophint", hint ? hint->opcode : NULL);
730  PRINTF_LN("prefix", "%u\n", op->prefix);
731  PRINTF_LN("id", "%d\n", op->id);
732  PRINTF_LN_STR("bytes", ab->bytes);
733  PRINTF_LN_NOT("val", "0x%08" PFMT64x "\n", op->val, UT64_MAX);
734  PRINTF_LN_NOT("ptr", "0x%08" PFMT64x "\n", op->ptr, UT64_MAX);
735  PRINTF_LN_NOT("disp", "0x%08" PFMT64x "\n", op->disp, UT64_MAX);
736  PRINTF_LN_NOT("refptr", "%d\n", op->refptr, -1);
737  PRINTF_LN("size", "%d\n", op->size);
738  PRINTF_LN_STR("sign", rz_str_bool(op->sign));
740  PRINTF_LN_STR("datatype", rz_analysis_datatype_to_string(op->datatype));
741  PRINTF_LN("cycles", "%d\n", op->cycles);
742  PRINTF_LN_NOT("failcycles", "%d\n", op->failcycles, 0);
743  PRINTF_LN_NOT("type2", "0x%x\n", op->type2, 0);
744  PRINTF_LN_STR("reg", op->reg);
745  PRINTF_LN_STR("ireg", op->ireg);
746  PRINTF_LN_NOT("scale", "%d\n", op->scale, 0);
747  PRINTF_LN_STR("esil", hint && hint->esil ? hint->esil : esilstr);
748  if (op->il_op) {
749  RzStrBuf *sbil = rz_strbuf_new("");
750  rz_il_op_effect_stringify(op->il_op, sbil);
751  PRINTF_LN_STR("rzil", rz_strbuf_get(sbil));
752  rz_strbuf_free(sbil);
753  }
754  PRINTF_LN_NOT("jump", "0x%08" PFMT64x "\n", op->jump, UT64_MAX);
755  if (op->direction != 0) {
756  const char *dir = op->direction == 1 ? "read"
757  : op->direction == 2 ? "write"
758  : op->direction == 4 ? "exec"
759  : op->direction == 8 ? "ref"
760  : "none";
761  PRINTF_LN("direction", "%s\n", dir);
762  }
763  PRINTF_LN_NOT("fail", "0x%08" PFMT64x "\n", op->fail, UT64_MAX);
764  PRINTF_LN_NOT("delay", "%d\n", op->delay, 0);
765  {
766  const char *arg = (op->type & RZ_ANALYSIS_OP_TYPE_COND) ? rz_type_cond_tostring(op->cond) : NULL;
767  PRINTF_LN_STR("cond", arg);
768  }
769  PRINTF_LN("family", "%s\n", rz_analysis_op_family_to_string(op->family));
770  PRINTF_LN_STR("stackop", op->stackop != RZ_ANALYSIS_STACK_NULL ? rz_analysis_stackop_tostring(op->stackop) : NULL);
771  PRINTF_LN_NOT("stackptr", "%" PFMT64u "\n", op->stackptr, 0);
772  }
773  rz_pvector_free(vec);
774 }
775 
776 #undef PJ_KS
777 #undef PJ_KN
778 #undef PRINTF_LN
779 #undef PRINTF_LN_NOT
780 #undef PRINTF_LN_STR
781 
782 static char *fcnjoin(RzList *list) {
784  RzListIter *iter;
785  RzStrBuf buf;
787  rz_list_foreach (list, iter, n) {
788  rz_strbuf_appendf(&buf, " 0x%08" PFMT64x, n->addr);
789  }
790  char *s = strdup(rz_strbuf_get(&buf));
792  return s;
793 }
794 
795 static char *ut64join(RzList *list) {
796  ut64 *n;
797  RzListIter *iter;
798  RzStrBuf buf;
800  rz_list_foreach (list, iter, n) {
801  rz_strbuf_appendf(&buf, " 0x%08" PFMT64x, *n);
802  }
803  char *s = strdup(rz_strbuf_get(&buf));
805  return s;
806 }
807 
808 static ut64 initializeEsil(RzCore *core) {
809  int romem = rz_config_get_i(core->config, "esil.romem");
810  int stats = rz_config_get_i(core->config, "esil.stats");
811  int iotrap = rz_config_get_i(core->config, "esil.iotrap");
812  int exectrap = rz_config_get_i(core->config, "esil.exectrap");
813  int stacksize = rz_config_get_i(core->config, "esil.stack.depth");
814  int noNULL = rz_config_get_i(core->config, "esil.noNULL");
815  unsigned int addrsize = rz_config_get_i(core->config, "esil.addr.size");
816  if (!(core->analysis->esil = rz_analysis_esil_new(stacksize, iotrap, addrsize))) {
817  return UT64_MAX;
818  }
819  ut64 addr;
820  RzAnalysisEsil *esil = core->analysis->esil;
821  esil->verbose = rz_config_get_i(core->config, "esil.verbose");
822  esil->cmd = rz_core_esil_cmd;
823  rz_analysis_esil_setup(esil, core->analysis, romem, stats, noNULL); // setup io
824  {
825  const char *cmd_esil_step = rz_config_get(core->config, "cmd.esil.step");
826  if (cmd_esil_step && *cmd_esil_step) {
827  esil->cmd_step = strdup(cmd_esil_step);
828  }
829  const char *cmd_esil_step_out = rz_config_get(core->config, "cmd.esil.stepout");
830  if (cmd_esil_step_out && *cmd_esil_step_out) {
831  esil->cmd_step_out = strdup(cmd_esil_step_out);
832  }
833  {
834  const char *s = rz_config_get(core->config, "cmd.esil.intr");
835  if (s) {
836  char *my = strdup(s);
837  if (my) {
838  rz_config_set(core->config, "cmd.esil.intr", my);
839  free(my);
840  }
841  }
842  }
843  }
844  esil->exectrap = exectrap;
846  RzBinAddr *entry = NULL;
847  RzBinInfo *info = NULL;
848  if (entries && !rz_list_empty(entries)) {
850  info = rz_bin_get_info(core->bin);
851  addr = info->has_va ? entry->vaddr : entry->paddr;
853  } else {
854  addr = core->offset;
855  }
856  // set memory read only
857  return addr;
858 }
859 
860 RZ_API int rz_core_esil_step(RzCore *core, ut64 until_addr, const char *until_expr, ut64 *prev_addr, bool stepOver) {
861 #define return_tail(x) \
862  { \
863  tail_return_value = x; \
864  goto tail_return; \
865  }
866  int tail_return_value = 0;
867  int ret;
868  ut8 code[32];
869  RzAnalysisOp op = { 0 };
870  RzAnalysisEsil *esil = core->analysis->esil;
871  const char *name = rz_reg_get_name(core->analysis->reg, RZ_REG_NAME_PC);
872  ut64 addr = 0;
873  bool breakoninvalid = rz_config_get_i(core->config, "esil.breakoninvalid");
874  int esiltimeout = rz_config_get_i(core->config, "esil.timeout");
875  ut64 startTime;
876 
877  if (esiltimeout > 0) {
878  startTime = rz_time_now_mono();
879  }
881 repeat:
882  if (rz_cons_is_breaked()) {
883  eprintf("[+] ESIL emulation interrupted at 0x%08" PFMT64x "\n", addr);
884  return_tail(0);
885  }
886  // Break if we have exceeded esil.timeout
887  if (esiltimeout > 0) {
888  ut64 elapsedTime = rz_time_now_mono() - startTime;
889  elapsedTime >>= 20;
890  if (elapsedTime >= esiltimeout) {
891  eprintf("[ESIL] Timeout exceeded.\n");
892  return_tail(0);
893  }
894  }
895  if (!esil) {
896  addr = initializeEsil(core);
897  esil = core->analysis->esil;
898  if (!esil) {
899  return_tail(0);
900  }
901  } else {
902  esil->trap = 0;
903  addr = rz_reg_getv(core->analysis->reg, name);
904  // eprintf ("PC=0x%"PFMT64x"\n", (ut64)addr);
905  }
906  if (prev_addr) {
907  *prev_addr = addr;
908  }
909  if (esil->exectrap) {
910  if (!rz_io_is_valid_offset(core->io, addr, RZ_PERM_X)) {
912  esil->trap_code = addr;
913  eprintf("[ESIL] Trap, trying to execute on non-executable memory\n");
914  return_tail(1);
915  }
916  }
917  rz_asm_set_pc(core->rasm, addr);
918  // run esil pin command here
920  if (dataAlign > 1) {
921  if (addr % dataAlign) {
922  if (esil->cmd && esil->cmd_trap) {
923  esil->cmd(esil, esil->cmd_trap, addr, RZ_ANALYSIS_TRAP_UNALIGNED);
924  }
925  if (breakoninvalid) {
926  rz_cons_printf("[ESIL] Stopped execution in an unaligned instruction (see e??esil.breakoninvalid)\n");
927  return_tail(0);
928  }
929  }
930  }
931  (void)rz_io_read_at_mapped(core->io, addr, code, sizeof(code));
932  // TODO: sometimes this is dupe
934  // if type is JMP then we execute the next N instructions
935  // update the esil pointer because RzAnalysis.op() can change it
936  esil = core->analysis->esil;
937  if (op.size < 1 || ret < 1) {
938  if (esil->cmd && esil->cmd_trap) {
939  esil->cmd(esil, esil->cmd_trap, addr, RZ_ANALYSIS_TRAP_INVALID);
940  }
941  if (breakoninvalid) {
942  eprintf("[ESIL] Stopped execution in an invalid instruction (see e??esil.breakoninvalid)\n");
943  return_tail(0);
944  }
945  op.size = 1; // avoid inverted stepping
946  }
947  if (stepOver) {
948  switch (op.type) {
959  if (addr == until_addr) {
960  return_tail(0);
961  } else {
962  rz_reg_setv(core->analysis->reg, "PC", op.addr + op.size);
963  }
964  return 1;
965  }
966  }
967  rz_reg_setv(core->analysis->reg, name, addr + op.size);
968  if (ret) {
970  const char *e = RZ_STRBUF_SAFEGET(&op.esil);
971  if (core->dbg->trace->enabled) {
972  RzReg *reg = core->dbg->reg;
973  core->dbg->reg = core->analysis->reg;
974  rz_debug_trace_op(core->dbg, &op);
975  core->dbg->reg = reg;
976  } else if (RZ_STR_ISNOTEMPTY(e)) {
977  rz_analysis_esil_parse(esil, e);
978  if (core->analysis->cur && core->analysis->cur->esil_post_loop) {
979  core->analysis->cur->esil_post_loop(esil, &op);
980  }
982  }
983  bool isNextFall = false;
984  if (op.type == RZ_ANALYSIS_OP_TYPE_CJMP) {
985  ut64 pc = rz_reg_getv(core->analysis->reg, name);
986  if (pc == addr + op.size) {
987  // do not opdelay here
988  isNextFall = true;
989  }
990  }
991  // only support 1 slot for now
992  if (op.delay && !isNextFall) {
993  ut8 code2[32];
994  ut64 naddr = addr + op.size;
995  RzAnalysisOp op2 = { 0 };
996  // emulate only 1 instruction
997  rz_analysis_esil_set_pc(esil, naddr);
998  (void)rz_io_read_at(core->io, naddr, code2, sizeof(code2));
999  // TODO: sometimes this is dupe
1000  ret = rz_analysis_op(core->analysis, &op2, naddr, code2, sizeof(code2), RZ_ANALYSIS_OP_MASK_ESIL | RZ_ANALYSIS_OP_MASK_HINT);
1001  if (ret > 0) {
1002  switch (op2.type) {
1007  // branches are illegal in a delay slot
1009  esil->trap_code = addr;
1010  eprintf("[ESIL] Trap, trying to execute a branch in a delay slot\n");
1011  return_tail(1);
1012  break;
1013  }
1014  const char *e = RZ_STRBUF_SAFEGET(&op2.esil);
1015  if (RZ_STR_ISNOTEMPTY(e)) {
1016  rz_analysis_esil_parse(esil, e);
1017  }
1018  } else {
1019  eprintf("Invalid instruction at 0x%08" PFMT64x "\n", naddr);
1020  }
1021  rz_analysis_op_fini(&op2);
1022  }
1023  tail_return_value = 1;
1024  }
1025  // esil->verbose ?
1026  // eprintf ("REPE 0x%llx %s => 0x%llx\n", addr, RZ_STRBUF_SAFEGET (&op.esil), rz_reg_getv (core->analysis->reg, "PC"));
1027 
1028  ut64 pc = rz_reg_getv(core->analysis->reg, name);
1029  if (core->analysis->pcalign > 0) {
1030  pc -= (pc % core->analysis->pcalign);
1031  rz_reg_setv(core->analysis->reg, name, pc);
1032  }
1033 
1034  st64 follow = (st64)rz_config_get_i(core->config, "dbg.follow");
1035  if (follow > 0) {
1036  ut64 pc = rz_reg_getv(core->analysis->reg, name);
1037  if ((pc < core->offset) || (pc > (core->offset + follow))) {
1038  rz_core_seek_to_register(core, "PC", false);
1039  }
1040  }
1041  // check breakpoints
1042  if (rz_bp_get_at(core->dbg->bp, pc)) {
1043  rz_cons_printf("[ESIL] hit breakpoint at 0x%" PFMT64x "\n", pc);
1044  return_tail(0);
1045  }
1046  // check addr
1047  if (until_addr != UT64_MAX) {
1048  if (pc == until_addr) {
1049  return_tail(0);
1050  }
1051  goto repeat;
1052  }
1053  // check esil
1054  if (esil && esil->trap) {
1055  if (core->analysis->esil->verbose) {
1056  eprintf("TRAP\n");
1057  }
1058  return_tail(0);
1059  }
1060  if (until_expr) {
1061  if (rz_analysis_esil_condition(core->analysis->esil, until_expr)) {
1062  if (core->analysis->esil->verbose) {
1063  eprintf("ESIL BREAK!\n");
1064  }
1065  return_tail(0);
1066  }
1067  goto repeat;
1068  }
1069 tail_return:
1072  return tail_return_value;
1073 }
1074 
1076  rz_return_val_if_fail(core->analysis->esil && core->analysis->esil->trace, -1);
1077  RzAnalysisEsil *esil = core->analysis->esil;
1078  if (esil->trace->idx > 0) {
1079  rz_analysis_esil_trace_restore(esil, esil->trace->idx - 1);
1081  return 1;
1082  }
1083  return 0;
1084 }
1085 
1087  rz_return_val_if_fail(core->analysis->esil && core->analysis->esil->trace, false);
1088  RzAnalysisEsil *esil = core->analysis->esil;
1089  if (esil->trace->idx == 0) {
1090  return true;
1091  }
1092 
1093  RzRegItem *ripc = rz_reg_get(esil->analysis->reg, "PC", -1);
1094  RzVector *vreg = ht_up_find(esil->trace->registers, ripc->offset | (ripc->arena << 16), NULL);
1095  if (!vreg) {
1096  RZ_LOG_ERROR("failed to find PC change vector\n");
1097  return false;
1098  }
1099 
1100  // Search for the nearest breakpoint in the tracepoints before the current position
1101  bool bp_found = false;
1102  int idx = 0;
1104  rz_vector_foreach_prev(vreg, reg) {
1105  if (reg->idx >= esil->trace->idx) {
1106  continue;
1107  }
1108  bp_found = rz_bp_get_in(core->dbg->bp, reg->data, RZ_PERM_X) != NULL;
1109  if (bp_found) {
1110  idx = reg->idx;
1111  eprintf("hit breakpoint at: 0x%" PFMT64x " idx: %d\n", reg->data, reg->idx);
1112  break;
1113  }
1114  }
1115 
1116  // Return to the nearest breakpoint or jump back to the first index if a breakpoint wasn't found
1118 
1120 
1121  return true;
1122 }
1123 
1125  ut64 type;
1126  PJ *pj;
1128  switch (state->mode) {
1129  case RZ_OUTPUT_MODE_JSON:
1130  pj = state->d.pj;
1131  pj_o(pj);
1133  pj_ks(pj, "program", "true");
1135  pj_ks(pj, "library", "true");
1137  pj_ks(pj, "exec", "true");
1139  pj_ks(pj, "read", "true");
1141  pj_ks(pj, "write", "true");
1143  pj_ks(pj, "flag", "true");
1145  pj_ks(pj, "func", "true");
1147  pj_ks(pj, "stack", "true");
1149  pj_ks(pj, "heap", "true");
1151  pj_ks(pj, "reg", "true");
1153  pj_ks(pj, "ascii", "true");
1155  pj_ks(pj, "sequence", "true");
1156  pj_end(pj);
1157  break;
1160  rz_cons_printf("program\n");
1162  rz_cons_printf("library\n");
1164  rz_cons_printf("exec\n");
1166  rz_cons_printf("read\n");
1168  rz_cons_printf("write\n");
1170  rz_cons_printf("flag\n");
1172  rz_cons_printf("func\n");
1174  rz_cons_printf("stack\n");
1176  rz_cons_printf("heap\n");
1178  rz_cons_printf("reg\n");
1180  rz_cons_printf("ascii\n");
1182  rz_cons_printf("sequence\n");
1183  break;
1184  default:
1186  break;
1187  }
1188 }
1189 
1190 typedef struct {
1196 } AeaStats;
1197 
1198 static void aea_stats_init(AeaStats *stats) {
1199  stats->regs = rz_list_newf(free);
1200  stats->regread = rz_list_newf(free);
1201  stats->regwrite = rz_list_newf(free);
1202  stats->regvalues = rz_list_newf(free);
1203  stats->inputregs = rz_list_newf(free);
1204 }
1205 
1206 static void aea_stats_fini(AeaStats *stats) {
1207  RZ_FREE(stats->regs);
1208  RZ_FREE(stats->regread);
1209  RZ_FREE(stats->regwrite);
1210  RZ_FREE(stats->inputregs);
1211 }
1212 
1213 static bool contains(RzList *list, const char *name) {
1214  RzListIter *iter;
1215  const char *n;
1216  rz_list_foreach (list, iter, n) {
1217  if (!strcmp(name, n))
1218  return true;
1219  }
1220  return false;
1221 }
1222 
1223 static char *oldregread = NULL;
1226 
1227 #define RZ_NEW_DUP(x) memcpy((void *)malloc(sizeof(x)), &(x), sizeof(x))
1228 typedef struct {
1230  int size;
1231 } AeaMemItem;
1232 
1233 static int mymemwrite(RzAnalysisEsil *esil, ut64 addr, const ut8 *buf, int len) {
1234  RzListIter *iter;
1235  AeaMemItem *n;
1236  rz_list_foreach (mymemxsw, iter, n) {
1237  if (addr == n->addr) {
1238  return len;
1239  }
1240  }
1241  if (!rz_io_is_valid_offset(esil->analysis->iob.io, addr, 0)) {
1242  return false;
1243  }
1244  n = RZ_NEW(AeaMemItem);
1245  if (n) {
1246  n->addr = addr;
1247  n->size = len;
1249  }
1250  return len;
1251 }
1252 
1253 static int mymemread(RzAnalysisEsil *esil, ut64 addr, ut8 *buf, int len) {
1254  RzListIter *iter;
1255  AeaMemItem *n;
1256  rz_list_foreach (mymemxsr, iter, n) {
1257  if (addr == n->addr) {
1258  return len;
1259  }
1260  }
1261  if (!rz_io_is_valid_offset(esil->analysis->iob.io, addr, 0)) {
1262  return false;
1263  }
1264  n = RZ_NEW(AeaMemItem);
1265  if (n) {
1266  n->addr = addr;
1267  n->size = len;
1269  }
1270  return len;
1271 }
1272 
1273 static int myregwrite(RzAnalysisEsil *esil, const char *name, ut64 *val) {
1274  AeaStats *stats = esil->user;
1275  if (oldregread && !strcmp(name, oldregread)) {
1276  rz_list_pop(stats->regread);
1278  }
1279  if (!IS_DIGIT(*name)) {
1280  if (!contains(stats->regs, name)) {
1281  rz_list_push(stats->regs, strdup(name));
1282  }
1283  if (!contains(stats->regwrite, name)) {
1284  rz_list_push(stats->regwrite, strdup(name));
1285  }
1286  char *v = rz_str_newf("%" PFMT64d, *val);
1287  if (!contains(stats->regvalues, v)) {
1288  rz_list_push(stats->regvalues, strdup(v));
1289  }
1290  free(v);
1291  }
1292  return 0;
1293 }
1294 
1295 static int myregread(RzAnalysisEsil *esil, const char *name, ut64 *val, int *len) {
1296  AeaStats *stats = esil->user;
1297  if (!IS_DIGIT(*name)) {
1298  if (!contains(stats->inputregs, name)) {
1299  if (!contains(stats->regwrite, name)) {
1300  rz_list_push(stats->inputregs, strdup(name));
1301  }
1302  }
1303  if (!contains(stats->regs, name)) {
1304  rz_list_push(stats->regs, strdup(name));
1305  }
1306  if (!contains(stats->regread, name)) {
1307  rz_list_push(stats->regread, strdup(name));
1308  }
1309  }
1310  return 0;
1311 }
1312 
1313 static void showregs(RzList *list) {
1314  if (!rz_list_empty(list)) {
1315  char *reg;
1316  RzListIter *iter;
1317  rz_list_foreach (list, iter, reg) {
1318  rz_cons_print(reg);
1319  if (iter->n) {
1320  rz_cons_printf(" ");
1321  }
1322  }
1323  }
1324  rz_cons_newline();
1325 }
1326 
1327 static void showmem(RzList *list) {
1328  if (!rz_list_empty(list)) {
1329  AeaMemItem *item;
1330  RzListIter *iter;
1331  rz_list_foreach (list, iter, item) {
1332  rz_cons_printf(" 0x%08" PFMT64x, item->addr);
1333  }
1334  }
1335  rz_cons_newline();
1336 }
1337 
1338 static void showregs_json(RzList *list, PJ *pj) {
1339  pj_a(pj);
1340  if (!rz_list_empty(list)) {
1341  char *reg;
1342  RzListIter *iter;
1343 
1344  rz_list_foreach (list, iter, reg) {
1345  pj_s(pj, reg);
1346  }
1347  }
1348  pj_end(pj);
1349 }
1350 
1351 static void showmem_json(RzList *list, PJ *pj) {
1352  pj_a(pj);
1353  if (!rz_list_empty(list)) {
1354  RzListIter *iter;
1355  AeaMemItem *item;
1356  rz_list_foreach (list, iter, item) {
1357  pj_n(pj, item->addr);
1358  }
1359  }
1360 
1361  pj_end(pj);
1362 }
1363 
1364 static bool cmd_aea(RzCore *core, int mode, ut64 addr, int length) {
1365  RzAnalysisEsil *esil;
1366  int ptr, ops, ops_end = 0, len, buf_sz, maxopsize;
1367  ut64 addr_end;
1368  AeaStats stats;
1369  const char *esilstr;
1370  RzAnalysisOp aop = RZ_EMPTY;
1371  ut8 *buf;
1372  RzList *regnow;
1373  PJ *pj = NULL;
1374  if (!core) {
1375  return false;
1376  }
1378  if (maxopsize < 1) {
1379  maxopsize = 16;
1380  }
1381  if (mode & 1) {
1382  // number of bytes / length
1383  buf_sz = length;
1384  } else {
1385  // number of instructions / opcodes
1386  ops_end = length;
1387  if (ops_end < 1) {
1388  ops_end = 1;
1389  }
1390  buf_sz = ops_end * maxopsize;
1391  }
1392  if (buf_sz < 1) {
1393  buf_sz = maxopsize;
1394  }
1395  addr_end = addr + buf_sz;
1396  buf = malloc(buf_sz);
1397  if (!buf) {
1398  return false;
1399  }
1400  (void)rz_io_read_at(core->io, addr, (ut8 *)buf, buf_sz);
1401  aea_stats_init(&stats);
1402 
1403  // esil_init (core);
1404  // esil = core->analysis->esil;
1405  rz_reg_arena_push(core->analysis->reg);
1406  int stacksize = rz_config_get_i(core->config, "esil.stack.depth");
1407  bool iotrap = rz_config_get_i(core->config, "esil.iotrap");
1408  int romem = rz_config_get_i(core->config, "esil.romem");
1409  int stats1 = rz_config_get_i(core->config, "esil.stats");
1410  int noNULL = rz_config_get_i(core->config, "esil.noNULL");
1411  unsigned int addrsize = rz_config_get_i(core->config, "esil.addr.size");
1412  esil = rz_analysis_esil_new(stacksize, iotrap, addrsize);
1413  rz_analysis_esil_setup(esil, core->analysis, romem, stats1, noNULL); // setup io
1414 #define hasNext(x) (x & 1) ? (addr < addr_end) : (ops < ops_end)
1415 
1416  mymemxsr = rz_list_new();
1417  mymemxsw = rz_list_new();
1418  esil->user = &stats;
1419  esil->cb.hook_reg_write = myregwrite;
1420  esil->cb.hook_reg_read = myregread;
1421  esil->cb.hook_mem_write = mymemwrite;
1422  esil->cb.hook_mem_read = mymemread;
1423  esil->nowrite = true;
1424  for (ops = ptr = 0; ptr < buf_sz && hasNext(mode); ops++, ptr += len) {
1425  len = rz_analysis_op(core->analysis, &aop, addr + ptr, buf + ptr, buf_sz - ptr, RZ_ANALYSIS_OP_MASK_ESIL | RZ_ANALYSIS_OP_MASK_HINT);
1426  esilstr = RZ_STRBUF_SAFEGET(&aop.esil);
1427  if (RZ_STR_ISNOTEMPTY(esilstr)) {
1428  if (len < 1) {
1429  eprintf("Invalid 0x%08" PFMT64x " instruction %02x %02x\n",
1430  addr + ptr, buf[ptr], buf[ptr + 1]);
1431  break;
1432  }
1433  rz_analysis_esil_parse(esil, esilstr);
1435  }
1436  rz_analysis_op_fini(&aop);
1437  }
1438  esil->nowrite = false;
1439  esil->cb.hook_reg_write = NULL;
1440  esil->cb.hook_reg_read = NULL;
1441  // esil_fini (core);
1442  rz_analysis_esil_free(esil);
1443  rz_reg_arena_pop(core->analysis->reg);
1444  regnow = rz_list_newf(free);
1445  {
1446  RzListIter *iter;
1447  char *reg;
1448  rz_list_foreach (stats.regs, iter, reg) {
1449  if (!contains(stats.regwrite, reg)) {
1450  rz_list_push(regnow, strdup(reg));
1451  }
1452  }
1453  }
1454  if ((mode >> 5) & 1) {
1455  RzListIter *iter;
1456  AeaMemItem *n;
1457  int c = 0;
1458  rz_cons_printf("f-mem.*\n");
1459  rz_list_foreach (mymemxsr, iter, n) {
1460  rz_cons_printf("f mem.read.%d 0x%08x @ 0x%08" PFMT64x "\n", c++, n->size, n->addr);
1461  }
1462  c = 0;
1463  rz_list_foreach (mymemxsw, iter, n) {
1464  rz_cons_printf("f mem.write.%d 0x%08x @ 0x%08" PFMT64x "\n", c++, n->size, n->addr);
1465  }
1466  }
1467 
1468  /* show registers used */
1469  if ((mode >> 1) & 1) {
1470  showregs(stats.regread);
1471  } else if ((mode >> 2) & 1) {
1472  showregs(stats.regwrite);
1473  } else if ((mode >> 3) & 1) {
1474  showregs(regnow);
1475  } else if ((mode >> 4) & 1) {
1476  pj = pj_new();
1477  if (!pj) {
1478  return false;
1479  }
1480  pj_o(pj);
1481  pj_k(pj, "A");
1482  showregs_json(stats.regs, pj);
1483  pj_k(pj, "I");
1484  showregs_json(stats.inputregs, pj);
1485  pj_k(pj, "R");
1486  showregs_json(stats.regread, pj);
1487  pj_k(pj, "W");
1488  showregs_json(stats.regwrite, pj);
1489  if (!rz_list_empty(stats.regvalues)) {
1490  pj_k(pj, "V");
1491  showregs_json(stats.regvalues, pj);
1492  }
1493  if (!rz_list_empty(regnow)) {
1494  pj_k(pj, "N");
1495  showregs_json(regnow, pj);
1496  }
1497  if (!rz_list_empty(mymemxsr)) {
1498  pj_k(pj, "@R");
1499  showmem_json(mymemxsr, pj);
1500  }
1501  if (!rz_list_empty(mymemxsw)) {
1502  pj_k(pj, "@W");
1503  showmem_json(mymemxsw, pj);
1504  }
1505 
1506  pj_end(pj);
1508  pj_free(pj);
1509  } else if ((mode >> 5) & 1) {
1510  // nothing
1511  } else {
1512  if (!rz_list_empty(stats.inputregs)) {
1513  rz_cons_printf(" I: ");
1514  showregs(stats.inputregs);
1515  }
1516  if (!rz_list_empty(stats.regs)) {
1517  rz_cons_printf(" A: ");
1518  showregs(stats.regs);
1519  }
1520  if (!rz_list_empty(stats.regread)) {
1521  rz_cons_printf(" R: ");
1522  showregs(stats.regread);
1523  }
1524  if (!rz_list_empty(stats.regwrite)) {
1525  rz_cons_printf(" W: ");
1526  showregs(stats.regwrite);
1527  }
1528  if (!rz_list_empty(stats.regvalues)) {
1529  rz_cons_printf(" V: ");
1530  showregs(stats.regvalues);
1531  }
1532  if (!rz_list_empty(regnow)) {
1533  rz_cons_printf(" N: ");
1534  showregs(regnow);
1535  }
1536  if (!rz_list_empty(mymemxsr)) {
1537  rz_cons_printf("@R:");
1538  showmem(mymemxsr);
1539  }
1540  if (!rz_list_empty(mymemxsw)) {
1541  rz_cons_printf("@W:");
1542  showmem(mymemxsw);
1543  }
1544  }
1545 
1548  mymemxsr = NULL;
1549  mymemxsw = NULL;
1550  aea_stats_fini(&stats);
1551  free(buf);
1552  RZ_FREE(regnow);
1553  return true;
1554 }
1555 
1556 // aeC
1558  for (int i = 1; i < argc; ++i) {
1559  const char *alias = rz_str_newf("A%d", i - 1);
1560  rz_reg_setv(core->analysis->reg, alias, rz_num_math(core->num, argv[i]));
1561  }
1562 
1563  ut64 sp = rz_reg_getv(core->analysis->reg, "SP");
1564  rz_reg_setv(core->analysis->reg, "SP", 0);
1565 
1566  rz_reg_setv(core->analysis->reg, "PC", core->offset);
1567  rz_core_esil_step(core, 0, NULL, NULL, false);
1569 
1570  rz_reg_setv(core->analysis->reg, "SP", sp);
1571  return RZ_CMD_STATUS_OK;
1572 }
1573 
1574 // aec
1576  rz_core_esil_step(core, UT64_MAX, "0", NULL, false);
1578  return RZ_CMD_STATUS_OK;
1579 }
1580 
1581 // aecb
1583  if (!rz_core_esil_continue_back(core)) {
1584  RZ_LOG_ERROR("cannot continue back\n");
1585  return RZ_CMD_STATUS_ERROR;
1586  }
1588  return RZ_CMD_STATUS_OK;
1589 }
1590 
1591 // aecs
1594 }
1595 
1596 // aecc
1599 }
1600 
1601 // aecu
1603  rz_core_esil_step(core, rz_num_math(core->num, argv[1]), NULL, NULL, false);
1605  return RZ_CMD_STATUS_OK;
1606 }
1607 
1608 // aecue
1610  rz_core_esil_step(core, UT64_MAX, argv[1], NULL, false);
1612  return RZ_CMD_STATUS_OK;
1613 }
1614 
1615 // aei
1618  return RZ_CMD_STATUS_OK;
1619 }
1620 
1621 // aei-
1624  return RZ_CMD_STATUS_OK;
1625 }
1626 
1627 // aeip
1629  rz_core_analysis_set_reg(core, "PC", core->offset);
1630  return RZ_CMD_STATUS_OK;
1631 }
1632 
1633 // aeim
1635  ut64 addr = argc > 1 ? rz_num_math(core->num, argv[1]) : UT64_MAX;
1636  ut32 size = argc > 2 ? (ut32)rz_num_math(core->num, argv[2]) : UT32_MAX;
1637  const char *name = argc > 3 ? argv[3] : NULL;
1639  return RZ_CMD_STATUS_OK;
1640 }
1641 
1642 // aeim-
1644  ut64 addr = argc > 1 ? rz_num_math(core->num, argv[1]) : UT64_MAX;
1645  ut32 size = argc > 2 ? (ut32)rz_num_math(core->num, argv[2]) : UT32_MAX;
1646  const char *name = argc > 3 ? argv[3] : NULL;
1648  return RZ_CMD_STATUS_OK;
1649 }
1650 
1651 // aeimp
1654  return RZ_CMD_STATUS_OK;
1655 }
1656 
1657 // aes
1658 RZ_IPI RzCmdStatus rz_il_step_handler(RzCore *core, int argc, const char **argv) {
1659  if (argc <= 1) {
1660  rz_core_esil_step(core, UT64_MAX, NULL, NULL, false);
1662  } else if (argc == 2) {
1663  int n = (int)rz_num_math(core->num, argv[1]);
1664  rz_core_analysis_esil_emulate(core, -1, -1, n);
1665  }
1666  return RZ_CMD_STATUS_OK;
1667 }
1668 
1669 // aesp
1671  int n = (int)rz_num_math(core->num, argv[1]);
1672  rz_core_analysis_esil_emulate(core, core->offset, -1, n);
1673  return RZ_CMD_STATUS_OK;
1674 }
1675 
1676 // aesb
1677 RZ_IPI RzCmdStatus rz_il_step_back_handler(RzCore *core, int argc, const char **argv) {
1678  if (!rz_core_esil_step_back(core)) {
1679  RZ_LOG_ERROR("cannot step back\n");
1680  return RZ_CMD_STATUS_ERROR;
1681  }
1683  return RZ_CMD_STATUS_OK;
1684 }
1685 
1686 // aeso
1687 RZ_IPI RzCmdStatus rz_il_step_over_handler(RzCore *core, int argc, const char **argv) {
1689  return RZ_CMD_STATUS_OK;
1690 }
1691 
1692 // aesou
1694  ut64 until_addr = rz_num_math(core->num, argv[1]);
1695  rz_core_analysis_esil_step_over_until(core, until_addr);
1696  return RZ_CMD_STATUS_OK;
1697 }
1698 
1699 // aess
1700 RZ_IPI RzCmdStatus rz_il_step_skip_handler(RzCore *core, int argc, const char **argv) {
1702  return RZ_CMD_STATUS_OK;
1703 }
1704 
1705 // aessu
1707  ut64 until_addr = rz_num_math(core->num, argv[1]);
1708  rz_core_analysis_esil_step_over_until(core, until_addr);
1709  return RZ_CMD_STATUS_OK;
1710 }
1711 
1712 // aessue
1715  return RZ_CMD_STATUS_OK;
1716 }
1717 
1718 // aesu
1720  ut64 until_addr = rz_num_math(core->num, argv[1]);
1721  rz_core_esil_step(core, until_addr, NULL, NULL, false);
1723  return RZ_CMD_STATUS_OK;
1724 }
1725 
1726 // aesue
1730  return RZ_CMD_STATUS_OK;
1731 }
1732 
1733 // aesuo
1735  RzList *optypes_list = rz_list_new_from_array((const void **)&argv[1], argc - 1);
1736  step_until_optype(core, optypes_list);
1737  rz_list_free(optypes_list);
1739  return RZ_CMD_STATUS_OK;
1740 }
1741 
1742 // aets+
1743 RZ_IPI RzCmdStatus rz_il_trace_start_handler(RzCore *core, int argc, const char **argv) {
1745 }
1746 
1747 // aets-
1748 RZ_IPI RzCmdStatus rz_il_trace_stop_handler(RzCore *core, int argc, const char **argv) {
1750 }
1751 
1752 static const char _handler_no_name[] = "<no name>";
1753 static bool _aeli_iter(void *user, const ut64 key, const void *value) {
1754  const RzAnalysisEsilInterrupt *interrupt = value;
1755  rz_cons_printf("%3" PFMT64x ": %s\n", key, interrupt->handler->name ? interrupt->handler->name : _handler_no_name);
1756  return true;
1757 }
1758 
1759 static void rz_analysis_aefa(RzCore *core, const char *arg) {
1760  ut64 to = rz_num_math(core->num, arg);
1761  ut64 at, from = core->offset;
1763  if (!from || from == UT64_MAX) {
1764  if (fcn) {
1765  from = fcn->addr;
1766  } else {
1767  eprintf("Usage: aefa [from] # if no from address is given, uses fcn.addr\n");
1768  return;
1769  }
1770  }
1771  eprintf("Emulate from 0x%08" PFMT64x " to 0x%08" PFMT64x "\n", from, to);
1772  eprintf("Resolve call args for 0x%08" PFMT64x "\n", to);
1773 
1774  // emulate
1776  ut64 off = core->offset;
1777  for (at = from; at < to; at++) {
1778  rz_core_analysis_set_reg(core, "PC", at);
1780  rz_core_seek(core, at, true);
1781  int delta = rz_num_get(core->num, "$l");
1782  if (delta < 1) {
1783  break;
1784  }
1785  at += delta - 1;
1786  }
1787  rz_core_seek(core, off, true);
1788 
1789  // the logic of identifying args by function types and
1790  // show json format and arg name goes into arA
1791  rz_core_cmd0(core, "arA");
1792 }
1793 
1795  rz_return_val_if_fail(esil, false);
1796  int i;
1797  if (esil->trap) {
1798  rz_cons_printf("ESIL TRAP type %d code 0x%08x %s\n",
1799  esil->trap, esil->trap_code,
1801  }
1802  if (esil->stackptr < 1) {
1803  return false;
1804  }
1805  for (i = esil->stackptr - 1; i >= 0; i--) {
1806  rz_cons_printf("%s\n", esil->stack[i]);
1807  }
1808  return true;
1809 }
1810 
1812  RzListIter *iter;
1813  RzAnalysisBlock *bb;
1814  if (!core->analysis->esil) {
1816  }
1819  if (fcn) {
1820  // emulate every instruction in the function recursively across all the basic blocks
1821  rz_list_foreach (fcn->bbs, iter, bb) {
1822  ut64 pc = bb->addr;
1823  ut64 end = bb->addr + bb->size;
1824  RzAnalysisOp op;
1825  int ret, bbs = end - pc;
1826  if (bbs < 1 || bbs > 0xfffff || pc >= end) {
1827  eprintf("Invalid block size\n");
1828  continue;
1829  }
1830  // eprintf ("[*] Emulating 0x%08"PFMT64x" basic block 0x%08" PFMT64x " - 0x%08" PFMT64x "\r[", fcn->addr, pc, end);
1831  ut8 *buf = calloc(1, bbs + 1);
1832  if (!buf) {
1833  break;
1834  }
1835  rz_io_read_at(core->io, pc, buf, bbs);
1836  int left;
1837  bool opskip;
1838  while (pc < end) {
1839  left = RZ_MIN(end - pc, 32);
1840  // rz_asm_set_pc (core->rasm, pc);
1841  ret = rz_analysis_op(core->analysis, &op, pc, buf + pc - bb->addr, left, RZ_ANALYSIS_OP_MASK_HINT | RZ_ANALYSIS_OP_MASK_ESIL); // read overflow
1842  opskip = false;
1843  switch (op.type) {
1846  opskip = true;
1847  break;
1848  }
1849  if (ret > 0) {
1850  if (opskip) {
1855  }
1856  pc += op.size;
1857  } else {
1858  pc += 4; // XXX
1859  }
1861  }
1862  free(buf);
1863  }
1864  } else {
1865  eprintf("Cannot find function at 0x%08" PFMT64x "\n", addr);
1866  }
1868 }
1869 
1870 static void cmd_analysis_esil(RzCore *core, const char *input) {
1871  RzAnalysisEsil *esil = core->analysis->esil;
1872  int stacksize = rz_config_get_i(core->config, "esil.stack.depth");
1873  int iotrap = rz_config_get_i(core->config, "esil.iotrap");
1874  int romem = rz_config_get_i(core->config, "esil.romem");
1875  int stats = rz_config_get_i(core->config, "esil.stats");
1876  int noNULL = rz_config_get_i(core->config, "esil.noNULL");
1877  unsigned int addrsize = rz_config_get_i(core->config, "esil.addr.size");
1878 
1879  switch (input[0]) {
1880  case 'p':
1881  switch (input[1]) {
1882  case 'c': // "aepc"
1883  if (input[2] == ' ' || input[2] == '=') {
1884  // seek to this address
1885  ut64 pc_val = rz_num_math(core->num, rz_str_trim_head_ro(input + 3));
1886  rz_core_analysis_set_reg(core, "PC", pc_val);
1887  } else {
1888  eprintf("Missing argument\n");
1889  }
1890  break;
1891  default:
1893  break;
1894  }
1895  break;
1896  case '*': // "ae*"
1897  // XXX: this is wip, not working atm
1898  if (core->analysis->esil) {
1899  rz_cons_printf("trap: %d\n", core->analysis->esil->trap);
1900  rz_cons_printf("trap-code: %d\n", core->analysis->esil->trap_code);
1901  } else {
1902  eprintf("esil vm not initialized. run `aei`\n");
1903  }
1904  break;
1905  case ' ': // "ae "
1906  // rz_analysis_esil_eval (core->analysis, input+1);
1907  if (!esil && !(core->analysis->esil = esil = rz_analysis_esil_new(stacksize, iotrap, addrsize))) {
1908  return;
1909  }
1910  rz_analysis_esil_setup(esil, core->analysis, romem, stats, noNULL); // setup io
1911  rz_analysis_esil_set_pc(esil, core->offset);
1912  rz_analysis_esil_parse(esil, input + 1);
1913  rz_core_esil_dumpstack(esil);
1915  break;
1916  case 'k': // "aek"
1917  switch (input[1]) {
1918  case '\0': // "aek"
1919  input = "123*";
1920  /* fall through */
1921  case ' ': // "aek "
1922  if (esil && esil->stats) {
1923  char *out = sdb_querys(esil->stats, NULL, 0, input + 2);
1924  if (out) {
1926  free(out);
1927  }
1928  } else {
1929  eprintf("esil.stats is empty. Run 'aei'\n");
1930  }
1931  break;
1932  case '-': // "aek-"
1933  if (esil) {
1934  sdb_reset(esil->stats);
1935  }
1936  break;
1937  }
1938  break;
1939  case 'l': // ael commands
1940  switch (input[1]) {
1941  case 'i': // aeli interrupts
1942  switch (input[2]) {
1943  case ' ': // "aeli" with arguments
1945  eprintf("Failed to load interrupts from '%s'.", input + 3);
1946  }
1947  break;
1948  case 0: // "aeli" with no args
1949  if (esil && esil->interrupts) {
1950  ht_up_foreach(esil->interrupts, _aeli_iter, NULL);
1951  }
1952  break;
1953  case 'r': // "aelir"
1954  if (esil && esil->interrupts) {
1955  ht_up_delete(esil->interrupts, rz_num_math(core->num, input + 3));
1956  }
1957  break;
1958  }
1959  }
1960  break;
1961  case 'b': // "aeb"
1963  break;
1964  case 'f': // "aef"
1965  if (input[1] == 'a') { // "aefa"
1967  } else { // This should be aefb -> because its emulating all the bbs
1968  __analysis_esil_function(core, core->offset);
1969  }
1970  break;
1971  case 'A': // "aeA"
1972  if (input[1] == '?') {
1974  } else if (input[1] == 'r') {
1975  cmd_aea(core, 1 + (1 << 1), core->offset, rz_num_math(core->num, input + 2));
1976  } else if (input[1] == 'w') {
1977  cmd_aea(core, 1 + (1 << 2), core->offset, rz_num_math(core->num, input + 2));
1978  } else if (input[1] == 'n') {
1979  cmd_aea(core, 1 + (1 << 3), core->offset, rz_num_math(core->num, input + 2));
1980  } else if (input[1] == 'j') {
1981  cmd_aea(core, 1 + (1 << 4), core->offset, rz_num_math(core->num, input + 2));
1982  } else if (input[1] == '*') {
1983  cmd_aea(core, 1 + (1 << 5), core->offset, rz_num_math(core->num, input + 2));
1984  } else if (input[1] == 'f') {
1985  RzAnalysisFunction *fcn = rz_analysis_get_fcn_in(core->analysis, core->offset, -1);
1986  if (fcn) {
1988  }
1989  } else {
1990  cmd_aea(core, 1, core->offset, (int)rz_num_math(core->num, input + 2));
1991  }
1992  break;
1993  case 'a': // "aea"
1994  {
1995  RzReg *reg = core->analysis->reg;
1996  ut64 pc = rz_reg_getv(reg, "PC");
1997  RzAnalysisOp *op = rz_core_analysis_op(core, pc, 0);
1998  if (!op) {
1999  break;
2000  }
2001  ut64 newPC = core->offset + op->size;
2002  rz_reg_setv(reg, "PC", newPC);
2003  if (input[1] == '?') {
2005  } else if (input[1] == 'r') {
2006  cmd_aea(core, 1 << 1, core->offset, rz_num_math(core->num, input + 2));
2007  } else if (input[1] == 'w') {
2008  cmd_aea(core, 1 << 2, core->offset, rz_num_math(core->num, input + 2));
2009  } else if (input[1] == 'n') {
2010  cmd_aea(core, 1 << 3, core->offset, rz_num_math(core->num, input + 2));
2011  } else if (input[1] == 'j') {
2012  cmd_aea(core, 1 << 4, core->offset, rz_num_math(core->num, input + 2));
2013  } else if (input[1] == '*') {
2014  cmd_aea(core, 1 << 5, core->offset, rz_num_math(core->num, input + 2));
2015  } else if (input[1] == 'b') { // "aeab"
2016  bool json = input[2] == 'j';
2017  int a = json ? 3 : 2;
2018  ut64 addr = (input[a] == ' ') ? rz_num_math(core->num, input + a) : core->offset;
2020  RzAnalysisBlock *b;
2021  RzListIter *iter;
2022  rz_list_foreach (l, iter, b) {
2023  int mode = json ? (1 << 4) : 1;
2024  cmd_aea(core, mode, b->addr, b->size);
2025  break;
2026  }
2027  } else if (input[1] == 'f') {
2028  RzAnalysisFunction *fcn = rz_analysis_get_fcn_in(core->analysis, core->offset, -1);
2029  // "aeafj"
2030  if (fcn) {
2031  switch (input[2]) {
2032  case 'j': // "aeafj"
2034  break;
2035  default:
2037  break;
2038  }
2039  break;
2040  }
2041  } else if (input[1] == 'b') { // "aeab"
2043  if (bb) {
2044  switch (input[2]) {
2045  case 'j': // "aeabj"
2046  cmd_aea(core, 1 << 4, bb->addr, bb->size);
2047  break;
2048  default:
2049  cmd_aea(core, 1, bb->addr, bb->size);
2050  break;
2051  }
2052  }
2053  } else {
2054  const char *arg = input[1] ? input + 2 : "";
2055  ut64 len = rz_num_math(core->num, arg);
2056  cmd_aea(core, 0, core->offset, len);
2057  }
2058  rz_reg_setv(reg, "PC", pc);
2059  } break;
2060  case 'x': { // "aex"
2061  char *hex;
2062  int ret, bufsz;
2063 
2065  hex = strdup(input);
2066  if (!hex) {
2067  break;
2068  }
2069 
2070  RzAnalysisOp aop = RZ_EMPTY;
2071  bufsz = rz_hex_str2bin(hex, (ut8 *)hex);
2072  ret = rz_analysis_op(core->analysis, &aop, core->offset,
2073  (const ut8 *)hex, bufsz, RZ_ANALYSIS_OP_MASK_ESIL);
2074  if (ret > 0) {
2075  const char *str = RZ_STRBUF_SAFEGET(&aop.esil);
2076  char *str2 = rz_str_newf(" %s", str);
2077  cmd_analysis_esil(core, str2);
2078  free(str2);
2079  }
2080  rz_analysis_op_fini(&aop);
2081  break;
2082  }
2083  case '?': // "ae?"
2084  if (input[1] == '?') {
2086  break;
2087  }
2088  /* fallthrough */
2089  default:
2091  break;
2092  }
2093 }
2094 
2096  int bufi = 0, minop = 1; // 4
2097  ut8 *buf = NULL;
2098  RzAnalysisOp op = { 0 };
2099  ut64 addr = core->offset, addr_end = 0;
2100 
2101  if (n_bytes > 0xffffff) {
2102  RZ_LOG_ERROR("number of bytes is too big (> 0xffffff)\n");
2103  return false;
2104  }
2105 
2106  RzBinFile *bf = rz_bin_cur(core->bin);
2107  if (!bf) {
2108  return false;
2109  }
2110 
2111  if (!n_bytes) {
2112  // ignore search.in to avoid problems. analysis != search
2113  RzIOMap *map = rz_io_map_get(core->io, addr);
2114  if (map && (map->perm & RZ_PERM_X)) {
2115  // search in current section
2116  if (map->itv.size > bf->size) {
2117  addr = map->itv.addr;
2118  if (bf->size > map->delta) {
2119  n_bytes = bf->size - map->delta;
2120  } else {
2121  RZ_LOG_ERROR("aaT: binary size is smaller than map delta\n");
2122  return false;
2123  }
2124  } else {
2125  addr = map->itv.addr;
2126  n_bytes = map->itv.size;
2127  }
2128  } else {
2129  if (map && map->itv.addr != map->delta && bf->size > (core->offset - map->itv.addr + map->delta)) {
2130  n_bytes = bf->size - (core->offset - map->itv.addr + map->delta);
2131  } else {
2132  if (bf->size > core->offset) {
2133  n_bytes = bf->size - core->offset;
2134  } else {
2135  RZ_LOG_ERROR("aaT: found an invalid range where binary size > current offset\n");
2136  return false;
2137  }
2138  }
2139  }
2140  }
2141 
2142  addr_end = addr + n_bytes;
2143  if (!(buf = malloc(4096))) {
2144  RZ_LOG_ERROR("aaT: cannot allocate buffer\n");
2145  return false;
2146  }
2147 
2148  bufi = 0;
2149  int trapcount = 0;
2150  int nopcount = 0;
2152  while (addr < addr_end) {
2153  if (rz_cons_is_breaked()) {
2154  break;
2155  }
2156  // TODO: too many ioreads here
2157  if (bufi > 4000) {
2158  bufi = 0;
2159  }
2160  if (!bufi) {
2161  rz_io_read_at(core->io, addr, buf, 4096);
2162  }
2163  if (rz_analysis_op(core->analysis, &op, addr, buf + bufi, 4096 - bufi, RZ_ANALYSIS_OP_MASK_BASIC) > 0) {
2164  if (op.size < 1) {
2165  // XXX must be +4 on arm/mips/.. like we do in disasm.c
2166  op.size = minop;
2167  }
2168  if (op.type == RZ_ANALYSIS_OP_TYPE_TRAP) {
2169  trapcount++;
2170  } else if (op.type == RZ_ANALYSIS_OP_TYPE_NOP) {
2171  nopcount++;
2172  } else {
2173  if (nopcount > 1) {
2174  rz_cons_printf("af @ 0x%08" PFMT64x "\n", addr);
2175  nopcount = 0;
2176  }
2177  if (trapcount > 0) {
2178  rz_cons_printf("af @ 0x%08" PFMT64x "\n", addr);
2179  trapcount = 0;
2180  }
2181  }
2182  } else {
2183  op.size = minop;
2184  }
2185  addr += (op.size > 0) ? op.size : 1;
2186  bufi += (op.size > 0) ? op.size : 1;
2188  }
2190  free(buf);
2191  return true;
2192 }
2193 
2194 static void _analysis_calls(RzCore *core, ut64 addr, ut64 addr_end, bool importsOnly) {
2195  RzAnalysisOp op;
2196  int depth = rz_config_get_i(core->config, "analysis.depth");
2197  const int addrbytes = core->io->addrbytes;
2198  const int bsz = 4096;
2199  int bufi = 0;
2200  int bufi_max = bsz - 16;
2201  if (addr_end - addr > UT32_MAX) {
2202  return;
2203  }
2204  ut8 *buf = malloc(bsz);
2205  ut8 *block0 = calloc(1, bsz);
2206  ut8 *block1 = malloc(bsz);
2207  if (!buf || !block0 || !block1) {
2208  eprintf("Error: cannot allocate buf or block\n");
2209  free(buf);
2210  free(block0);
2211  free(block1);
2212  return;
2213  }
2214  memset(block1, -1, bsz);
2216  if (minop < 1) {
2217  minop = 1;
2218  }
2219  int setBits = rz_config_get_i(core->config, "asm.bits");
2221  while (addr < addr_end && !rz_cons_is_breaked()) {
2222  // TODO: too many ioreads here
2223  if (bufi > bufi_max) {
2224  bufi = 0;
2225  }
2226  if (!bufi) {
2227  (void)rz_io_read_at(core->io, addr, buf, bsz);
2228  }
2229  if (!memcmp(buf, block0, bsz) || !memcmp(buf, block1, bsz)) {
2230  // eprintf ("Error: skipping uninitialized block \n");
2231  addr += bsz;
2232  continue;
2233  }
2235  if (hint && hint->bits) {
2236  setBits = hint->bits;
2237  }
2238  rz_analysis_hint_free(hint);
2239  if (setBits != core->rasm->bits) {
2240  rz_config_set_i(core->config, "asm.bits", setBits);
2241  }
2242  if (rz_analysis_op(core->analysis, &op, addr, buf + bufi, bsz - bufi, 0) > 0) {
2243  if (op.size < 1) {
2244  op.size = minop;
2245  }
2246  if (op.type == RZ_ANALYSIS_OP_TYPE_CALL) {
2247  bool isValidCall = true;
2248  if (importsOnly) {
2249  RzFlagItem *f = rz_flag_get_i(core->flags, op.jump);
2250  if (!f || !strstr(f->name, "imp.")) {
2251  isValidCall = false;
2252  }
2253  }
2254  RzBinReloc *rel = rz_core_getreloc(core, addr, op.size);
2255  if (rel && (rel->import || rel->symbol)) {
2256  isValidCall = false;
2257  }
2258  if (isValidCall) {
2259  ut8 buf[4];
2260  rz_io_read_at(core->io, op.jump, buf, 4);
2261  isValidCall = memcmp(buf, "\x00\x00\x00\x00", 4);
2262  }
2263  if (isValidCall) {
2264  // add xref here
2266  if (rz_io_is_valid_offset(core->io, op.jump, 1)) {
2268  }
2269  }
2270  }
2271  } else {
2272  op.size = minop;
2273  }
2274  if ((int)op.size < 1) {
2275  op.size = minop;
2276  }
2277  addr += op.size;
2278  bufi += addrbytes * op.size;
2280  }
2282  free(buf);
2283  free(block0);
2284  free(block1);
2285 }
2286 
2287 RZ_API void rz_core_analysis_calls(RZ_NONNULL RzCore *core, bool imports_only) {
2288  rz_return_if_fail(core);
2289 
2290  RzList *ranges = NULL;
2291  RzIOMap *r;
2292  ut64 addr;
2293  RzBinFile *binfile = rz_bin_cur(core->bin);
2294  addr = core->offset;
2295  if (binfile) {
2296  ranges = rz_core_get_boundaries_prot(core, RZ_PERM_X, NULL, "analysis");
2297  }
2299  if (!binfile || rz_list_length(ranges) < 1) {
2300  RzListIter *iter;
2301  RzIOMap *map;
2302  rz_list_free(ranges);
2303  ranges = rz_core_get_boundaries_prot(core, 0, NULL, "analysis");
2304  if (ranges) {
2305  rz_list_foreach (ranges, iter, map) {
2306  ut64 addr = map->itv.addr;
2307  _analysis_calls(core, addr, rz_itv_end(map->itv), imports_only);
2308  }
2309  }
2310  } else {
2311  RzListIter *iter;
2312  if (binfile) {
2313  rz_list_foreach (ranges, iter, r) {
2314  addr = r->itv.addr;
2315  // this normally will happen on fuzzed binaries, dunno if with huge
2316  // binaries as well
2317  if (rz_cons_is_breaked()) {
2318  break;
2319  }
2320  _analysis_calls(core, addr, rz_itv_end(r->itv), imports_only);
2321  }
2322  }
2323  }
2325  rz_list_free(ranges);
2326 }
2327 
2329  st64 n = argc > 1 ? rz_num_math(core->num, argv[1]) : -1;
2330  char *sysc = rz_core_syscall_as_string(core, n, core->offset);
2331  if (!sysc) {
2332  RZ_LOG_ERROR("Cannot resolve syscall: %" PFMT64d "\n", n);
2333  return RZ_CMD_STATUS_ERROR;
2334  }
2335  rz_cons_println(sysc);
2336  free(sysc);
2337  return RZ_CMD_STATUS_OK;
2338 }
2339 
2340 static const char *syscallNumber(int n) {
2341  return sdb_fmt(n > 1000 ? "0x%x" : "%d", n);
2342 }
2343 
2345  RzListIter *iter;
2346  RzSyscallItem *si;
2349  rz_list_foreach (list, iter, si) {
2350  switch (state->mode) {
2352  rz_cons_printf("%s = 0x%02x.%s\n",
2353  si->name, si->swi, syscallNumber(si->num));
2354  break;
2355  case RZ_OUTPUT_MODE_JSON:
2356  pj_o(state->d.pj);
2357  pj_ks(state->d.pj, "name", si->name);
2358  pj_ki(state->d.pj, "swi", si->swi);
2359  pj_ki(state->d.pj, "num", si->num);
2360  pj_end(state->d.pj);
2361  break;
2362  default:
2364  break;
2365  }
2366  }
2368  rz_list_free(list);
2369  return RZ_CMD_STATUS_OK;
2370 }
2371 
2374  if (num < 1) {
2375  RZ_LOG_ERROR("Cannot resolve syscall: %s\n", argv[1]);
2376  return RZ_CMD_STATUS_ERROR;
2377  }
2379  return RZ_CMD_STATUS_OK;
2380 }
2381 
2383  st64 num = rz_num_math(NULL, argv[1]);
2384  if (num < 1) {
2385  RZ_LOG_ERROR("Cannot resolve syscall: %s\n", argv[1]);
2386  return RZ_CMD_STATUS_ERROR;
2387  }
2389  if (!si) {
2390  RZ_LOG_ERROR("Cannot resolve syscall: %" PFMT64d "\n", num);
2391  return RZ_CMD_STATUS_ERROR;
2392  }
2393  rz_cons_println(si->name);
2394  return RZ_CMD_STATUS_OK;
2395 }
2396 
2397 static void syscall_dump(RzSyscallItem *si, bool is_c) {
2398  if (is_c) {
2399  rz_cons_printf("#define SYS_%s %s\n", si->name, syscallNumber(si->num));
2400  } else {
2401  rz_cons_printf(".equ SYS_%s %s\n", si->name, syscallNumber(si->num));
2402  }
2403 }
2404 
2405 static RzCmdStatus syscalls_dump(RzCore *core, int argc, const char **argv, bool is_c) {
2406  if (argc > 1) {
2407  st64 n = rz_num_math(core->num, argv[1]);
2408  if (n < 1) {
2409  n = rz_syscall_get_num(core->analysis->syscall, argv[1]);
2410  if (n == -1) {
2411  RZ_LOG_ERROR("Cannot resolve syscall: %s\n", argv[1]);
2412  return RZ_CMD_STATUS_ERROR;
2413  }
2414  rz_cons_printf(".equ SYS_%s %s\n", argv[1], syscallNumber(n));
2415  return RZ_CMD_STATUS_OK;
2416  }
2417  RzSyscallItem *si = rz_syscall_get(core->analysis->syscall, n, -1);
2418  if (!si) {
2419  RZ_LOG_ERROR("Cannot resolve syscall: %" PFMT64d "\n", n);
2420  return RZ_CMD_STATUS_ERROR;
2421  }
2422  // Workaround until syscalls searching code is fixed
2423  si->num = n;
2424  syscall_dump(si, is_c);
2426  } else {
2427  RzListIter *iter;
2428  RzSyscallItem *si;
2430  rz_list_foreach (list, iter, si) {
2431  syscall_dump(si, is_c);
2432  }
2433  rz_list_free(list);
2434  }
2435  return RZ_CMD_STATUS_OK;
2436 }
2437 
2439  return syscalls_dump(core, argc, argv, false);
2440 }
2441 
2443  return syscalls_dump(core, argc, argv, true);
2444 }
2445 
2448  if (fcn) {
2449  rz_cons_printf(" ; %s", fcn->name);
2450  } else {
2451  rz_cons_printf(" ; 0x%" PFMT64x, addr);
2452  }
2453 }
2454 
2456  switch (xrefi->type) {
2462  return rz_flag_get_by_spaces(core->flags, xrefi->to, RZ_FLAGS_FS_STRINGS, NULL);
2463  default:
2464  return rz_flag_get_at(core->flags, xrefi->to, true);
2465  }
2466 }
2467 
2468 #define var_ref_list(a, d, t) sdb_fmt("var.0x%" PFMT64x ".%d.%d.%s", \
2469  a, 1, d, (t == 'R') ? "reads" : "writes");
2470 
2471 static char *getViewerPath(void) {
2472  int i;
2473  const char *viewers[] = {
2474 #if __WINDOWS__
2475  "explorer",
2476 #else
2477  "open",
2478  "geeqie",
2479  "gqview",
2480  "eog",
2481  "xdg-open",
2482 #endif
2483  NULL
2484  };
2485  for (i = 0; viewers[i]; i++) {
2486  char *viewerPath = rz_file_path(viewers[i]);
2487  if (viewerPath && strcmp(viewerPath, viewers[i])) {
2488  return viewerPath;
2489  }
2490  free(viewerPath);
2491  }
2492  return NULL;
2493 }
2494 
2495 static char *dot_executable_path(void) {
2496  const char *dot = "dot";
2497  char *dotPath = rz_file_path(dot);
2498  if (!strcmp(dotPath, dot)) {
2499  free(dotPath);
2500  dot = "xdot";
2501  dotPath = rz_file_path(dot);
2502  if (!strcmp(dotPath, dot)) {
2503  free(dotPath);
2504  return NULL;
2505  }
2506  }
2507  return dotPath;
2508 }
2509 
2510 static bool convert_dot_to_image(RzCore *core, const char *dot_file, const char *save_path) {
2511  char *dot = dot_executable_path();
2512  bool result = false;
2513  if (!dot) {
2514  eprintf("Graphviz not found\n");
2515  return false;
2516  }
2517  const char *ext = rz_config_get(core->config, "graph.gv.format");
2518 
2519  char *cmd = NULL;
2520  if (save_path && *save_path) {
2521  cmd = rz_str_newf("!%s -T%s -o%s a.dot;", dot, ext, save_path);
2522  } else {
2523  char *viewer = getViewerPath();
2524  if (viewer) {
2525  cmd = rz_str_newf("!%s -T%s -oa.%s a.dot;!%s a.%s",
2526  dot, ext, ext, viewer, ext);
2527  free(viewer);
2528  } else {
2529  eprintf("Cannot find a valid picture viewer\n");
2530  goto end;
2531  }
2532  }
2533  rz_core_cmd0(core, cmd);
2534  result = true;
2535 end:
2536  free(cmd);
2537  free(dot);
2538  return result;
2539 }
2540 
2541 static bool convert_dotcmd_to_image(RzCore *core, char *rz_cmd, const char *save_path) {
2542  if (save_path && *save_path) {
2543  rz_cons_printf("Saving to file '%s'...\n", save_path);
2544  rz_cons_flush();
2545  }
2546  rz_core_cmdf(core, "%s > a.dot", rz_cmd); // TODO: check error here
2547  return convert_dot_to_image(core, "a.dot", save_path);
2548 }
2549 
2550 static bool convert_dot_str_to_image(RzCore *core, char *str, const char *save_path) {
2551  if (save_path && *save_path) {
2552  rz_cons_printf("Saving to file '%s'...\n", save_path);
2553  rz_cons_flush();
2554  }
2555  if (!rz_file_dump("a.dot", (const unsigned char *)str, -1, false)) {
2556  return false;
2557  }
2558  return convert_dot_to_image(core, "a.dot", save_path);
2559 }
2560 
2562  convert_dotcmd_to_image(core, "aggd", filename);
2563 }
2564 
2565 static void cmd_agraph_node(RzCore *core, const char *input) {
2566  switch (*input) {
2567  case ' ': { // "agn"
2568  int n_args = 0;
2569  char **args = rz_str_argv(input, &n_args);
2570  if (n_args < 1 || n_args > 3) {
2571  rz_cons_printf("Wrong arguments\n");
2573  break;
2574  }
2575  const char *title = args[0];
2576  const char *body = n_args > 1 ? args[1] : "";
2577  int color = n_args > 2 ? atoi(args[2]) : -1;
2578  rz_core_agraph_add_node(core, title, body, color);
2580  break;
2581  }
2582  case '-': { // "agn-"
2583  char **args;
2584  int n_args;
2585 
2586  input++;
2587  args = rz_str_argv(input, &n_args);
2588  if (n_args != 1) {
2589  rz_cons_printf("Wrong arguments\n");
2591  break;
2592  }
2593  rz_core_agraph_del_node(core, args[0]);
2595  break;
2596  }
2597  case '?': // "agn?"
2598  default:
2600  break;
2601  }
2602 }
2603 
2604 static void cmd_agraph_edge(RzCore *core, const char *input) {
2605  char **args;
2606  int n_args;
2607 
2608  switch (*input) {
2609  case ' ': // "age"
2610  args = rz_str_argv(input + 1, &n_args);
2611  if (n_args != 2) {
2612  rz_cons_printf("Wrong arguments\n");
2614  break;
2615  }
2616 
2617  rz_core_agraph_add_edge(core, args[0], args[1]);
2619  break;
2620  case '-': // "age-"
2621  args = rz_str_argv(input + 1, &n_args);
2622  if (n_args != 2) {
2623  rz_cons_printf("Wrong arguments\n");
2625  break;
2626  }
2627 
2628  rz_core_agraph_del_edge(core, args[0], args[1]);
2630  break;
2631  case '?': // "age?"
2632  default:
2634  break;
2635  }
2636 }
2637 
2638 RZ_API void rz_core_agraph_print(RzCore *core, int use_utf, const char *input) {
2639  if (use_utf != -1) {
2640  rz_config_set_i(core->config, "scr.utf8", use_utf);
2641  }
2642  switch (*input) {
2643  case 0:
2645  break;
2646  case 't': // "aggt" - tiny graph
2648  break;
2649  case 'k': // "aggk"
2651  break;
2652  case 'v': // "aggv"
2653  case 'i': // "aggi" - open current core->graph in interactive mode
2655  break;
2656  case 'd': // "aggd" - dot format
2658  break;
2659  case '*': // "agg*" -
2661  break;
2662  case 'J': // "aggJ"
2663  case 'j': // "aggj"
2665  break;
2666  case 'g': // "aggg"
2668  break;
2669  case 'w': { // "aggw"
2670  const char *filename = rz_str_trim_head_ro(input + 1);
2672  break;
2673  }
2674  default:
2675  eprintf("Usage: see ag?\n");
2676  }
2677 }
2678 
2679 static void print_graph_agg(RzGraph /*<RzGraphNodeInfo *>*/ *graph) {
2680  RzGraphNodeInfo *print_node;
2681  RzGraphNode *node, *target;
2682  RzListIter *it, *edge_it;
2683  rz_list_foreach (graph->nodes, it, node) {
2684  char *encbody;
2685  int len;
2686  print_node = node->data;
2687  if (RZ_STR_ISNOTEMPTY(print_node->body)) {
2688  len = strlen(print_node->body);
2689  if (len > 0 && print_node->body[len - 1] == '\n') {
2690  len--;
2691  }
2692  encbody = rz_base64_encode_dyn((const ut8 *)print_node->body, len);
2693  rz_cons_printf("agn \"%s\" base64:%s\n", print_node->title, encbody);
2694  free(encbody);
2695  } else {
2696  rz_cons_printf("agn \"%s\"\n", print_node->title);
2697  }
2698  }
2699  rz_list_foreach (graph->nodes, it, node) {
2700  print_node = node->data;
2701  rz_list_foreach (node->out_nodes, edge_it, target) {
2702  RzGraphNodeInfo *to = target->data;
2703  rz_cons_printf("age \"%s\" \"%s\"\n", print_node->title, to->title);
2704  }
2705  }
2706 }
2707 
2708 static char *print_graph_dot(RzCore *core, RzGraph /*<RzGraphNodeInfo *>*/ *graph) {
2709  const char *font = rz_config_get(core->config, "graph.font");
2710  char *node_properties = rz_str_newf("fontname=\"%s\"", font);
2711  char *result = rz_graph_drawable_to_dot(graph, node_properties, NULL);
2712  free(node_properties);
2713  return result;
2714 }
2715 
2716 static void rz_core_graph_print(RzCore *core, RzGraph /*<RzGraphNodeInfo *>*/ *graph, int use_utf, bool use_offset, const char *input) {
2717  RzAGraph *agraph = NULL;
2718  RzListIter *it;
2719  RzListIter *edge_it;
2720  RzGraphNode *graphNode, *target;
2721  RzGraphNodeInfo *print_node;
2722  if (use_utf != -1) {
2723  rz_config_set_i(core->config, "scr.utf8", use_utf);
2724  }
2725  switch (*input) {
2726  case 0:
2727  case 't':
2728  case 'k':
2729  case 'v':
2730  case 'i': {
2731  agraph = create_agraph_from_graph(graph);
2732  switch (*input) {
2733  case 0:
2734  agraph->can->linemode = rz_config_get_i(core->config, "graph.linemode");
2735  agraph->can->color = rz_config_get_i(core->config, "scr.color");
2736  rz_agraph_set_title(agraph,
2737  rz_config_get(core->config, "graph.title"));
2738  rz_agraph_print(agraph);
2739  break;
2740  case 't': { // "ag_t" - tiny graph
2741  agraph->is_tiny = true;
2742  int e = rz_config_get_i(core->config, "graph.edges");
2743  rz_config_set_i(core->config, "graph.edges", 0);
2744  rz_core_visual_graph(core, agraph, NULL, false);
2745  rz_config_set_i(core->config, "graph.edges", e);
2746  break;
2747  }
2748  case 'k': // "ag_k"
2749  {
2750  Sdb *db = rz_agraph_get_sdb(agraph);
2751  char *o = sdb_querys(db, "null", 0, "*");
2752  rz_cons_print(o);
2753  free(o);
2754  break;
2755  }
2756  case 'v': // "ag_v"
2757  case 'i': // "ag_i" - open current core->graph in interactive mode
2758  {
2759  RzANode *ran = rz_agraph_get_first_node(agraph);
2760  if (ran) {
2761  ut64 oseek = core->offset;
2762  rz_agraph_set_title(agraph, rz_config_get(core->config, "graph.title"));
2763  rz_agraph_set_curnode(agraph, ran);
2764  agraph->force_update_seek = true;
2765  agraph->need_set_layout = true;
2766  agraph->layout = rz_config_get_i(core->config, "graph.layout");
2767  bool ov = rz_cons_is_interactive();
2768  agraph->need_update_dim = true;
2769  int update_seek = rz_core_visual_graph(core, agraph, NULL, true);
2770  rz_config_set_i(core->config, "scr.interactive", ov);
2771  rz_cons_show_cursor(true);
2772  rz_cons_enable_mouse(false);
2773  if (update_seek != -1) {
2774  rz_core_seek(core, oseek, false);
2775  }
2776  } else {
2777  eprintf("This graph contains no nodes\n");
2778  }
2779  break;
2780  }
2781  }
2782  break;
2783  }
2784  case 'd': { // "ag_d" - dot format
2785  char *dot_text = print_graph_dot(core, graph);
2786  if (dot_text) {
2787  rz_cons_print(dot_text);
2788  free(dot_text);
2789  }
2790  break;
2791  }
2792  case '*': // "ag_*" -
2793  print_graph_agg(graph);
2794  break;
2795  case 'J': // "ag_J"
2796  case 'j': { // "ag_j"
2797  PJ *pj = pj_new();
2798  if (pj) {
2799  rz_graph_drawable_to_json(graph, pj, use_offset);
2801  pj_free(pj);
2802  }
2803  } break;
2804  case 'g': // "ag_g"
2805  rz_cons_printf("graph\n[\n"
2806  "hierarchic 1\n"
2807  "label \"\"\n"
2808  "directed 1\n");
2809  rz_list_foreach (graph->nodes, it, graphNode) {
2810  print_node = graphNode->data;
2811  rz_cons_printf(" node [\n"
2812  " id %d\n"
2813  " label \"%s\"\n"
2814  " ]\n",
2815  graphNode->idx, print_node->title);
2816  }
2817  rz_list_foreach (graph->nodes, it, graphNode) {
2818  rz_list_foreach (graphNode->out_nodes, edge_it, target) {
2819  rz_cons_printf(" edge [\n"
2820  " source %d\n"
2821  " target %d\n"
2822  " ]\n",
2823  graphNode->idx, target->idx);
2824  }
2825  }
2826  rz_cons_print("]\n");
2827  break;
2828  case 'w': { // "ag_w"
2829  const char *filename = rz_str_trim_head_ro(input + 1);
2830  char *dot_text = print_graph_dot(core, graph);
2831  if (dot_text) {
2832  convert_dot_str_to_image(core, dot_text, filename);
2833  free(dot_text);
2834  }
2835  break;
2836  }
2837  default:
2838  eprintf("Usage: see ag?\n");
2839  }
2840 }
2841 
2842 static void cmd_analysis_graph(RzCore *core, const char *input) {
2843  core->graph->show_node_titles = rz_config_get_i(core->config, "graph.ntitles");
2844  rz_cons_enable_highlight(false);
2845  switch (input[0]) {
2846  case 'f': // "agf"
2847  switch (input[1]) {
2848  case 0: // "agf"
2849  rz_core_visual_graph(core, NULL, NULL, false);
2850  break;
2851  case ' ': { // "agf "
2852  RzAnalysisFunction *fcn = rz_analysis_get_fcn_in(core->analysis, core->offset, 0);
2853  rz_core_visual_graph(core, NULL, fcn, false);
2854  break;
2855  }
2856  case 'v': // "agfv"
2857  eprintf("\rRendering graph...\n");
2859  if (fcn) {
2860  rz_core_visual_graph(core, NULL, fcn, 1);
2861  }
2862  rz_cons_enable_mouse(false);
2863  rz_cons_show_cursor(true);
2864  break;
2865  case 't': { // "agft" - tiny graph
2866  int e = rz_config_get_i(core->config, "graph.edges");
2867  rz_config_set_i(core->config, "graph.edges", 0);
2868  RzAnalysisFunction *fcn = rz_analysis_get_fcn_in(core->analysis, core->offset, 0);
2869  rz_core_visual_graph(core, NULL, fcn, 2);
2870  rz_config_set_i(core->config, "graph.edges", e);
2871  break;
2872  }
2873  case 'd': // "agfd"
2874  if (input[2] == 'm') {
2875  rz_core_analysis_graph(core, rz_num_math(core->num, input + 3),
2877  } else {
2878  rz_core_analysis_graph(core, rz_num_math(core->num, input + 2),
2880  }
2881  break;
2882  case 'j': // "agfj"
2884  break;
2885  case 'J': { // "agfJ"
2886  // Honor asm.graph=false in json as well
2887  RzConfigHold *hc = rz_config_hold_new(core->config);
2888  rz_config_hold_i(hc, "asm.offset", NULL);
2889  const bool o_graph_offset = rz_config_get_i(core->config, "graph.offset");
2890  rz_config_set_i(core->config, "asm.offset", o_graph_offset);
2891  rz_core_analysis_graph(core, rz_num_math(core->num, input + 2),
2894  rz_config_hold_free(hc);
2895  break;
2896  }
2897  case 'g': { // "agfg"
2898  RzAnalysisFunction *fcn = rz_analysis_get_fcn_in(core->analysis, core->offset, 0);
2899  rz_core_print_bb_gml(core, fcn);
2900  break;
2901  }
2902  case 'k': // "agfk"
2903  rz_core_agraph_reset(core);
2904  rz_core_cmdf(core, ".agf* @ %" PFMT64u "", core->offset);
2906  break;
2907  case '*': { // "agf*"
2908  RzAnalysisFunction *fcn = rz_analysis_get_fcn_in(core->analysis, core->offset, 0);
2909  rz_core_print_bb_custom(core, fcn);
2910  break;
2911  }
2912  case 'w': { // "agfw"
2913  char *cmdargs = rz_str_newf("agfd @ 0x%" PFMT64x, core->offset);
2914  convert_dotcmd_to_image(core, cmdargs, input + 2);
2915  free(cmdargs);
2916  break;
2917  }
2918  default:
2919  eprintf("Usage: see ag?\n");
2920  break;
2921  }
2922  break;
2923  case '-': // "ag-"
2924  rz_core_agraph_reset(core);
2925  break;
2926  case 'n': // "agn"
2927  cmd_agraph_node(core, input + 1);
2928  break;
2929  case 'e': // "age"
2930  cmd_agraph_edge(core, input + 1);
2931  break;
2932  case 'g': // "agg"
2933  rz_core_agraph_print(core, -1, input + 1);
2934  break;
2935  case 's': // "ags"
2936  rz_core_analysis_graph(core, rz_num_math(core->num, input + 1), 0);
2937  break;
2938  case 'C': // "agC"
2939  switch (input[1]) {
2940  case 'v': // "agCv"
2941  case 't': // "agCt"
2942  case 'k': // "agCk"
2943  case 'w': // "agCw"
2944  case ' ': // "agC "
2945  case 0: {
2946  core->graph->is_callgraph = true;
2947  rz_core_agraph_reset(core);
2948  rz_core_cmdf(core, ".agC*;");
2949  rz_core_agraph_print(core, -1, input + 1);
2950  core->graph->is_callgraph = false;
2951  break;
2952  }
2953  case 'J': // "agCJ"
2954  case 'j': // "agCj"
2956  break;
2957  case 'g': // "agCg"
2959  break;
2960  case 'd': // "agCd"
2962  break;
2963  case '*': // "agC*"
2965  break;
2966  default:
2967  eprintf("Usage: see ag?\n");
2968  break;
2969  }
2970  break;
2971  case 'r': // "agr" references graph
2972  switch (input[1]) {
2973  case '*': { // "agr*"
2974  rz_core_analysis_coderefs(core, core->offset);
2975  } break;
2976  default: {
2977  core->graph->is_callgraph = true;
2978  rz_core_agraph_reset(core);
2979  rz_core_cmdf(core, ".agr* @ %" PFMT64u ";", core->offset);
2980  rz_core_agraph_print(core, -1, input + 1);
2981  core->graph->is_callgraph = false;
2982  break;
2983  }
2984  }
2985  break;
2986  case 'R': // "agR" global refs
2987  switch (input[1]) {
2988  case '*': { // "agR*"
2989  ut64 from = rz_config_get_i(core->config, "graph.from");
2990  ut64 to = rz_config_get_i(core->config, "graph.to");
2991  RzListIter *it;
2992  RzAnalysisFunction *fcn;
2993  rz_list_foreach (core->analysis->fcns, it, fcn) {
2994  if ((from == UT64_MAX && to == UT64_MAX) || RZ_BETWEEN(from, fcn->addr, to)) {
2995  rz_core_analysis_coderefs(core, fcn->addr);
2996  }
2997  }
2998  break;
2999  }
3000  default: {
3001  core->graph->is_callgraph = true;
3002  rz_core_agraph_reset(core);
3003  rz_core_cmdf(core, ".agR*;");
3004  rz_core_agraph_print(core, -1, input + 1);
3005  core->graph->is_callgraph = false;
3006  break;
3007  }
3008  }
3009  break;
3010  case 'x': { // "agx" cross refs
3011  RzGraph *graph = rz_core_analysis_codexrefs(core, core->offset);
3012  if (!graph) {
3013  eprintf("Couldn't create graph");
3014  break;
3015  }
3016  rz_core_graph_print(core, graph, -1, true, input + 1);
3017  rz_graph_free(graph);
3018  break;
3019  }
3020  case 'i': { // "agi" import graph
3021  RzGraph *graph = rz_core_analysis_importxrefs(core);
3022  if (!graph) {
3023  eprintf("Couldn't create graph");
3024  break;
3025  }
3026  rz_core_graph_print(core, graph, -1, true, input + 1);
3027  rz_graph_free(graph);
3028  break;
3029  }
3030  case 'c': // "agc"
3031  switch (input[1]) {
3032  case 'v': // "agcv"
3033  case 't': // "agct"
3034  case 'k': // "agck"
3035  case 'w': // "agcw"
3036  case ' ': { // "agc "
3037  core->graph->is_callgraph = true;
3038  rz_core_agraph_reset(core);
3039  rz_core_cmdf(core, ".agc* @ %" PFMT64u "; agg%s;", core->offset, input + 1);
3040  core->graph->is_callgraph = false;
3041  break;
3042  }
3043  case 0: // "agc "
3044  core->graph->is_callgraph = true;
3045  rz_core_agraph_reset(core);
3046  rz_core_cmd0(core, ".agc* $$");
3048  core->graph->is_callgraph = false;
3049  break;
3050  case 'g': { // "agg"
3052  break;
3053  }
3054  case 'd': { // "aggd"
3056  break;
3057  }
3058  case 'J': // "aggJ"
3059  case 'j': { // "aggj"
3061  break;
3062  }
3063  case '*': { // "agg*"
3065  break;
3066  }
3067  default:
3068  eprintf("Usage: see ag?\n");
3069  break;
3070  }
3071  break;
3072  case 'j': // "agj" alias for agfj
3073  rz_core_cmdf(core, "agfj%s", input + 1);
3074  break;
3075  case 'J': // "agJ" alias for agfJ
3076  rz_core_cmdf(core, "agfJ%s", input + 1);
3077  break;
3078  case 'k': // "agk" alias for agfk
3079  rz_core_cmdf(core, "agfk%s", input + 1);
3080  break;
3081  case 'l': // "agl"
3083  break;
3084  case 'a': // "aga"
3085  switch (input[1]) {
3086  case '*': {
3087  rz_core_analysis_datarefs(core, core->offset);
3088  break;
3089  }
3090  default:
3091  rz_core_agraph_reset(core);
3092  rz_core_cmdf(core, ".aga* @ %" PFMT64u ";", core->offset);
3093  rz_core_agraph_print(core, -1, input + 1);
3094  break;
3095  }
3096  break;
3097  case 'A': // "agA" global data refs
3098  switch (input[1]) {
3099  case '*': {
3100  ut64 from = rz_config_get_i(core->config, "graph.from");
3101  ut64 to = rz_config_get_i(core->config, "graph.to");
3102  RzListIter *it;
3103  RzAnalysisFunction *fcn;
3104  rz_list_foreach (core->analysis->fcns, it, fcn) {
3105  if ((from == UT64_MAX && to == UT64_MAX) || RZ_BETWEEN(from, fcn->addr, to)) {
3106  rz_core_analysis_datarefs(core, fcn->addr);
3107  }
3108  }
3109  break;
3110  }
3111  default:
3112  rz_core_agraph_reset(core);
3113  rz_core_cmdf(core, ".agA*;");
3114  rz_core_agraph_print(core, -1, input + 1);
3115  break;
3116  }
3117  break;
3118  case 'd': { // "agd"
3120  switch (input[1]) {
3121  case 'j': { // "agdj"
3122  ut64 addr = input[2] ? rz_num_math(core->num, input + 2) : core->offset;
3125  break;
3126  }
3127  case 'J': { // "agdJ"
3128  ut64 addr = input[2] ? rz_num_math(core->num, input + 2) : core->offset;
3131  break;
3132  }
3133  case '*': { // "agd*"
3134  ut64 addr = input[2] ? rz_num_math(core->num, input + 2) : core->offset;
3137  break;
3138  }
3139  case ' ': // "agd "
3140  case 0:
3141  case 't': // "agdt"
3142  case 'k': // "agdk"
3143  case 'v': // "agdv"
3144  case 'g': { // "agdg"
3145  ut64 addr = input[2] ? rz_num_math(core->num, input + 2) : core->offset;
3146  rz_core_agraph_reset(core);
3147  rz_core_cmdf(core, ".agd* @ %" PFMT64u "; agg%s;", addr, input + 1);
3148  break;
3149  }
3150  case 'd': { // "agdd"
3151  ut64 addr = input[2] ? rz_num_math(core->num, input + 2) : core->offset;
3153  rz_core_analysis_graph(core, addr, diff_opt);
3154  break;
3155  }
3156  case 'w': { // "agdw"
3157  char *cmdargs = rz_str_newf("agdd 0x%" PFMT64x, core->offset);
3158  convert_dotcmd_to_image(core, cmdargs, input + 2);
3159  free(cmdargs);
3160  break;
3161  }
3162  }
3163  break;
3164  }
3165  case 'v': // "agv" alias for "agfv"
3166  rz_core_cmdf(core, "agfv%s", input + 1);
3167  break;
3168  case 'w': { // "agw"
3169  char *cmdargs = rz_str_newf("agfd @ 0x%" PFMT64x, core->offset);
3170  convert_dotcmd_to_image(core, cmdargs, input + 1);
3171  free(cmdargs);
3172  break;
3173  }
3174  default:
3176  break;
3177  }
3178 }
3179 
3180 static bool analysis_fcn_data(RzCore *core, const char *input) {
3182  if (fcn) {
3183  int i;
3184  bool gap = false;
3185  ut64 gap_addr = UT64_MAX;
3187  char *bitmap = calloc(1, fcn_size);
3188  if (bitmap) {
3189  RzAnalysisBlock *b;
3190  RzListIter *iter;
3191  rz_list_foreach (fcn->bbs, iter, b) {
3192  int f = b->addr - fcn->addr;
3193  int t = RZ_MIN(f + b->size, fcn_size);
3194  if (f >= 0) {
3195  while (f < t) {
3196  bitmap[f++] = 1;
3197  }
3198  }
3199  }
3200  }
3201  for (i = 0; i < fcn_size; i++) {
3202  ut64 here = fcn->addr + i;
3203  if (bitmap && bitmap[i]) {
3204  if (gap) {
3205  rz_cons_printf("Cd %" PFMT64u " @ 0x%08" PFMT64x "\n", here - gap_addr, gap_addr);
3206  gap = false;
3207  }
3208  gap_addr = UT64_MAX;
3209  } else {
3210  if (!gap) {
3211  gap = true;
3212  gap_addr = here;
3213  }
3214  }
3215  }
3216  if (gap) {
3217  rz_cons_printf("Cd %" PFMT64u " @ 0x%08" PFMT64x "\n", fcn->addr + fcn_size - gap_addr, gap_addr);
3218  }
3219  free(bitmap);
3220  return true;
3221  }
3222  return false;
3223 }
3224 
3225 static bool analysis_fcn_data_gaps(RzCore *core, const char *input) {
3226  ut64 end = UT64_MAX;
3227  RzAnalysisFunction *fcn;
3228  RzListIter *iter;
3229  int i, wordsize = (core->rasm->bits == 64) ? 8 : 4;
3230  rz_list_sort(core->analysis->fcns, cmpaddr);
3231  rz_list_foreach (core->analysis->fcns, iter, fcn) {
3232  if (end != UT64_MAX) {
3233  int range = fcn->addr - end;
3234  if (range > 0) {
3235  for (i = 0; i + wordsize < range; i += wordsize) {
3236  rz_cons_printf("Cd %d @ 0x%08" PFMT64x "\n", wordsize, end + i);
3237  }
3238  rz_cons_printf("Cd %d @ 0x%08" PFMT64x "\n", range - i, end + i);
3239  // rz_cons_printf ("Cd %d @ 0x%08"PFMT64x"\n", range, end);
3240  }
3241  }
3243  }
3244  return true;
3245 }
3246 
3249  return RZ_CMD_STATUS_OK;
3250 }
3251 
3254  return RZ_CMD_STATUS_OK;
3255 }
3256 
3259  return RZ_CMD_STATUS_OK;
3260 }
3261 
3264  return RZ_CMD_STATUS_OK;
3265 }
3266 
3268  if (argc == 2) {
3269  char *classname = (char *)argv[1];
3270  char *demangled = rz_analysis_rtti_demangle_class_name(core->analysis, classname);
3271  if (demangled) {
3272  rz_cons_println(demangled);
3273  free(demangled);
3274  }
3275  return RZ_CMD_STATUS_OK;
3276  }
3277  return RZ_CMD_STATUS_ERROR;
3278 }
3279 
3282  return RZ_CMD_STATUS_ERROR;
3283  }
3284  return RZ_CMD_STATUS_OK;
3285 }
3286 
3288  const char *var_name = argv[1];
3289  ut64 addr = rz_num_math(core->num, argv[2]);
3290  const char *type = argv[3];
3291 
3292  char *errmsg = NULL;
3293  RzType *typ = rz_type_parse_string_single(core->analysis->typedb->parser, type, &errmsg);
3294  if (errmsg) {
3295  RZ_LOG_ERROR("%s : Error parsing type: \"%s\" message:\n%s\n", __FUNCTION__, type, errmsg);
3296  free(errmsg);
3297  return RZ_CMD_STATUS_ERROR;
3298  }
3300  if (!glob) {
3301  return RZ_CMD_STATUS_ERROR;
3302  }
3304 
3305  if (!rz_analysis_var_global_add(core->analysis, glob)) {
3307  return RZ_CMD_STATUS_ERROR;
3308  }
3309  return RZ_CMD_STATUS_OK;
3310 }
3311 
3313  ut64 addr = rz_num_math(core->num, argv[1]);
3314 
3316  return RZ_CMD_STATUS_ERROR;
3317  }
3318 
3319  return RZ_CMD_STATUS_OK;
3320 }
3321 
3324  return RZ_CMD_STATUS_ERROR;
3325  }
3326 
3327  return RZ_CMD_STATUS_OK;
3328 }
3329 
3331  const char *oldname = argv[1];
3332  const char *newname = argv[2];
3333  if (!rz_analysis_var_global_rename(core->analysis, oldname, newname)) {
3334  return RZ_CMD_STATUS_ERROR;
3335  }
3336  return RZ_CMD_STATUS_OK;
3337 }
3338 
3340  const char *name = argv[1];
3341  const char *type = argv[2];
3343  if (!glob) {
3344  RZ_LOG_ERROR("Global variable '%s' does not exist!\n", name);
3345  return RZ_CMD_STATUS_ERROR;
3346  }
3347  char *errmsg = NULL;
3348  RzType *typ = rz_type_parse_string_single(core->analysis->typedb->parser, type, &errmsg);
3349  if (errmsg) {
3350  RZ_LOG_ERROR("%s : Error parsing type: \"%s\" message:\n%s\n", __FUNCTION__, type, errmsg);
3351  free(errmsg);
3352  return RZ_CMD_STATUS_ERROR;
3353  }
3355  return RZ_CMD_STATUS_OK;
3356 }
3357 
3358 RZ_IPI int rz_cmd_analysis(void *data, const char *input) {
3359  const char *r;
3360  RzCore *core = (RzCore *)data;
3361  ut32 tbs = core->blocksize;
3362  switch (input[0]) {
3363  case 'p': // "ap"
3364  {
3365  const ut8 *prelude = (const ut8 *)"\xe9\x2d"; //: fffff000";
3366  const int prelude_sz = 2;
3367  const int bufsz = 4096;
3368  ut8 *buf = calloc(1, bufsz);
3369  ut64 off = core->offset;
3370  if (input[1] == ' ') {
3371  off = rz_num_math(core->num, input + 1);
3372  rz_io_read_at(core->io, off - bufsz + prelude_sz, buf, bufsz);
3373  } else {
3374  rz_io_read_at(core->io, off - bufsz + prelude_sz, buf, bufsz);
3375  }
3376  // const char *prelude = "\x2d\xe9\xf0\x47"; //:fffff000";
3377  rz_mem_reverse(buf, bufsz);
3378  // rz_print_hexdump (NULL, off, buf, bufsz, 16, -16);
3379  const ut8 *pos = rz_mem_mem(buf, bufsz, prelude, prelude_sz);
3380  if (pos) {
3381  int delta = (size_t)(pos - buf);
3382  eprintf("POS = %d\n", delta);
3383  eprintf("HIT = 0x%" PFMT64x "\n", off - delta);
3384  rz_cons_printf("0x%08" PFMT64x "\n", off - delta);
3385  } else {
3386  eprintf("Cannot find prelude\n");
3387  }
3388  free(buf);
3389  } break;
3390  case 'e': cmd_analysis_esil(core, input + 1); break; // "ae"
3391  case 'F': // "aF"
3393  break;
3394  case 'g': // "ag"
3395  cmd_analysis_graph(core, input + 1);
3396  break;
3397  case '*': // "a*"
3398  rz_core_cmd0_rzshell(core, "afl*");
3399  rz_core_cmd0_rzshell(core, "ah*");
3400  rz_core_cmd0_rzshell(core, "ax*");
3401  break;
3402  case 'd': // "ad"
3403  switch (input[1]) {
3404  case 'f': // "adf"
3405  if (input[2] == 'g') {
3407  } else {
3408  analysis_fcn_data(core, input + 1);
3409  }
3410  break;
3411  case 't': // "adt"
3412  cmd_analysis_trampoline(core, input + 2);
3413  break;
3414  case ' ': { // "ad"
3415  const int default_depth = 1;
3416  const char *p;
3417  int a, b;
3418  a = rz_num_math(core->num, input + 2);
3419  p = strchr(input + 2, ' ');
3420  b = p ? rz_num_math(core->num, p + 1) : default_depth;
3421  if (a < 1) {
3422  a = 1;
3423  }
3424  if (b < 1) {
3425  b = 1;
3426  }
3427  rz_core_analysis_data(core, core->offset, a, b, 0);
3428  } break;
3429  case 'k': // "adk"
3431  core->offset, core->block, core->blocksize);
3432  rz_cons_println(r);
3433  break;
3434  case '\0': // "ad"
3435  rz_core_analysis_data(core, core->offset, 2 + (core->blocksize / 4), 1, 0);
3436  break;
3437  case '4': // "ad4"
3438  rz_core_analysis_data(core, core->offset, 2 + (core->blocksize / 4), 1, 4);
3439  break;
3440  case '8': // "ad8"
3441  rz_core_analysis_data(core, core->offset, 2 + (core->blocksize / 4), 1, 8);
3442  break;
3443  default:
3445  break;
3446  }
3447  break;
3448  default:
3450  break;
3451  }
3452  if (tbs != core->blocksize) {
3453  rz_core_block_size(core, tbs);
3454  }
3455  if (rz_cons_is_breaked()) {
3456  rz_cons_clear_line(1);
3457  }
3458  return 0;
3459 }
3460 
3463  if (!fcn) {
3464  return RZ_CMD_STATUS_ERROR;
3465  }
3467  return RZ_CMD_STATUS_OK;
3468 }
3469 
3472  if (!b) {
3473  eprintf("Cannot find basic block\n");
3474  return RZ_CMD_STATUS_ERROR;
3475  }
3476  RzAnalysisFunction *fcn = rz_list_first(b->fcns);
3478  return RZ_CMD_STATUS_OK;
3479 }
3480 
3483  if (!fcn) {
3484  return RZ_CMD_STATUS_ERROR;
3485  }
3486  while (!rz_list_empty(fcn->bbs)) {
3488  }
3489  return RZ_CMD_STATUS_OK;
3490 }
3491 
3493  ut64 switch_addr = rz_num_math(core->num, argv[1]);
3494  ut64 case_addr = rz_num_math(core->num, argv[2]);
3495  RzList *blocks = rz_analysis_get_blocks_in(core->analysis, switch_addr);
3496  if (!rz_list_empty(blocks)) {
3498  return RZ_CMD_STATUS_ERROR;
3499  }
3500  rz_analysis_block_add_switch_case(rz_list_first(blocks), switch_addr, 0, case_addr);
3502  return RZ_CMD_STATUS_OK;
3503 }
3504 
3506  ut64 switch_addr = rz_num_math(core->num, argv[1]);
3507  RzList *blocks = rz_analysis_get_blocks_in(core->analysis, switch_addr);
3508  if (rz_list_empty(blocks)) {
3509  RZ_LOG_ERROR("No basic block exists at '%s' (0x%" PFMT64x ")\n", argv[1], switch_addr);
3511  return RZ_CMD_STATUS_ERROR;
3512  }
3514  if (!b->switch_op) {
3515  RZ_LOG_ERROR("Block does not have a switch case\n");
3516  return RZ_CMD_STATUS_INVALID;
3517  }
3519  if (!e) {
3520  RZ_LOG_ERROR("Enum '%s' does not exist\n", argv[2]);
3521  return RZ_CMD_STATUS_INVALID;
3522  }
3523  rz_type_free(b->switch_op->enum_type);
3524  b->switch_op->enum_type = rz_type_identifier_of_base_type(core->analysis->typedb, e, true);
3526  return RZ_CMD_STATUS_OK;
3527 }
3528 
3531  if (!fcn) {
3532  return RZ_CMD_STATUS_ERROR;
3533  }
3534  rz_core_analysis_fcn_returns(core, fcn);
3535  return RZ_CMD_STATUS_OK;
3536 }
3537 
3540  if (!fcn) {
3541  return RZ_CMD_STATUS_ERROR;
3542  }
3543  rz_core_analysis_bbs_asciiart(core, fcn);
3544  return RZ_CMD_STATUS_OK;
3545 }
3546 
3549  if (!bb) {
3550  eprintf("No basic block at 0x%" PFMT64x, core->offset);
3551  return RZ_CMD_STATUS_ERROR;
3552  }
3553  rz_core_analysis_bb_info_print(core, bb, core->offset, state);
3554  return RZ_CMD_STATUS_OK;
3555 }
3556 
3559  ut64 fcn_addr = rz_num_math(core->num, argv[1]);
3560  ut64 addr = rz_num_math(core->num, argv[2]);
3561  ut64 size = rz_num_math(core->num, argv[3]);
3562  ut64 jump = argc > 4 ? rz_num_math(core->num, argv[4]) : UT64_MAX;
3563  ut64 fail = argc > 5 ? rz_num_math(core->num, argv[5]) : UT64_MAX;
3564  RzAnalysisDiff *diff = NULL;
3565  if (argc > 6) {
3566  diff = rz_analysis_diff_new();
3568  }
3570  if (!fcn) {
3571  eprintf("Cannot find function at 0x%" PFMT64x "\n", fcn_addr);
3572  goto err;
3573  }
3574  if (!rz_analysis_fcn_add_bb(core->analysis, fcn, addr, size, jump, fail, diff)) {
3575  eprintf("Cannot add basic block at 0x%" PFMT64x " to fcn at 0x%" PFMT64x "\n", addr, fcn_addr);
3576  goto err;
3577  }
3578  res = RZ_CMD_STATUS_OK;
3579 err:
3580  rz_analysis_diff_free(diff);
3581  return res;
3582 }
3583 
3585  ut64 addr = rz_num_math(core->num, argv[1]);
3586  ut32 color = (ut32)rz_num_math(core->num, argv[2]);
3588  if (!block) {
3589  eprintf("No basic block at 0x%08" PFMT64x "\n", addr);
3590  return RZ_CMD_STATUS_ERROR;
3591  }
3592  block->colorize = color;
3593  return RZ_CMD_STATUS_OK;
3594 }
3595 
3597  int bits = atoi(argv[1]);
3599  if (!fcn) {
3600  return RZ_CMD_STATUS_ERROR;
3601  }
3602  RzListIter *iter;
3603  RzAnalysisBlock *bb;
3604  rz_list_foreach (fcn->bbs, iter, bb) {
3606  rz_analysis_hint_set_bits(core->analysis, bb->addr + bb->size, core->analysis->bits);
3607  }
3608  fcn->bits = bits;
3609  return RZ_CMD_STATUS_OK;
3610 }
3611 
3614  if (!f) {
3615  return RZ_CMD_STATUS_ERROR;
3616  }
3617 
3618  if (argc > 1) {
3619  // set signature
3621  } else {
3622  // get signature
3623  char *str = NULL;
3624  switch (mode) {
3625  case RZ_OUTPUT_MODE_STANDARD: {
3627  break;
3628  }
3629  case RZ_OUTPUT_MODE_JSON: {
3631  break;
3632  }
3633  default:
3635  return RZ_CMD_STATUS_ERROR;
3636  }
3638  free(str);
3639  }
3640  return RZ_CMD_STATUS_OK;
3641 }
3642 
3645  return RZ_CMD_STATUS_OK;
3646 }
3647 
3650  if (!fcn) {
3651  return RZ_CMD_STATUS_ERROR;
3652  }
3653  char *error_msg = NULL;
3654  RzType *ret_type = rz_type_parse_string_single(core->analysis->typedb->parser, argv[1], &error_msg);
3655  if (!ret_type || error_msg) {
3656  eprintf("Cannot parse type \"%s\":\n%s\n", argv[1], error_msg);
3657  free(error_msg);
3658  return RZ_CMD_STATUS_ERROR;
3659  }
3660  if (!rz_type_func_ret_set(core->analysis->typedb, fcn->name, ret_type)) {
3661  eprintf("Cannot find type %s\n", argv[1]);
3662  return RZ_CMD_STATUS_ERROR;
3663  }
3664  fcn->ret_type = ret_type;
3665  return RZ_CMD_STATUS_OK;
3666 }
3667 
3668 static void xref_print_to_json(RZ_UNUSED RzCore *core, RzAnalysisXRef *xref, PJ *pj) {
3669  pj_o(pj);
3670  pj_kn(pj, "from", xref->from);
3671  pj_kn(pj, "to", xref->to);
3672  pj_ks(pj, "type", rz_analysis_xrefs_type_tostring(xref->type));
3673  pj_end(pj);
3674 }
3675 
3677  RzAnalysisXRef *xref;
3678  RzListIter *iter;
3679  pj_a(pj);
3680  rz_list_foreach (list, iter, xref) {
3681  xref_print_to_json(core, xref, pj);
3682  }
3683  pj_end(pj);
3684 }
3685 
3688  if (!fcn) {
3689  return RZ_CMD_STATUS_ERROR;
3690  }
3691 
3692  ut64 oaddr = core->offset;
3695  if (state->mode == RZ_OUTPUT_MODE_JSON) {
3696  xref_list_print_to_json(core, xrefs, state->d.pj);
3698  goto exit;
3699  }
3700  RzAnalysisXRef *xref;
3701  RzListIter *iter;
3702  rz_list_foreach (xrefs, iter, xref) {
3703  switch (state->mode) {
3705  rz_cons_printf("%c 0x%08" PFMT64x " -> ", xref->type, xref->from);
3706  switch (xref->type) {
3708  rz_cons_printf("0x%08" PFMT64x " ", xref->to);
3709  break;
3713  rz_cons_printf("0x%08" PFMT64x " ", xref->to);
3714  rz_core_seek(core, xref->from, 1);
3716  break;
3718  char *s = rz_core_cmd_strf(core, "pxr 8 @ 0x%08" PFMT64x, xref->to);
3719  char *nl = strchr(s, '\n');
3720  if (nl) {
3721  *nl = 0;
3722  }
3723  rz_cons_printf("%s\n", s);
3724  free(s);
3725  break;
3726  }
3727  }
3728  break;
3729  default:
3732  goto exit;
3733  }
3734  }
3735  rz_core_seek(core, oaddr, 1);
3736 exit:
3737  rz_list_free(xrefs);
3738  return status;
3739 }
3740 
3743  if (!fcn) {
3744  return RZ_CMD_STATUS_ERROR;
3745  }
3746 
3747  fcn->maxstack = rz_num_math(core->num, argv[1]);
3748  return RZ_CMD_STATUS_OK;
3749 }
3750 
3753  if (!fcn) {
3754  return RZ_CMD_STATUS_ERROR;
3755  }
3756 
3757  PJ *pj = NULL;
3758  switch (mode) {
3760  rz_cons_printf("0x%08" PFMT64x "\n", fcn->addr);
3761  break;
3762  case RZ_OUTPUT_MODE_JSON:
3763  pj = pj_new();
3764  if (!pj) {
3765  return RZ_CMD_STATUS_ERROR;
3766  }
3767  pj_o(pj);
3768  if (fcn) {
3769  pj_ki(pj, "address", fcn->addr);
3770  }
3771  pj_end(pj);
3773  pj_free(pj);
3774  break;
3775  default:
3777  }
3778  return RZ_CMD_STATUS_OK;
3779 }
3780 
3782  ut64 addr_end = rz_num_math(core->num, argv[1]);
3783  if (addr_end < core->offset) {
3784  eprintf("Invalid address ranges\n");
3785  return RZ_CMD_STATUS_ERROR;
3786  }
3787  rz_core_analysis_function_until(core, addr_end);
3788  return RZ_CMD_STATUS_OK;
3789 }
3790 
3791 static int var_comparator(const RzAnalysisVar *a, const RzAnalysisVar *b) {
3792  return (a && b) ? (a->delta > b->delta) - (a->delta < b->delta) : 0;
3793 }
3794 
3796  RzAnalysisVar *var;
3797  RzListIter *iter;
3798  if (state->mode == RZ_OUTPUT_MODE_JSON) {
3799  pj_a(state->d.pj);
3800  }
3801  RzList *list = rz_analysis_var_list(analysis, fcn, kind);
3802  if (!list) {
3803  goto fail;
3804  }
3806  rz_list_foreach (list, iter, var) {
3807  if (var->kind != kind) {
3808  continue;
3809  }
3810  switch (state->mode) {
3811  case RZ_OUTPUT_MODE_RIZIN: {
3812  // we can't express all type info here :(
3813  char *vartype = rz_type_as_string(analysis->typedb, var->type);
3814  if (kind == RZ_ANALYSIS_VAR_KIND_REG) { // registers
3815  RzRegItem *i = rz_reg_index_get(analysis->reg, var->delta);
3816  if (!i) {
3817  RZ_LOG_ERROR("Register not found");
3818  free(vartype);
3819  break;
3820  }
3821  rz_cons_printf("afv%c %s %s %s @ 0x%" PFMT64x "\n",
3822  kind, i->name, var->name, vartype, fcn->addr);
3823  } else {
3824  int delta = kind == RZ_ANALYSIS_VAR_KIND_BPV
3825  ? var->delta + fcn->bp_off
3826  : var->delta;
3827  rz_cons_printf("afv%c %d %s %s @ 0x%" PFMT64x "\n",
3828  kind, delta, var->name, vartype,
3829  fcn->addr);
3830  }
3831  free(vartype);
3832  break;
3833  }
3834  case RZ_OUTPUT_MODE_JSON:
3835  switch (var->kind) {
3836  case RZ_ANALYSIS_VAR_KIND_BPV: {
3837  char *vartype = rz_type_as_string(analysis->typedb, var->type);
3838  st64 delta = (st64)var->delta + fcn->bp_off;
3839  pj_o(state->d.pj);
3840  pj_ks(state->d.pj, "name", var->name);
3841  pj_ks(state->d.pj, "kind", var->isarg ? "arg" : "var");
3842  pj_ks(state->d.pj, "type", vartype);
3843  pj_k(state->d.pj, "ref");
3844  pj_o(state->d.pj);
3845  pj_ks(state->d.pj, "base", analysis->reg->name[RZ_REG_NAME_BP]);
3846  pj_kN(state->d.pj, "offset", delta);
3847  pj_end(state->d.pj);
3848  pj_end(state->d.pj);
3849  free(vartype);
3850  } break;
3851  case RZ_ANALYSIS_VAR_KIND_REG: {
3852  RzRegItem *i = rz_reg_index_get(analysis->reg, var->delta);
3853  if (!i) {
3854  RZ_LOG_ERROR("Register not found");
3855  break;
3856  }
3857  char *vartype = rz_type_as_string(analysis->typedb, var->type);
3858  pj_o(state->d.pj);
3859  pj_ks(state->d.pj, "name", var->name);
3860  pj_ks(state->d.pj, "kind", "reg");
3861  pj_ks(state->d.pj, "type", vartype);
3862  pj_ks(state->d.pj, "ref", i->name);
3863  pj_end(state->d.pj);
3864  free(vartype);
3865  } break;
3866  case RZ_ANALYSIS_VAR_KIND_SPV: {
3867  st64 delta = (st64)var->delta + fcn->maxstack;
3868  pj_o(state->d.pj);
3869  pj_ks(state->d.pj, "name", var->name);
3870  pj_ks(state->d.pj, "kind", var->isarg ? "arg" : "var");
3871  char *vartype = rz_type_as_string(analysis->typedb, var->type);
3872  pj_ks(state->d.pj, "type", vartype);
3873  pj_k(state->d.pj, "ref");
3874  pj_o(state->d.pj);
3875  pj_ks(state->d.pj, "base", analysis->reg->name[RZ_REG_NAME_SP]);
3876  pj_kN(state->d.pj, "offset", delta);
3877  pj_end(state->d.pj);
3878  pj_end(state->d.pj);
3879  free(vartype);
3880  } break;
3881  }
3882  break;
3883  default:
3884  switch (kind) {
3885  case RZ_ANALYSIS_VAR_KIND_BPV: {
3886  int delta = var->delta + fcn->bp_off;
3887  char *vartype = rz_type_as_string(analysis->typedb, var->type);
3888  if (var->isarg) {
3889  rz_cons_printf("arg %s %s @ %s+0x%x\n",
3890  vartype, var->name,
3891  analysis->reg->name[RZ_REG_NAME_BP],
3892  delta);
3893  } else {
3894  char sign = (-var->delta <= fcn->bp_off) ? '+' : '-';
3895  rz_cons_printf("var %s %s @ %s%c0x%x\n",
3896  vartype, var->name,
3897  analysis->reg->name[RZ_REG_NAME_BP],
3898  sign, RZ_ABS(delta));
3899  }
3900  free(vartype);
3901  } break;
3902  case RZ_ANALYSIS_VAR_KIND_REG: {
3903  RzRegItem *i = rz_reg_index_get(analysis->reg, var->delta);
3904  if (!i) {
3905  RZ_LOG_ERROR("Register not found");
3906  break;
3907  }
3908  char *vartype = rz_type_as_string(analysis->typedb, var->type);
3909  rz_cons_printf("arg %s %s @ %s\n", vartype, var->name, i->name);
3910  free(vartype);
3911  } break;
3912  case RZ_ANALYSIS_VAR_KIND_SPV: {
3913  int delta = fcn->maxstack + var->delta;
3914  char *vartype = rz_type_as_string(analysis->typedb, var->type);
3915  if (!var->isarg) {
3916  char sign = (-var->delta <= fcn->maxstack) ? '+' : '-';
3917  rz_cons_printf("var %s %s @ %s%c0x%x\n",
3918  vartype, var->name,
3919  analysis->reg->name[RZ_REG_NAME_SP],
3920  sign, RZ_ABS(delta));
3921  } else {
3922  rz_cons_printf("arg %s %s @ %s+0x%x\n",
3923  vartype, var->name,
3924  analysis->reg->name[RZ_REG_NAME_SP],
3925  delta);
3926  }
3927  free(vartype);
3928  } break;
3929  }
3930  }
3931  }
3932 fail:
3933  if (state->mode == RZ_OUTPUT_MODE_JSON) {
3934  pj_end(state->d.pj);
3935  }
3936  rz_list_free(list);
3937 }
3938 
3941  if (!fcn) {
3942  return RZ_CMD_STATUS_ERROR;
3943  }
3944 
3945  const char *bp = NULL;
3946  RzList *list;
3947  RzListIter *iter;
3948  RzAnalysisVar *var;
3949  switch (state->mode) {
3954  break;
3955  case RZ_OUTPUT_MODE_RIZIN:
3957  rz_cons_printf("f-fcnvar*\n");
3958  list = rz_analysis_var_all_list(core->analysis, fcn);
3959  rz_list_foreach (list, iter, var) {
3960  rz_cons_printf("f fcnvar.%s @ %s%s%d\n", var->name, bp,
3961  var->delta >= 0 ? "+" : "", var->delta);
3962  }
3963  break;
3964  case RZ_OUTPUT_MODE_JSON:
3965  pj_o(state->d.pj);
3966  pj_k(state->d.pj, "sp");
3968  pj_k(state->d.pj, "bp");
3970  pj_k(state->d.pj, "reg");
3972  pj_end(state->d.pj);
3973  break;
3974  default:
3976  }
3977  return RZ_CMD_STATUS_OK;
3978 }
3979 
3982  if (!fcn) {
3983  return RZ_CMD_STATUS_ERROR;
3984  }
3985 
3986  ut64 oaddr = core->offset;
3987  RzListIter *iter;
3988  RzAnalysisVar *var;
3990  rz_list_foreach (list, iter, var) {
3991  rz_cons_printf("* %s\n", var->name);
3992  RzAnalysisVarAccess *acc;
3993  rz_vector_foreach(&var->accesses, acc) {
3994  if (!(acc->type & RZ_ANALYSIS_VAR_ACCESS_TYPE_READ)) {
3995  continue;
3996  }
3997  rz_cons_printf("R 0x%" PFMT64x " ", fcn->addr + acc->offset);
3998  rz_core_seek(core, fcn->addr + acc->offset, 1);
4000  }
4001  rz_vector_foreach(&var->accesses, acc) {
4002  if (!(acc->type & RZ_ANALYSIS_VAR_ACCESS_TYPE_WRITE)) {
4003  continue;
4004  }
4005  rz_cons_printf("W 0x%" PFMT64x " ", fcn->addr + acc->offset);
4006  rz_core_seek(core, fcn->addr + acc->offset, 1);
4008  }
4009  }
4010  rz_core_seek(core, oaddr, 0);
4011  rz_list_free(list);
4012  return RZ_CMD_STATUS_OK;
4013 }
4014 
4017  if (!fcn) {
4018  return RZ_CMD_STATUS_ERROR;
4019  }
4020 
4024  return RZ_CMD_STATUS_OK;
4025 }
4026 
4029  if (!fcn) {
4030  return RZ_CMD_STATUS_ERROR;
4031  }
4032 
4034  rz_core_recover_vars(core, fcn, false);
4035  return RZ_CMD_STATUS_OK;
4036 }
4037 
4040  if (!fcn) {
4041  return RZ_CMD_STATUS_ERROR;
4042  }
4043 
4044  RzAnalysisVar *v;
4045  char *r = NULL;
4046  switch (argc) {
4047  case 1:
4048  r = rz_core_analysis_all_vars_display(core, fcn, true);
4049  break;
4050  case 2:
4052  if (!v) {
4053  eprintf("Cannot find variable '%s' in current function\n", argv[1]);
4054  return RZ_CMD_STATUS_ERROR;
4055  }
4056  r = rz_core_analysis_var_display(core, v, true);
4057  break;
4058  default:
4060  }
4061  rz_cons_print(r);
4062  free(r);
4063  return RZ_CMD_STATUS_OK;
4064 }
4065 
4066 // EBP BASED
4067 static int delta_cmp(const void *a, const void *b) {
4068  const RzAnalysisVar *va = a;
4069  const RzAnalysisVar *vb = b;
4070  return vb->delta - va->delta;
4071 }
4072 
4073 static int delta_cmp2(const void *a, const void *b) {
4074  const RzAnalysisVar *va = a;
4075  const RzAnalysisVar *vb = b;
4076  return va->delta - vb->delta;
4077 }
4078 
4081  if (!fcn) {
4082  return RZ_CMD_STATUS_ERROR;
4083  }
4084  RzListIter *iter;
4085  RzAnalysisVar *p;
4088  rz_list_foreach (list, iter, p) {
4089  if (p->isarg || p->delta > 0) {
4090  continue;
4091  }
4092  const char *pad = rz_str_pad(' ', 10 - strlen(p->name));
4093  char *ptype = rz_type_as_string(core->analysis->typedb, p->type);
4094  rz_cons_printf("0x%08" PFMT64x " %s:%s%s\n", (ut64)-p->delta, p->name, pad, ptype);
4095  free(ptype);
4096  }
4098  rz_list_foreach (list, iter, p) {
4099  if (!p->isarg && p->delta < 0) {
4100  continue;
4101  }
4102  // TODO: only stack vars if (p->kind == 's') { }
4103  const char *pad = rz_str_pad(' ', 10 - strlen(p->name));
4104  char *ptype = rz_type_as_string(core->analysis->typedb, p->type);
4105  // XXX this 0x6a is a hack
4106  rz_cons_printf("0x%08" PFMT64x " %s:%s%s\n", ((ut64)p->delta) - 0x6a, p->name, pad, ptype);
4107  free(ptype);
4108  }
4109  rz_list_free(list);
4110  return RZ_CMD_STATUS_OK;
4111 }
4112 
4114  const char *newname = argv[1];
4115  const char *oldname = argv[2];
4116  bool result = rz_core_analysis_var_rename(core, oldname, newname);
4117  return result ? RZ_CMD_STATUS_OK : RZ_CMD_STATUS_OK;
4118 }
4119 
4120 static RzCmdStatus analysis_function_vars_accesses(RzCore *core, int access_type, const char *varname) {
4122  if (!fcn) {
4123  return RZ_CMD_STATUS_ERROR;
4124  }
4125 
4126  if (!varname) {
4128  RzListIter *iter;
4129  RzAnalysisVar *var;
4130  rz_list_foreach (list, iter, var) {
4131  var_accesses_list(fcn, var, NULL, access_type, var->name);
4132  }
4133  rz_list_free(list);
4134  } else {
4136  if (!var) {
4137  eprintf("Cannot find variable %s\n", varname);
4138  return RZ_CMD_STATUS_ERROR;
4139  }
4140  var_accesses_list(fcn, var, NULL, access_type, var->name);
4141  }
4142  return RZ_CMD_STATUS_OK;
4143 }
4144 
4147 }
4148 
4151 }
4152 
4155  if (!fcn) {
4156  return RZ_CMD_STATUS_ERROR;
4157  }
4158 
4160  if (!v) {
4161  eprintf("Cannot find variable %s\n", argv[1]);
4162  return RZ_CMD_STATUS_ERROR;
4163  }
4164  char *error_msg = NULL;
4165  RzType *v_type = rz_type_parse_string_single(core->analysis->typedb->parser, argv[2], &error_msg);
4166  if (!v_type || error_msg) {
4167  eprintf("Cannot parse type \"%s\":\n%s\n", argv[2], error_msg);
4168  free(error_msg);
4169  return RZ_CMD_STATUS_ERROR;
4170  }
4171  rz_analysis_var_set_type(v, v_type, true);
4172  return RZ_CMD_STATUS_OK;
4173 }
4174 
4175 RZ_IPI RzCmdStatus rz_analysis_function_args_and_vars_xrefs_handler(RzCore *core, int argc, const char **argv, RzOutputMode mode, bool use_args, bool use_vars) {
4177  if (!fcn) {
4178  return RZ_CMD_STATUS_ERROR;
4179  }
4180  PJ *pj = NULL;
4181  if (mode == RZ_OUTPUT_MODE_JSON) {
4182  pj = pj_new();
4183  pj_o(pj);
4184  pj_k(pj, "reads");
4185  } else {
4186  rz_cons_printf("afvR\n");
4187  }
4188  if (use_args) {
4189  list_vars(core, fcn, pj, 'R', argv[1], IS_ARG);
4190  }
4191  if (use_vars) {
4192  list_vars(core, fcn, pj, 'R', argv[1], IS_VAR);
4193  }
4194  if (mode == RZ_OUTPUT_MODE_JSON) {
4195  pj_k(pj, "writes");
4196  } else {
4197  rz_cons_printf("afvW\n");
4198  }
4199  if (use_args) {
4200  list_vars(core, fcn, pj, 'W', argv[1], IS_ARG);
4201  }
4202  if (use_vars) {
4203  list_vars(core, fcn, pj, 'W', argv[1], IS_VAR);
4204  }
4205  if (mode == RZ_OUTPUT_MODE_JSON) {
4206  pj_end(pj);
4207  char *j = pj_drain(pj);
4208  rz_cons_printf("%s\n", j);
4209  free(j);
4210  }
4211  return RZ_CMD_STATUS_OK;
4212 }
4213 
4215  return rz_analysis_function_args_and_vars_xrefs_handler(core, argc, argv, mode, true, true);
4216 }
4217 
4219  return rz_analysis_function_args_and_vars_xrefs_handler(core, argc, argv, mode, true, false);
4220 }
4221 
4223  return rz_analysis_function_args_and_vars_xrefs_handler(core, argc, argv, mode, false, true);
4224 }
4225 
4227  core_analysis_var_list_show(core->analysis, fcn, kind, state);
4228  return RZ_CMD_STATUS_OK;
4229 }
4230 
4231 static RzCmdStatus analysis_function_vars_del(RzCore *core, RzAnalysisVarKind kind, const char *varname) {
4233  if (!fcn) {
4234  return RZ_CMD_STATUS_ERROR;
4235  }
4236  rz_core_analysis_function_delete_var(core, fcn, kind, varname);
4237  return RZ_CMD_STATUS_OK;
4238 }
4239 
4242  if (!fcn) {
4243  return RZ_CMD_STATUS_ERROR;
4244  }
4246  return RZ_CMD_STATUS_OK;
4247 }
4248 
4251  if (!fcn) {
4252  return RZ_CMD_STATUS_ERROR;
4253  }
4254 
4256  if (!var) {
4257  eprintf("Cannot find variable with delta %d\n", delta);
4258  return RZ_CMD_STATUS_ERROR;
4259  }
4260 
4261  RzAnalysisOp *op = rz_core_analysis_op(core, addr, 0);
4262  const char *ireg = op ? op->ireg : NULL;
4263  if (kind == RZ_ANALYSIS_VAR_KIND_SPV) {
4264  delta -= fcn->maxstack;
4265  }
4266  rz_analysis_var_set_access(var, ireg, addr, access_type, delta);
4268  return RZ_CMD_STATUS_OK;
4269 }
4270 
4272 
4275  if (!fcn) {
4276  return RZ_CMD_STATUS_ERROR;
4277  }
4278 
4279  if (argc == 1) {
4281  } else {
4282  const char *varname = argv[2];
4283  const char *vartype = argc > 3 ? argv[3] : "int";
4284  int delta = (int)rz_num_math(core->num, argv[1]) - fcn->bp_off;
4285  bool isarg = delta > 0;
4286  char *error_msg = NULL;
4287  RzType *var_type = rz_type_parse_string_single(core->analysis->typedb->parser, vartype, &error_msg);
4288  if (!var_type || error_msg) {
4289  eprintf("Cannot parse type \"%s\":\n%s\n", vartype, error_msg);
4290  free(error_msg);
4291  return RZ_CMD_STATUS_ERROR;
4292  }
4293  rz_analysis_function_set_var(fcn, delta, RZ_ANALYSIS_VAR_KIND_BPV, var_type, 4, isarg, varname);
4294  rz_type_free(var_type);
4295  }
4296  return RZ_CMD_STATUS_OK;
4297 }
4298 
4301 }
4302 
4305 }
4306 
4308  int delta = (int)rz_num_math(core->num, argv[1]);
4309  ut64 addr = rz_num_math(core->num, argv[2]);
4311 }
4312 
4314  int delta = (int)rz_num_math(core->num, argv[1]);
4315  ut64 addr = rz_num_math(core->num, argv[2]);
4317 }
4318 
4320 
4323  if (!fcn) {
4324  return RZ_CMD_STATUS_ERROR;
4325  }
4326 
4327  if (argc == 1) {
4329  } else {
4330  const char *varname = argv[2];
4331  const char *vartype = argc > 3 ? argv[3] : "int";
4332  RzRegItem *i = rz_reg_get(core->analysis->reg, argv[1], -1);
4333  if (!i) {
4334  eprintf("Register not found");
4335  return RZ_CMD_STATUS_ERROR;
4336  }
4337  int delta = i->index;
4338  bool isarg = true;
4339  char *error_msg = NULL;
4340  RzType *var_type = rz_type_parse_string_single(core->analysis->typedb->parser, vartype, &error_msg);
4341  if (!var_type || error_msg) {
4342  eprintf("Cannot parse type \"%s\":\n%s\n", vartype, error_msg);
4343  free(error_msg);
4344  return RZ_CMD_STATUS_ERROR;
4345  }
4346  rz_analysis_function_set_var(fcn, delta, RZ_ANALYSIS_VAR_KIND_REG, var_type, 4, isarg, varname);
4347  rz_type_free(var_type);
4348  }
4349  return RZ_CMD_STATUS_OK;
4350 }
4351 
4354 }
4355 
4358 }
4359 
4361  RzRegItem *i = rz_reg_get(core->analysis->reg, argv[1], -1);
4362  if (!i) {
4363  eprintf("Register not found");
4364  return RZ_CMD_STATUS_ERROR;
4365  }
4366  int delta = i->index;
4367  ut64 addr = rz_num_math(core->num, argv[2]);
4369 }
4370 
4372  RzRegItem *i = rz_reg_get(core->analysis->reg, argv[1], -1);
4373  if (!i) {
4374  eprintf("Register not found");
4375  return RZ_CMD_STATUS_ERROR;
4376  }
4377  int delta = i->index;
4378  ut64 addr = rz_num_math(core->num, argv[2]);
4380 }
4381 
4383 
4386  if (!fcn) {
4387  return RZ_CMD_STATUS_ERROR;
4388  }
4389 
4390  if (argc == 1) {
4392  } else {
4393  const char *varname = argv[2];
4394  const char *vartype = argc > 3 ? argv[3] : "int";
4395  int delta = (int)rz_num_math(core->num, argv[1]);
4396  bool isarg = delta > fcn->maxstack;
4397  char *error_msg = NULL;
4398  RzType *var_type = rz_type_parse_string_single(core->analysis->typedb->parser, vartype, &error_msg);
4399  if (!var_type || error_msg) {
4400  eprintf("Cannot parse type \"%s\":\n%s\n", vartype, error_msg);
4401  free(error_msg);
4402  return RZ_CMD_STATUS_ERROR;
4403  }
4404  rz_analysis_function_set_var(fcn, delta, RZ_ANALYSIS_VAR_KIND_SPV, var_type, 4, isarg, varname);
4405  rz_type_free(var_type);
4406  }
4407  return RZ_CMD_STATUS_OK;
4408 }
4409 
4412 }
4413 
4415  int delta = (int)rz_num_math(core->num, argv[1]);
4416  ut64 addr = rz_num_math(core->num, argv[2]);
4418 }
4419 
4421  int delta = (int)rz_num_math(core->num, argv[1]);
4422  ut64 addr = rz_num_math(core->num, argv[2]);
4424 }
4425 
4426 static RzCmdStatus xrefs_set(RzCore *core, int argc, const char **argv, RzAnalysisXRefType type) {
4427  ut64 from = core->offset;
4428  ut64 to = rz_num_math(core->num, argv[1]);
4430 }
4431 
4433  return xrefs_set(core, argc, argv, RZ_ANALYSIS_XREF_TYPE_NULL);
4434 }
4435 
4437  return xrefs_set(core, argc, argv, RZ_ANALYSIS_XREF_TYPE_CODE);
4438 }
4439 
4441  return xrefs_set(core, argc, argv, RZ_ANALYSIS_XREF_TYPE_CALL);
4442 }
4443 
4445  return xrefs_set(core, argc, argv, RZ_ANALYSIS_XREF_TYPE_DATA);
4446 }
4447 
4449  return xrefs_set(core, argc, argv, RZ_ANALYSIS_XREF_TYPE_STRING);
4450 }
4451 
4452 static void xrefs_list_print(RzCore *core, RzList *list) {
4453  RzListIter *iter;
4454  RzAnalysisXRef *xref;
4455 
4456  rz_list_foreach (list, iter, xref) {
4457  char *name = core->analysis->coreb.getNameDelta(core->analysis->coreb.core, xref->from);
4458  if (name) {
4459  rz_str_replace_ch(name, ' ', 0, true);
4460  rz_cons_printf("%40s", name);
4461  free(name);
4462  } else {
4463  rz_cons_printf("%40s", "?");
4464  }
4465  rz_cons_printf(" 0x%" PFMT64x " -> %9s -> 0x%" PFMT64x, xref->from, rz_analysis_xrefs_type_tostring(xref->type), xref->to);
4466  name = core->analysis->coreb.getNameDelta(core->analysis->coreb.core, xref->to);
4467  if (name) {
4468  rz_str_replace_ch(name, ' ', 0, true);
4469  rz_cons_printf(" %s\n", name);
4470  free(name);
4471  } else {
4472  rz_cons_printf("\n");
4473  }
4474  }
4475 }
4476 
4478  switch (type) {
4480  return "axc";
4482  return "axC";
4484  return "axd";
4486  return "axs";
4488  return "ax";
4489  }
4490  return "ax";
4491 }
4492 
4494  RzListIter *iter;
4495  RzAnalysisXRef *xref;
4496  rz_list_foreach (list, iter, xref) {
4497  rz_cons_printf("%s 0x%" PFMT64x " @ 0x%" PFMT64x "\n", xref_type2cmd(xref->type), xref->to, xref->from);
4498  }
4499 }
4500 
4502  RzListIter *iter;
4503  RzAnalysisXRef *xref;
4506  switch (state->mode) {
4508  xrefs_list_print(core, list);
4509  break;
4510  case RZ_OUTPUT_MODE_QUIET:
4511  rz_list_foreach (list, iter, xref) {
4512  rz_cons_printf("0x%08" PFMT64x " -> 0x%08" PFMT64x " %s\n", xref->from, xref->to, rz_analysis_xrefs_type_tostring(xref->type));
4513  }
4514  break;
4515  case RZ_OUTPUT_MODE_JSON:
4516  xref_list_print_to_json(core, list, state->d.pj);
4517  break;
4518  case RZ_OUTPUT_MODE_RIZIN:
4520  break;
4521  default:
4524  break;
4525  }
4526  rz_list_free(list);
4527  return status;
4528 }
4529 
4531  RzAnalysisXRef *xref;
4532  RzListIter *iter;
4535  switch (state->mode) {
4537  rz_list_foreach (list, iter, xref) {
4538  RzAnalysisFunction *fcn = rz_analysis_get_fcn_in(core->analysis, xref->from, 0);
4539  char *buf_asm = rz_core_disasm_instruction(core, xref->from, core->offset, fcn, true);
4540  const char *comment = rz_meta_get_string(core->analysis, RZ_META_TYPE_COMMENT, xref->from);
4541  char *print_comment = NULL;
4542  const char *nl = comment ? strchr(comment, '\n') : NULL;
4543  if (nl) { // display only until the first newline
4544  comment = print_comment = rz_str_ndup(comment, nl - comment);
4545  }
4546  char *buf_fcn = comment
4547  ? rz_str_newf("%s; %s", fcn ? fcn->name : "(nofunc)", comment)
4548  : rz_str_newf("%s", fcn ? fcn->name : "(nofunc)");
4550  rz_cons_printf("%s 0x%" PFMT64x " [%s] %s\n",
4551  buf_fcn, xref->from, rz_analysis_xrefs_type_tostring(xref->type), buf_asm);
4552  free(buf_asm);
4553  free(buf_fcn);
4554  }
4555  break;
4556  case RZ_OUTPUT_MODE_QUIET:
4557  rz_list_foreach (list, iter, xref) {
4558  rz_cons_printf("0x%08" PFMT64x "\n", xref->from);
4559  }
4560  break;
4561  case RZ_OUTPUT_MODE_JSON:
4562  xref_list_print_to_json(core, list, state->d.pj);
4563  break;
4564  case RZ_OUTPUT_MODE_RIZIN:
4566  break;
4567  default:
4570  break;
4571  }
4572  rz_list_free(list);
4573  return status;
4574 }
4575 
4577  RzAnalysisXRef *xref;
4578  RzListIter *iter;
4579  char str[512];
4582  switch (state->mode) {
4584  rz_list_foreach (list, iter, xref) {
4585  ut8 buf[16];
4586  char *desc;
4587  RzAsmOp asmop;
4588  RzFlagItem *flag = rz_flag_get_at(core->flags, xref->to, false);
4589  if (flag) {
4590  desc = flag->name;
4591  } else {
4592  rz_io_read_at(core->io, xref->to, buf, sizeof(buf));
4593  rz_asm_set_pc(core->rasm, xref->to);
4594  rz_asm_disassemble(core->rasm, &asmop, buf, sizeof(buf));
4595  RzAnalysisHint *hint = rz_analysis_hint_get(core->analysis, xref->to);
4596  rz_parse_filter(core->parser, xref->from, core->flags, hint, rz_asm_op_get_asm(&asmop),
4597  str, sizeof(str), core->print->big_endian);
4598  rz_analysis_hint_free(hint);
4599  desc = str;
4600  }
4601  rz_cons_printf("%c 0x%" PFMT64x " %s",
4602  xref->type ? xref->type : ' ', xref->to, desc);
4603 
4604  if (xref->type == RZ_ANALYSIS_XREF_TYPE_CALL) {
4605  RzAnalysisOp aop = { 0 };
4606  rz_analysis_op(core->analysis, &aop, xref->to, buf, sizeof(buf), RZ_ANALYSIS_OP_MASK_BASIC);
4607  if (aop.type == RZ_ANALYSIS_OP_TYPE_UCALL) {
4608  cmd_analysis_ucall_ref(core, xref->to);
4609  }
4610  }
4611  rz_cons_newline();
4612  }
4613  break;
4614  case RZ_OUTPUT_MODE_QUIET:
4615  rz_list_foreach (list, iter, xref) {
4616  rz_cons_printf("0x%08" PFMT64x "\n", xref->to);
4617  }
4618  break;
4619  case RZ_OUTPUT_MODE_JSON:
4620  xref_list_print_to_json(core, list, state->d.pj);
4621  break;
4622  case RZ_OUTPUT_MODE_RIZIN:
4624  break;
4625  default:
4628  break;
4629  }
4630  rz_list_free(list);
4631  return status;
4632 }
4633 
4635  RzAnalysisXRef *xref;
4636  RzListIter *iter;
4637  ut64 addr = core->offset;
4639  rz_list_foreach (list, iter, xref) {
4640  char *str = rz_core_cmd_strf(core, "fd @ 0x%" PFMT64x, xref->from);
4641  if (!str) {
4642  str = strdup("?\n");
4643  }
4645  rz_cons_printf("agn 0x%" PFMT64x " \"%s\"\n", xref->from, str);
4646  free(str);
4647  }
4649  rz_cons_printf("agn 0x%" PFMT64x " \"%s\"\n", addr, fcn ? fcn->name : "$$");
4650  rz_list_foreach (list, iter, xref) {
4651  rz_cons_printf("age 0x%" PFMT64x " 0x%" PFMT64x "\n", xref->from, addr);
4652  }
4653  rz_list_free(list);
4654  return RZ_CMD_STATUS_OK;
4655 }
4656 
4658  bool all = true;
4659  ut64 from = 0;
4660  ut64 to = rz_num_math(core->num, argv[1]);
4661  if (argc == 3) {
4662  from = rz_num_math(core->num, argv[2]);
4663  all = false;
4664  }
4665  RzAnalysisXRef *xref;
4666  RzListIter *iter;
4668  rz_list_foreach (list, iter, xref) {
4669  if (all || from == xref->from) {
4670  rz_analysis_xref_del(core->analysis, xref->from, xref->to);
4671  }
4672  }
4673  rz_list_free(list);
4674  return RZ_CMD_STATUS_OK;
4675 }
4676 
4679 }
4680 
4682  ut64 src = rz_num_math(core->num, argv[1]);
4683  RzAnalysisXRef *xref;
4684  RzListIter *iter;
4686  rz_list_foreach (list, iter, xref) {
4687  rz_cons_printf("0x%08" PFMT64x " %s\n", xref->from, rz_analysis_xrefs_type_tostring(xref->type));
4688  rz_analysis_xrefs_set(core->analysis, xref->from, core->offset, xref->type);
4689  }
4690  rz_list_free(list);
4691  return RZ_CMD_STATUS_OK;
4692 }
4693 
4695  char taddr[64];
4696  pj_o(pj);
4697  pj_k(pj, rz_strf(taddr, "%" PFMT64u, addr));
4698  pj_o(pj);
4699  pj_ks(pj, "type", "fcn");
4700  pj_kn(pj, "fcn_addr", fcn->addr);
4701  pj_ks(pj, "name", fcn->name);
4702  pj_k(pj, "refs");
4703  pj_a(pj);
4704 }
4705 
4706 static void xrefs_graph(RzCore *core, ut64 addr, int level, HtUU *ht, RzOutputMode mode, PJ *pj) {
4707  char pre[128];
4708  RzListIter *iter;
4709  RzAnalysisXRef *xref;
4710  bool is_json = mode == RZ_OUTPUT_MODE_JSON;
4711  bool is_rz = mode == RZ_OUTPUT_MODE_RIZIN;
4712  int spaces = (level + 1) * 2;
4713  if (spaces > sizeof(pre) - 4) {
4714  spaces = sizeof(pre) - 4;
4715  }
4716  memset(pre, ' ', sizeof(pre));
4717  strcpy(pre + spaces, "- ");
4718 
4719  RzList *xrefs = rz_analysis_xrefs_get_to(core->analysis, addr);
4720  bool open_object = false;
4721  if (!rz_list_empty(xrefs)) {
4723  if (fcn) {
4724  if (is_rz) {
4725  rz_cons_printf("agn 0x%08" PFMT64x " %s\n", fcn->addr, fcn->name);
4726  } else if (is_json) {
4727  xrefs_graph_fcn_start_json(pj, fcn, addr);
4728  open_object = true;
4729  } else {
4730  rz_cons_printf("%s0x%08" PFMT64x " fcn 0x%08" PFMT64x " %s\n",
4731  pre + 2, addr, fcn->addr, fcn->name);
4732  }
4733  } else {
4734  if (is_rz) {
4735  rz_cons_printf("age 0x%08" PFMT64x "\n", addr);
4736  } else if (is_json) {
4737  char taddr[64];
4738  pj_o(pj);
4739  pj_k(pj, sdb_itoa(addr, taddr, 10));
4740  pj_o(pj);
4741  pj_k(pj, "refs");
4742  pj_a(pj);
4743  open_object = true;
4744  } else {
4745  rz_cons_printf("%s0x%08" PFMT64x "\n", pre + 2, addr);
4746  }
4747  }
4748  }
4749  rz_list_foreach (xrefs, iter, xref) {
4751  if (fcn) {
4752  if (is_rz) {
4753  rz_cons_printf("agn 0x%08" PFMT64x " %s\n", fcn->addr, fcn->name);
4754  rz_cons_printf("age 0x%08" PFMT64x " 0x%08" PFMT64x "\n", fcn->addr, addr);
4755  } else if (is_json) {
4756  xrefs_graph_fcn_start_json(pj, fcn, xref->from);
4757  } else {
4758  rz_cons_printf("%s0x%08" PFMT64x " fcn 0x%08" PFMT64x " %s\n", pre, xref->from, fcn->addr, fcn->name);
4759  }
4760  if (ht_uu_insert(ht, fcn->addr, 1)) {
4761  xrefs_graph(core, fcn->addr, level + 1, ht, mode, pj);
4762  }
4763  if (is_json) {
4764  pj_end(pj);
4765  pj_end(pj);
4766  pj_end(pj);
4767  }
4768  } else {
4769  if (is_rz) {
4770  rz_cons_printf("agn 0x%08" PFMT64x " ???\n", xref->from);
4771  rz_cons_printf("age 0x%08" PFMT64x " 0x%08" PFMT64x "\n", xref->from, addr);
4772  } else if (is_json) {
4773  char taddr[64];
4774  pj_o(pj);
4775  pj_k(pj, sdb_itoa(xref->from, taddr, 10));
4776  pj_o(pj);
4777  pj_ks(pj, "type", "???");
4778  pj_k(pj, "refs");
4779  pj_a(pj);
4780  } else {
4781  rz_cons_printf("%s0x%08" PFMT64x " ???\n", pre, xref->from);
4782  }
4783  if (ht_uu_insert(ht, xref->from, 1)) {
4784  xrefs_graph(core, xref->from, level + 1, ht, mode, pj);
4785  }
4786  if (is_json) {
4787  pj_end(pj);
4788  pj_end(pj);
4789  pj_end(pj);
4790  }
4791  }
4792  }
4793  if (is_json) {
4794  if (open_object) {
4795  pj_end(pj);
4796  pj_end(pj);
4797  pj_end(pj);
4798  }
4799  }
4800  rz_list_free(xrefs);
4801 }
4802 
4804  HtUU *ht = ht_uu_new0();
4805  if (!ht) {
4806  return RZ_CMD_STATUS_ERROR;
4807  }
4808  PJ *pj = state->mode == RZ_OUTPUT_MODE_JSON ? state->d.pj : NULL;
4809  xrefs_graph(core, core->offset, 0, ht, state->mode, pj);
4810  ht_uu_free(ht);
4811  return RZ_CMD_STATUS_OK;
4812 }
4813 
4814 #define CMD_REGS_PREFIX analysis
4815 #define CMD_REGS_REG_PATH analysis->reg
4816 #define CMD_REGS_SYNC NULL
4817 #include "cmd_regs_meta.inc"
4818 #undef CMD_REGS_PREFIX
4819 #undef CMD_REGS_REG_PATH
4820 #undef CMD_REGS_SYNC
4821 
4822 static int RzAnalysisRef_cmp(const RzAnalysisXRef *xref1, const RzAnalysisXRef *xref2) {
4823  return xref1->to != xref2->to;
4824 }
4825 
4828  RzTableColumnType *typeNumber = rz_table_type("number");
4829  rz_table_add_column(t, typeNumber, "addr", 0);
4830  rz_table_add_column(t, typeString, "name", 0);
4831  rz_table_add_column(t, typeNumber, "size", 0);
4832  rz_table_add_column(t, typeNumber, "xrefsTo", 0);
4833  rz_table_add_column(t, typeNumber, "xrefsFrom", 0);
4834  rz_table_add_column(t, typeNumber, "calls", 0);
4835  rz_table_add_column(t, typeNumber, "nbbs", 0);
4836  rz_table_add_column(t, typeNumber, "edges", 0);
4837  rz_table_add_column(t, typeNumber, "cc", 0);
4838  rz_table_add_column(t, typeNumber, "cost", 0);
4839  rz_table_add_column(t, rz_table_type("boolean"), "noreturn", 0);
4840  if (verbose) {
4841  rz_table_add_column(t, typeNumber, "min bound", 0);
4842  rz_table_add_column(t, typeNumber, "range", 0);
4843  rz_table_add_column(t, typeNumber, "max bound", 0);
4844  rz_table_add_column(t, typeNumber, "locals", 0);
4845  rz_table_add_column(t, typeNumber, "args", 0);
4846  rz_table_add_column(t, typeNumber, "frame", 0);
4847  rz_table_add_column(t, typeNumber, "loops", 0);
4848  }
4849 
4850  RzListIter *iter;
4851  RzAnalysisFunction *fcn;
4852  rz_list_foreach (list, iter, fcn) {
4853  RzList *xrefs_to = rz_analysis_function_get_xrefs_to(fcn);
4854  ut32 xref_to_num = rz_list_length(xrefs_to);
4855  rz_list_free(xrefs_to);
4856 
4858  ut32 xref_from_num = rz_list_length(xrefs);
4859  rz_list_free(xrefs);
4860 
4861  RzList *calls = rz_core_analysis_fcn_get_calls(core, fcn);
4862  // Uniquify the list by ref->addr
4863  RzList *uniq_calls = rz_list_uniq(calls, (RzListComparator)RzAnalysisRef_cmp);
4864  ut32 calls_num = rz_list_length(uniq_calls);
4865  rz_list_free(uniq_calls);
4866  rz_list_free(calls);
4867 
4868  if (verbose) {
4869  int locals = rz_analysis_var_count(core->analysis, fcn, 's', 0);
4870  locals += rz_analysis_var_count(core->analysis, fcn, 'b', 0);
4871  locals += rz_analysis_var_count(core->analysis, fcn, 'r', 0);
4872 
4873  int args = rz_analysis_var_count(core->analysis, fcn, 's', 1);
4874  args += rz_analysis_var_count(core->analysis, fcn, 'b', 1);
4875  args += rz_analysis_var_count(core->analysis, fcn, 'r', 1);
4876 
4877  rz_table_add_rowf(t, "XsndddddddbXnXdddd", fcn->addr,
4879  xref_to_num, xref_from_num, calls_num,
4884  locals, args, fcn->maxstack, rz_analysis_function_loops(fcn), NULL);
4885  } else {
4886  rz_table_add_rowf(t, "Xsndddddddb", fcn->addr,
4888  xref_to_num, xref_from_num, calls_num,
4891  fcn->is_noreturn, NULL);
4892  }
4893  }
4894 }
4895 
4896 static void function_list_print(RzCore *core, RzList *list) {
4897  RzListIter *it;
4898  RzAnalysisFunction *fcn;
4899  rz_list_foreach (list, it, fcn) {
4900  char *msg, *name = rz_core_analysis_fcn_name(core, fcn);
4901  ut64 realsize = rz_analysis_function_realsize(fcn);
4903  if (realsize == size) {
4904  msg = rz_str_newf("%-12" PFMT64u, size);
4905  } else {
4906  msg = rz_str_newf("%-4" PFMT64u " -> %-4" PFMT64u, size, realsize);
4907  }
4908  rz_cons_printf("0x%08" PFMT64x " %4d %4s %s\n",
4909  fcn->addr, rz_list_length(fcn->bbs), msg, name);
4910  free(name);
4911  free(msg);
4912  }
4913 }
4914 
4916  RzListIter *it;
4917  RzAnalysisFunction *fcn;
4918  rz_list_foreach (list, it, fcn) {
4919  rz_cons_printf("0x%08" PFMT64x " %s\n", fcn->addr, fcn->name);
4920  }
4921 }
4922 
4924  switch (fcn->type) {
4926  return 'l';
4928  return 's';
4930  return 'i';
4931  default:
4932  break;
4933  }
4934  return 'f';
4935 }
4936 
4937 static const char *diff_type_to_str(RzAnalysisDiff *diff) {
4938  if (diff->type == RZ_ANALYSIS_DIFF_TYPE_NULL) {
4939  return "new";
4940  }
4941  return diff->type == RZ_ANALYSIS_DIFF_TYPE_MATCH ? "match" : "unmatch";
4942 }
4943 
4944 static char diff_type_to_char(RzAnalysisDiff *diff) {
4945  return diff->type == RZ_ANALYSIS_DIFF_TYPE_NULL ? 'n' : diff->type;
4946 }
4947 
4949  RzAnalysisBlock *bbi;
4950  RzListIter *iter;
4951 
4952  rz_list_foreach (fcn->bbs, iter, bbi) {
4953  rz_cons_printf("afb+ 0x%08" PFMT64x " 0x%08" PFMT64x " %" PFMT64u " ",
4954  fcn->addr, bbi->addr, bbi->size);
4955  rz_cons_printf("0x%08" PFMT64x " ", bbi->jump);
4956  rz_cons_printf("0x%08" PFMT64x, bbi->fail);
4957  if (bbi->diff) {
4958  rz_cons_printf(" %c", diff_type_to_char(bbi->diff));
4959  }
4960  rz_cons_printf("\n");
4961  }
4962 }
4963 
4965  RzListIter *it;
4966  RzAnalysisFunction *fcn;
4967  rz_list_foreach (list, it, fcn) {
4968  const char *defaultCC = rz_analysis_cc_default(core->analysis);
4969  char *name = rz_core_analysis_fcn_name(core, fcn);
4970  rz_cons_printf("\"f %s %" PFMT64u " @ 0x%08" PFMT64x "\"\n", name, rz_analysis_function_linear_size(fcn), fcn->addr);
4971  rz_cons_printf("\"af+ %s %c %c @ 0x%08" PFMT64x "\"\n",
4972  name, // rz_analysis_fcn_size (fcn), name,
4973  function_type_to_char(fcn),
4974  diff_type_to_char(fcn->diff),
4975  fcn->addr);
4976  // FIXME: this command prints something annoying. Does it have important side-effects?
4977  fcn_list_bbs(fcn);
4978  if (fcn->bits != 0) {
4979  rz_cons_printf("afB %d @ 0x%08" PFMT64x "\n", fcn->bits, fcn->addr);
4980  }
4981  // FIXME command injection vuln here
4982  if (fcn->cc || defaultCC) {
4983  rz_cons_printf("afc %s @ 0x%08" PFMT64x "\n", fcn->cc ? fcn->cc : defaultCC, fcn->addr);
4984  }
4985  /* show variables and arguments */
4986  core_analysis_var_list_show(core->analysis, fcn, 'b', state);
4987  core_analysis_var_list_show(core->analysis, fcn, 'r', state);
4988  core_analysis_var_list_show(core->analysis, fcn, 's', state);
4989  /* Show references */
4991  xref_list_print_as_cmd(core, xrefs);
4992  rz_list_free(xrefs);
4993  /*Saving Function stack frame*/
4994  rz_cons_printf("afS %d @ 0x%" PFMT64x "\n", fcn->maxstack, fcn->addr);
4995  free(name);
4996  }
4997 }
4998 
5000  int ebbs = 0;
5001  pj_o(state->d.pj);
5002  pj_kn(state->d.pj, "offset", fcn->addr);
5003  char *name = rz_core_analysis_fcn_name(core, fcn);
5004  if (name) {
5005  pj_ks(state->d.pj, "name", name);
5006  }
5007  free(name);
5008  pj_kn(state->d.pj, "size", rz_analysis_function_linear_size(fcn));
5009  pj_kb(state->d.pj, "is-pure", rz_analysis_function_purity(fcn));
5010  pj_kn(state->d.pj, "realsz", rz_analysis_function_realsize(fcn));
5011  pj_kb(state->d.pj, "noreturn", fcn->is_noreturn);
5012  pj_ki(state->d.pj, "stackframe", fcn->maxstack);
5013  if (fcn->cc) {
5014  pj_ks(state->d.pj, "calltype", fcn->cc); // calling conventions
5015  }
5016  pj_ki(state->d.pj, "cost", rz_analysis_function_cost(fcn)); // execution cost
5017  pj_ki(state->d.pj, "cc", rz_analysis_function_complexity(fcn)); // cyclic cost
5018  pj_ki(state->d.pj, "loops", rz_analysis_function_loops(fcn));
5019  pj_ki(state->d.pj, "bits", fcn->bits);
5020  pj_ks(state->d.pj, "type", rz_analysis_fcntype_tostring(fcn->type));
5021  pj_ki(state->d.pj, "nbbs", rz_list_length(fcn->bbs));
5022  pj_ki(state->d.pj, "edges", rz_analysis_function_count_edges(fcn, &ebbs));
5023  pj_ki(state->d.pj, "ebbs", ebbs);
5024  {
5026  if (sig) {
5027  rz_str_trim(sig);
5028  pj_ks(state->d.pj, "signature", sig);
5029  free(sig);
5030  }
5031  }
5032  pj_kn(state->d.pj, "minbound", rz_analysis_function_min_addr(fcn));
5033  pj_kn(state->d.pj, "maxbound", rz_analysis_function_max_addr(fcn));
5034 
5035  int outdegree = 0;
5036  RzListIter *iter;
5037  RzAnalysisXRef *xrefi;
5039  if (!rz_list_empty(xrefs)) {
5040  pj_k(state->d.pj, "callrefs");
5041  pj_a(state->d.pj);
5042  rz_list_foreach (xrefs, iter, xrefi) {
5043  if (xrefi->type == RZ_ANALYSIS_XREF_TYPE_CALL) {
5044  outdegree++;
5045  }
5046  if (xrefi->type == RZ_ANALYSIS_XREF_TYPE_CODE ||
5047  xrefi->type == RZ_ANALYSIS_XREF_TYPE_CALL) {
5048  xref_print_to_json(core, xrefi, state->d.pj);
5049  }
5050  }
5051  pj_end(state->d.pj);
5052 
5053  pj_k(state->d.pj, "datarefs");
5054  pj_a(state->d.pj);
5055  rz_list_foreach (xrefs, iter, xrefi) {
5056  if (xrefi->type == RZ_ANALYSIS_XREF_TYPE_DATA ||
5057  xrefi->type == RZ_ANALYSIS_XREF_TYPE_STRING) {
5058  xref_print_to_json(core, xrefi, state->d.pj);
5059  }
5060  }
5061  pj_end(state->d.pj);
5062  }
5063  rz_list_free(xrefs);
5064 
5065  int indegree = 0;
5066  xrefs = rz_analysis_function_get_xrefs_to(fcn);
5067  if (!rz_list_empty(xrefs)) {
5068  pj_k(state->d.pj, "codexrefs");
5069  pj_a(state->d.pj);
5070  rz_list_foreach (xrefs, iter, xrefi) {
5071  if (xrefi->type == RZ_ANALYSIS_XREF_TYPE_CODE ||
5072  xrefi->type == RZ_ANALYSIS_XREF_TYPE_CALL) {
5073  indegree++;
5074  xref_print_to_json(core, xrefi, state->d.pj);
5075  }
5076  }
5077 
5078  pj_end(state->d.pj);
5079  pj_k(state->d.pj, "dataxrefs");
5080  pj_a(state->d.pj);
5081 
5082  rz_list_foreach (xrefs, iter, xrefi) {
5083  if (xrefi->type == RZ_ANALYSIS_XREF_TYPE_DATA) {
5084  xref_print_to_json(core, xrefi, state->d.pj);
5085  }
5086  }
5087  pj_end(state->d.pj);
5088  }
5089  rz_list_free(xrefs);
5090 
5091  pj_ki(state->d.pj, "indegree", indegree);
5092  pj_ki(state->d.pj, "outdegree", outdegree);
5093 
5095  pj_ki(state->d.pj, "nlocals", rz_analysis_var_count(core->analysis, fcn, 'b', 0) + rz_analysis_var_count(core->analysis, fcn, 'r', 0) + rz_analysis_var_count(core->analysis, fcn, 's', 0));
5096  pj_ki(state->d.pj, "nargs", rz_analysis_var_count(core->analysis, fcn, 'b', 1) + rz_analysis_var_count(core->analysis, fcn, 'r', 1) + rz_analysis_var_count(core->analysis, fcn, 's', 1));
5097 
5098  pj_k(state->d.pj, "bpvars");
5099  core_analysis_var_list_show(core->analysis, fcn, 'b', state);
5100  pj_k(state->d.pj, "spvars");
5101  core_analysis_var_list_show(core->analysis, fcn, 's', state);
5102  pj_k(state->d.pj, "regvars");
5103  core_analysis_var_list_show(core->analysis, fcn, 'r', state);
5104 
5105  pj_ks(state->d.pj, "difftype", diff_type_to_str(fcn->diff));
5106  if (fcn->diff->addr != -1) {
5107  pj_kn(state->d.pj, "diffaddr", fcn->diff->addr);
5108  }
5109  if (fcn->diff->name) {
5110  pj_ks(state->d.pj, "diffname", fcn->diff->name);
5111  }
5112  }
5113  pj_end(state->d.pj);
5114 }
5115 
5117  RzListIter *it;
5118  RzAnalysisFunction *fcn;
5119  pj_a(state->d.pj);
5120  rz_list_foreach (list, it, fcn) {
5121  function_print_to_json(core, fcn, state);
5122  }
5123  pj_end(state->d.pj);
5124 }
5125 
5129  switch (state->mode) {
5131  function_list_print(core, list);
5132  break;
5133  case RZ_OUTPUT_MODE_LONG:
5136  function_list_print_to_table(core, list, state->d.t, true);
5137  } else {
5138  res = RZ_CMD_STATUS_ERROR;
5139  }
5140  break;
5141  case RZ_OUTPUT_MODE_QUIET:
5143  break;
5144  case RZ_OUTPUT_MODE_RIZIN:
5146  break;
5147  case RZ_OUTPUT_MODE_JSON:
5149  break;
5150  case RZ_OUTPUT_MODE_TABLE:
5151  function_list_print_to_table(core, list, state->d.t, false);
5152  break;
5153  default:
5156  break;
5157  }
5158  return res;
5159 }
5160 
5164  rz_list_free(list);
5165  return RZ_CMD_STATUS_OK;
5166 }
5167 
5169  rz_cons_printf("%d\n", rz_list_length(core->analysis->fcns));
5170  return RZ_CMD_STATUS_OK;
5171 }
5172 
5174  RzAnalysisFunction *fcn;
5175  RzListIter *iter;
5176  ut64 total = 0;
5177  rz_list_foreach (core->analysis->fcns, iter, fcn) {
5178  total += rz_analysis_function_realsize(fcn);
5179  }
5180  rz_cons_printf("%" PFMT64u "\n", total);
5181  return RZ_CMD_STATUS_OK;
5182 }
5183 
5184 // Lists function names and their calls (uniqified)
5186  PJ *pj = state->d.pj;
5187  if (state->mode == RZ_OUTPUT_MODE_JSON) {
5188  pj_a(pj);
5189  }
5190 
5191  RzListIter *fcniter;
5192  RzAnalysisFunction *fcn;
5193  rz_list_foreach (fcns, fcniter, fcn) {
5194  // Get all refs for a function
5195  RzList *xrefs = rz_core_analysis_fcn_get_calls(core, fcn);
5196  // Uniquify the list by ref->addr
5197  RzList *uniq_xrefs = rz_list_uniq(xrefs, (RzListComparator)RzAnalysisRef_cmp);
5198 
5199  // don't enter for functions with 0 refs
5200  if (!rz_list_empty(uniq_xrefs)) {
5201  if (state->mode == RZ_OUTPUT_MODE_JSON) { // begin json output of function
5202  pj_o(pj);
5203  pj_ks(pj, "name", fcn->name);
5204  pj_kn(pj, "addr", fcn->addr);
5205  pj_k(pj, "calls");
5206  pj_a(pj);
5207  } else {
5208  rz_cons_printf("%s", fcn->name);
5209  }
5210 
5211  if (state->mode == RZ_OUTPUT_MODE_STANDARD) {
5212  rz_cons_printf(":\n");
5213  } else if (state->mode == RZ_OUTPUT_MODE_QUIET) {
5214  rz_cons_printf(" -> ");
5215  }
5216 
5217  RzListIter *refiter;
5218  RzAnalysisXRef *xrefi;
5219  rz_list_foreach (uniq_xrefs, refiter, xrefi) {
5220  RzFlagItem *f = rz_flag_get_i(core->flags, xrefi->to);
5221  char *dst = rz_str_newf((f ? f->name : "0x%08" PFMT64x), xrefi->to);
5222  if (state->mode == RZ_OUTPUT_MODE_JSON) { // Append calee json item
5223  pj_o(pj);
5224  pj_ks(pj, "name", dst);
5225  pj_kn(pj, "addr", xrefi->from);
5226  pj_end(pj); // close referenced item
5227  } else if (state->mode == RZ_OUTPUT_MODE_QUIET) {
5228  rz_cons_printf("%s ", dst);
5229  } else {
5230  rz_cons_printf(" %s\n", dst);
5231  }
5232  free(dst);
5233  }
5234  if (state->mode == RZ_OUTPUT_MODE_JSON) {
5235  pj_end(pj); // close list of calls
5236  pj_end(pj); // close function item
5237  } else {
5238  rz_cons_newline();
5239  }
5240  }
5241  rz_list_free(xrefs);
5242  rz_list_free(uniq_xrefs);
5243  }
5244 
5245  if (state->mode == RZ_OUTPUT_MODE_JSON) {
5246  pj_end(pj);
5247  }
5248 }
5249 
5253  switch (state->mode) {
5255  case RZ_OUTPUT_MODE_QUIET:
5256  case RZ_OUTPUT_MODE_JSON:
5258  break;
5259  default:
5262  break;
5263  }
5264  return res;
5265 }
5266 
5269  if (!fcns) {
5270  return RZ_CMD_STATUS_ERROR;
5271  }
5272  rz_list_sort(fcns, fcn_cmpaddr);
5274  if (!flist) {
5275  rz_list_free(fcns);
5276  return RZ_CMD_STATUS_ERROR;
5277  }
5278  char temp[32];
5279  RzListIter *iter;
5280  RzAnalysisFunction *fcn;
5281  rz_list_foreach (fcns, iter, fcn) {
5283  char *fcn_name = rz_core_analysis_fcn_name(core, fcn);
5284  RzListInfo *info = rz_listinfo_new(fcn_name, inter, inter, -1, rz_strf(temp, "%d", fcn->bits));
5285  free(fcn_name);
5286  if (!info) {
5287  break;
5288  }
5289  rz_list_append(flist, info);
5290  }
5291  RzTable *table = rz_core_table(core);
5292  rz_table_visual_list(table, flist, core->offset, core->blocksize,
5293  rz_cons_get_size(NULL), rz_config_get_i(core->config, "scr.color"));
5294  char *tablestr = rz_table_tostring(table);
5295  rz_cons_printf("\n%s\n", tablestr);
5296  free(tablestr);
5297  rz_table_free(table);
5298  rz_list_free(flist);
5299  rz_list_free(fcns);
5300  return RZ_CMD_STATUS_OK;
5301 }
5302 
5304  int tag = traced->tag;
5305  RzListIter *iter;
5306  RzDebugTracepoint *trace;
5307 
5308  rz_list_foreach (traced->traces, iter, trace) {
5309  if (!trace->tag || (tag & trace->tag)) {
5310  if (rz_analysis_function_contains(fcn, trace->addr)) {
5311  rz_cons_printf("\ntraced: %d\n", trace->times);
5312  return;
5313  }
5314  }
5315  }
5316 }
5317 
5319  RzListIter *iter;
5320  RzAnalysisXRef *xrefi;
5321  int ebbs = 0;
5322  char *name = rz_core_analysis_fcn_name(core, fcn);
5323 
5324  rz_cons_printf("#\noffset: 0x%08" PFMT64x "\nname: %s\nsize: %" PFMT64u,
5326  rz_cons_printf("\nis-pure: %s", rz_str_bool(rz_analysis_function_purity(fcn)));
5328  rz_cons_printf("\nstackframe: %d", fcn->maxstack);
5329  if (fcn->cc) {
5330  rz_cons_printf("\ncall-convention: %s", fcn->cc);
5331  }
5332  rz_cons_printf("\ncyclomatic-cost: %d", rz_analysis_function_cost(fcn));
5333  rz_cons_printf("\ncyclomatic-complexity: %d", rz_analysis_function_complexity(fcn));
5334  rz_cons_printf("\nloops: %d", rz_analysis_function_loops(fcn));
5335  rz_cons_printf("\nbits: %d", fcn->bits);
5336  rz_cons_printf("\ntype: %s", rz_analysis_fcntype_tostring(fcn->type));
5338  rz_cons_printf(" [%s]", diff_type_to_str(fcn->diff));
5339  }
5340  rz_cons_printf("\nnum-bbs: %d", rz_list_length(fcn->bbs));
5341  rz_cons_printf("\nedges: %d", rz_analysis_function_count_edges(fcn, &ebbs));
5342  rz_cons_printf("\nend-bbs: %d", ebbs);
5343  rz_cons_printf("\ncall-refs:");
5344  int outdegree = 0;
5346  rz_list_foreach (xrefs, iter, xrefi) {
5347  if (xrefi->type == RZ_ANALYSIS_XREF_TYPE_CALL) {
5348  outdegree++;
5349  }
5350  if (xrefi->type == RZ_ANALYSIS_XREF_TYPE_CODE || xrefi->type == RZ_ANALYSIS_XREF_TYPE_CALL) {
5351  rz_cons_printf(" 0x%08" PFMT64x " %c", xrefi->to,
5352  xrefi->type == RZ_ANALYSIS_XREF_TYPE_CALL ? 'C' : 'J');
5353  }
5354  }
5355  rz_cons_printf("\ndata-refs:");
5356  rz_list_foreach (xrefs, iter, xrefi) {
5357  // global or local?
5358  if (xrefi->type == RZ_ANALYSIS_XREF_TYPE_DATA) {
5359  rz_cons_printf(" 0x%08" PFMT64x, xrefi->to);
5360  }
5361  }
5362  rz_list_free(xrefs);
5363 
5364  int indegree = 0;
5365  rz_cons_printf("\ncode-xrefs:");
5366  xrefs = rz_analysis_function_get_xrefs_to(fcn);
5367  rz_list_foreach (xrefs, iter, xrefi) {
5368  if (xrefi->type == RZ_ANALYSIS_XREF_TYPE_CODE || xrefi->type == RZ_ANALYSIS_XREF_TYPE_CALL) {
5369  indegree++;
5370  rz_cons_printf(" 0x%08" PFMT64x " %c", xrefi->from,
5371  xrefi->type == RZ_ANALYSIS_XREF_TYPE_CALL ? 'C' : 'J');
5372  }
5373  }
5374  rz_cons_printf("\nnoreturn: %s", rz_str_bool(fcn->is_noreturn));
5375  rz_cons_printf("\nin-degree: %d", indegree);
5376  rz_cons_printf("\nout-degree: %d", outdegree);
5377  rz_cons_printf("\ndata-xrefs:");
5378  rz_list_foreach (xrefs, iter, xrefi) {
5379  if (xrefi->type == RZ_ANALYSIS_XREF_TYPE_DATA) {
5380  rz_cons_printf(" 0x%08" PFMT64x, xrefi->from);
5381  }
5382  }
5383  rz_list_free(xrefs);
5384 
5386  int args_count = rz_analysis_var_count(core->analysis, fcn, 'b', 1);
5387  args_count += rz_analysis_var_count(core->analysis, fcn, 's', 1);
5388  args_count += rz_analysis_var_count(core->analysis, fcn, 'r', 1);
5389  int var_count = rz_analysis_var_count(core->analysis, fcn, 'b', 0);
5390  var_count += rz_analysis_var_count(core->analysis, fcn, 's', 0);
5391  var_count += rz_analysis_var_count(core->analysis, fcn, 'r', 0);
5392 
5393  rz_cons_printf("\nlocals: %d\nargs: %d\n", var_count, args_count);
5394  core_analysis_var_list_show(core->analysis, fcn, 'b', state);
5395  core_analysis_var_list_show(core->analysis, fcn, 's', state);
5396  core_analysis_var_list_show(core->analysis, fcn, 'r', state);
5397  rz_cons_printf("diff: type: %s", diff_type_to_str(fcn->diff));
5398  if (fcn->diff->addr != -1) {
5399  rz_cons_printf("addr: 0x%" PFMT64x, fcn->diff->addr);
5400  }
5401  if (fcn->diff->name) {
5402  rz_cons_printf("function: %s", fcn->diff->name);
5403  }
5404  }
5405  free(name);
5406 
5407  // traced
5408  if (core->dbg->trace->enabled) {
5409  fcn_print_trace_info(core->dbg->trace, fcn);
5410  }
5411 }
5412 
5414  RzListIter *iter;
5415  RzAnalysisFunction *fcn;
5416  rz_list_foreach (fcns, iter, fcn) {
5417  fcn_print_info(core, fcn, state);
5418  }
5419  rz_cons_newline();
5420 }
5421 
5425  switch (state->mode) {
5427  fcn_list_print_info(core, list, state);
5428  break;
5429  case RZ_OUTPUT_MODE_RIZIN:
5431  break;
5432  case RZ_OUTPUT_MODE_JSON:
5434  break;
5435  default:
5438  break;
5439  }
5440  rz_list_free(list);
5441  return res;
5442 }
5443 
5446  if (!fcn) {
5447  return RZ_CMD_STATUS_ERROR;
5448  }
5449  if (argc == 2) {
5450  if (!fcn->imports) {
5452  if (!fcn->imports) {
5453  return RZ_CMD_STATUS_ERROR;
5454  }
5455  }
5456  char *import = strdup(argv[1]);
5457  if (!import || !rz_list_append(fcn->imports, import)) {
5458  free(import);
5459  return RZ_CMD_STATUS_ERROR;
5460  }
5461  } else {
5462  char *imp;
5463  RzListIter *iter;
5464  rz_list_foreach (fcn->imports, iter, imp) {
5465  rz_cons_printf("%s\n", imp);
5466  }
5467  }
5468  return RZ_CMD_STATUS_OK;
5469 }
5470 
5473  if (!fcn) {
5474  return RZ_CMD_STATUS_ERROR;
5475  }
5476  rz_list_free(fcn->imports);
5477  fcn->imports = NULL;
5478  return RZ_CMD_STATUS_OK;
5479 }
5480 
5481 static void ht_inc(HtPU *ht, const char *key) {
5482  bool found;
5483  HtPUKv *kv = ht_pu_find_kv(ht, key, &found);
5484  if (kv) {
5485  kv->value++;
5486  } else {
5487  ht_pu_insert(ht, key, 1);
5488  }
5489 }
5490 
5495 };
5496 
5497 static void update_stat_for_op(RzCore *core, HtPU *ht, ut64 addr, int mode) {
5499  if (!op) {
5500  return;
5501  }
5502  RzStrBuf buf;
5503  const char *key;
5504  rz_strbuf_init(&buf);
5505  if (mode == STATS_MODE_FML) {
5507  } else if (mode == STATS_MODE_TYPE) {
5509  } else {
5510  char *sp = strchr(op->mnemonic, ' ');
5511  if (sp) {
5512  rz_strbuf_setbin(&buf, (ut8 *)op->mnemonic, sp - op->mnemonic);
5513  } else {
5514  rz_strbuf_set(&buf, op->mnemonic);
5515  }
5516  key = rz_strbuf_get(&buf);
5517  }
5518  ht_inc(ht, key);
5519  rz_strbuf_fini(&buf);
5521 }
5522 
5523 static void gather_opcode_stat_for_fcn(RzCore *core, HtPU *ht, RzAnalysisFunction *fcn, int mode) {
5524  RzAnalysisBlock *bb;
5525  RzListIter *iter;
5526  rz_list_foreach (fcn->bbs, iter, bb) {
5527  update_stat_for_op(core, ht, bb->addr, mode);
5528  for (int i = 0; i < bb->op_pos_size; i++) {
5529  ut16 op_pos = bb->op_pos[i];
5530  update_stat_for_op(core, ht, bb->addr + op_pos, mode);
5531  }
5532  }
5533 }
5534 
5535 static bool list_keys_cb(RzList *list, char *k, RZ_UNUSED ut64 v) {
5536  rz_list_push(list, k);
5537  return true;
5538 }
5539 
5540 static void print_stats(RzCore *core, HtPU *ht, RzAnalysisFunction *fcn, RzCmdStateOutput *state) {
5541  const char *name;
5542  RzListIter *iter;
5544  ht_pu_foreach(ht, (HtPUForeachCallback)list_keys_cb, list);
5546  if (state->mode == RZ_OUTPUT_MODE_TABLE) {
5547  RzTable *t = state->d.t;
5549  RzTableColumnType *typeNumber = rz_table_type("number");
5550  rz_table_add_column(t, typeString, "name", 0);
5551  rz_list_foreach (list, iter, name) {
5552  rz_table_add_column(t, typeNumber, name, 0);
5553  }
5554  RzPVector *items = rz_pvector_new(free);
5555  if (!items) {
5556  RZ_LOG_ERROR("Failed to allocate memory.\n");
5557  rz_list_free(list);
5558  return;
5559  }
5560  rz_pvector_push(items, strdup(fcn->name));
5561  rz_list_foreach (list, iter, name) {
5562  int nv = (int)ht_pu_find(ht, name, NULL);
5563  rz_pvector_push(items, rz_str_newf("%d", nv));
5564  }
5565  rz_table_add_row_vec(t, items);
5566  } else {
5567  rz_list_foreach (list, iter, name) {
5568  ut32 nv = (ut32)ht_pu_find(ht, name, NULL);
5569  rz_cons_printf("%4u %s\n", nv, name);
5570  }
5571  }
5572  rz_list_free(list);
5573 }
5574 
5576  int mode = STATS_MODE_DEF;
5577  if (argc > 1) {
5578  mode = !strcmp(argv[1], "family") ? STATS_MODE_FML : STATS_MODE_TYPE;
5579  }
5581  if (!fcn) {
5582  return RZ_CMD_STATUS_ERROR;
5583  }
5584  HtPU *ht = ht_pu_new0();
5585  if (!ht) {
5586  return RZ_CMD_STATUS_ERROR;
5587  }
5588  gather_opcode_stat_for_fcn(core, ht, fcn, mode);
5589  print_stats(core, ht, fcn, state);
5590  ht_pu_free(ht);
5591  return RZ_CMD_STATUS_OK;
5592 }
5593 
5594 static bool add_keys_to_set_cb(HtPU *ht, const char *k, RZ_UNUSED const ut64 v) {
5595  if (strcmp(k, ".addr")) {
5596  ht_pu_insert(ht, k, 1);
5597  }
5598  return true;
5599 }
5600 
5602  if (state->mode != RZ_OUTPUT_MODE_TABLE) {
5603  return RZ_CMD_STATUS_ERROR;
5604  }
5606  int mode = STATS_MODE_DEF;
5607  if (argc > 1) {
5608  mode = !strcmp(argv[1], "family") ? STATS_MODE_FML : STATS_MODE_TYPE;
5609  }
5611  HtPU *keys_set = ht_pu_new0();
5612  RzList *dbs = rz_list_newf((RzListFree)ht_pu_free);
5613  if (!keys || !keys_set || !dbs) {
5614  goto exit;
5615  }
5616 
5617  RzListIter *iter;
5618  RzAnalysisFunction *fcn;
5619  rz_list_foreach (core->analysis->fcns, iter, fcn) {
5620  HtPU *db = ht_pu_new0();
5621  if (!db) {
5622  break;
5623  }
5624  gather_opcode_stat_for_fcn(core, db, fcn, mode);
5625  ht_pu_insert(db, ".addr", fcn->addr);
5626  rz_list_append(dbs, db);
5627  }
5628 
5629  HtPU *db;
5630  rz_list_foreach (dbs, iter, db) {
5631  ht_pu_foreach(db, (HtPUForeachCallback)add_keys_to_set_cb, keys_set);
5632  }
5633 
5634  ht_pu_foreach(keys_set, (HtPUForeachCallback)list_keys_cb, keys);
5636 
5637  RzTable *t = state->d.t;
5639  RzTableColumnType *typeNumber = rz_table_type("number");
5640  rz_table_add_column(t, typeString, "name", 0);
5641  rz_table_add_column(t, typeNumber, "addr", 0);
5642 
5643  char *key;
5644  rz_list_foreach (keys, iter, key) {
5645  rz_table_add_column(t, typeNumber, key, 0);
5646  }
5647 
5648  RzListIter *iter2;
5649  rz_list_foreach (dbs, iter2, db) {
5650  RzPVector *items = rz_pvector_new(free);
5651  if (!items) {
5652  break;
5653  }
5654  ut64 fcnAddr = ht_pu_find(db, ".addr", NULL);
5656  rz_pvector_push(items, fcn ? strdup(fcn->name) : strdup(""));
5657  rz_pvector_push(items, fcn ? rz_str_newf("0x%08" PFMT64x, fcnAddr) : strdup("0"));
5658  rz_list_foreach (keys, iter, key) {
5659  ut32 n = (ut32)ht_pu_find(db, key, NULL);
5660  rz_pvector_push(items, rz_str_newf("%u", n));
5661  }
5662  rz_table_add_row_vec(t, items);
5663  }
5664  res = RZ_CMD_STATUS_OK;
5665 exit:
5666  rz_list_free(keys);
5667  rz_list_free(dbs);
5668  ht_pu_free(keys_set);
5669  return res;
5670 }
5671 
5674 }
5675 
5678  if (!fcn) {
5679  return RZ_CMD_STATUS_ERROR;
5680  }
5681  char *name = rz_core_analysis_function_autoname(core, fcn);
5682  if (!name) {
5683  return RZ_CMD_STATUS_ERROR;
5684  }
5685  rz_cons_printf("%s\n", name);
5686  free(name);
5687  return RZ_CMD_STATUS_OK;
5688 }
5689 
5692  if (!fcn) {
5693  return RZ_CMD_STATUS_ERROR;
5694  }
5695  PJ *pj = state->mode == RZ_OUTPUT_MODE_JSON ? state->d.pj : NULL;
5697  return RZ_CMD_STATUS_OK;
5698 }
5699 
5702  if (!fcn) {
5703  return RZ_CMD_STATUS_ERROR;
5704  }
5705  ut64 seek = core->offset;
5706  rz_analysis_esil_set_pc(core->analysis->esil, fcn->addr);
5707  rz_core_analysis_type_match(core, fcn, NULL);
5708  rz_core_seek(core, seek, true);
5709  return RZ_CMD_STATUS_OK;
5710 }
5711 
5713  int show_color = rz_config_get_i(core->config, "scr.color");
5714  int cols = rz_config_get_i(core->config, "hex.cols") * 4;
5715  ut64 code_size = rz_num_get(core->num, "$SS");
5716  ut64 base_addr = rz_num_get(core->num, "$S");
5717 
5718  if (code_size < 1) {
5719  return RZ_CMD_STATUS_WRONG_ARGS;
5720  }
5721  char *bitmap = calloc(1, code_size + 64);
5722  if (!bitmap) {
5723  return RZ_CMD_STATUS_ERROR;
5724  }
5725 
5726  RzListIter *iter, *iter2;
5727  RzAnalysisFunction *fcn;
5728  RzAnalysisBlock *b;
5729  // for each function
5730  rz_list_foreach (core->analysis->fcns, iter, fcn) {
5731  // for each basic block in the function
5732  rz_list_foreach (fcn->bbs, iter2, b) {
5733  // if it is not within range, continue
5734  if ((fcn->addr < base_addr) || (fcn->addr >= base_addr + code_size))
5735  continue;
5736  // otherwise mark each byte in the BB in the bitmap
5737  int counter = 1;
5738  for (counter = 0; counter < b->size; counter++) {
5739  bitmap[b->addr + counter - base_addr] = '=';
5740  }
5741  bitmap[fcn->addr - base_addr] = 'F';
5742  }
5743  }
5744  // print the bitmap
5745  int assigned = 0;
5746  if (cols < 1) {
5747  cols = 1;
5748  }
5749  for (ut64 i = 0; i < code_size; i += 1) {
5750  if (!(i % cols)) {
5751  rz_cons_printf("\n0x%08" PFMT64x " ", base_addr + i);
5752  }
5753  if (bitmap[i]) {
5754  assigned++;
5755  }
5756  if (show_color) {
5757  if (bitmap[i]) {
5758  rz_cons_printf("%s%c\x1b[0m", Color_GREEN, bitmap[i]);
5759  } else {
5760  rz_cons_printf(".");
5761  }
5762  } else {
5763  rz_cons_printf("%c", bitmap[i] ? bitmap[i] : '.');
5764  }
5765  }
5766  rz_cons_printf("\n%d / %" PFMT64u " (%.2lf%%) bytes assigned to a function\n", assigned, code_size, 100.0 * ((float)assigned) / code_size);
5767  free(bitmap);
5768  return RZ_CMD_STATUS_OK;
5769 }
5770 
5772  ut64 addr = rz_num_math(core->num, argv[1]);
5773  rz_core_analysis_fcn_merge(core, core->offset, addr);
5774  return RZ_CMD_STATUS_OK;
5775 }
5776 
5779  if (!fcn) {
5780  return RZ_CMD_STATUS_ERROR;
5781  }
5782  if (argc == 1) {
5783  rz_cons_println(fcn->cc);
5784  return RZ_CMD_STATUS_OK;
5785  }
5786  if (!rz_analysis_cc_exist(core->analysis, argv[1])) {
5787  RZ_LOG_ERROR("Unknown calling convention. See `afcl` for available ones.\n");
5788  return RZ_CMD_STATUS_WRONG_ARGS;
5789  }
5790  fcn->cc = rz_str_constpool_get(&core->analysis->constpool, argv[1]);
5791  return RZ_CMD_STATUS_OK;
5792 }
5793 
5796  return RZ_CMD_STATUS_OK;
5797 }
5798 
5800  if (!rz_file_exists(argv[1])) {
5801  RZ_LOG_ERROR("File \"%s\" does not exist\n", argv[1]);
5802  return RZ_CMD_STATUS_WRONG_ARGS;
5803  }
5804  Sdb *db = sdb_new(0, argv[1], 0);
5805  if (!db) {
5806  return RZ_CMD_STATUS_ERROR;
5807  }
5808  sdb_merge(core->analysis->sdb_cc, db);
5809  sdb_close(db);
5810  sdb_free(db);
5811  return RZ_CMD_STATUS_OK;
5812 }
5813 
5816  if (!fcn) {
5817  return RZ_CMD_STATUS_ERROR;
5818  }
5819  PJ *pj = state->mode == RZ_OUTPUT_MODE_JSON ? state->d.pj : NULL;
5820  rz_core_analysis_cc_print(core, fcn->cc, pj);
5821  return RZ_CMD_STATUS_OK;
5822 }
5823 
5826  if (rz_list_empty(list)) {
5827  RZ_LOG_ERROR("No function found in 0x%08" PFMT64x ".\n", core->offset);
5828  rz_list_free(list);
5829  return RZ_CMD_STATUS_ERROR;
5830  }
5831  RzListIter *it;
5832  RzAnalysisFunction *fcn;
5833  rz_list_foreach (list, it, fcn) {
5834  st64 delta = core->offset - fcn->addr;
5835  if (delta > 0) {
5836  rz_cons_printf("%s + %" PFMT64d "\n", fcn->name, delta);
5837  } else if (delta < 0) {
5838  rz_cons_printf("%s - %" PFMT64d "\n", fcn->name, -delta);
5839  } else {
5840  rz_cons_printf("%s\n", fcn->name);
5841  }
5842  }
5843  rz_list_free(list);
5844  return RZ_CMD_STATUS_OK;
5845 }
5846 
5848  const char *name = argc == 2 ? argv[1] : NULL;
5849  bool analyze_recursively = true;
5850  if (!strcmp(argv[0], "af")) {
5851  analyze_recursively = rz_config_get_b(core->config, "analysis.calls");
5852  }
5853  return bool2status(rz_core_analysis_function_add(core, name, core->offset, analyze_recursively));
5854 }
5855 
5858  if (!diff) {
5859  RZ_LOG_ERROR("Cannot init RzAnalysisDiff\n");
5860  return RZ_CMD_STATUS_ERROR;
5861  }
5862  if (argc == 4) {
5863  switch (argv[3][0]) {
5864  case 'm':
5866  break;
5867  case 'u':
5869  break;
5870  default:
5871  break;
5872  }
5873  }
5875  if (argc >= 3) {
5876  switch (argv[2][0]) {
5877  case 'l':
5879  break;
5880  case 'i':
5882  break;
5883  case 's':
5885  break;
5886  default:
5887  break;
5888  }
5889  }
5890  RzAnalysisFunction *fcn = rz_analysis_create_function(core->analysis, argv[1], core->offset, type, diff);
5891  if (!fcn) {
5892  rz_analysis_diff_free(diff);
5893  RZ_LOG_ERROR("Cannot add function (duplicated)\n");
5894  return RZ_CMD_STATUS_ERROR;
5895  }
5896  return RZ_CMD_STATUS_OK;
5897 }
5898 
5901  if (!f) {
5902  return RZ_CMD_STATUS_ERROR;
5903  }
5904  ut64 addr = f->addr;
5908  return RZ_CMD_STATUS_OK;
5909 }
5910 
5913  RzListIter *iter, *iter_tmp;
5914  rz_list_foreach_safe (core->analysis->fcns, iter, iter_tmp, f) {
5916  rz_core_analysis_undefine(core, f->addr);
5917  }
5918  return RZ_CMD_STATUS_OK;
5919 }
5920 
5923  if (!blocks) {
5924  return RZ_CMD_STATUS_ERROR;
5925  }
5927  if (block && !rz_list_empty(block->fcns)) {
5928  ut64 table = rz_num_math(core->num, argv[1]);
5929  ut64 elements = rz_num_math(core->num, argv[2]);
5930  rz_analysis_jmptbl(core->analysis, rz_list_first(block->fcns), block, core->offset, table, elements, UT64_MAX);
5931  } else {
5932  RZ_LOG_ERROR("No function defined here\n");
5933  }
5935  return RZ_CMD_STATUS_OK;
5936 }
5937 
5939  if (!strcmp(argv[0], "afa") || rz_config_get_b(core->config, "dbg.funcarg")) {
5941  }
5942  return RZ_CMD_STATUS_OK;
5943 }
5944 
5947  return RZ_CMD_STATUS_OK;
5948 }
5949 
5950 RZ_IPI RzCmdStatus rz_il_vm_step_handler(RzCore *core, int argc, const char **argv) {
5951  ut64 repeat_times = argc == 1 ? 1 : rz_num_math(NULL, argv[1]);
5952  for (ut64 i = 0; i < repeat_times; ++i) {
5953  if (!rz_core_il_step(core)) {
5954  break;
5955  }
5956  }
5957  return RZ_CMD_STATUS_OK;
5958 }
5959 
5961  ut64 repeat_times = argc == 1 ? 1 : rz_num_math(NULL, argv[1]);
5962  PJ *pj = NULL;
5963  if (mode == RZ_OUTPUT_MODE_JSON) {
5964  pj = pj_new();
5965  if (!pj) {
5966  RZ_LOG_ERROR("cannot allocate PJ.\n");
5967  return RZ_CMD_STATUS_ERROR;
5968  }
5969  pj_a(pj);
5970  }
5971  for (ut64 i = 0; i < repeat_times; ++i) {
5972  if (!rz_core_analysis_il_step_with_events(core, pj)) {
5973  break;
5974  }
5975  }
5976  if (mode == RZ_OUTPUT_MODE_JSON) {
5977  pj_end(pj);
5979  pj_free(pj);
5980  }
5981  return RZ_CMD_STATUS_OK;
5982 }
5983 
5985  ut64 address = rz_num_math(core->num, argv[1]);
5986 
5987  if (!core->analysis->il_vm) {
5988  RZ_LOG_ERROR("RzIL: the VM is not initialized.\n");
5989  return RZ_CMD_STATUS_ERROR;
5990  }
5991 
5992  while (1) {
5994  if (pc == address) {
5995  break;
5996  }
5997  if (rz_cons_is_breaked()) {
5998  rz_cons_printf("CTRL+C was pressed.\n");
5999  break;
6000  }
6001  if (!rz_core_il_step(core)) {
6002  break;
6003  }
6004  }
6005  return RZ_CMD_STATUS_OK;
6006 }
6007 
6009  if (argc == 3) {
6010  ut64 value = rz_num_math(core->num, argv[2]);
6011  if (rz_core_analysis_il_vm_set(core, argv[1], value)) {
6012  rz_cons_printf("%s = 0x%" PFMT64x "\n", argv[1], value);
6013  }
6014  } else {
6015  // print variable or all variables
6016  rz_core_analysis_il_vm_status(core, argc == 2 ? argv[1] : NULL, mode);
6017  }
6018  return RZ_CMD_STATUS_OK;
6019 }
6020 
6023  return RZ_CMD_STATUS_OK;
6024 }
6025 
6028  return RZ_CMD_STATUS_OK;
6029 }
6030 
6032  ut64 size = 1;
6033  if (argc == 2) {
6034  size = rz_num_math(core->num, argv[1]);
6035  }
6036  rz_analysis_hint_del(core->analysis, core->offset, size);
6037  return RZ_CMD_STATUS_OK;
6038 }
6039 
6042  return RZ_CMD_STATUS_OK;
6043 }
6044 
6046  const char *arch = !strcmp(argv[1], "0") ? NULL : argv[1];
6048  return RZ_CMD_STATUS_OK;
6049 }
6050 
6053  return RZ_CMD_STATUS_OK;
6054 }
6055 
6057  ut64 bits = rz_num_math(core->num, argv[1]);
6059  return RZ_CMD_STATUS_OK;
6060 }
6061 
6064  return RZ_CMD_STATUS_OK;
6065 }
6066 
6069  return RZ_CMD_STATUS_OK;
6070 }
6071 
6074  return RZ_CMD_STATUS_OK;
6075 }
6076 
6078  ut64 jump = rz_num_math(core->num, argv[1]);
6080  return RZ_CMD_STATUS_OK;
6081 }
6082 
6085  return RZ_CMD_STATUS_OK;
6086 }
6087 
6089  rz_analysis_hint_set_esil(core->analysis, core->offset, argv[1]);
6090  return RZ_CMD_STATUS_OK;
6091 }
6092 
6095  return RZ_CMD_STATUS_OK;
6096 }
6097 
6099  rz_analysis_hint_set_opcode(core->analysis, core->offset, argv[1]);
6100  return RZ_CMD_STATUS_OK;
6101 }
6102 
6105  return RZ_CMD_STATUS_OK;
6106 }
6107 
6109  ut64 size = rz_num_math(core->num, argv[1]);
6111  return RZ_CMD_STATUS_OK;
6112 }
6113 
6116  return RZ_CMD_STATUS_OK;
6117 }
6118 
6120  ut64 fail = rz_num_math(core->num, argv[1]);
6122  return RZ_CMD_STATUS_OK;
6123 }
6124 
6127  return RZ_CMD_STATUS_OK;
6128 }
6129 
6131  ut64 size = rz_num_math(core->num, argv[1]);
6133  return RZ_CMD_STATUS_OK;
6134 }
6135 
6138  return RZ_CMD_STATUS_OK;
6139 }
6140 
6142  rz_analysis_hint_set_syntax(core->analysis, core->offset, argv[1]);
6143  return RZ_CMD_STATUS_OK;
6144 }
6145 
6148  return RZ_CMD_STATUS_OK;
6149 }
6150 
6152  ut64 ptr = rz_num_math(core->num, argv[1]);
6153  rz_analysis_hint_set_pointer(core->analysis, core->offset, ptr);
6154  return RZ_CMD_STATUS_OK;
6155 }
6156 
6159  return RZ_CMD_STATUS_OK;
6160 }
6161 
6163  ut64 ret = rz_num_math(core->num, argv[1]);
6164  rz_analysis_hint_set_ret(core->analysis, core->offset, ret);
6165  return RZ_CMD_STATUS_OK;
6166 }
6167 
6170  return RZ_CMD_STATUS_OK;
6171 }
6172 
6174  ut64 val = rz_num_math(core->num, argv[1]);
6176  return RZ_CMD_STATUS_OK;
6177 }
6178 
6181  return RZ_CMD_STATUS_OK;
6182 }
6183 
6186  if (type < 0) {
6187  return RZ_CMD_STATUS_WRONG_ARGS;
6188  }
6190  return RZ_CMD_STATUS_OK;
6191 }
6192 
6195  return RZ_CMD_STATUS_OK;
6196 }
6197 
6199  int base = rz_num_base_of_string(core->num, argv[1]);
6200  if (argc == 3) {
6201  ut64 nword = rz_num_math(core->num, argv[2]);
6202  rz_analysis_hint_set_nword(core->analysis, core->offset, (int)(nword));
6203  }
6204  rz_analysis_hint_set_immbase(core->analysis, core->offset, base);
6205  return RZ_CMD_STATUS_OK;
6206 }
6207 
6210  return RZ_CMD_STATUS_OK;
6211 }
6212 
6215 }
6216 
6219  return RZ_CMD_STATUS_OK;
6220 }
6221 
6223  ut64 toff = rz_num_math(core->num, argv[1]);
6224  if (!toff) {
6225  return RZ_CMD_STATUS_WRONG_ARGS;
6226  }
6227  RzList *typeoffs = rz_type_db_get_by_offset(core->analysis->typedb, toff);
6228  RzListIter *iter;
6229  RzTypePath *ty;
6230  // We only print type paths here
6231  rz_list_foreach (typeoffs, iter, ty) {
6232  rz_cons_printf("%s\n", ty->path);
6233  }
6234  rz_list_free(typeoffs);
6235  return RZ_CMD_STATUS_OK;
6236 }
6237 
6238 static void analysis_class_print(RzAnalysis *analysis, const char *class_name, bool detailed) {
6239  rz_cons_printf("[%s", class_name);
6240 
6241  RzVector *bases = rz_analysis_class_base_get_all(analysis, class_name);
6242  if (bases) {
6243  RzAnalysisBaseClass *base;
6244  bool first = true;
6245  rz_vector_foreach(bases, base) {
6246  if (first) {
6247  rz_cons_print(": ");
6248  first = false;
6249  } else {
6250  rz_cons_print(", ");
6251  }
6252  rz_cons_print(base->class_name);
6253  }
6254  rz_vector_free(bases);
6255  }
6256 
6257  rz_cons_print("]\n");
6258 
6259  if (detailed) {
6260  RzVector *vtables = rz_analysis_class_vtable_get_all(analysis, class_name);
6261  if (vtables) {
6262  RzAnalysisVTable *vtable;
6263  rz_vector_foreach(vtables, vtable) {
6264  rz_cons_printf(" (vtable at 0x%" PFMT64x, vtable->addr);
6265  if (vtable->offset > 0) {
6266  rz_cons_printf(" in class at +0x%" PFMT64x ")\n", vtable->offset);
6267  } else {
6268  rz_cons_print(")\n");
6269  }
6270  }
6271  rz_vector_free(vtables);
6272  }
6273 
6274  RzVector *methods = rz_analysis_class_method_get_all(analysis, class_name);
6275  if (methods && rz_vector_len(methods) > 0) {
6276  RzTable *table = rz_table_new();
6277  rz_table_set_columnsf(table, "dsxxs", "nth", "name", "addr", "vt_offset", "type");
6279  char *method_type[] = { "DEFAULT", "VIRTUAL", "V_DESTRUCTOR", "DESTRUCTOR", "CONSTRUCTOR" };
6280  RzAnalysisMethod *meth;
6281  int i = 1;
6282  rz_vector_foreach(methods, meth) {
6283  RzPVector *row_vec = rz_pvector_new(free);
6284  if (!row_vec) {
6285  RZ_LOG_ERROR("Failed to allocate memory.\n");
6286  rz_table_free(table);
6287  rz_vector_free(methods);
6288  return;
6289  }
6290  rz_pvector_push(row_vec, rz_str_newf("%d", i++));
6291  rz_pvector_push(row_vec, rz_str_new(meth->real_name));
6292  rz_pvector_push(row_vec, rz_str_newf("0x%" PFMT64x, meth->addr));
6293  if (meth->vtable_offset >= 0) {
6294  rz_pvector_push(row_vec, rz_str_newf("0x%" PFMT64x, meth->vtable_offset));
6295  } else {
6296  rz_pvector_push(row_vec, rz_str_new("-1"));
6297  }
6298  rz_pvector_push(row_vec, rz_str_new(method_type[meth->method_type]));
6299  rz_table_add_row_vec(table, row_vec);
6300  }
6301  char *s = rz_table_tostring(table);
6302  rz_cons_printf("%s\n", s);
6303  free(s);
6304  rz_table_free(table);
6305  }
6306  rz_vector_free(methods);
6307  }
6308 }
6309 
6310 static void analysis_class_print_to_json(RzAnalysis *analysis, PJ *pj, const char *class_name) {
6311  pj_o(pj);
6312  pj_ks(pj, "name", class_name);
6313 
6314  pj_k(pj, "bases");
6315  pj_a(pj);
6316  RzVector *bases = rz_analysis_class_base_get_all(analysis, class_name);
6317  if (bases) {
6318  RzAnalysisBaseClass *base;
6319  rz_vector_foreach(bases, base) {
6320  pj_o(pj);
6321  pj_ks(pj, "id", base->id);
6322  pj_ks(pj, "name", base->class_name);
6323  pj_kn(pj, "offset", base->offset);
6324  pj_end(pj);
6325  }
6326  rz_vector_free(bases);
6327  }
6328  pj_end(pj);
6329 
6330  pj_k(pj, "vtables");
6331  pj_a(pj);
6332  RzVector *vtables = rz_analysis_class_vtable_get_all(analysis, class_name);
6333  if (vtables) {
6334  RzAnalysisVTable *vtable;
6335  rz_vector_foreach(vtables, vtable) {
6336  pj_o(pj);
6337  pj_ks(pj, "id", vtable->id);
6338  pj_kn(pj, "addr", vtable->addr);
6339  pj_kn(pj, "offset", vtable->offset);
6340  pj_end(pj);
6341  }
6342  }
6343  pj_end(pj);
6344 
6345  pj_k(pj, "methods");
6346  pj_a(pj);
6347  RzVector *methods = rz_analysis_class_method_get_all(analysis, class_name);
6348  if (methods) {
6349  char *method_type[] = { "DEFAULT", "VIRTUAL", "V_DESTRUCTOR", "DESTRUCTOR", "CONSTRUCTOR" };
6350  RzAnalysisMethod *meth;
6351  rz_vector_foreach(methods, meth) {
6352  pj_o(pj);
6353  pj_ks(pj, "name", meth->real_name);
6354  pj_kn(pj, "addr", meth->addr);
6355  pj_ks(pj, "type", method_type[meth->method_type]);
6356  if (meth->vtable_offset >= 0) {
6357  pj_kn(pj, "vtable_offset", (ut64)meth->vtable_offset);
6358  }
6359  pj_end(pj);
6360  }
6361  rz_vector_free(methods);
6362  }
6363  pj_end(pj);
6364 
6365  pj_end(pj);
6366 }
6367 
6368 typedef struct {
6370  PJ *pj;
6371 } ListJsonCtx;
6372 
6373 static bool analysis_class_print_to_json_cb(void *user, const char *k, const char *v) {
6374  ListJsonCtx *ctx = user;
6375  analysis_class_print_to_json(ctx->analysis, ctx->pj, k);
6376  return true;
6377 }
6378 
6379 static void analysis_class_list_print_to_json(RzAnalysis *analysis, PJ *pj) {
6380  ListJsonCtx ctx;
6381  ctx.analysis = analysis;
6382  ctx.pj = pj;
6383  pj_a(pj);
6385  pj_end(pj);
6386  return;
6387 }
6388 
6389 static void analysis_class_print_as_cmd(RzAnalysis *analysis, const char *class_name) {
6390  RzVector *bases = rz_analysis_class_base_get_all(analysis, class_name);
6391  if (bases) {
6392  RzAnalysisBaseClass *base;
6393  rz_vector_foreach(bases, base) {
6394  rz_cons_printf("acb %s %s %" PFMT64u "\n", class_name, base->class_name, base->offset);
6395  }
6396  rz_vector_free(bases);
6397  }
6398 
6399  RzVector *vtables = rz_analysis_class_vtable_get_all(analysis, class_name);
6400  if (vtables) {
6401  RzAnalysisVTable *vtable;
6402  rz_vector_foreach(vtables, vtable) {
6403  rz_cons_printf("acv %s 0x%" PFMT64x " %" PFMT64u "\n", class_name, vtable->addr, vtable->offset);
6404  }
6405  rz_vector_free(vtables);
6406  }
6407 
6408  RzVector *methods = rz_analysis_class_method_get_all(analysis, class_name);
6409  if (methods) {
6410  RzAnalysisMethod *meth;
6411  rz_vector_foreach(methods, meth) {
6412  rz_cons_printf("acm %s %s 0x%" PFMT64x " %" PFMT64d "\n", class_name, meth->name, meth->addr, meth->vtable_offset);
6413  }
6414  rz_vector_free(methods);
6415  }
6416 }
6417 
6419  if (state->mode == RZ_OUTPUT_MODE_JSON) {
6421  return RZ_CMD_STATUS_OK;
6422  }
6423 
6425  SdbListIter *iter;
6426  SdbKv *kv;
6427  if (state->mode == RZ_OUTPUT_MODE_RIZIN) {
6428  ls_foreach (classes, iter, kv) {
6429  // need to create all classes first, so they can be referenced
6430  rz_cons_printf("ac %s\n", sdbkv_key(kv));
6431  }
6432  ls_foreach (classes, iter, kv) {
6434  }
6435  } else {
6436  ls_foreach (classes, iter, kv) {
6438  }
6439  }
6440  ls_free(classes);
6441  return RZ_CMD_STATUS_OK;
6442 }
6443 
6444 static inline void log_err_nonexist_class() {
6445  RZ_LOG_ERROR("Class does not exist.\n");
6446 }
6447 
6449  const char *class_name = argv[1];
6450  if (!rz_analysis_class_exists(core->analysis, class_name)) {
6452  return RZ_CMD_STATUS_ERROR;
6453  }
6454  switch (state->mode) {
6456  case RZ_OUTPUT_MODE_LONG:
6457  analysis_class_print(core->analysis, class_name, state->mode == RZ_OUTPUT_MODE_LONG);
6458  break;
6459  case RZ_OUTPUT_MODE_JSON:
6460  analysis_class_print_to_json(core->analysis, state->d.pj, class_name);
6461  break;
6462  default:
6464  break;
6465  }
6466  return RZ_CMD_STATUS_OK;
6467 }
6468 
6469 static RzCmdStatus class_error(RzAnalysisClassErr err) {
6471  switch (err) {
6472  case RZ_ANALYSIS_CLASS_ERR_SUCCESS:
6474  break;
6475  case RZ_ANALYSIS_CLASS_ERR_NONEXISTENT_CLASS:
6477  break;
6478  case RZ_ANALYSIS_CLASS_ERR_CLASH:
6479  RZ_LOG_ERROR("A class with this name already exists.\n");
6480  break;
6481  default:
6482  break;
6483  }
6484  return status;
6485 }
6486 
6488  const char *class_name = argv[1];
6489  if (strchr(class_name, ' ')) {
6490  RZ_LOG_ERROR("Invalid class name.\n");
6491  return RZ_CMD_STATUS_WRONG_ARGS;
6492  }
6493  RzAnalysisClassErr err = rz_analysis_class_create(core->analysis, class_name);
6494  return class_error(err);
6495 }
6496 
6499  return RZ_CMD_STATUS_OK;
6500 }
6501 
6503  const char *old_name = argv[1];
6504  const char *new_name = argv[2];
6505  if (strchr(new_name, ' ')) {
6506  RZ_LOG_ERROR("Invalid class name.\n");
6507  return RZ_CMD_STATUS_WRONG_ARGS;
6508  }
6509  RzAnalysisClassErr err = rz_analysis_class_rename(core->analysis, old_name, new_name);
6510  return class_error(err);
6511 }
6512 
6515  if (!graph) {
6516  RZ_LOG_ERROR("Couldn't create graph.\n");
6517  return RZ_CMD_STATUS_ERROR;
6518  }
6519  rz_core_graph_print(core, graph, -1, false, "");
6520  rz_graph_free(graph);
6521  return RZ_CMD_STATUS_OK;
6522 }
6523 
6524 static RzCmdStatus class_method_error(RzAnalysisClassErr err) {
6526  switch (err) {
6527  case RZ_ANALYSIS_CLASS_ERR_NONEXISTENT_ATTR:
6528  RZ_LOG_ERROR("Method does not exist.\n");
6529  break;
6530  case RZ_ANALYSIS_CLASS_ERR_CLASH:
6531  RZ_LOG_ERROR("Method already exists.\n");
6532  break;
6533  default:
6534  status = class_error(err);
6535  break;
6536  }
6537  return status;
6538 }
6539 
6541  RzAnalysisMethod meth;
6542  meth.name = strdup(argv[2]);
6543  meth.real_name = strdup(argv[2]);
6544  meth.method_type = RZ_ANALYSIS_CLASS_METHOD_DEFAULT;
6545  meth.addr = rz_num_math(core->num, argv[3]);
6546  meth.vtable_offset = -1;
6547  if (argc == 5) {
6548  meth.vtable_offset = (st64)rz_num_math(core->num, argv[4]);
6549  }
6550  RzAnalysisClassErr err = rz_analysis_class_method_set(core->analysis, argv[1], &meth);
6552  return class_method_error(err);
6553 }
6554 
6556  RzAnalysisClassErr err = rz_analysis_class_method_delete(core->analysis, argv[1], argv[2]);
6557  return class_method_error(err);
6558 }
6559 
6561  RzAnalysisClassErr err = rz_analysis_class_method_rename(core->analysis, argv[1], argv[2], argv[3]);
6562  return class_method_error(err);
6563 }
6564 
6565 static RzCmdStatus class_base_error(RzAnalysisClassErr err) {
6567  switch (err) {
6568  case RZ_ANALYSIS_CLASS_ERR_NONEXISTENT_ATTR:
6569  RZ_LOG_ERROR("Base class does not exist.\n");
6570  break;
6571  case RZ_ANALYSIS_CLASS_ERR_CLASH:
6572  RZ_LOG_ERROR("Base class already exists.\n");
6573  break;
6574  default:
6575  status = class_error(err);
6576  break;
6577  }
6578  return status;
6579 }
6580 
6582  RzAnalysisBaseClass base;
6583  base.id = NULL;
6584  base.offset = 0;
6585  base.class_name = strdup(argv[2]);
6586  if (argc == 4) {
6587  base.offset = rz_num_math(core->num, argv[3]);
6588  }
6589  RzAnalysisClassErr err = rz_analysis_class_base_set(core->analysis, argv[1], &base);
6591  return class_base_error(err);
6592 }
6593 
6595  RzAnalysisClassErr err = rz_analysis_class_base_delete(core->analysis, argv[1], argv[2]);
6596  return class_base_error(err);
6597 }
6598 
6600  const char *class_name = argv[1];
6601  if (!rz_analysis_class_exists(core->analysis, class_name)) {
6603  return RZ_CMD_STATUS_ERROR;
6604  }
6605  char *class_name_sanitized = rz_str_sanitize_sdb_key(class_name);
6606  if (!class_name_sanitized) {
6607  return RZ_CMD_STATUS_ERROR;
6608  }
6609  rz_cons_printf("%s:\n", class_name_sanitized);
6610  free(class_name_sanitized);
6611 
6612  RzVector *bases = rz_analysis_class_base_get_all(core->analysis, class_name);
6613  RzAnalysisBaseClass *base;
6614  rz_vector_foreach(bases, base) {
6615  rz_cons_printf(" %4s %s @ +0x%" PFMT64x "\n", base->id, base->class_name, base->offset);
6616  }
6617  rz_vector_free(bases);
6618  return RZ_CMD_STATUS_OK;
6619 }
6620 
6621 static RzCmdStatus class_vtable_error(RzAnalysisClassErr err) {
6623  switch (err) {
6624  case RZ_ANALYSIS_CLASS_ERR_NONEXISTENT_ATTR:
6625  RZ_LOG_ERROR("Vtable does not exist.\n");
6626  break;
6627  case RZ_ANALYSIS_CLASS_ERR_CLASH:
6628  RZ_LOG_ERROR("Vtable already exists.\n");
6629  break;
6630  default:
6631  status = class_error(err);
6632  break;
6633  }
6634  return status;
6635 }
6636 
6638  RzAnalysisVTable vtable;
6639  vtable.id = NULL;
6640  vtable.addr = rz_num_math(core->num, argv[2]);
6641  vtable.offset = 0;
6642  vtable.size = 0;
6643  if (argc >= 4) {
6644  vtable.offset = rz_num_math(core->num, argv[3]);
6645  }
6646  if (argc == 5) {
6647  vtable.size = rz_num_math(core->num, argv[4]);
6648  }
6649  RzAnalysisClassErr err = rz_analysis_class_vtable_set(core->analysis, argv[1], &vtable);
6651  return class_vtable_error(err);
6652 }
6653 
6655  RzAnalysisClassErr err = rz_analysis_class_vtable_delete(core->analysis, argv[1], argv[2]);
6656  return class_vtable_error(err);
6657 }
6658 
6660  const char *class_name = argv[1];
6661  if (!rz_analysis_class_exists(core->analysis, class_name)) {
6663  return RZ_CMD_STATUS_ERROR;
6664  }
6665  char *class_name_sanitized = rz_str_sanitize_sdb_key(class_name);
6666  if (!class_name_sanitized) {
6667  return RZ_CMD_STATUS_ERROR;
6668  }
6669  rz_cons_printf("%s:\n", class_name_sanitized);
6670  free(class_name_sanitized);
6671 
6672  RzVector *vtables = rz_analysis_class_vtable_get_all(core->analysis, class_name);
6673  if (vtables) {
6674  RzAnalysisVTable *vtable;
6675  rz_vector_foreach(vtables, vtable) {
6676  rz_cons_printf(" %4s vtable 0x%" PFMT64x " @ +0x%" PFMT64x " size:+0x%" PFMT64x "\n", vtable->id, vtable->addr, vtable->offset, vtable->size);
6677  }
6678  rz_vector_free(vtables);
6679  }
6680  return RZ_CMD_STATUS_OK;
6681 }
6682 
6683 static void list_all_functions_at_vtable_offset(RzAnalysis *analysis, const char *class_name, ut64 offset) {
6684  RVTableContext vtableContext;
6685  rz_analysis_vtable_begin(analysis, &vtableContext);
6686  ut8 function_ptr_size = vtableContext.word_size;
6687  RzVector *vtables = rz_analysis_class_vtable_get_all(analysis, class_name);
6688 
6689  if (!vtables) {
6690  return;
6691  }
6692 
6693  RzAnalysisVTable *vtable;
6694  rz_vector_foreach(vtables, vtable) {
6695  if (vtable->size < offset + function_ptr_size || offset % function_ptr_size) {
6696  continue;
6697  }
6698  ut64 func_address;
6699  if (vtableContext.read_addr(analysis, vtable->addr + offset, &func_address)) {
6700  rz_cons_printf("Function address: 0x%08" PFMT64x ", in %s vtable %s\n", func_address, class_name, vtable->id);
6701  }
6702  }
6703  rz_vector_free(vtables);
6704 }
6705 
6707  ut64 offset = rz_num_math(core->num, argv[1]);
6708  const char *class_name = argc == 3 ? argv[2] : NULL;
6709  if (class_name && !rz_analysis_class_exists(core->analysis, class_name)) {
6711  return RZ_CMD_STATUS_ERROR;
6712  }
6713 
6714  if (class_name) {
6716  return RZ_CMD_STATUS_OK;
6717  }
6719  SdbListIter *iter;
6720  SdbKv *kv;
6721  ls_foreach (classes, iter, kv) {
6722  const char *name = sdbkv_key(kv);
6724  }
6725  ls_free(classes);
6726  return RZ_CMD_STATUS_OK;
6727 }
6728 
6730  ut8 *buf;
6731  st32 len;
6732 
6733  if (!(buf = malloc(strlen(argv[1]) + 1))) {
6734  return RZ_CMD_STATUS_ERROR;
6735  }
6736 
6737  len = rz_hex_str2bin(argv[1], buf);
6738  if (len <= 0) {
6739  free(buf);
6740  return RZ_CMD_STATUS_ERROR;
6741  }
6742 
6743  switch (state->mode) {
6744  case RZ_OUTPUT_MODE_JSON:
6745  core_analysis_bytes_json(core, buf, len, 0, state->d.pj);
6746  break;
6749  break;
6750  default:
6752  break;
6753  }
6754 
6755  free(buf);
6756  return RZ_CMD_STATUS_OK;
6757 }
6758 
6760  switch (state->mode) {
6761  case RZ_OUTPUT_MODE_JSON:
6762  core_analysis_bytes_json(core, core->block, core->blocksize, 0, state->d.pj);
6763  break;
6765  core_analysis_bytes_standard(core, core->block, core->blocksize, 0);
6766  break;
6767  default:
6769  break;
6770  }
6771 
6772  return RZ_CMD_STATUS_OK;
6773 }
6774 
6776  core_analysis_bytes_esil(core, core->block, core->blocksize, 0);
6777  return RZ_CMD_STATUS_OK;
6778 }
6779 
6781  core_analysis_bytes_desc(core, core->block, core->blocksize, 0);
6782  return RZ_CMD_STATUS_OK;
6783 }
6784 
6786  core_analysis_bytes_size(core, core->block, core->blocksize, 0);
6787  return RZ_CMD_STATUS_OK;
6788 }
6789 
6791  st32 l;
6792  ut32 count = 1, obs = core->blocksize;
6793 
6794  if (argc > 1) {
6795  l = (st32)rz_num_math(core->num, argv[1]);
6796  if (l <= 0) {
6797  RZ_LOG_ERROR("Invalid zero or negative arguments.\n");
6798  return RZ_CMD_STATUS_ERROR;
6799  }
6800 
6801  count = l;
6802  l *= 8;
6803  if (l > obs) {
6804  rz_core_block_size(core, l);
6805  }
6806  }
6807 
6808  switch (state->mode) {
6809  case RZ_OUTPUT_MODE_JSON:
6810  core_analysis_bytes_json(core, core->block, core->blocksize, count, state->d.pj);
6811  break;
6813  core_analysis_bytes_standard(core, core->block, core->blocksize, count);
6814  break;
6815  default:
6817  break;
6818  }
6819 
6820  if (obs != core->blocksize) {
6821  rz_core_block_size(core, obs);
6822  }
6823  return RZ_CMD_STATUS_OK;
6824 }
6825 
6827  ut32 count = 1, obs = core->blocksize;
6828  st32 l;
6829 
6830  if (argc > 1) {
6831  l = (st32)rz_num_math(core->num, argv[1]);
6832  if (l <= 0) {
6833  RZ_LOG_ERROR("Invalid zero or negative arguments.\n");
6834  return RZ_CMD_STATUS_ERROR;
6835  }
6836  count = l;
6837  l *= 8;
6838  if (l > obs) {
6839  rz_core_block_size(core, l);
6840  }
6841  }
6842 
6843  core_analysis_bytes_size(core, core->block, core->blocksize, count);
6844 
6845  if (obs != core->blocksize) {
6846  rz_core_block_size(core, obs);
6847  }
6848  return RZ_CMD_STATUS_OK;
6849 }
6850 
6852  ut32 count = 1, obs = core->blocksize;
6853  st32 l;
6854 
6855  if (argc > 1) {
6856  l = (st32)rz_num_math(core->num, argv[1]);
6857  if (l <= 0) {
6858  RZ_LOG_ERROR("Invalid zero or negative arguments.\n");
6859  return RZ_CMD_STATUS_ERROR;
6860  }
6861  count = l;
6862  l *= 8;
6863  if (l > obs) {
6864  rz_core_block_size(core, l);
6865  }
6866  }
6867 
6868  core_analysis_bytes_esil(core, core->block, core->blocksize, count);
6869 
6870  if (obs != core->blocksize) {
6871  rz_core_block_size(core, obs);
6872  }
6873  return RZ_CMD_STATUS_OK;
6874 }
6875 
6876 RZ_IPI RzCmdStatus rz_analyze_opcode_handler(RzCore *core, int argc, const char **argv) {
6877  int cur;
6878  char *d;
6879 
6880  if (argc < 2) {
6881  cur = RZ_MAX(core->print->cur, 0);
6882  core_analysis_bytes_desc(core, core->block + cur, core->blocksize, 1);
6883  } else {
6884  d = rz_asm_describe(core->rasm, argv[1]);
6885  if (RZ_STR_ISEMPTY(d)) {
6886  RZ_LOG_ERROR("Unknown mnemonic\n");
6887  free(d);
6888  return RZ_CMD_STATUS_ERROR;
6889  }
6890  rz_cons_println(d);
6891  free(d);
6892  }
6893  return RZ_CMD_STATUS_OK;
6894 }
6895 
6896 RZ_IPI RzCmdStatus rz_display_opcode_handler(RzCore *core, int argc, const char **argv) {
6897  sdb_foreach(core->rasm->pair, listOpDescriptions, core);
6898  return RZ_CMD_STATUS_OK;
6899 }
6900 
6901 RZ_IPI RzCmdStatus rz_analyze_cycles_handler(RzCore *core, int argc, const char **argv) {
6902  RzList *hooks;
6903  RzListIter *iter;
6904  RzAnalysisCycleHook *hook;
6905  char *instr_tmp = NULL;
6906  st32 ccl = 0;
6907  RzConfigHold *hc = rz_config_hold_new(core->config);
6908 
6909  rz_config_hold_i(hc, "asm.cmt.right", "asm.functions", "asm.lines", "asm.xrefs", NULL);
6910 
6911  if (argc > 1) {
6912  ccl = (st32)rz_num_get(core->num, argv[1]);
6913  if (ccl < 0) {
6914  RZ_LOG_ERROR("Invalid negative arguments.\n");
6915  return RZ_CMD_STATUS_ERROR;
6916  }
6917  }
6918 
6919  rz_config_set_i(core->config, "asm.cmt.right", true);
6920  rz_config_set_i(core->config, "asm.functions", false);
6921  rz_config_set_i(core->config, "asm.lines", false);
6922  rz_config_set_i(core->config, "asm.xrefs", false);
6923 
6924  hooks = rz_core_analysis_cycles(core, ccl); // analysisyse
6925  rz_cons_clear_line(1);
6926  rz_list_foreach (hooks, iter, hook) {
6927  instr_tmp = rz_core_disassemble_instr(core, hook->addr, 1);
6928  rz_cons_printf("After %4i cycles:\t%s", (ccl - hook->cycles), instr_tmp);
6929  rz_cons_flush();
6930  free(instr_tmp);
6931  }
6932  rz_list_free(hooks);
6933 
6935  rz_config_hold_free(hc);
6936  return RZ_CMD_STATUS_OK;
6937 }
6938 
6939 RZ_IPI RzCmdStatus rz_convert_mne_handler(RzCore *core, int argc, const char **argv) {
6940  st32 id;
6941 
6942  if (rz_str_isnumber(argv[1])) {
6943  id = (st32)rz_num_math(core->num, argv[1]);
6944  // id starts from 1
6945  if (id <= 0) {
6946  RZ_LOG_ERROR("Invalid negative or zero arguments.\n");
6947  return RZ_CMD_STATUS_ERROR;
6948  }
6949 
6950  char *ops = rz_asm_mnemonics(core->rasm, id, false);
6951  if (!ops) {
6952  RZ_LOG_ERROR("Can not find mnemonic by id.\n");
6953  return RZ_CMD_STATUS_ERROR;
6954  }
6955 
6957  free(ops);
6958  } else {
6959  id = rz_asm_mnemonics_byname(core->rasm, argv[1]);
6960  if (id <= 0) {
6961  RZ_LOG_ERROR("Can not find id by mnemonic.\n");
6962  return RZ_CMD_STATUS_ERROR;
6963  }
6964  rz_cons_printf("%d\n", id);
6965  }
6966  return RZ_CMD_STATUS_OK;
6967 }
6968 
6969 RZ_IPI RzCmdStatus rz_list_mne_handler(RzCore *core, int argc, const char **argv) {
6970  char *nl, *ptr, *ops = rz_asm_mnemonics(core->rasm, -1, false);
6971 
6972  if (!ops) {
6973  return RZ_CMD_STATUS_ERROR;
6974  }
6975  ptr = ops;
6976  nl = strchr(ptr, '\n');
6977  while (nl) {
6978  *nl = 0;
6979  char *desc = rz_asm_describe(core->rasm, ptr);
6980  if (desc) {
6981  const char *pad = rz_str_pad(' ', 16 - strlen(ptr));
6982  rz_cons_printf("%s%s%s\n", ptr, pad, desc);
6983  free(desc);
6984  } else {
6985  rz_cons_printf("%s\n", ptr);
6986  }
6987  ptr = nl + 1;
6988  nl = strchr(ptr, '\n');
6989  }
6990  free(ops);
6991  return RZ_CMD_STATUS_OK;
6992 }
6993 
6995  return rz_core_asm_plugins_print(core, NULL, state);
6996 }
6997 
6999  if (argc > 1) {
7000  bool ret = rz_core_analysis_rename(core, argv[1], core->offset);
7001  if (!ret) {
7002  // name exists when error happens
7003  RZ_LOG_ERROR("Error happens while handling name: %s\n", argv[1]);
7004  return RZ_CMD_STATUS_ERROR;
7005  }
7006  return RZ_CMD_STATUS_OK;
7007  }
7008 
7010 }
7011 
7013  bool reg_flags_defined = rz_flag_space_count(core->flags, RZ_FLAGS_FS_REGISTERS) != 0;
7014  if (argc > 1) {
7015  rz_core_analysis_esil(core, core->offset, rz_num_get(core->num, argv[1]), NULL);
7016  } else {
7018  }
7019  if (!reg_flags_defined) {
7020  // hack to not leak flags if not wanted
7022  }
7023  return RZ_CMD_STATUS_OK;
7024 }
7025 
7027  bool reg_flags_defined = rz_flag_space_count(core->flags, RZ_FLAGS_FS_REGISTERS) != 0;
7029  if (!reg_flags_defined) {
7030  // hack to not leak flags if not wanted
7032  }
7033  return RZ_CMD_STATUS_OK;
7034 }
7035 
7037  RzListIter *iter;
7038  RzAnalysisXRef *xref;
7039  RzList *list = NULL;
7040  size_t i;
7041  for (i = 0; i < block->ninstr; i++) {
7042  ut64 ia = block->addr + block->op_pos[i];
7043  RzList *xrefs = rz_analysis_xrefs_get_to(block->analysis, ia);
7044  rz_list_foreach (xrefs, iter, xref) {
7045  if (!list) {
7046  list = rz_list_newf(free);
7047  }
7048  rz_list_push(list, ut64_new(xref->from));
7049  }
7050  }
7051  return list;
7052 }
7053 
7055  ut8 *data = malloc(block->size);
7056  if (!data) {
7057  return NULL;
7058  }
7059  RzList *list = NULL;
7060  RzAnalysisOp op;
7061  block->analysis->iob.read_at(block->analysis->iob.io, block->addr, data, block->size);
7062  for (size_t i = 0; i < block->size; i++) {
7063  int ret = rz_analysis_op(block->analysis, &op, block->addr + i, data + i, block->size - i, RZ_ANALYSIS_OP_MASK_HINT);
7064  if (ret < 1) {
7065  continue;
7066  }
7067  if (op.type == RZ_ANALYSIS_OP_TYPE_CALL) {
7068  if (!list) {
7069  list = rz_list_newf(free);
7070  }
7071  rz_list_push(list, ut64_new(op.jump));
7072  }
7074  if (op.size > 0) {
7075  i += op.size - 1;
7076  }
7077  }
7078  return list;
7079 }
7080 
7083  if (!bb) {
7084  RZ_LOG_ERROR("No basic block at 0x%" PFMT64x "\n", core->offset);
7085  return RZ_CMD_STATUS_ERROR;
7086  }
7087  rz_core_analysis_bb_info_print(core, bb, core->offset, state);
7088  return RZ_CMD_STATUS_OK;
7089 }
7090 
7092  PJ *pj = state->mode == RZ_OUTPUT_MODE_JSON ? state->d.pj : NULL;
7093  RzTable *table = state->mode == RZ_OUTPUT_MODE_TABLE ? state->d.t : NULL;
7094 
7096  rz_cmd_state_output_set_columnsf(state, "xnddsssss", "addr", "size",
7097  "traced", "ninstr", "jump", "fail", "fcns", "calls", "xrefs");
7099  RBIter iter;
7100  RzAnalysisBlock *block;
7101  rz_rbtree_foreach (core->analysis->bb_tree, iter, block, RzAnalysisBlock, _rb) {
7102  RzList *xrefs = get_xrefs(block);
7103  RzList *calls = get_calls(block);
7104  switch (state->mode) {
7105  case RZ_OUTPUT_MODE_JSON:
7106  pj_o(pj);
7107  pj_kn(pj, "addr", block->addr);
7108  pj_kb(pj, "traced", block->traced);
7109  pj_kn(pj, "ninstr", block->ninstr);
7110  pj_kn(pj, "size", block->size);
7111  if (block->jump != UT64_MAX) {
7112  pj_kn(pj, "jump", block->jump);
7113  }
7114  if (block->fail != UT64_MAX) {
7115  pj_kn(pj, "fail", block->fail);
7116  }
7117  if (xrefs) {
7118  pj_ka(pj, "xrefs");
7119  RzListIter *iter2;
7120  ut64 *addr;
7121  rz_list_foreach (xrefs, iter2, addr) {
7122  pj_n(pj, *addr);
7123  }
7124  pj_end(pj);
7125  }
7126  if (calls) {
7127  pj_ka(pj, "calls");
7128  RzListIter *iter2;
7129  ut64 *addr;
7130  rz_list_foreach (calls, iter2, addr) {
7131  pj_n(pj, *addr);
7132  }
7133  pj_end(pj);
7134  }
7135  pj_ka(pj, "fcns");
7136  RzListIter *iter2;
7137  RzAnalysisFunction *fcn;
7138  rz_list_foreach (block->fcns, iter2, fcn) {
7139  pj_n(pj, fcn->addr);
7140  }
7141  pj_end(pj);
7142  pj_end(pj);
7143  break;
7144  case RZ_OUTPUT_MODE_TABLE: {
7145  char *jump = block->jump != UT64_MAX ? rz_str_newf("0x%08" PFMT64x, block->jump) : strdup("");
7146  char *fail = block->fail != UT64_MAX ? rz_str_newf("0x%08" PFMT64x, block->fail) : strdup("");
7147  char *call = ut64join(calls);
7148  char *xref = ut64join(calls);
7149  char *fcns = fcnjoin(block->fcns);
7150  rz_table_add_rowf(table, "xnddsssss",
7151  block->addr,
7152  block->size,
7153  block->traced,
7154  block->ninstr,
7155  jump,
7156  fail,
7157  fcns,
7158  call,
7159  xref);
7160  free(jump);
7161  free(fail);
7162  free(call);
7163  free(xref);
7164  free(fcns);
7165  } break;
7166  case RZ_OUTPUT_MODE_QUIET:
7167  rz_cons_printf("0x%08" PFMT64x "\n", block->addr);
7168  break;
7170  rz_cons_printf("0x%08" PFMT64x, block->addr);
7171  if (block->jump != UT64_MAX) {
7172  rz_cons_printf(" .j 0x%08" PFMT64x, block->jump);
7173  }
7174  if (block->fail != UT64_MAX) {
7175  rz_cons_printf(" .f 0x%08" PFMT64x, block->fail);
7176  }
7177  if (xrefs) {
7178  RzListIter *iter2;
7179  rz_cons_printf(" .x");
7180  ut64 *addr;
7181  rz_list_foreach (xrefs, iter2, addr) {
7182  rz_cons_printf(" 0x%08" PFMT64x, *addr);
7183  }
7184  }
7185  if (calls) {
7186  rz_cons_printf(" .c");
7187  RzListIter *iter2;
7188  ut64 *addr;
7189  rz_list_foreach (calls, iter2, addr) {
7190  rz_cons_printf(" 0x%08" PFMT64x, *addr);
7191  }
7192  }
7193  if (block->fcns) {
7194  RzListIter *iter2;
7195  RzAnalysisFunction *fcn;
7196  rz_list_foreach (block->fcns, iter2, fcn) {
7197  rz_cons_printf(" .u 0x%" PFMT64x, fcn->addr);
7198  }
7199  }
7200  rz_cons_printf(" .s %" PFMT64d "\n", block->size);
7201  break;
7202  default:
7205  iter.len = 0;
7206  }
7207  rz_list_free(xrefs);
7208  rz_list_free(calls);
7209  }
7211  return status;
7212 }
7213 
7215  ut64 addr = rz_num_math(core->num, argv[1]);
7217  if (!block) {
7218  RZ_LOG_ERROR("No basic block at 0x%" PFMT64x "\n", core->offset);
7219  return RZ_CMD_STATUS_ERROR;
7220  }
7222  if (!path) {
7223  return RZ_CMD_STATUS_ERROR;
7224  }
7227  RzListIter *it;
7228  rz_list_foreach (path, it, block) {
7229  switch (state->mode) {
7230  case RZ_OUTPUT_MODE_JSON:
7231  pj_n(state->d.pj, block->addr);
7232  break;
7234  rz_cons_printf("0x%08" PFMT64x "\n", block->addr);
7235  break;
7236  default:
7239  it = NULL;
7240  }
7241  }
7243  rz_list_free(path);
7244  return status;
7245 }
7246 
7247 typedef enum {
7252 
7254  ut64 timeout = rz_config_get_i(core->config, "analysis.timeout");
7255  char *debugger = NULL;
7256  ut64 old_offset = core->offset;
7257  const char *notify = "Analyze all flags starting with sym. and entry0 (aa)";
7258  rz_core_notify_begin(core, "%s", notify);
7261  rz_core_analysis_all(core);
7262  rz_core_notify_done(core, "%s", notify);
7263  rz_core_task_yield(&core->tasks);
7265  goto finish;
7266  }
7267  // Run pending analysis immediately after analysis
7268  // Usefull when running commands with ";" or via rizin -c,-i
7269  debugger = core->dbg->cur ? strdup(core->dbg->cur->name) : strdup("esil");
7270  if (core->io && core->io->desc && core->io->desc->plugin && !core->io->desc->plugin->isdbg) {
7271  // set it only if is debugging
7272  RZ_FREE(debugger);
7273  }
7274  rz_cons_clear_line(1);
7276 finish:
7277  rz_core_seek(core, old_offset, true);
7278  // XXX this shouldnt be called. flags muts be created wheen the function is registered
7281  RZ_FREE(debugger);
7282 }
7283 
7284 RZ_IPI RzCmdStatus rz_analyze_simple_handler(RzCore *core, int argc, const char **argv) {
7286  return RZ_CMD_STATUS_OK;
7287 }
7288 
7291  return RZ_CMD_STATUS_OK;
7292 }
7293 
7296  return RZ_CMD_STATUS_OK;
7297 }
7298 
7300  rz_core_analysis_calls(core, false);
7301  return RZ_CMD_STATUS_OK;
7302 }
7303 
7305  rz_core_analysis_calls(core, true);
7306  return RZ_CMD_STATUS_OK;
7307 }
7308 
7310  RzListIter *iter;
7311  RzAnalysisXRef *xref;
7313  rz_list_foreach (list, iter, xref) {
7314  if (xref->type == RZ_ANALYSIS_XREF_TYPE_DATA && rz_io_is_valid_offset(core->io, xref->to, false)) {
7315  rz_core_analysis_fcn(core, xref->from, xref->to, RZ_ANALYSIS_XREF_TYPE_NULL, 1);
7316  }
7317  }
7318  rz_list_free(list);
7319  return RZ_CMD_STATUS_OK;
7320 }
7321 
7323  const bool old_hasnext = rz_config_get_b(core->config, "analysis.hasnext");
7324  rz_config_set_b(core->config, "analysis.hasnext", true);
7325  rz_core_cmd0(core, "afr @@c:isq"); // TODO: replace with C apis.
7326  rz_config_set_b(core->config, "analysis.hasnext", old_hasnext);
7327  return RZ_CMD_STATUS_OK;
7328 }
7329 
7331  rz_core_cmd0(core, "aef @@F"); // TODO: replace with C apis.
7332  return RZ_CMD_STATUS_OK;
7333 }
7334 
7336  ut64 old_offset = core->offset;
7337  RzListIter *iter;
7338  RzIOMap *map;
7339  RzList *list = rz_core_get_boundaries_prot(core, RZ_PERM_X, NULL, "analysis");
7340  if (!list) {
7341  RZ_LOG_ERROR("Cannot find maps with exec permisions.\n");
7342  return RZ_CMD_STATUS_ERROR;
7343  }
7344 
7345  const bool hasnext = rz_config_get_b(core->config, "analysis.hasnext");
7346  rz_list_foreach (list, iter, map) {
7347  rz_core_seek(core, map->itv.addr, true);
7348  rz_config_set_b(core->config, "analysis.hasnext", true);
7349  rz_core_analysis_function_add(core, NULL, core->offset, true);
7350  rz_config_set_b(core->config, "analysis.hasnext", hasnext);
7351  }
7352 
7353  rz_list_free(list);
7354  rz_core_seek(core, old_offset, true);
7355  return RZ_CMD_STATUS_OK;
7356 }
7357 
7360 }
7361 
7363  const char *filter = argc == 2 ? argv[1] : NULL;
7365 }
7366 
7368  rz_core_analysis_sigdb_print(core, state->d.t);
7369  return RZ_CMD_STATUS_OK;
7370 }
7371 
7373  st64 fcns = rz_list_length(core->analysis->fcns);
7374  st64 strs = rz_flag_count(core->flags, "str.*");
7375  st64 syms = rz_flag_count(core->flags, "sym.*");
7376  st64 imps = rz_flag_count(core->flags, "sym.imp.*");
7377  st64 sigs = rz_flag_count(core->flags, "flirt.*");
7381  st64 xrfs = rz_analysis_xrefs_count(core->analysis);
7382  double precentage = (code > 0) ? (covr * 100.0 / code) : 0;
7383 
7384  switch (state->mode) {
7386  rz_cons_printf("functions: %" PFMT64d "\n", fcns);
7387  rz_cons_printf("xrefs: %" PFMT64d "\n", xrfs);
7388  rz_cons_printf("calls: %" PFMT64d "\n", call);
7389  rz_cons_printf("strings: %" PFMT64d "\n", strs);
7390  rz_cons_printf("symbols: %" PFMT64d "\n", syms);
7391  rz_cons_printf("imports: %" PFMT64d "\n", imps);
7392  rz_cons_printf("signatures: %" PFMT64d "\n", sigs);
7393  rz_cons_printf("coverage: %" PFMT64d "\n", covr);
7394  rz_cons_printf("code size: %" PFMT64d "\n", code);
7395  rz_cons_printf("percentuage: %.2f%% (coverage on code size)\n", precentage);
7396  break;
7397  case RZ_OUTPUT_MODE_JSON:
7398  pj_o(state->d.pj);
7399  pj_ki(state->d.pj, "fcns", fcns);
7400  pj_ki(state->d.pj, "xrefs", xrfs);
7401  pj_ki(state->d.pj, "calls", call);
7402  pj_ki(state->d.pj, "strings", strs);
7403  pj_ki(state->d.pj, "symbols", syms);
7404  pj_ki(state->d.pj, "imports", imps);
7405  pj_ki(state->d.pj, "signatures", sigs);
7406  pj_ki(state->d.pj, "covrage", covr);
7407  pj_ki(state->d.pj, "codesz", code);
7408  pj_ki(state->d.pj, "percent", precentage);
7409  pj_end(state->d.pj);
7410  break;
7411  default:
7413  return RZ_CMD_STATUS_ERROR;
7414  }
7415  return RZ_CMD_STATUS_OK;
7416 }
7417 
7420  return RZ_CMD_STATUS_OK;
7421 }
7422 
7425  RZ_LOG_ERROR("cannot recover golang functions.\n");
7426  return RZ_CMD_STATUS_ERROR;
7427  }
7429  return RZ_CMD_STATUS_OK;
7430 }
7431 
7433  return bool2status(cmd_analysis_objc(core, false));
7434 }
7435 
7438  return RZ_CMD_STATUS_OK;
7439 }
7440 
7443  return RZ_CMD_STATUS_OK;
7444 }
7445 
7447  rz_core_search_preludes(core, true);
7448  return RZ_CMD_STATUS_OK;
7449 }
7450 
7452  size_t n_bytes = argc == 2 ? rz_num_math(core->num, argv[1]) : 0;
7453  return bool2status(rz_core_analysis_refs(core, n_bytes));
7454 }
7455 
7456 static bool analyze_function_at_flag(RzFlagItem *fi, RzCore *core) {
7457  bool analyze_recursively = rz_config_get_b(core->config, "analysis.calls");
7458  rz_core_analysis_function_add(core, NULL, fi->offset, analyze_recursively);
7459  return true;
7460 }
7461 
7463  bool analyze_recursively = rz_config_get_b(core->config, "analysis.calls");
7464  RzBinObject *obj = rz_bin_cur_object(core->bin);
7465  if (!obj) {
7466  RZ_LOG_ERROR("Cannot get current bin object\n");
7467  return RZ_CMD_STATUS_ERROR;
7468  }
7469 
7471  RzListIter *it;
7472  RzBinSymbol *symbol;
7473 
7474  rz_list_foreach (symbols, it, symbol) {
7475  rz_core_analysis_function_add(core, NULL, symbol->vaddr, analyze_recursively);
7476  }
7477 
7479  return RZ_CMD_STATUS_OK;
7480 }
7481 
7485  return RZ_CMD_STATUS_OK;
7486 }
7487 
7489  ut64 func_offset = argc == 2 ? rz_num_math(core->num, argv[1]) : UT64_MAX;
7490  RzAnalysisFunction *fcn;
7491 
7492  if (func_offset != UT64_MAX) {
7493  fcn = rz_analysis_get_function_at(core->analysis, func_offset);
7494  if (!fcn) {
7495  RZ_LOG_ERROR("Cannot find function '%s'\n", argv[1]);
7496  return RZ_CMD_STATUS_ERROR;
7497  }
7498  rz_core_link_stroff(core, fcn);
7499  return RZ_CMD_STATUS_OK;
7500  } else if (rz_list_empty(core->analysis->fcns)) {
7501  RZ_LOG_ERROR("Couldn't find any functions\n");
7502  return RZ_CMD_STATUS_ERROR;
7503  }
7504 
7505  RzListIter *it;
7506  rz_list_foreach (core->analysis->fcns, it, fcn) {
7507  if (rz_cons_is_breaked()) {
7508  break;
7509  }
7510  rz_core_link_stroff(core, fcn);
7511  }
7512  return RZ_CMD_STATUS_OK;
7513 }
7514 
7516  ut64 n_bytes = argc == 2 ? rz_num_math(core->num, argv[1]) : 0;
7517  return bool2status(print_cmd_analysis_after_traps_print(core, n_bytes));
7518 }
7519 
7521  size_t min_len = argc == 2 ? rz_num_math(core->num, argv[1]) : 16;
7522  if (min_len < 1) {
7523  min_len = 1;
7524  }
7525 
7526  ut64 code_size = rz_num_get(core->num, "$SS");
7527  ut64 base_addr = rz_num_get(core->num, "$S");
7528  ut64 chunk_size, chunk_offset, i;
7529  RzListIter *iter, *iter2;
7530  RzAnalysisFunction *fcn;
7531  RzAnalysisBlock *b;
7532  char *bitmap;
7533  int counter;
7534 
7535  if (code_size < 1) {
7536  RZ_LOG_ERROR("Invalid code size (size < 1)\n");
7537  return RZ_CMD_STATUS_ERROR;
7538  }
7539 
7540  bitmap = calloc(1, code_size + 64);
7541  if (!bitmap) {
7542  RZ_LOG_ERROR("Cannot allocate bitmap buffer\n");
7543  return RZ_CMD_STATUS_ERROR;
7544  }
7545 
7546  // for each function
7547  rz_list_foreach (core->analysis->fcns, iter, fcn) {
7548  // for each basic block in the function
7549  rz_list_foreach (fcn->bbs, iter2, b) {
7550  // if it is not withing range, continue
7551  if ((fcn->addr < base_addr) || (fcn->addr >= base_addr + code_size))
7552  continue;
7553  // otherwise mark each byte in the BB in the bitmap
7554  for (counter = 0; counter < b->size; counter++) {
7555  bitmap[b->addr + counter - base_addr] = '=';
7556  }
7557  // finally, add a special marker to show the beginning of a
7558  // function
7559  bitmap[fcn->addr - base_addr] = 'F';
7560  }
7561  }
7562 
7563  // Now we print the list of memory regions that are not assigned to a function
7564  chunk_size = 0;
7565  chunk_offset = 0;
7566  for (i = 0; i < code_size; i++) {
7567  if (bitmap[i]) {
7568  // We only print a region is its size is bigger than 15 bytes
7569  if (chunk_size >= min_len) {
7570  fcn = rz_analysis_get_fcn_in(core->analysis, base_addr + chunk_offset, RZ_ANALYSIS_FCN_TYPE_FCN | RZ_ANALYSIS_FCN_TYPE_SYM);
7571  if (fcn) {
7572  rz_cons_printf("0x%08" PFMT64x " %6" PFMT64u " %s\n", base_addr + chunk_offset, chunk_size, fcn->name);
7573  } else {
7574  rz_cons_printf("0x%08" PFMT64x " %6" PFMT64u "\n", base_addr + chunk_offset, chunk_size);
7575  }
7576  }
7577  chunk_size = 0;
7578  chunk_offset = i + 1;
7579  continue;
7580  }
7581  chunk_size += 1;
7582  }
7583  if (chunk_size >= 16) {
7584  fcn = rz_analysis_get_fcn_in(core->analysis, base_addr + chunk_offset, RZ_ANALYSIS_FCN_TYPE_FCN | RZ_ANALYSIS_FCN_TYPE_SYM);
7585  if (fcn) {
7586  rz_cons_printf("0x%08" PFMT64x " %6" PFMT64u " %s\n", base_addr + chunk_offset, chunk_size, fcn->name);
7587  } else {
7588  rz_cons_printf("0x%08" PFMT64x " %6" PFMT64u "\n", base_addr + chunk_offset, chunk_size);
7589  }
7590  }
7591  free(bitmap);
7592 
7593  return RZ_CMD_STATUS_OK;
7594 }
7595 
7598  return RZ_CMD_STATUS_OK;
7599 }
7600 
7602  cmd_address_info(core, core->offset, state);
7603  return RZ_CMD_STATUS_OK;
7604 }
7605 
7607  char *imp;
7608  RzListIter *iter;
7609 
7610  if (RZ_STR_ISNOTEMPTY(argv[1])) {
7612  return RZ_CMD_STATUS_OK;
7613  }
7614  rz_list_foreach (core->analysis->imports, iter, imp) {
7615  switch (state->mode) {
7617  rz_cons_printf("%s\n", imp);
7618  break;
7619  default:
7621  break;
7622  }
7623  }
7624 
7625  return RZ_CMD_STATUS_OK;
7626 }
7627 
7630  return RZ_CMD_STATUS_OK;
7631 }
size_t len
Definition: 6502dis.c:15
static struct @29 ops[]
ut8 op
Definition: 6502dis.c:13
static void print_comment(const aarch64_inst *inst, struct disassemble_info *info)
Definition: aarch64-dis.c:3074
si
RZ_API int rz_core_visual_graph(RzCore *core, RzAGraph *g, RzAnalysisFunction *_fcn, int is_interactive)
Definition: agraph.c:4114
RZ_API void rz_agraph_set_title(RzAGraph *g, const char *title)
Definition: agraph.c:3720
RZ_API RzANode * rz_agraph_get_first_node(const RzAGraph *g)
Definition: agraph.c:3846
RZ_API Sdb * rz_agraph_get_sdb(RzAGraph *g)
Definition: agraph.c:3679
RZ_API void rz_agraph_set_curnode(RzAGraph *g, RzANode *a)
Definition: agraph.c:2696
RZ_API void rz_agraph_print(RzAGraph *g)
Definition: agraph.c:3687
static void update_seek(RzConsCanvas *can, RzANode *n, int force)
Definition: agraph.c:2511
RZ_API RzAGraph * create_agraph_from_graph(const RzGraph *graph)
Create RzAGraph from generic RzGraph with RzGraphNodeInfo as node data.
Definition: agraph.c:4916
RZ_API void rz_analysis_diff_free(RzAnalysisDiff *diff)
Definition: diff.c:22
RZ_API RZ_OWN RzAnalysisDiff * rz_analysis_diff_new(void)
Definition: diff.c:9
RZ_API RZ_BORROW RzList * rz_analysis_function_list(RzAnalysis *analysis)
Definition: function.c:378
RZ_API RzAnalysisFunction * rz_analysis_get_function_at(RzAnalysis *analysis, ut64 addr)
Definition: function.c:184
RZ_API ut64 rz_analysis_function_max_addr(RzAnalysisFunction *fcn)
Definition: function.c:328
RZ_API ut64 rz_analysis_function_size_from_entry(RzAnalysisFunction *fcn)
Definition: function.c:333
RZ_API RzList * rz_analysis_get_functions_in(RzAnalysis *analysis, ut64 addr)
Definition: function.c:20
RZ_API ut64 rz_analysis_function_linear_size(RzAnalysisFunction *fcn)
Definition: function.c:318
RZ_API void rz_analysis_function_remove_block(RzAnalysisFunction *fcn, RzAnalysisBlock *bb)
Definition: function.c:286
RZ_API ut64 rz_analysis_function_realsize(const RzAnalysisFunction *fcn)
Definition: function.c:338
RZ_API RzAnalysisFunction * rz_analysis_create_function(RzAnalysis *analysis, const char *name, ut64 addr, int type, RzAnalysisDiff *diff)
Definition: function.c:146
RZ_API ut64 rz_analysis_function_min_addr(RzAnalysisFunction *fcn)
Definition: function.c:323
RZ_API bool rz_analysis_function_contains(RzAnalysisFunction *fcn, ut64 addr)
Definition: function.c:361
RZ_API void rz_analysis_add_import(RzAnalysis *analysis, const char *imp)
Definition: analysis.c:693
RZ_API void rz_analysis_purge_imports(RzAnalysis *analysis)
Definition: analysis.c:719
RZ_API int rz_analysis_archinfo(RzAnalysis *analysis, int query)
Definition: analysis.c:449
#define e(frag)
RZ_API bool cmd_analysis_objc(RzCore *core, bool auto_analysis)
#define PFMT32x
static bool finish(void *user)
Definition: analysis_pyc.c:133
RZ_API void rz_core_analysis_type_match(RzCore *core, RzAnalysisFunction *fcn, HtUU *loop_table)
Definition: analysis_tp.c:816
#define RZ_IPI
Definition: analysis_wasm.c:11
RZ_API char * rz_asm_op_get_asm(RzAsmOp *op)
Definition: aop.c:37
lzma_index ** i
Definition: index.h:629
lzma_index * src
Definition: index.h:567
static const char ext[]
Definition: apprentice.c:1981
RZ_API int rz_reg_arena_push(RzReg *reg)
Definition: arena.c:236
RZ_API void rz_reg_arena_pop(RzReg *reg)
Definition: arena.c:216
ut16 val
Definition: armass64_const.h:6
static bool err
Definition: armass.c:435
RZ_API int rz_asm_mnemonics_byname(RzAsm *a, const char *name)
Definition: asm.c:1255
RZ_API char * rz_asm_describe(RzAsm *a, const char *str)
Definition: asm.c:1187
RZ_API char * rz_asm_mnemonics(RzAsm *a, int id, bool json)
Definition: asm.c:1247
RZ_API int rz_asm_set_pc(RzAsm *a, ut64 pc)
Definition: asm.c:533
RZ_API int rz_asm_disassemble(RzAsm *a, RzAsmOp *op, const ut8 *buf, int len)
Definition: asm.c:543
int jump(int a, int b)
Definition: bcj_test.c:35
int call(int a, int b)
Definition: bcj_test.c:25
RZ_DEPRECATE RZ_API RZ_BORROW RzBinInfo * rz_bin_get_info(RzBin *bin)
Definition: bin.c:585
RZ_DEPRECATE RZ_API RZ_BORROW RzList * rz_bin_get_entries(RZ_NONNULL RzBin *bin)
Definition: bin.c:567
RZ_API RzBinObject * rz_bin_cur_object(RzBin *bin)
Definition: bin.c:900
RZ_API RzBinFile * rz_bin_cur(RzBin *bin)
Definition: bin.c:895
static RzList * classes(RzBinFile *bf)
Definition: bin_dex.c:71
RzList * entries(RzBinFile *bf)
Definition: bin_ne.c:98
RzBinInfo * info(RzBinFile *bf)
Definition: bin_ne.c:86
RzList * symbols(RzBinFile *bf)
Definition: bin_ne.c:102
static const char * typeString(ut32 n, int *bits)
Definition: bin_symbols.c:62
const char * desc
Definition: bin_vsf.c:19
static void rz_cmd(int in, int out, const char *cmd)
Definition: rizin.c:7
int bits(struct state *s, int need)
Definition: blast.c:72
RZ_API RzAnalysisBlock * rz_analysis_get_block_at(RzAnalysis *analysis, ut64 addr)
Definition: block.c:90
RZ_API void rz_analysis_block_add_switch_case(RzAnalysisBlock *block, ut64 switch_addr, ut64 case_value, ut64 case_addr)
Definition: block.c:575
RZ_API RzList * rz_analysis_get_blocks_in(RzAnalysis *analysis, ut64 addr)
Definition: block.c:133
RZ_API RzAnalysisBlock * rz_analysis_find_most_relevant_block_in(RzAnalysis *analysis, ut64 off)
Definition: block.c:997
RZ_API RZ_NULLABLE RzList * rz_analysis_block_shortest_path(RzAnalysisBlock *block, ut64 dst)
Definition: block.c:622
const lzma_allocator const uint8_t size_t uint8_t * out
Definition: block.h:528
RZ_API const RzList * rz_bin_object_get_symbols(RZ_NONNULL RzBinObject *obj)
Get list of RzBinSymbol representing the symbols in the binary object.
Definition: bobj.c:817
RZ_API RzBreakpointItem * rz_bp_get_in(RzBreakpoint *bp, ut64 addr, int perm)
Definition: bp.c:139
RZ_API RZ_BORROW RzBreakpointItem * rz_bp_get_at(RZ_NONNULL RzBreakpoint *bp, ut64 addr)
Get the breakpoint at exactly addr.
Definition: bp.c:102
RZ_API RZ_OWN RzType * rz_type_parse_string_single(RzTypeParser *parser, const char *code, char **error_msg)
Parses the single C type definition.
Definition: c_cpp_parser.c:309
RZ_IPI void rz_core_agraph_add_edge(RzCore *core, const char *un, const char *vn)
Definition: cagraph.c:39
RZ_IPI void rz_core_agraph_print_interactive(RzCore *core)
Definition: cagraph.c:88
RZ_IPI void rz_core_agraph_print_tiny(RzCore *core)
Definition: cagraph.c:72
RZ_IPI void rz_core_agraph_reset(RzCore *core)
Definition: cagraph.c:8
RZ_IPI void rz_core_agraph_print_json(RzCore *core)
Definition: cagraph.c:164
RZ_IPI void rz_core_agraph_print_dot(RzCore *core)
Definition: cagraph.c:147
RZ_IPI void rz_core_agraph_del_edge(RzCore *core, const char *un, const char *vn)
Definition: cagraph.c:52
RZ_IPI void rz_core_agraph_print_rizin(RzCore *core)
Definition: cagraph.c:159
RZ_IPI void rz_core_agraph_print_sdb(RzCore *core)
Definition: cagraph.c:81
RZ_IPI void rz_core_agraph_del_node(RzCore *core, const char *title)
Definition: cagraph.c:35
RZ_IPI void rz_core_agraph_print_gml(RzCore *core)
Definition: cagraph.c:195
RZ_IPI void rz_core_agraph_print_ascii(RzCore *core)
Definition: cagraph.c:65
RZ_IPI void rz_core_agraph_add_node(RzCore *core, const char *title, const char *body, int color)
Definition: cagraph.c:12
static RzNumCalcValue expr(RzNum *, RzNumCalc *, int)
Definition: calc.c:167
RZ_API void rz_core_analysis_function_strings_print(RZ_NONNULL RzCore *core, RZ_NONNULL RzAnalysisFunction *fcn, RZ_NULLABLE PJ *pj)
Print all string flags referenced by the function.
Definition: canalysis.c:612
RZ_IPI void rz_core_analysis_bb_info_print(RzCore *core, RzAnalysisBlock *bb, ut64 addr, RzCmdStateOutput *state)
Definition: canalysis.c:496
RZ_API RzGraph * rz_core_analysis_codexrefs(RzCore *core, ut64 addr)
Definition: canalysis.c:2412
RZ_API void rz_core_analysis_fcn_merge(RzCore *core, ut64 addr, ut64 addr2)
Definition: canalysis.c:4042
RZ_IPI char * rz_core_analysis_all_vars_display(RzCore *core, RzAnalysisFunction *fcn, bool add_name)
Definition: canalysis.c:6206
RZ_API RzList * rz_core_analysis_fcn_get_calls(RzCore *core, RzAnalysisFunction *fcn)
Definition: canalysis.c:2663
RZ_API char * rz_core_analysis_fcn_name(RzCore *core, RzAnalysisFunction *fcn)
Definition: canalysis.c:2647
RZ_IPI void rz_core_analysis_cc_print(RzCore *core, RZ_NONNULL const char *cc, RZ_NULLABLE PJ *pj)
Print Calling Convention info.
Definition: canalysis.c:6686
RZ_API RZ_OWN RzPVector * rz_core_analysis_bytes(RZ_NONNULL RzCore *core, RZ_NONNULL const ut8 *buf, int len, int nops)
Definition: canalysis.c:6817
RZ_API void rz_core_analysis_hint_print(RzAnalysis *a, ut64 addr, RzCmdStateOutput *state)
Definition: canalysis.c:1433
RZ_API void rz_core_recover_vars(RzCore *core, RzAnalysisFunction *fcn, bool argonly)
Definition: canalysis.c:2779
RZ_API bool rz_core_analysis_esil_trace_stop(RzCore *core)
Stop ESIL trace session.
Definition: canalysis.c:6770
RZ_API int rz_core_print_bb_custom(RzCore *core, RzAnalysisFunction *fcn)
Definition: canalysis.c:2118
RZ_API void rz_core_analysis_sigdb_print(RZ_NONNULL RzCore *core, RZ_NONNULL RzTable *table)
Adds all the signatures to a RzTable structure.
Definition: canalysis.c:6026
RZ_API int rz_core_analysis_all(RzCore *core)
Definition: canalysis.c:3552
RZ_IPI void rz_core_analysis_bbs_asciiart(RzCore *core, RzAnalysisFunction *fcn)
Definition: canalysis.c:305
RZ_IPI char * rz_core_analysis_var_display(RzCore *core, RzAnalysisVar *var, bool add_name)
Definition: canalysis.c:6148
RZ_API bool rz_core_analysis_continue_until_call(RZ_NONNULL RzCore *core)
Continue until call.
Definition: canalysis.c:7041
RZ_API ut64 rz_core_analysis_address(RzCore *core, ut64 addr)
Definition: canalysis.c:168
RZ_API void rz_core_analysis_undefine(RzCore *core, ut64 off)
Definition: canalysis.c:4028
RZ_API bool rz_core_analysis_function_add(RzCore *core, const char *name, ut64 addr, bool analyze_recursively)
Definition: canalysis.c:5298
RZ_IPI bool rz_core_analysis_function_delete_var(RzCore *core, RzAnalysisFunction *fcn, RzAnalysisVarKind kind, const char *id)
Definition: canalysis.c:6133
RZ_IPI bool rz_core_analysis_function_set_signature(RzCore *core, RzAnalysisFunction *fcn, const char *newsig)
Definition: canalysis.c:6380
RZ_API void rz_core_analysis_coderefs(RzCore *core, ut64 addr)
Definition: canalysis.c:2342
RZ_API void rz_core_analysis_callgraph(RzCore *core, ut64 addr, int fmt)
Definition: canalysis.c:2425
RZ_API void rz_core_analysis_flag_every_function(RzCore *core)
Definition: canalysis.c:5202
RZ_API void rz_core_analysis_datarefs(RzCore *core, ut64 addr)
Definition: canalysis.c:2314
RZ_API void rz_core_analysis_hint_list_print(RzAnalysis *a, RzCmdStateOutput *state)
Definition: canalysis.c:1422
RZ_API RzAnalysisOp * rz_core_analysis_op(RzCore *core, ut64 addr, int mask)
Definition: canalysis.c:1033
RZ_API void rz_core_analysis_autoname_all_fcns(RzCore *core)
Definition: canalysis.c:504
RZ_API bool rz_core_analysis_continue_until_syscall(RZ_NONNULL RzCore *core)
Continue until syscall.
Definition: canalysis.c:7005
RZ_API st64 rz_core_analysis_code_count(RZ_NONNULL RzCore *core)
Compute analysis code count.
Definition: canalysis.c:7098
RZ_IPI void rz_core_analysis_value_pointers(RzCore *core, RzOutputMode mode)
Definition: canalysis.c:6502
RZ_API bool rz_core_analysis_everything(RzCore *core, bool experimental, char *dh_orig)
Definition: canalysis.c:5784
RZ_API RzList * rz_core_analysis_cycles(RzCore *core, int ccl)
Definition: canalysis.c:3847
RZ_API RZ_BORROW const char * rz_core_analysis_name_type_to_str(RzCoreAnalysisNameType typ)
Convert typ to string (const char*)
Definition: canalysis.c:7140
RZ_IPI char * rz_core_analysis_function_signature(RzCore *core, RzOutputMode mode, char *fcn_name)
Definition: canalysis.c:5382
RZ_API bool rz_core_analysis_esil_trace_start(RzCore *core)
Start ESIL trace session.
Definition: canalysis.c:6746
RZ_API void rz_core_analysis_esil(RzCore *core, ut64 addr, ut64 size, RZ_NULLABLE RzAnalysisFunction *fcn)
Definition: canalysis.c:4499
RZ_IPI bool rz_core_analysis_types_propagation(RzCore *core)
Definition: canalysis.c:6325
RZ_IPI void rz_core_analysis_bbs_info_print(RzCore *core, RzAnalysisFunction *fcn, RzCmdStateOutput *state)
Definition: canalysis.c:478
RZ_API void rz_core_analysis_propagate_noreturn(RzCore *core, ut64 addr)
Definition: canalysis.c:5630
RZ_IPI void rz_core_analysis_function_signature_editor(RzCore *core, ut64 addr)
Definition: canalysis.c:6409
RZ_API bool rz_core_analysis_function_rename(RzCore *core, ut64 addr, const char *_name)
Definition: canalysis.c:5270
RZ_API bool rz_core_analysis_graph(RzCore *core, ut64 addr, int opts)
Definition: canalysis.c:2917
RZ_API st64 rz_core_analysis_coverage_count(RZ_NONNULL RzCore *core)
Compute analysis coverage count.
Definition: canalysis.c:7072
RZ_API st64 rz_core_analysis_calls_count(RZ_NONNULL RzCore *core)
Compute analysis function xrefs count.
Definition: canalysis.c:7115
RZ_IPI void rz_core_analysis_function_until(RzCore *core, ut64 addr_end)
Definition: canalysis.c:6425
RZ_API int rz_core_analysis_fcn(RzCore *core, ut64 at, ut64 from, int reftype, int depth)
Definition: canalysis.c:2026
RZ_API void rz_core_analysis_resolve_jumps(RZ_NONNULL RzCore *core)
Resolves any unresolved jump.
Definition: canalysis.c:3242
RZ_API bool rz_core_analysis_rename(RZ_NONNULL RzCore *core, RZ_NONNULL const char *name, ut64 addr)
Rename whatever var/flag/function is used at addr to name.
Definition: canalysis.c:7166
RZ_IPI bool rz_analysis_var_global_list_show(RzAnalysis *analysis, RzCmdStateOutput *state, RZ_NULLABLE const char *name)
Definition: canalysis.c:6220
RZ_IPI int fcn_cmpaddr(const void *_a, const void *_b)
Definition: canalysis.c:40
RZ_API int rz_core_print_bb_gml(RzCore *core, RzAnalysisFunction *fcn)
Definition: canalysis.c:2193
RZ_API RzGraph * rz_core_analysis_importxrefs(RzCore *core)
Definition: canalysis.c:2387
RZ_API RZ_OWN RzCoreAnalysisName * rz_core_analysis_name(RZ_NONNULL RzCore *core, ut64 addr)
Get information on whatever var/flag/function is used at addr.
Definition: canalysis.c:7203
RZ_API int rz_core_analysis_data(RzCore *core, ut64 addr, int count, int depth, int wordsize)
Definition: canalysis.c:3635
RZ_API RZ_OWN char * rz_core_analysis_function_autoname(RZ_NONNULL RzCore *core, RZ_NONNULL RzAnalysisFunction *fcn)
Suggest a name for the function.
Definition: canalysis.c:545
RZ_API bool rz_core_analysis_sigdb_apply(RZ_NONNULL RzCore *core, RZ_NULLABLE int *n_applied, RZ_NULLABLE const char *filter)
tries to apply the signatures in the flirt.sigdb.path
Definition: canalysis.c:6057
RZ_API void rz_core_analysis_name_free(RZ_NULLABLE RzCoreAnalysisName *p)
Definition: canalysis.c:7153
RZ_IPI void rz_core_analysis_fcn_returns(RzCore *core, RzAnalysisFunction *fcn)
Definition: canalysis.c:328
RZ_API bool rz_core_analysis_refs(RZ_NONNULL RzCore *core, size_t nbytes)
Analyze xrefs and prints the result.
Definition: canalysis.c:3272
RZ_API bool rz_core_analysis_hint_set_offset(RZ_NONNULL RzCore *core, RZ_NONNULL const char *struct_member)
Set analysis hint for the first immediate of the instruction at current offset to struct_member.
Definition: canalysis.c:6947
RZ_IPI bool rz_core_analysis_var_rename(RzCore *core, const char *name, const char *newname)
Definition: canalysis.c:5728
RZ_API void rz_core_print_func_args(RzCore *core)
Definition: carg.c:203
RZ_API RzCmdStatus rz_core_asm_plugins_print(RzCore *core, const char *arch, RzCmdStateOutput *state)
Definition: casm.c:150
RZ_API bool rz_analysis_cc_exist(RzAnalysis *analysis, const char *convention)
Definition: cc.c:116
RZ_API const char * rz_analysis_cc_default(RzAnalysis *analysis)
Definition: cc.c:200
RZ_API bool rz_core_esil_cmd(RzAnalysisEsil *esil, const char *cmd, ut64 a1, ut64 a2)
Definition: cconfig.c:1669
RZ_IPI void rz_core_analysis_esil_emulate(RzCore *core, ut64 addr, ut64 until_addr, int off)
Definition: cil.c:305
RZ_IPI void rz_core_analysis_esil_init_mem_p(RzCore *core)
Definition: cil.c:213
RZ_IPI void rz_core_analysis_esil_emulate_bb(RzCore *core)
Definition: cil.c:380
RZ_IPI bool rz_core_analysis_il_vm_set(RzCore *core, const char *var_name, ut64 value)
Set a vm variable from user input.
Definition: cil.c:451
RZ_IPI void rz_core_analysis_esil_references_all_functions(RzCore *core)
Definition: cil.c:290
RZ_API void rz_core_analysis_esil_init_mem(RZ_NONNULL RzCore *core, RZ_NULLABLE const char *name, ut64 addr, ut32 size)
Definition: cil.c:149
RZ_IPI void rz_core_analysis_esil_default(RzCore *core)
Definition: cil.c:409
RZ_IPI bool rz_core_analysis_il_step_with_events(RzCore *core, PJ *pj)
Definition: cil.c:655
RZ_IPI void rz_core_analysis_esil_step_over_until(RzCore *core, ut64 addr)
Definition: cil.c:280
RZ_IPI bool rz_core_il_step(RzCore *core)
Definition: cil.c:630
RZ_IPI void rz_core_analysis_il_vm_status(RzCore *core, const char *var_name, RzOutputMode mode)
Definition: cil.c:531
RZ_IPI int rz_core_analysis_set_reg(RzCore *core, const char *regname, ut64 val)
Definition: cil.c:389
RZ_API void rz_core_analysis_esil_step_over(RZ_NONNULL RzCore *core)
Definition: cil.c:269
RZ_API void rz_core_analysis_esil_reinit(RZ_NONNULL RzCore *core)
Reinitialize ESIL.
Definition: cil.c:54
RZ_API void rz_core_analysis_esil_deinit(RZ_NONNULL RzCore *core)
Deinitialize ESIL.
Definition: cil.c:66
RZ_IPI void rz_core_analysis_esil_step_over_untilexpr(RzCore *core, const char *expr)
Definition: cil.c:285
RZ_API void rz_core_analysis_esil_init_mem_del(RZ_NONNULL RzCore *core, RZ_NULLABLE const char *name, ut64 addr, ut32 size)
Remove ESIL VM stack.
Definition: cil.c:241
RZ_IPI void rz_core_analysis_il_reinit(RzCore *core)
Definition: cil.c:434
RZ_API RzVector * rz_analysis_class_base_get_all(RzAnalysis *analysis, const char *class_name)
Definition: class.c:928
RZ_API RzAnalysisClassErr rz_analysis_class_vtable_delete(RzAnalysis *analysis, const char *class_name, const char *vtable_id)
Definition: class.c:1235
RZ_API RzAnalysisClassErr rz_analysis_class_method_rename(RzAnalysis *analysis, const char *class_name, const char *old_meth_name, const char *new_meth_name)
Definition: class.c:788
RZ_API RzAnalysisClassErr rz_analysis_class_base_set(RzAnalysis *analysis, const char *class_name, RzAnalysisBaseClass *base)
Definition: class.c:983
RZ_API RzVector * rz_analysis_class_method_get_all(RzAnalysis *analysis, const char *class_name)
Definition: class.c:735
RZ_API void rz_analysis_class_base_fini(RzAnalysisBaseClass *base)
Definition: class.c:880
RZ_API bool rz_analysis_class_exists(RzAnalysis *analysis, const char *name)
Definition: class.c:167
RZ_API void rz_analysis_class_vtable_fini(RzAnalysisVTable *vtable)
Definition: class.c:1069
RZ_API RzAnalysisClassErr rz_analysis_class_rename(RzAnalysis *analysis, const char *old_name, const char *new_name)
Definition: class.c:196
RZ_API RzAnalysisClassErr rz_analysis_class_method_delete(RzAnalysis *analysis, const char *class_name, const char *meth_name)
Definition: class.c:855
RZ_API RzAnalysisClassErr rz_analysis_class_base_delete(RzAnalysis *analysis, const char *class_name, const char *base_id)
Definition: class.c:1010
RZ_API RzGraph * rz_analysis_class_get_inheritance_graph(RzAnalysis *analysis)
Creates RzGraph from class inheritance information where each node has RzGraphNodeInfo as generic dat...
Definition: class.c:1261
RZ_API RzAnalysisClassErr rz_analysis_class_vtable_set(RzAnalysis *analysis, const char *class_name, RzAnalysisVTable *vtable)
Definition: class.c:1153
RZ_API RzAnalysisClassErr rz_analysis_class_method_set(RzAnalysis *analysis, const char *class_name, RzAnalysisMethod *meth)
Definition: class.c:770
RZ_API SdbList * rz_analysis_class_get_all(RzAnalysis *analysis, bool sorted)
Definition: class.c:177
RZ_API void rz_analysis_class_method_fini(RzAnalysisMethod *meth)
Definition: class.c:606
RZ_API RzVector * rz_analysis_class_vtable_get_all(RzAnalysis *analysis, const char *class_name)
Definition: class.c:1118
RZ_API void rz_analysis_class_foreach(RzAnalysis *analysis, SdbForeachCallback cb, void *user)
Definition: class.c:181
RZ_API RzAnalysisClassErr rz_analysis_class_create(RzAnalysis *analysis, const char *name)
Definition: class.c:79
RZ_API void rz_analysis_class_delete(RzAnalysis *analysis, const char *name)
Definition: class.c:98
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
RZ_API char * rz_core_cmd_strf(RzCore *core, const char *fmt,...)
Definition: cmd.c:5472
RZ_API int rz_core_cmdf(RzCore *core, const char *fmt,...)
Definition: cmd.c:5413
RZ_API RzCmdStatus rz_core_cmd0_rzshell(RzCore *core, const char *cmd)
Definition: cmd.c:5424
RZ_API char * rz_core_disassemble_instr(RzCore *core, ut64 addr, int l)
Definition: cmd.c:5375
RZ_IPI RzCmdStatus rz_analysis_global_variable_add_handler(RzCore *core, int argc, const char **argv)
static void update_stat_for_op(RzCore *core, HtPU *ht, ut64 addr, int mode)
RZ_IPI RzCmdStatus rz_analysis_function_blocks_list_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state)
RZ_IPI RzCmdStatus rz_analysis_esil_deinit_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_analyze_all_functions_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_analysis_function_until_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_analysis_function_vars_del_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_analysis_function_vars_regs_getref_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_analysis_function_blocks_switch_type_handler(RzCore *core, int argc, const char **argv)
RZ_IPI int rz_cmd_analysis(void *data, const char *input)
static int delta_cmp2(const void *a, const void *b)
RZ_IPI RzCmdStatus rz_analysis_function_vars_bp_del_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_analysis_function_import_list_del_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_analysis_esil_init_mem_p_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_analysis_syscall_dump_c_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_analysis_functions_map_handler(RzCore *core, int argc, const char **argv)
static void var_accesses_list(RzAnalysisFunction *fcn, RzAnalysisVar *var, PJ *pj, int access_type, const char *name)
Definition: cmd_analysis.c:275
RZ_IPI RzCmdStatus rz_analysis_class_method_add_handler(RzCore *core, int argc, const char **argv)
static void fcn_list_print_info(RzCore *core, RzList *fcns, RzCmdStateOutput *state)
RZ_IPI RzCmdStatus rz_analyse_name_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state)
RZ_IPI void rz_core_agraph_print_write(RzCore *core, const char *filename)
RZ_IPI RzCmdStatus rz_analysis_print_rtti_all_handler(RzCore *core, int argc, const char **argv, RzOutputMode mode)
static RzFlagItem * core_flag_get_at_as_ref_type(RzCore *core, RzAnalysisXRef *xrefi)
RZ_IPI RzCmdStatus rz_analysis_basic_block_info_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state)
RZ_IPI RzCmdStatus rz_analyze_all_functions_esil_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_il_step_until_addr_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_list_mne_handler(RzCore *core, int argc, const char **argv)
static int var_comparator(const RzAnalysisVar *a, const RzAnalysisVar *b)
RZ_IPI RzCmdStatus rz_analysis_hint_del_all_handler(RzCore *core, int argc, const char **argv)
static bool analysis_fcn_data(RzCore *core, const char *input)
RZ_IPI RzCmdStatus rz_analysis_all_esil_handler(RzCore *core, int argc, const char **argv)
static void rz_analysis_aefa(RzCore *core, const char *arg)
static RzList * get_calls(RzAnalysisBlock *block)
RZ_IPI RzCmdStatus rz_il_vm_step_until_addr_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_analysis_hint_set_high_handler(RzCore *core, int argc, const char **argv)
static const char * xref_type2cmd(RzAnalysisXRefType type)
RZ_API bool rz_core_esil_continue_back(RZ_NONNULL RzCore *core)
RZ_IPI RzCmdStatus rz_analysis_hint_del_immbase_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_analyze_everything_experimental_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_analysis_recover_rtti_all_handler(RzCore *core, int argc, const char **argv)
RZ_API void rz_core_analysis_calls(RZ_NONNULL RzCore *core, bool imports_only)
static void function_list_print(RzCore *core, RzList *list)
RZ_IPI RzCmdStatus rz_analysis_function_cc_reg_usage_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state)
RZ_IPI RzCmdStatus rz_analysis_hint_del_handler(RzCore *core, int argc, const char **argv)
static void cmd_agraph_edge(RzCore *core, const char *input)
static char * oldregread
RZ_IPI RzCmdStatus rz_analysis_hint_del_optype_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_analysis_function_signature_type_handler(RzCore *core, int argc, const char **argv)
static RzCmdStatus class_error(RzAnalysisClassErr err)
RZ_IPI RzCmdStatus rz_analysis_function_autoname_handler(RzCore *core, int argc, const char **argv)
#define PRINTF_LN(k, fmt, arg)
Definition: cmd_analysis.c:673
static void print_graph_agg(RzGraph *graph)
RZ_IPI RzCmdStatus rz_analysis_hint_set_esil_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_analysis_hint_set_ptr_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_analysis_class_add_handler(RzCore *core, int argc, const char **argv)
static void cmd_analysis_ucall_ref(RzCore *core, ut64 addr)
RZ_IPI RzCmdStatus rz_analysis_hint_del_size_handler(RzCore *core, int argc, const char **argv)
static void __analysis_esil_function(RzCore *core, ut64 addr)
static void fcn_list_bbs(RzAnalysisFunction *fcn)
static bool analyze_function_at_flag(RzFlagItem *fi, RzCore *core)
RZ_IPI RzCmdStatus rz_analysis_xrefs_graph_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state)
RZ_IPI RzCmdStatus rz_analysis_esil_init_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_delete_global_imports_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state)
static void core_perform_auto_analysis(RzCore *core, CoreAnalysisType type)
RZ_IPI RzCmdStatus rz_analysis_function_blocks_del_all_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_analysis_function_analyze_args_handler(RzCore *core, int argc, const char **argv)
static char diff_type_to_char(RzAnalysisDiff *diff)
static int myregwrite(RzAnalysisEsil *esil, const char *name, ut64 *val)
RZ_IPI RzCmdStatus rz_analysis_function_blocks_color_handler(RzCore *core, int argc, const char **argv)
static void function_print_to_json(RzCore *core, RzAnalysisFunction *fcn, RzCmdStateOutput *state)
RZ_IPI RzCmdStatus rz_analysis_global_variable_delete_byaddr_handler(RzCore *core, int argc, const char **argv)
static void rz_core_graph_print(RzCore *core, RzGraph *graph, int use_utf, bool use_offset, const char *input)
static bool analysis_class_print_to_json_cb(void *user, const char *k, const char *v)
static void function_list_print_as_cmd(RzCore *core, RzList *list, RzCmdStateOutput *state)
static void showregs(RzList *list)
RZ_IPI RzCmdStatus rz_analysis_hint_del_stackframe_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_analysis_xrefs_set_d_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_analysis_hint_del_val_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_analysis_function_stacksz_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_display_opcode_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_analyze_all_unresolved_jumps_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_analysis_global_variable_delete_byname_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_analysis_hint_list_at_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state)
RZ_IPI RzCmdStatus rz_il_vm_step_handler(RzCore *core, int argc, const char **argv)
static int RzAnalysisRef_cmp(const RzAnalysisXRef *xref1, const RzAnalysisXRef *xref2)
RZ_IPI RzCmdStatus rz_analysis_appcall_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_analysis_syscall_dump_assembly_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_analyze_value_to_maps_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state)
RZ_IPI RzCmdStatus rz_analysis_function_vars_regs_del_all_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_analysis_function_setbits_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_analysis_class_list_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state)
RZ_IPI RzCmdStatus rz_analyze_function_linked_offsets_handler(RzCore *core, int argc, const char **argv)
static bool _aeli_iter(void *user, const ut64 key, const void *value)
static void cmd_analysis_graph(RzCore *core, const char *input)
static RzList * mymemxsr
static int mymemread(RzAnalysisEsil *esil, ut64 addr, ut8 *buf, int len)
static RzCmdStatus syscalls_dump(RzCore *core, int argc, const char **argv, bool is_c)
RZ_IPI RzCmdStatus rz_analysis_xrefs_copy_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_analysis_function_vars_xrefs_args_handler(RzCore *core, int argc, const char **argv, RzOutputMode mode)
RZ_IPI RzCmdStatus rz_il_step_skip_until_addr_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_analysis_function_blocks_edge_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_analysis_function_signature_editor_handler(RzCore *core, int argc, const char **argv)
static RzCmdStatus analysis_function_vars_accesses(RzCore *core, int access_type, const char *varname)
RZ_IPI RzCmdStatus rz_analysis_function_list_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state)
RZ_IPI RzCmdStatus rz_analysis_hint_set_val_handler(RzCore *core, int argc, const char **argv)
static void cmd_analysis_esil(RzCore *core, const char *input)
RZ_IPI RzCmdStatus rz_analyze_n_ins_size_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_analysis_function_vars_bp_getref_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_analysis_function_vars_display_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_analysis_class_vtable_lookup_handler(RzCore *core, int argc, const char **argv)
static bool listOpDescriptions(void *_core, const char *k, const char *v)
Definition: cmd_analysis.c:270
static void xrefs_graph_fcn_start_json(PJ *pj, RzAnalysisFunction *fcn, ut64 addr)
static char * fcnjoin(RzList *list)
Definition: cmd_analysis.c:782
static void function_list_print_quiet(RZ_UNUSED RzCore *core, RzList *list)
RZ_IPI RzCmdStatus rz_analysis_hint_del_high_handler(RzCore *core, int argc, const char **argv)
static void cmd_agraph_node(RzCore *core, const char *input)
static void xrefs_graph(RzCore *core, ut64 addr, int level, HtUU *ht, RzOutputMode mode, PJ *pj)
static RzCmdStatus analysis_function_vars_getsetref(RzCore *core, int delta, ut64 addr, RzAnalysisVarKind kind, RzAnalysisVarAccessType access_type)
static bool print_cmd_analysis_after_traps_print(RZ_NONNULL RzCore *core, ut64 n_bytes)
static RzList * mymemxsw
RZ_IPI RzCmdStatus rz_il_step_until_expr_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_analysis_function_blocks_add_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_analyze_recursively_all_function_types_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_analyze_all_objc_references_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_analysis_function_vars_bp_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state)
------— Base pointer based variable handlers ----------—
RZ_IPI RzCmdStatus rz_analysis_xrefs_list_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state)
RZ_IPI RzCmdStatus rz_il_step_over_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_analysis_class_base_del_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_global_imports_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state)
RZ_IPI RzCmdStatus rz_analysis_xrefs_from_list_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state)
RZ_IPI RzCmdStatus rz_analysis_continue_until_breakpoint_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_analysis_class_graph_handler(RzCore *core, int argc, const char **argv)
static RzCmdStatus class_method_error(RzAnalysisClassErr err)
static RzCmdStatus class_vtable_error(RzAnalysisClassErr err)
RZ_IPI RzCmdStatus rz_analysis_syscall_print_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state)
STATS_MODE
@ STATS_MODE_TYPE
@ STATS_MODE_DEF
@ STATS_MODE_FML
RZ_IPI RzCmdStatus rz_analysis_function_vars_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state)
static void function_list_print_to_table(RzCore *core, RzList *list, RzTable *t, bool verbose)
RZ_IPI RzCmdStatus rz_analysis_function_opcode_stat_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state)
RZ_IPI RzCmdStatus rz_analyze_n_ins_esil_handler(RzCore *core, int argc, const char **argv)
static bool convert_dot_to_image(RzCore *core, const char *dot_file, const char *save_path)
static void showregs_json(RzList *list, PJ *pj)
static RzCmdStatus analysis_function_vars_del_all(RzCore *core, RzAnalysisVarKind kind)
RZ_IPI RzCmdStatus rz_analysis_esil_init_p_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_convert_mne_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_analysis_function_vars_regs_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state)
------— Register-based variable handlers ----------—
RZ_IPI RzCmdStatus rz_analysis_function_analyze_jmptable_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_analysis_xrefs_del_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_analysis_class_vtable_add_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_analysis_function_import_list_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_analyze_n_bytes_desc_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_analysis_hint_del_ptr_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_analysis_class_info_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state)
RZ_IPI RzCmdStatus rz_analysis_class_rename_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_analysis_hint_set_immbase_handler(RzCore *core, int argc, const char **argv)
static const char * syscallNumber(int n)
RZ_IPI RzCmdStatus rz_analysis_function_strings_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state)
RZ_IPI RzCmdStatus rz_analysis_function_blocks_asciiart_handler(RzCore *core, int argc, const char **argv)
static bool contains(RzList *list, const char *name)
RZ_IPI RzCmdStatus rz_analysis_function_vars_regs_del_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_analysis_function_list_calls_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state)
static void aea_stats_fini(AeaStats *stats)
static void showmem_json(RzList *list, PJ *pj)
static void function_list_print_to_json(RzCore *core, RzList *list, RzCmdStateOutput *state)
RZ_IPI RzCmdStatus rz_analysis_function_add_recu_handler(RzCore *core, int argc, const char **argv)
static bool convert_dotcmd_to_image(RzCore *core, char *rz_cmd, const char *save_path)
static ut64 initializeEsil(RzCore *core)
Definition: cmd_analysis.c:808
static void ht_inc(HtPU *ht, const char *key)
static const char * help_detail_ae[]
Definition: cmd_analysis.c:92
static bool cmd_aea(RzCore *core, int mode, ut64 addr, int length)
static int esil_cost(RzCore *core, ut64 addr, const char *expr)
Definition: cmd_analysis.c:477
RZ_IPI RzCmdStatus rz_analyze_opcode_handler(RzCore *core, int argc, const char **argv)
static void analysis_class_print_to_json(RzAnalysis *analysis, PJ *pj, const char *class_name)
static bool analysis_fcn_data_gaps(RzCore *core, const char *input)
RZ_IPI RzCmdStatus rz_autoname_all_functions_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_analysis_function_rename_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_analysis_function_xrefs_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state)
RZ_IPI RzCmdStatus rz_analysis_class_vtable_del_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_analyze_simple_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_analysis_function_vars_sp_getref_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_analyze_n_bytes_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state)
RZ_IPI RzCmdStatus rz_analysis_function_vars_detect_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_analysis_function_describe_offset_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_analysis_rtti_demangle_class_name_handler(RzCore *core, int argc, const char **argv)
static void core_analysis_bytes_json(RzCore *core, const ut8 *buf, int len, int nops, PJ *pj)
Definition: cmd_analysis.c:590
RZ_IPI RzCmdStatus rz_analysis_global_variable_retype_handler(RzCore *core, int argc, const char **argv)
static const char * help_msg_aea[]
Definition: cmd_analysis.c:157
static int mymemwrite(RzAnalysisEsil *esil, ut64 addr, const ut8 *buf, int len)
RZ_IPI RzCmdStatus rz_analyze_all_preludes_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_analysis_function_type_matching_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_analysis_hint_del_ret_handler(RzCore *core, int argc, const char **argv)
static bool list_keys_cb(RzList *list, char *k, RZ_UNUSED ut64 v)
RZ_IPI RzCmdStatus rz_il_step_skip_until_expr_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_autoname_all_functions_noreturn_handler(RzCore *core, int argc, const char **argv)
RZ_API int rz_core_esil_step_back(RzCore *core)
RZ_IPI RzCmdStatus rz_analysis_list_vtables_handler(RzCore *core, int argc, const char **argv, RzOutputMode mode)
RZ_IPI RzCmdStatus rz_analysis_basic_block_find_paths_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state)
static void cmd_analysis_trampoline(RzCore *core, const char *input)
Definition: cmd_analysis.c:444
static void fcn_print_info(RzCore *core, RzAnalysisFunction *fcn, RzCmdStateOutput *state)
RZ_IPI RzCmdStatus rz_analysis_function_vars_xrefs_handler(RzCore *core, int argc, const char **argv, RzOutputMode mode)
RZ_IPI RzCmdStatus rz_analysis_function_vars_bp_del_all_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_analyze_n_bytes_size_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_analysis_info_show_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state)
RZ_IPI RzCmdStatus rz_analysis_xrefs_to_graph_cmd_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_analysis_function_count_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_analysis_class_base_list_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_il_step_until_opt_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_analysis_list_struct_offsets_handler(RzCore *core, int argc, const char **argv)
static RzCmdStatus analysis_function_vars_kind_list(RzCore *core, RzAnalysisFunction *fcn, RzAnalysisVarKind kind, RzCmdStateOutput *state)
RZ_IPI RzCmdStatus rz_il_step_handler(RzCore *core, int argc, const char **argv)
static char * ut64join(RzList *list)
Definition: cmd_analysis.c:795
RZ_IPI RzCmdStatus rz_analysis_hint_del_arch_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_analysis_function_size_sum_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_analysis_continue_until_syscall_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_analysis_hint_set_opcode_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_analysis_function_create_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_analysis_esil_init_mem_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_analysis_function_signature_handler(RzCore *core, int argc, const char **argv, RzOutputMode mode)
RZ_IPI RzCmdStatus rz_analyze_all_function_calls_to_imports_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_analysis_function_cc_load_handler(RzCore *core, int argc, const char **argv)
#define PJ_KN(pj, key, value)
Definition: cmd_analysis.c:382
RZ_API void rz_core_agraph_print(RzCore *core, int use_utf, const char *input)
static void xrefs_list_print(RzCore *core, RzList *list)
RZ_IPI RzCmdStatus rz_print_analysis_details_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state)
RZ_IPI RzCmdStatus rz_analysis_hint_set_jump_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_analysis_function_cc_set_get_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_analysis_function_list_ascii_handler(RzCore *core, int argc, const char **argv)
static RzList * get_xrefs(RzAnalysisBlock *block)
RZ_IPI RzCmdStatus rz_analysis_class_base_add_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_analysis_hint_set_fail_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_analysis_hint_list_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state)
RZ_IPI RzCmdStatus rz_il_vm_step_with_events_handler(RzCore *core, int argc, const char **argv, RzOutputMode mode)
RZ_IPI RzCmdStatus rz_analyze_symbols_entries_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_analysis_function_vars_sp_del_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_analysis_continue_until_esil_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_apply_signatures_from_sigdb_handler(RzCore *core, int argc, const char **argv)
static RzCmdStatus xrefs_set(RzCore *core, int argc, const char **argv, RzAnalysisXRefType type)
RZ_IPI RzCmdStatus rz_analysis_class_del_handler(RzCore *core, int argc, const char **argv)
static int delta_cmp(const void *a, const void *b)
static const char * help_msg_ad[]
Definition: cmd_analysis.c:41
RZ_IPI RzCmdStatus rz_analysis_function_args_and_vars_xrefs_handler(RzCore *core, int argc, const char **argv, RzOutputMode mode, bool use_args, bool use_vars)
static char * print_graph_dot(RzCore *core, RzGraph *graph)
static bool convert_dot_str_to_image(RzCore *core, char *str, const char *save_path)
RZ_IPI RzCmdStatus rz_analysis_xrefs_set_0_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_analyze_all_consecutive_functions_in_section_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_il_trace_stop_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_analysis_continue_until_except_handler(RzCore *core, int argc, const char **argv)
static void analysis_class_print_as_cmd(RzAnalysis *analysis, const char *class_name)
static const char _handler_no_name[]
RZ_IPI RzCmdStatus rz_analysis_syscall_show_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_print_commands_after_traps_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_analyze_n_bytes_esil_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_analysis_xrefs_set_c_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_analysis_hint_set_offset_handler(RzCore *core, int argc, const char **argv)
static int mw(RzAnalysisEsil *esil, ut64 addr, const ut8 *buf, int len)
Definition: cmd_analysis.c:465
static RzAnalysisFunction * analysis_get_function_in(RzAnalysis *analysis, ut64 offset)
Helper to get function in offset.
Definition: cmd_analysis.c:239
RZ_IPI RzCmdStatus rz_il_step_back_handler(RzCore *core, int argc, const char **argv)
static void xref_list_print_as_cmd(RZ_UNUSED RzCore *core, RzList *list)
RZ_IPI RzCmdStatus rz_analysis_function_vars_type_handler(RzCore *core, int argc, const char **argv)
static void core_analysis_var_list_show(RzAnalysis *analysis, RzAnalysisFunction *fcn, int kind, RzCmdStateOutput *state)
RZ_IPI RzCmdStatus rz_analysis_function_vars_regs_setref_handler(RzCore *core, int argc, const char **argv)
static void core_analysis_bytes_esil(RzCore *core, const ut8 *buf, int len, int nops)
Definition: cmd_analysis.c:552
RZ_IPI RzCmdStatus rz_analyze_all_data_references_to_code_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_analysis_function_vars_dis_refs_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_il_vm_initialize_handler(RzCore *core, int argc, const char **argv)
RzVarListType
Definition: cmd_analysis.c:305
@ IS_ARG_AND_VAR
Definition: cmd_analysis.c:308
@ IS_VAR
Definition: cmd_analysis.c:306
@ IS_ARG
Definition: cmd_analysis.c:307
RZ_IPI RzCmdStatus rz_analysis_class_method_rename_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_analysis_function_vars_xrefs_vars_handler(RzCore *core, int argc, const char **argv, RzOutputMode mode)
RZ_IPI RzCmdStatus rz_il_trace_start_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_analysis_hint_del_bits_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_analysis_hint_del_offset_handler(RzCore *core, int argc, const char **argv)
#define hasNext(x)
HEAPTYPE(ut64)
RZ_IPI RzCmdStatus rz_analysis_hint_set_optype_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_analyze_symbols_entries_flags_handler(RzCore *core, int argc, const char **argv)
static char * dot_executable_path(void)
RZ_IPI RzCmdStatus rz_analysis_syscall_name_handler(RzCore *core, int argc, const char **argv)
static void syscall_dump(RzSyscallItem *si, bool is_c)
#define PRINTF_LN_STR(k, arg)
Definition: cmd_analysis.c:688
static void print_trampolines(RzCore *core, ut64 a, ut64 b, size_t element_size)
Definition: cmd_analysis.c:427
RZ_IPI RzCmdStatus rz_analysis_hint_set_ret_handler(RzCore *core, int argc, const char **argv)
static void core_analysis_bytes_desc(RzCore *core, const ut8 *buf, int len, int nops)
Definition: cmd_analysis.c:516
RZ_IPI RzCmdStatus rz_analysis_syscall_number_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_analysis_continue_until_addr_handler(RzCore *core, int argc, const char **argv)
static bool core_analysis_name_print(RzCore *core, RzCmdStateOutput *state)
Definition: cmd_analysis.c:390
RZ_IPI RzCmdStatus rz_analysis_global_variable_rename_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_analysis_hint_del_opcode_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_analyze_everything_handler(RzCore *core, int argc, const char **argv)
static void showmem(RzList *list)
static char function_type_to_char(RzAnalysisFunction *fcn)
RZ_IPI RzCmdStatus rz_analysis_function_vars_bp_setref_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_analysis_xrefs_set_s_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_analysis_hint_set_bits_handler(RzCore *core, int argc, const char **argv)
static void cmd_address_info(RzCore *core, const ut64 addr, RzCmdStateOutput *state)
RZ_IPI RzCmdStatus rz_analysis_xrefs_to_list_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state)
static void gather_opcode_stat_for_fcn(RzCore *core, HtPU *ht, RzAnalysisFunction *fcn, int mode)
RZ_IPI RzCmdStatus rz_il_step_skip_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_il_step_over_until_addr_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_analysis_hint_set_size_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_analysis_esil_init_mem_remove_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_analysis_function_list_in_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_il_step_evaluate_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_analysis_hint_del_syntax_handler(RzCore *core, int argc, const char **argv)
static void core_analysis_bytes_size(RzCore *core, const ut8 *buf, int len, int nops)
Definition: cmd_analysis.c:492
RZ_IPI RzCmdStatus rz_print_areas_no_functions_handler(RzCore *core, int argc, const char **argv)
static void analysis_class_print(RzAnalysis *analysis, const char *class_name, bool detailed)
RZ_IPI RzCmdStatus rz_analysis_continue_until_call_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_recover_all_golang_functions_strings_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_analysis_function_vars_rename_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_analysis_print_global_variable_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state)
RZ_IPI RzCmdStatus rz_analysis_class_method_del_handler(RzCore *core, int argc, const char **argv)
static void _analysis_calls(RzCore *core, ut64 addr, ut64 addr_end, bool importsOnly)
static RzCmdStatus analysis_function_vars_del(RzCore *core, RzAnalysisVarKind kind, const char *varname)
RZ_IPI RzCmdStatus rz_analysis_function_vars_stackframe_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_analyze_all_function_calls_handler(RzCore *core, int argc, const char **argv)
static void fcn_print_trace_info(RzDebugTrace *traced, RzAnalysisFunction *fcn)
RZ_IPI RzCmdStatus rz_analysis_function_del_handler(RzCore *core, int argc, const char **argv)
static void list_vars(RzCore *core, RzAnalysisFunction *fcn, PJ *pj, int type, const char *name, RzVarListType vlt)
Definition: cmd_analysis.c:311
RZ_IPI RzCmdStatus rz_analysis_hint_del_fail_handler(RzCore *core, int argc, const char **argv)
static const char * help_msg_a[]
Definition: cmd_analysis.c:14
static const char * help_msg_agn[]
Definition: cmd_analysis.c:222
RZ_IPI RzCmdStatus rz_analysis_basic_block_list_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state)
RZ_IPI RzCmdStatus rz_analysis_function_vars_writes_handler(RzCore *core, int argc, const char **argv)
#define PRINTF_LN_NOT(k, fmt, arg, notv)
Definition: cmd_analysis.c:683
#define return_tail(x)
RZ_IPI RzCmdStatus rz_analysis_function_info_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state)
RZ_IPI RzCmdStatus rz_list_signatures_in_sigdb_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state)
RZ_API bool rz_core_esil_dumpstack(RzAnalysisEsil *esil)
RZ_IPI RzCmdStatus rz_analysis_function_blocks_info_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state)
static const char * help_msg_ae[]
Definition: cmd_analysis.c:53
static const char * help_msg_age[]
Definition: cmd_analysis.c:212
RZ_IPI RzCmdStatus rz_analysis_function_blocks_del_handler(RzCore *core, int argc, const char **argv)
#define PJ_KS(pj, key, value)
Definition: cmd_analysis.c:375
RZ_IPI RzCmdStatus rz_analyze_xrefs_section_bytes_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_analysis_hint_set_arch_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_analysis_function_vars_sp_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state)
------— Stack-based variable handlers ----------—
RZ_IPI RzCmdStatus rz_analysis_hint_del_esil_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_analysis_functions_merge_handler(RzCore *core, int argc, const char **argv)
CoreAnalysisType
@ CORE_ANALYSIS_EXPERIMENTAL
aaaa
@ CORE_ANALYSIS_DEEP
aaa
@ CORE_ANALYSIS_SIMPLE
aa
RZ_IPI RzCmdStatus rz_analysis_function_all_opcode_stat_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state)
RZ_IPI RzCmdStatus rz_analysis_function_vars_sp_setref_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_analysis_xrefs_set_C_handler(RzCore *core, int argc, const char **argv)
static int myregread(RzAnalysisEsil *esil, const char *name, ut64 *val, int *len)
RZ_IPI RzCmdStatus rz_analysis_function_del_all_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_analyze_cycles_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_analysis_class_vtable_list_handler(RzCore *core, int argc, const char **argv)
static int cmpaddr(const void *_a, const void *_b)
Definition: cmd_analysis.c:264
RZ_IPI RzCmdStatus rz_analysis_hint_del_jump_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_analysis_hint_set_stackframe_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_list_plugins_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state)
RZ_IPI RzCmdStatus rz_analyze_n_ins_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state)
RZ_IPI RzCmdStatus rz_analyze_bytes_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state)
static char * getViewerPath(void)
RZ_IPI RzCmdStatus rz_analysis_print_rtti_handler(RzCore *core, int argc, const char **argv, RzOutputMode mode)
static void xref_list_print_to_json(RZ_UNUSED RzCore *core, RzList *list, PJ *pj)
static void list_all_functions_at_vtable_offset(RzAnalysis *analysis, const char *class_name, ut64 offset)
RZ_IPI RzCmdStatus rz_analysis_function_returns_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_il_vm_status_handler(RzCore *core, int argc, const char **argv, RzOutputMode mode)
static const char * help_msg_ag[]
Definition: cmd_analysis.c:181
RZ_IPI RzCmdStatus rz_analysis_function_vars_reads_handler(RzCore *core, int argc, const char **argv)
RZ_IPI RzCmdStatus rz_analysis_function_address_handler(RzCore *core, int argc, const char **argv, RzOutputMode mode)
static void log_err_nonexist_class()
static void print_stats(RzCore *core, HtPU *ht, RzAnalysisFunction *fcn, RzCmdStateOutput *state)
RZ_IPI RzCmdStatus rz_analysis_xrefs_del_all_handler(RzCore *core, int argc, const char **argv)
static void xref_print_to_json(RZ_UNUSED RzCore *core, RzAnalysisXRef *xref, PJ *pj)
static void aea_stats_init(AeaStats *stats)
RZ_IPI RzCmdStatus rz_analysis_all_esil_functions_handler(RzCore *core, int argc, const char **argv)
RZ_API int rz_core_esil_step(RzCore *core, ut64 until_addr, const char *until_expr, ut64 *prev_addr, bool stepOver)
Definition: cmd_analysis.c:860
static bool add_keys_to_set_cb(HtPU *ht, const char *k, RZ_UNUSED const ut64 v)
static void core_analysis_bytes_standard(RzCore *core, const ut8 *buf, int len, int nops)
Definition: cmd_analysis.c:699
RZ_IPI RzCmdStatus rz_analysis_hint_set_syntax_handler(RzCore *core, int argc, const char **argv)
static void function_print_calls(RzCore *core, RzList *fcns, RzCmdStateOutput *state)
static void analysis_class_list_print_to_json(RzAnalysis *analysis, PJ *pj)
static int mr(RzAnalysisEsil *esil, ut64 addr, ut8 *buf, int len)
Definition: cmd_analysis.c:471
static RzCmdStatus class_base_error(RzAnalysisClassErr err)
static const char * diff_type_to_str(RzAnalysisDiff *diff)
RZ_IPI RzCmdStatus rz_analysis_function_cc_list_handler(RzCore *core, int argc, const char **argv, RzOutputMode mode)
RZ_API bool rz_cmd_state_output_init(RZ_NONNULL RzCmdStateOutput *state, RzOutputMode mode)
Initialize a RzCmdStateOutput structure and its inner fields based on the provided mode.
Definition: cmd_api.c:2634
RZ_API void rz_cmd_state_output_set_columnsf(RzCmdStateOutput *state, const char *fmt,...)
Specify the columns of the command output.
Definition: cmd_api.c:2589
RZ_API void rz_cmd_state_output_array_start(RzCmdStateOutput *state)
Mark the start of an array of elements in the output.
Definition: cmd_api.c:2558
RZ_API void rz_cmd_state_output_fini(RZ_NONNULL RzCmdStateOutput *state)
Clear the inner fields of RzCmdStateOutput structure, but do not free it.
Definition: cmd_api.c:2603
static int value
Definition: cmd_api.c:93
RZ_API void rz_cmd_state_output_array_end(RzCmdStateOutput *state)
Mark the end of an array of elements in the output.
Definition: cmd_api.c:2572
static bool step_until_optype(RzCore *core, RzList *optypes_list)
Definition: cmd_debug.c:486
static RzCore * _core
Definition: cmd_debug.c:1622
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 int rz_core_search_preludes(RzCore *core, bool log)
Definition: cmd_search.c:330
RZ_IPI bool rz_core_seek_to_register(RzCore *core, const char *regname, bool is_silent)
Definition: cmd_seek.c:22
RZ_API ut64 rz_config_get_i(RzConfig *cfg, RZ_NONNULL const char *name)
Definition: config.c:119
RZ_API bool rz_config_get_b(RzConfig *cfg, RZ_NONNULL const char *name)
Definition: config.c:142
RZ_API RzConfigNode * rz_config_set(RzConfig *cfg, RZ_NONNULL const char *name, const char *value)
Definition: config.c:267
RZ_API RzConfigNode * rz_config_set_i(RzConfig *cfg, RZ_NONNULL const char *name, const ut64 i)
Definition: config.c:419
RZ_API RZ_BORROW const char * rz_config_get(RzConfig *cfg, RZ_NONNULL const char *name)
Definition: config.c:75
RZ_API RzConfigNode * rz_config_set_b(RzConfig *cfg, RZ_NONNULL const char *name, bool value)
Definition: config.c:201
RZ_API void rz_cons_break_timeout(int timeout)
Definition: cons.c:421
RZ_API int rz_cons_get_size(int *rows)
Definition: cons.c:1446
RZ_API void rz_cons_enable_highlight(const bool enable)
Definition: cons.c:496
RZ_API bool rz_cons_enable_mouse(const bool enable)
Definition: cons.c:500
RZ_API void rz_cons_clear_line(int std_err)
Definition: cons.c:756
RZ_API void rz_cons_newline(void)
Definition: cons.c:1274
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 int rz_cons_printf(const char *format,...)
Definition: cons.c:1202
RZ_API bool rz_cons_is_interactive(void)
Definition: cons.c:365
RZ_API void rz_cons_show_cursor(int cursor)
Definition: cons.c:1581
RZ_API void rz_cons_flush(void)
Definition: cons.c:959
RZ_API bool rz_cons_is_breaked(void)
Definition: cons.c:373
RZ_API void rz_cons_println(const char *str)
Definition: cons.c:233
RZ_API bool rz_core_analysis_recover_golang_functions(RzCore *core)
reads pclntab table in go binaries and recovers functions. Follows the code https://github....
Definition: golang.c:405
RZ_API void rz_core_analysis_resolve_golang_strings(RzCore *core)
Attempts to recover all golang string.
Definition: golang.c:1613
#define RZ_API
static RzCmdStatus bool2status(bool val)
Definition: core_private.h:208
RZ_IPI void rz_core_types_calling_conventions_print(RzCore *core, RzOutputMode mode)
Definition: ctypes.c:19
RZ_API void rz_core_reg_update_flags(RzCore *core)
Update or create flags for all registers where it makes sense.
Definition: creg.c:106
#define NULL
Definition: cris-opc.c:27
#define r
Definition: crypto_rc6.c:12
cs_arch arch
Definition: cstool.c:13
RZ_API RZ_OWN char * rz_core_syscall_as_string(RzCore *core, st64 n, ut64 addr)
Returns the syscall representation as a string.
Definition: csyscall.c:26
RZ_API void rz_core_link_stroff(RzCore *core, RzAnalysisFunction *fcn)
Definition: ctypes.c:717
static static fork const void static count static fd const char const char static newpath const char static path const char path
Definition: sflib.h:35
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 cmd
Definition: sflib.h:79
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
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 length
Definition: sflib.h:133
RZ_API const char * rz_analysis_datatype_to_string(RzAnalysisDataType t)
Definition: data.c:409
RZ_API const char * rz_analysis_data_kind(RzAnalysis *a, ut64 addr, const ut8 *buf, int len)
Definition: data.c:346
uint16_t ut16
uint32_t ut32
RZ_API RZ_OWN char * rz_core_disasm_instruction(RzCore *core, ut64 addr, ut64 reladdr, RZ_NULLABLE RzAnalysisFunction *fcn, bool color)
Returns a disassembly of one instruction.
Definition: disasm.c:6770
RZ_API int rz_core_print_disasm_instructions(RzCore *core, int nb_bytes, int nb_opcodes)
Definition: disasm.c:6030
const char * k
Definition: dsignal.c:11
const char * v
Definition: dsignal.c:12
size_t map(int syms, int left, int len)
Definition: enough.c:237
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_condition(RzAnalysisEsil *esil, const char *str)
Definition: esil.c:3113
RZ_API bool rz_analysis_esil_set_pc(RzAnalysisEsil *esil, ut64 addr)
Definition: esil.c:155
RZ_API const char * rz_analysis_esil_trapstr(int type)
Definition: esil.c:1412
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_API void rz_analysis_esil_free(RzAnalysisEsil *esil)
Definition: esil.c:163
RZ_API bool rz_analysis_esil_load_interrupts_from_lib(RzAnalysisEsil *esil, const char *path)
RZ_API void rz_analysis_esil_trace_restore(RzAnalysisEsil *esil, int idx)
Definition: esil_trace.c:347
RZ_API int rz_analysis_fcn_del(RzAnalysis *a, ut64 addr)
Definition: fcn.c:1675
RZ_API ut32 rz_analysis_function_cost(RzAnalysisFunction *fcn)
Definition: fcn.c:2080
RZ_API int rz_analysis_function_loops(RzAnalysisFunction *fcn)
Definition: fcn.c:1784
RZ_DEPRECATE RZ_API RzAnalysisFunction * rz_analysis_get_fcn_in(RzAnalysis *analysis, ut64 addr, int type)
Definition: fcn.c:1687
RZ_API bool rz_analysis_function_purity(RzAnalysisFunction *fcn)
Definition: fcn.c:2136
RZ_API char * rz_analysis_function_get_json(RzAnalysisFunction *function)
Definition: fcn.c:1855
RZ_API bool rz_analysis_fcn_add_bb(RzAnalysis *a, RzAnalysisFunction *fcn, ut64 addr, ut64 size, ut64 jump, ut64 fail, RZ_BORROW RzAnalysisDiff *diff)
Definition: fcn.c:1739
RZ_DEPRECATE RZ_API RzAnalysisFunction * rz_analysis_get_fcn_in_bounds(RzAnalysis *analysis, ut64 addr, int type)
Definition: fcn.c:1708
RZ_API int rz_analysis_function_count_edges(const RzAnalysisFunction *fcn, RZ_NULLABLE int *ebbs)
Definition: fcn.c:2113
RZ_API void rz_analysis_del_jmprefs(RzAnalysis *analysis, RzAnalysisFunction *fcn)
Definition: fcn.c:1592
RZ_API const char * rz_analysis_fcntype_tostring(int type)
Definition: fcn.c:35
RZ_API int rz_analysis_fcn_del_locs(RzAnalysis *analysis, ut64 addr)
Definition: fcn.c:1657
RZ_API int rz_analysis_function_complexity(RzAnalysisFunction *fcn)
Definition: fcn.c:1799
RZ_API RZ_OWN char * rz_analysis_function_get_signature(RZ_NONNULL RzAnalysisFunction *function)
Definition: fcn.c:1895
RZ_API RzFlagItem * rz_flag_get_i(RzFlag *f, ut64 off)
Definition: flag.c:317
RZ_API int rz_flag_count(RzFlag *f, const char *glob)
Definition: flag.c:776
RZ_API void rz_flag_unset_all_in_space(RzFlag *f, const char *space_name)
Unset all flag items in the space with the given name.
Definition: flag.c:692
RZ_API RzFlagItem * rz_flag_get_at(RzFlag *f, ut64 off, bool closest)
Definition: flag.c:404
RZ_API RzFlagItem * rz_flag_get_by_spaces(RzFlag *f, ut64 off,...)
Definition: flag.c:326
RZ_API void rz_flag_foreach_glob(RzFlag *f, const char *glob, RzFlagItemCb cb, void *user)
Definition: flag.c:818
RZ_API char * sdb_fmt(const char *fmt,...)
Definition: fmt.c:26
RZ_API bool rz_core_gdiff_function_1_file(RzCore *c, ut64 addr, ut64 addr2)
Calculates basic block differences of 2 functions within the same file.
Definition: gdiff.c:17
RZ_API RZ_OWN RzType * rz_type_identifier_of_base_type(const RzTypeDB *typedb, RZ_NONNULL const RzBaseType *btype, bool is_const)
Creates a new RzType indentifier from the given RzBaseType.
Definition: helpers.c:15
RZ_API RZ_BORROW const char * rz_type_cond_tostring(RzTypeCond cc)
RzTypeCond enum to string.
Definition: helpers.c:471
RZ_API void rz_analysis_hint_set_val(RzAnalysis *a, ut64 addr, ut64 v)
Definition: hint.c:275
RZ_API void rz_analysis_hint_set_nword(RzAnalysis *a, ut64 addr, int nword)
Definition: hint.c:209
RZ_API RzAnalysisHint * rz_analysis_hint_get(RzAnalysis *a, ut64 addr)
Definition: hint.c:506
RZ_API void rz_analysis_hint_set_high(RzAnalysis *a, ut64 addr)
Definition: hint.c:225
RZ_API void rz_analysis_hint_clear(RzAnalysis *a)
Definition: hint.c:85
RZ_API void rz_analysis_hint_unset_stackframe(RzAnalysis *a, ut64 addr)
Definition: hint.c:359
RZ_API void rz_analysis_hint_unset_type(RzAnalysis *a, ut64 addr)
Definition: hint.c:355
RZ_API void rz_analysis_hint_set_stackframe(RzAnalysis *a, ut64 addr, ut64 size)
Definition: hint.c:271
RZ_API void rz_analysis_hint_unset_fail(RzAnalysis *a, ut64 addr)
Definition: hint.c:343
RZ_API void rz_analysis_hint_set_ret(RzAnalysis *a, ut64 addr, ut64 val)
Definition: hint.c:241
RZ_API void rz_analysis_hint_unset_offset(RzAnalysis *a, ut64 addr)
Definition: hint.c:335
RZ_API void rz_analysis_hint_unset_size(RzAnalysis *a, ut64 addr)
Definition: hint.c:299
RZ_API void rz_analysis_hint_unset_syntax(RzAnalysis *a, ut64 addr)
Definition: hint.c:323
RZ_API void rz_analysis_hint_unset_jump(RzAnalysis *a, ut64 addr)
Definition: hint.c:339
RZ_API void rz_analysis_hint_set_jump(RzAnalysis *a, ut64 addr, ut64 jump)
Definition: hint.c:213
RZ_API void rz_analysis_hint_unset_arch(RzAnalysis *a, ut64 addr)
Definition: hint.c:363
RZ_API void rz_analysis_hint_set_opcode(RzAnalysis *a, ut64 addr, const char *opcode)
Definition: hint.c:251
RZ_API void rz_analysis_hint_set_bits(RzAnalysis *a, ut64 addr, int bits)
Definition: hint.c:288
RZ_API void rz_analysis_hint_free(RzAnalysisHint *h)
Definition: hint.c:371
RZ_API void rz_analysis_hint_set_syntax(RzAnalysis *a, ut64 addr, const char *syn)
Definition: hint.c:245
RZ_API void rz_analysis_hint_del(RzAnalysis *a, ut64 addr, ut64 size)
Definition: hint.c:105
RZ_API void rz_analysis_hint_set_fail(RzAnalysis *a, ut64 addr, ut64 fail)
Definition: hint.c:217
RZ_API void rz_analysis_hint_unset_opcode(RzAnalysis *a, ut64 addr)
Definition: hint.c:307
RZ_API void rz_analysis_hint_unset_esil(RzAnalysis *a, ut64 addr)
Definition: hint.c:303
RZ_API void rz_analysis_hint_set_esil(RzAnalysis *a, ut64 addr, const char *esil)
Definition: hint.c:257
RZ_API void rz_analysis_hint_unset_immbase(RzAnalysis *a, ut64 addr)
Definition: hint.c:315
RZ_API void rz_analysis_hint_unset_bits(RzAnalysis *a, ut64 addr)
Definition: hint.c:367
RZ_API void rz_analysis_hint_unset_ret(RzAnalysis *a, ut64 addr)
Definition: hint.c:331
RZ_API void rz_analysis_hint_unset_high(RzAnalysis *a, ut64 addr)
Definition: hint.c:311
RZ_API void rz_analysis_hint_set_arch(RzAnalysis *a, ut64 addr, RZ_NULLABLE const char *arch)
Definition: hint.c:279
RZ_API void rz_analysis_hint_set_immbase(RzAnalysis *a, ut64 addr, int base)
Definition: hint.c:229
RZ_API void rz_analysis_hint_set_type(RzAnalysis *a, ut64 addr, int type)
Definition: hint.c:263
RZ_API void rz_analysis_hint_unset_val(RzAnalysis *a, ut64 addr)
Definition: hint.c:351
RZ_API void rz_analysis_hint_unset_pointer(RzAnalysis *a, ut64 addr)
Definition: hint.c:327
RZ_API void rz_analysis_hint_set_pointer(RzAnalysis *a, ut64 addr, ut64 ptr)
Definition: hint.c:237
RZ_API void rz_analysis_hint_set_size(RzAnalysis *a, ut64 addr, ut64 size)
Definition: hint.c:267
RZ_API void rz_config_hold_restore(RzConfigHold *h)
Restore whatever config options were previously saved in h.
Definition: hold.c:132
RZ_API RzConfigHold * rz_config_hold_new(RzConfig *cfg)
Create an opaque object to save/restore some configuration options.
Definition: hold.c:116
RZ_API bool rz_config_hold_i(RzConfigHold *h,...)
Save the current values of a list of config options that have integer values.
Definition: hold.c:81
RZ_API void rz_config_hold_free(RzConfigHold *h)
Free a RzConfigHold object h.
Definition: hold.c:152
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
RZ_API const KEY_TYPE bool * found
Definition: ht_inc.h:130
RZ_API void rz_il_op_effect_json(RZ_NONNULL RzILOpEffect *op, RZ_NONNULL PJ *pj)
Definition: il_export.c:731
RZ_API void rz_il_op_effect_stringify(RZ_NONNULL RzILOpEffect *op, RZ_NONNULL RzStrBuf *sb)
Definition: il_export.c:711
voidpf void uLong size
Definition: ioapi.h:138
const char * filename
Definition: ioapi.h:137
voidpf uLong offset
Definition: ioapi.h:144
const char int mode
Definition: ioapi.h:137
voidpf void * buf
Definition: ioapi.h:138
RZ_API bool rz_analysis_jmptbl(RzAnalysis *analysis, RzAnalysisFunction *fcn, RzAnalysisBlock *block, ut64 jmpaddr, ut64 table, ut64 tablesize, ut64 default_addr)
Definition: jmptbl.c:46
#define reg(n)
uint8_t ut8
Definition: lh5801.h:11
return memset(p, 0, total)
void * p
Definition: libc.cpp:67
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
const char * spaces(int count)
RZ_API RzTable * rz_core_table(RzCore *core)
Definition: core.c:3449
RZ_API RzBinReloc * rz_core_getreloc(RzCore *core, ut64 addr, int size)
Definition: core.c:178
RZ_API void rz_core_notify_begin(RZ_NONNULL RzCore *core, RZ_NONNULL const char *format,...)
Prints a message definining the beginning of a task.
Definition: core.c:33
RZ_API bool rz_core_block_size(RzCore *core, ut32 bsize)
Definition: core.c:2842
RZ_API void rz_core_notify_done(RZ_NONNULL RzCore *core, RZ_NONNULL const char *format,...)
Prints a message definining the end of a task which succeeded.
Definition: core.c:60
static void list(RzEgg *egg)
Definition: rz-gg.c:52
RZ_API RZ_OWN RzList * rz_list_uniq(RZ_NONNULL const RzList *list, RZ_NONNULL RzListComparator cmp)
Returns a new RzList which contains only unique values.
Definition: list.c:756
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 RZ_OWN RzList * rz_list_clone(RZ_NONNULL const RzList *list)
Shallow copies of the list (but doesn't free its elements)
Definition: list.c:496
RZ_API RZ_OWN RzList * rz_list_new_from_array(RZ_NONNULL const void **arr, size_t arr_size)
Allocates a new RzList and adds an array elements to it.
Definition: list.c:260
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
RZ_API RZ_OWN RzList * rz_list_new(void)
Returns a new initialized RzList pointer (free method is not initialized)
Definition: list.c:235
RZ_API void rz_list_sort(RZ_NONNULL RzList *list, RZ_NONNULL RzListComparator cmp)
Sorts via merge sort or via insertion sort a list.
Definition: list.c:743
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 RZ_BORROW RzListIter * rz_list_push(RZ_NONNULL RzList *list, void *item)
Alias for rz_list_append.
Definition: list.c:60
RZ_API ut32 rz_list_length(RZ_NONNULL const RzList *list)
Returns the length of the list.
Definition: list.c:109
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
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 char * sdb_querys(Sdb *r, char *buf, size_t len, const char *_cmd)
Definition: query.c:164
void * malloc(size_t size)
Definition: malloc.c:123
void * calloc(size_t number, size_t size)
Definition: malloc.c:102
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
static static fork const void static count static fd const char const char static newpath char char argv
Definition: sflib.h:40
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")
static const char struct stat static buf struct stat static buf static vhangup int status
Definition: sflib.h:145
RZ_API void ls_free(SdbList *list)
Definition: ls.c:191
#define ls_foreach(list, it, pos)
Definition: ls.h:31
char * dst
Definition: lz4.h:724
@ RZ_ABS
RZ_API const char * rz_meta_get_string(RzAnalysis *a, RzAnalysisMetaType type, ut64 addr)
Definition: meta.c:146
int args
Definition: mipsasm.c:18
int n
Definition: mipsasm.c:19
int type
Definition: mipsasm.c:17
int idx
Definition: setup.py:197
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 const char * rz_analysis_optype_to_string(int type)
Definition: op.c:310
int id
Definition: op.c:540
RZ_API int rz_analysis_optype_from_string(RZ_NONNULL const char *name)
Definition: op.c:294
RZ_API const char * rz_analysis_stackop_tostring(int s)
Definition: op.c:521
RZ_API int rz_analysis_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8 *data, int len, RzAnalysisOpMask mask)
Definition: op.c:96
RZ_API const char * rz_analysis_op_family_to_string(int id)
Definition: op.c:560
static struct @218 keys[]
int off
Definition: pal.c:13
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
static const char hex[16]
Definition: print.c:21
static void pad(RzStrBuf *sb, ut32 count)
Definition: protobuf.c:36
RZ_API ut64 rz_reg_getv(RzReg *reg, const char *name)
Definition: reg.c:332
RZ_API RzRegItem * rz_reg_get(RzReg *reg, const char *name, int type)
Definition: reg.c:344
RZ_API const char * rz_reg_get_name(RzReg *reg, int role)
Definition: reg.c:147
RZ_API RzRegItem * rz_reg_index_get(RzReg *reg, int idx)
Definition: reg.c:262
RZ_API ut64 rz_reg_setv(RzReg *reg, const char *name, ut64 val)
Definition: reg.c:326
static void repeat(struct parse *, sopno, int, int)
Definition: regcomp.c:1155
#define eprintf(x, y...)
Definition: rlcc.c:7
static RzSocket * s
Definition: rtr.c:28
RZ_API char * rz_analysis_rtti_demangle_class_name(RzAnalysis *analysis, const char *name)
Definition: rtti.c:8
RZ_API void rz_analysis_rtti_print_at_vtable(RzAnalysis *analysis, ut64 addr, RzOutputMode mode)
Definition: rtti.c:17
RZ_API void rz_analysis_rtti_print_all(RzAnalysis *analysis, RzOutputMode mode)
Definition: rtti.c:36
RZ_API void rz_analysis_rtti_recover_all(RzAnalysis *analysis)
Definition: rtti.c:87
RZ_API bool rz_reg_set_value_by_role(RzReg *reg, RzRegisterId role, ut64 val)
Definition: rvalue.c:269
RZ_API ut64 rz_reg_get_value_by_role(RzReg *reg, RzRegisterId role)
Definition: rvalue.c:181
#define RZ_ANALYSIS_ADDR_TYPE_STACK
Definition: rz_analysis.h:91
#define RZ_ANALYSIS_ADDR_TYPE_SEQUENCE
Definition: rz_analysis.h:96
#define RZ_ANALYSIS_ARCHINFO_DATA_ALIGN
Definition: rz_analysis.h:101
#define RZ_ANALYSIS_ADDR_TYPE_ASCII
Definition: rz_analysis.h:95
@ RZ_ANALYSIS_DIFF_TYPE_MATCH
Definition: rz_analysis.h:206
@ RZ_ANALYSIS_DIFF_TYPE_UNMATCH
Definition: rz_analysis.h:207
@ RZ_ANALYSIS_DIFF_TYPE_NULL
Definition: rz_analysis.h:205
@ RZ_ANALYSIS_FCN_TYPE_SYM
Definition: rz_analysis.h:195
@ RZ_ANALYSIS_FCN_TYPE_IMP
Definition: rz_analysis.h:196
@ RZ_ANALYSIS_FCN_TYPE_ANY
Definition: rz_analysis.h:199
@ RZ_ANALYSIS_FCN_TYPE_LOC
Definition: rz_analysis.h:194
@ RZ_ANALYSIS_FCN_TYPE_ROOT
Definition: rz_analysis.h:198
@ RZ_ANALYSIS_FCN_TYPE_FCN
Definition: rz_analysis.h:193
#define RZ_ANALYSIS_ADDR_TYPE_EXEC
Definition: rz_analysis.h:85
@ RZ_ANALYSIS_STACK_NULL
Definition: rz_analysis.h:455
RzAnalysisXRefType
Definition: rz_analysis.h:898
@ RZ_ANALYSIS_XREF_TYPE_CODE
Definition: rz_analysis.h:900
@ RZ_ANALYSIS_XREF_TYPE_NULL
Definition: rz_analysis.h:899
@ RZ_ANALYSIS_XREF_TYPE_STRING
Definition: rz_analysis.h:903
@ RZ_ANALYSIS_XREF_TYPE_CALL
Definition: rz_analysis.h:901
@ RZ_ANALYSIS_XREF_TYPE_DATA
Definition: rz_analysis.h:902
#define RZ_ANALYSIS_ADDR_TYPE_HEAP
Definition: rz_analysis.h:90
@ RZ_ANALYSIS_TRAP_EXEC_ERR
Definition: rz_analysis.h:956
@ RZ_ANALYSIS_TRAP_INVALID
Definition: rz_analysis.h:957
@ RZ_ANALYSIS_TRAP_UNALIGNED
Definition: rz_analysis.h:958
#define RZ_ANALYSIS_ADDR_TYPE_FLAG
Definition: rz_analysis.h:88
#define RZ_ANALYSIS_ARCHINFO_MAX_OP_SIZE
Definition: rz_analysis.h:99
#define RZ_ANALYSIS_ADDR_TYPE_LIBRARY
Definition: rz_analysis.h:94
@ RZ_META_TYPE_COMMENT
Definition: rz_analysis.h:295
#define RZ_ANALYSIS_ADDR_TYPE_REG
Definition: rz_analysis.h:92
#define RZ_ANALYSIS_ADDR_TYPE_WRITE
Definition: rz_analysis.h:87
RzAnalysisVarAccessType
Definition: rz_analysis.h:711
@ RZ_ANALYSIS_VAR_ACCESS_TYPE_READ
Definition: rz_analysis.h:713
@ RZ_ANALYSIS_VAR_ACCESS_TYPE_WRITE
Definition: rz_analysis.h:714
@ RZ_ANALYSIS_OP_MASK_DISASM
Definition: rz_analysis.h:445
@ RZ_ANALYSIS_OP_MASK_BASIC
Definition: rz_analysis.h:440
@ RZ_ANALYSIS_OP_MASK_OPEX
Definition: rz_analysis.h:444
@ RZ_ANALYSIS_OP_MASK_ESIL
Definition: rz_analysis.h:441
@ RZ_ANALYSIS_OP_MASK_HINT
Definition: rz_analysis.h:443
@ RZ_ANALYSIS_OP_MASK_IL
Definition: rz_analysis.h:446
#define RZ_ANALYSIS_ADDR_TYPE_FUNC
Definition: rz_analysis.h:89
#define RZ_ANALYSIS_ARCHINFO_MIN_OP_SIZE
Definition: rz_analysis.h:98
RzAnalysisVarKind
Definition: rz_analysis.h:702
@ RZ_ANALYSIS_VAR_KIND_REG
Definition: rz_analysis.h:703
@ RZ_ANALYSIS_VAR_KIND_SPV
Definition: rz_analysis.h:705
@ RZ_ANALYSIS_VAR_KIND_BPV
Definition: rz_analysis.h:704
#define RZ_ANALYSIS_ADDR_TYPE_READ
Definition: rz_analysis.h:86
@ RZ_ANALYSIS_OP_TYPE_JMP
Definition: rz_analysis.h:368
@ RZ_ANALYSIS_OP_TYPE_UJMP
Definition: rz_analysis.h:369
@ RZ_ANALYSIS_OP_TYPE_SWI
Definition: rz_analysis.h:393
@ RZ_ANALYSIS_OP_TYPE_TRAP
Definition: rz_analysis.h:392
@ RZ_ANALYSIS_OP_TYPE_CALL
Definition: rz_analysis.h:378
@ RZ_ANALYSIS_OP_TYPE_CRET
Definition: rz_analysis.h:386
@ RZ_ANALYSIS_OP_TYPE_RJMP
Definition: rz_analysis.h:370
@ RZ_ANALYSIS_OP_TYPE_CJMP
Definition: rz_analysis.h:373
@ RZ_ANALYSIS_OP_TYPE_COND
Definition: rz_analysis.h:361
@ RZ_ANALYSIS_OP_TYPE_UCALL
Definition: rz_analysis.h:379
@ RZ_ANALYSIS_OP_TYPE_RET
Definition: rz_analysis.h:385
@ RZ_ANALYSIS_OP_TYPE_NOP
Definition: rz_analysis.h:389
@ RZ_ANALYSIS_OP_TYPE_RCALL
Definition: rz_analysis.h:380
#define RZ_ANALYSIS_ADDR_TYPE_PROGRAM
Definition: rz_analysis.h:93
#define rz_warn_if_reached()
Definition: rz_assert.h:29
#define rz_return_if_fail(expr)
Definition: rz_assert.h:100
#define rz_return_val_if_fail(expr, val)
Definition: rz_assert.h:108
#define rz_return_val_if_reached(val)
Definition: rz_assert.h:122
RZ_API char * rz_base64_encode_dyn(const ut8 *bin, size_t sz)
Definition: ubase64.c:92
enum rz_cmd_status_t RzCmdStatus
@ RZ_CMD_STATUS_OK
command handler exited in the right way
Definition: rz_cmd.h:24
@ RZ_CMD_STATUS_WRONG_ARGS
command handler could not handle the arguments passed to it
Definition: rz_cmd.h:25
@ RZ_CMD_STATUS_INVALID
command could not be executed (e.g. shell level error, bad expression, etc.)
Definition: rz_cmd.h:27
@ RZ_CMD_STATUS_ERROR
command handler had issues while running (e.g. allocation error, etc.)
Definition: rz_cmd.h:26
#define Color_RESET
Definition: rz_cons.h:617
#define Color_GREEN
Definition: rz_cons.h:627
#define RZ_FLAGS_FS_IMPORTS
Definition: rz_core.h:59
#define RZ_GRAPH_FORMAT_JSON
Definition: rz_core.h:78
#define RZ_FLAGS_FS_REGISTERS
Definition: rz_core.h:61
#define RZ_CORE_ANALYSIS_JSON_FORMAT_DISASM
Definition: rz_core.h:54
#define RZ_CORE_ANALYSIS_STAR
Definition: rz_core.h:55
#define RZ_GRAPH_FORMAT_CMD
Definition: rz_core.h:81
#define RZ_GRAPH_FORMAT_DOT
Definition: rz_core.h:80
#define RZ_GRAPH_FORMAT_GML
Definition: rz_core.h:79
#define RZ_CORE_ANALYSIS_GRAPHBODY
Definition: rz_core.h:50
#define RZ_FLAGS_FS_STRINGS
Definition: rz_core.h:66
#define RZ_FLAGS_FS_CLASSES
Definition: rz_core.h:57
#define RZ_CORE_ANALYSIS_GRAPHLINES
Definition: rz_core.h:49
#define RZ_FLAGS_FS_SYMBOLS
Definition: rz_core.h:67
#define RZ_GRAPH_FORMAT_GMLFCN
Definition: rz_core.h:77
#define RZ_CORE_ANALYSIS_JSON
Definition: rz_core.h:52
#define RZ_CORE_ANALYSIS_GRAPHDIFF
Definition: rz_core.h:51
#define RZ_FLAGS_FS_FUNCTIONS
Definition: rz_core.h:58
RZ_API bool rz_file_exists(const char *str)
Definition: file.c:192
RZ_API bool rz_file_dump(const char *file, const ut8 *buf, int len, bool append)
Definition: file.c:838
RZ_API char * rz_file_path(const char *bin)
Definition: file.c:354
bool(* RzFlagItemCb)(RzFlagItem *fi, void *user)
Definition: rz_flag.h:74
RZ_API void rz_graph_free(RzGraph *g)
Definition: graph.c:124
RZ_API void rz_graph_drawable_to_json(RzGraph *graph, PJ *pj, bool use_offset)
Convert graph to JSON.
RZ_API char * rz_graph_drawable_to_dot(RzGraph *graph, const char *node_properties, const char *edge_properties)
Convert graph to Graphviz dot format.
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 bool rz_io_read_at(RzIO *io, ut64 addr, ut8 *buf, int len)
Definition: io.c:300
RZ_API RzIOMap * rz_io_map_get(RzIO *io, ut64 addr)
Definition: io_map.c:176
RZ_API bool rz_io_read_at_mapped(RzIO *io, ut64 addr, ut8 *buf, int len)
Definition: io.c:318
RZ_API bool rz_io_is_valid_offset(RzIO *io, ut64 offset, int hasperm)
Definition: ioutils.c:20
static ut64 rz_itv_end(RzInterval itv)
Definition: rz_itv.h:42
void(* RzListFree)(void *ptr)
Definition: rz_list.h:11
int(* RzListComparator)(const void *value, const void *list_data)
Definition: rz_list.h:33
#define RZ_LOG_ERROR(fmtstr,...)
Definition: rz_log.h:58
RZ_API void rz_mem_reverse(ut8 *b, int l)
Definition: mem.c:327
RZ_API const ut8 * rz_mem_mem(const ut8 *haystack, int hlen, const ut8 *needle, int nlen)
Definition: mem.c:246
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 size_t rz_num_base_of_string(RzNum *num, RZ_NONNULL const char *str)
Convert the base suffix to the numeric value.
Definition: unum.c:935
RZ_API PJ * pj_j(PJ *j, const char *k)
Definition: pj.c:243
RZ_API PJ * pj_ka(PJ *j, const char *k)
Definition: pj.c:163
RZ_API PJ * pj_new(void)
Definition: pj.c:25
RZ_API PJ * pj_kb(PJ *j, const char *k, bool v)
Definition: pj.c:177
RZ_API char * pj_drain(PJ *j)
Definition: pj.c:50
RZ_API PJ * pj_ki(PJ *j, const char *k, int d)
Definition: pj.c:149
RZ_API PJ * pj_k(PJ *j, const char *k)
Definition: pj.c:104
RZ_API PJ * pj_end(PJ *j)
Definition: pj.c:87
RZ_API const char * pj_string(PJ *pj)
Definition: pj.c:57
RZ_API void pj_free(PJ *j)
Definition: pj.c:34
RZ_API PJ * pj_o(PJ *j)
Definition: pj.c:75
RZ_API PJ * pj_s(PJ *j, const char *k)
Definition: pj.c:197
RZ_API PJ * pj_ks(PJ *j, const char *k, const char *v)
Definition: pj.c:170
RZ_API PJ * pj_n(PJ *j, ut64 n)
Definition: pj.c:252
RZ_API PJ * pj_kn(PJ *j, const char *k, ut64 n)
Definition: pj.c:121
RZ_API PJ * pj_a(PJ *j)
Definition: pj.c:81
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_rbtree_foreach(root, it, data, struc, rb)
Definition: rz_rbtree.h:101
@ RZ_REG_NAME_SP
Definition: rz_reg.h:44
@ RZ_REG_NAME_BP
Definition: rz_reg.h:46
@ RZ_REG_NAME_PC
Definition: rz_reg.h:43
#define RZ_STR_ISNOTEMPTY(x)
Definition: rz_str.h:68
RZ_API char * rz_str_newf(const char *fmt,...) RZ_PRINTF_CHECK(1
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
RZ_API char * rz_str_sanitize_sdb_key(const char *s)
Definition: str.c:1405
RZ_API char * rz_str_new(const char *str)
Definition: str.c:865
RZ_API RZ_BORROW char * rz_str_trim_tail(RZ_NONNULL char *str)
Removes whitespace characters (space, tab, newline etc.) from the end of a string and replaces them w...
Definition: str_trim.c:125
RZ_API const char * rz_str_bool(int b)
Definition: str.c:3896
#define RZ_STR_ISEMPTY(x)
Definition: rz_str.h:67
RZ_API bool rz_str_isnumber(const char *str)
Definition: str.c:3550
RZ_API const char * rz_str_trim_head_ro(const char *str)
Definition: str_trim.c:86
RZ_API int rz_str_replace_ch(char *s, char a, char b, bool g)
Definition: str.c:139
RZ_API char ** rz_str_argv(const char *str, int *_argc)
Definition: str.c:2509
RZ_API void rz_str_trim(RZ_NONNULL RZ_INOUT char *str)
Removes whitespace characters (space, tab, newline etc.) from the beginning and end of a string.
Definition: str_trim.c:190
RZ_API const char * rz_str_pad(const char ch, int len)
Definition: str.c:3236
RZ_API void rz_str_argv_free(char **argv)
Definition: str.c:2633
RZ_API size_t rz_str_split(char *str, char ch)
Split string str in place by using ch as a delimiter.
Definition: str.c:406
#define rz_strf(buf,...)
Convenience macro for local temporary strings.
Definition: rz_str.h:59
RZ_API const char * rz_str_constpool_get(RzStrConstPool *pool, const char *str)
Definition: str_constpool.c:19
#define IS_DIGIT(x)
Definition: rz_str_util.h:11
#define RZ_STRBUF_SAFEGET(sb)
Definition: rz_strbuf.h:18
RZ_API const char * rz_strbuf_set(RzStrBuf *sb, const char *s)
Definition: strbuf.c:153
RZ_API char * rz_strbuf_get(RzStrBuf *sb)
Definition: strbuf.c:321
RZ_API void rz_strbuf_fini(RzStrBuf *sb)
Definition: strbuf.c:365
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
RZ_API bool rz_strbuf_appendf(RzStrBuf *sb, const char *fmt,...) RZ_PRINTF_CHECK(2
RZ_API bool rz_strbuf_setbin(RzStrBuf *sb, const ut8 *s, size_t len)
Definition: strbuf.c:85
RZ_API void rz_strbuf_init(RzStrBuf *sb)
Definition: strbuf.c:33
RZ_API bool rz_table_align(RzTable *t, int nth, int align)
Definition: table.c:1192
RZ_API void rz_table_add_column(RzTable *t, RzTableColumnType *type, const char *name, int maxWidth)
Definition: table.c:134
RZ_API void rz_table_visual_list(RzTable *table, RzList *list, ut64 seek, ut64 len, int width, bool va)
Definition: table.c:1205
RZ_API void rz_table_add_rowf(RzTable *t, const char *fmt,...)
Definition: table.c:316
RZ_API void rz_table_add_row_vec(RZ_NONNULL RzTable *t, RZ_NONNULL RzPVector *items)
Add a new row to RzTable.
Definition: table.c:176
RZ_API void rz_table_free(RzTable *t)
Definition: table.c:114
@ RZ_TABLE_ALIGN_RIGHT
Definition: rz_table.h:35
RZ_API void rz_table_set_columnsf(RzTable *t, const char *fmt,...)
Specify the types and names of the referenced table.
Definition: table.c:234
RZ_API char * rz_table_tostring(RzTable *t)
Definition: table.c:510
RZ_API RzTable * rz_table_new(void)
Definition: table.c:103
RZ_API RzTableColumnType * rz_table_type(const char *name)
Definition: table.c:24
RZ_API ut64 rz_time_now_mono(void)
Returns the current time in microseconds, using the monotonic clock.
Definition: time.c:102
#define PFMT64d
Definition: rz_types.h:394
#define RZ_UNUSED
Definition: rz_types.h:73
#define RZ_NONNULL
Definition: rz_types.h:64
#define RZ_NEW(x)
Definition: rz_types.h:285
#define RZ_PERM_X
Definition: rz_types.h:95
#define PFMT64u
Definition: rz_types.h:395
RzOutputMode
Enum to describe the way data are printed.
Definition: rz_types.h:38
@ RZ_OUTPUT_MODE_TABLE
Definition: rz_types.h:46
@ RZ_OUTPUT_MODE_LONG
Definition: rz_types.h:44
@ RZ_OUTPUT_MODE_JSON
Definition: rz_types.h:40
@ RZ_OUTPUT_MODE_QUIET
Definition: rz_types.h:42
@ RZ_OUTPUT_MODE_RIZIN
Definition: rz_types.h:41
@ RZ_OUTPUT_MODE_STANDARD
Definition: rz_types.h:39
#define RZ_FREE(x)
Definition: rz_types.h:369
#define PFMT64x
Definition: rz_types.h:393
#define RZ_EMPTY
Definition: rz_types_base.h:68
#define RZ_MIN(x, y)
#define st64
Definition: rz_types_base.h:10
#define UT32_MAX
Definition: rz_types_base.h:99
#define RZ_MAX(x, y)
#define UT64_MAX
Definition: rz_types_base.h:86
#define RZ_BETWEEN(x, y, z)
#define st32
Definition: rz_types_base.h:12
RZ_API RzPVector * rz_pvector_new(RzPVectorFree free)
Definition: vector.c:302
#define rz_vector_foreach(vec, it)
Definition: rz_vector.h:169
static void ** rz_pvector_push(RzPVector *vec, void *x)
Definition: rz_vector.h:300
RZ_API void rz_vector_free(RzVector *vec)
Definition: vector.c:75
RZ_API void rz_pvector_free(RzPVector *vec)
Definition: vector.c:336
#define rz_vector_foreach_prev(vec, it)
Definition: rz_vector.h:173
static size_t rz_vector_len(const RzVector *vec)
Definition: rz_vector.h:82
#define rz_pvector_foreach(vec, it)
Definition: rz_vector.h:334
RZ_API Sdb * sdb_new(const char *path, const char *name, int lock)
Definition: sdb.c:47
RZ_API void sdb_close(Sdb *s)
Definition: sdb.c:416
RZ_API bool sdb_merge(Sdb *d, Sdb *s)
Definition: sdb.c:144
RZ_API bool sdb_free(Sdb *s)
Definition: sdb.c:206
RZ_API void sdb_reset(Sdb *s)
Definition: sdb.c:433
RZ_API bool sdb_foreach(Sdb *s, SdbForeachCallback cb, void *user)
Definition: sdb.c:758
RZ_API char * sdb_itoa(ut64 n, char *s, int base)
Definition: util.c:38
static char * sdbkv_key(const SdbKv *kv)
Definition: sdbht.h:21
RZ_API bool rz_core_seek(RzCore *core, ut64 addr, bool rb)
Seek to addr.
Definition: seek.c:116
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
static int
Definition: sfsocketcall.h:114
static struct sockaddr static addrlen static backlog const void msg
Definition: sfsocketcall.h:119
int size_t
Definition: sftypes.h:40
#define d(i)
Definition: sha256.c:44
#define b(i)
Definition: sha256.c:42
#define f(i)
Definition: sha256.c:46
#define c(i)
Definition: sha256.c:43
#define a(i)
Definition: sha256.c:41
RzList * regvalues
RzList * regread
RzList * regs
RzList * inputregs
RzList * regwrite
RzAnalysis * analysis
Definition: inftree9.h:24
Definition: zipcmp.c:77
Definition: ls.h:17
Definition: ls.h:22
Definition: z80asm.h:102
Definition: rz_pj.h:12
RzAnalysis * analysis
Definition: rz_analysis.h:887
RzAnalysisDiff * diff
Definition: rz_analysis.h:872
int(* hook_mem_read)(ANALYSIS_ESIL *esil, ut64 addr, ut8 *buf, int len)
Definition: rz_analysis.h:1032
int(* hook_reg_read)(ANALYSIS_ESIL *esil, const char *name, ut64 *res, int *size)
Definition: rz_analysis.h:1036
int(* hook_mem_write)(ANALYSIS_ESIL *esil, ut64 addr, const ut8 *buf, int len)
Definition: rz_analysis.h:1034
RzAnalysisEsilHookRegWriteCB hook_reg_write
Definition: rz_analysis.h:1038
RzAnalysisEsilInterruptHandler * handler
Definition: rz_analysis.h:1171
RzAnalysis * analysis
Definition: rz_analysis.h:1043
RzAnalysisEsilCallbacks cb
Definition: rz_analysis.h:1078
RzAnalysisEsilTrace * trace
Definition: rz_analysis.h:1077
bool(* cmd)(ANALYSIS_ESIL *esil, const char *name, ut64 a0, ut64 a1)
Definition: rz_analysis.h:1089
RzAnalysisDiff * diff
Definition: rz_analysis.h:263
Generic drawable graph node.
RzAnalysisEsilLoopCB esil_post_loop
Definition: rz_analysis.h:1267
RzAnalysisXRefType type
Definition: rz_analysis.h:909
RBTree bb_tree
Definition: rz_analysis.h:564
RzStrConstPool constpool
Definition: rz_analysis.h:620
RzList * fcns
Definition: rz_analysis.h:565
struct rz_analysis_plugin_t * cur
Definition: rz_analysis.h:586
struct rz_analysis_esil_t * esil
Definition: rz_analysis.h:584
RzSyscall * syscall
Definition: rz_analysis.h:570
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
RzIOBind iob
Definition: rz_analysis.h:574
RzTypeDB * typedb
Definition: rz_analysis.h:602
RzCoreBind coreb
Definition: rz_analysis.h:580
Global variables.
Definition: rz_analysis.h:744
RzAnalysisVarKind kind
Definition: rz_analysis.h:728
int force_update_seek
Definition: rz_agraph.h:71
bool show_node_titles
Definition: rz_agraph.h:77
bool need_set_layout
Definition: rz_agraph.h:69
RzConsCanvas * can
Definition: rz_agraph.h:47
Sdb * pair
Definition: rz_asm.h:112
int bits
Definition: rz_asm.h:100
XX curplugin == o->plugin.
Definition: rz_bin.h:298
int has_va
Definition: rz_bin.h:228
RzBinImport * import
Definition: rz_bin.h:714
RzBinSymbol * symbol
Definition: rz_bin.h:713
Represent the output state of a command handler.
Definition: rz_cmd.h:91
RzConsPrintablePalette pal
Definition: rz_cons.h:491
RzConsContext * context
Definition: rz_cons.h:502
void * core
Definition: rz_bind.h:31
RzCoreGetNameDelta getNameDelta
Definition: rz_bind.h:41
RzCons * cons
Definition: rz_core.h:312
RzBin * bin
Definition: rz_core.h:298
ut64 offset
Definition: rz_core.h:301
RzAsm * rasm
Definition: rz_core.h:323
RzAnalysis * analysis
Definition: rz_core.h:322
RzDebug * dbg
Definition: rz_core.h:329
RzIO * io
Definition: rz_core.h:313
RzNum * num
Definition: rz_core.h:316
RzAGraph * graph
Definition: rz_core.h:333
RzParse * parser
Definition: rz_core.h:326
RzCoreTaskScheduler tasks
Definition: rz_core.h:362
ut8 * block
Definition: rz_core.h:305
RzFlag * flags
Definition: rz_core.h:330
RzPrint * print
Definition: rz_core.h:327
ut32 blocksize
Definition: rz_core.h:303
RzConfig * config
Definition: rz_core.h:300
const char * name
Definition: rz_debug.h:359
struct rz_debug_plugin_t * cur
Definition: rz_debug.h:295
RzDebugTrace * trace
Definition: rz_debug.h:281
RzReg * reg
Definition: rz_debug.h:286
RzBreakpoint * bp
Definition: rz_debug.h:288
RzList * traces
Definition: rz_debug.h:220
ut64 offset
Definition: rz_flag.h:38
char * name
Definition: rz_flag.h:35
void * data
Definition: rz_graph.h:12
unsigned int idx
Definition: rz_graph.h:11
RzList * out_nodes
Definition: rz_graph.h:13
RzList * nodes
Definition: rz_graph.h:29
RzIOReadAt read_at
Definition: rz_io.h:240
RzIO * io
Definition: rz_io.h:232
struct rz_io_plugin_t * plugin
Definition: rz_io.h:103
bool isdbg
Definition: rz_io.h:124
size_t addrbytes
Definition: rz_io.h:66
struct rz_io_desc_t * desc
Definition: rz_io.h:60
bool subrel
Definition: rz_parse.h:26
int big_endian
Definition: rz_print.h:124
int flags
Definition: rz_print.h:137
int arena
In which arena is this reg living. Usually equals type.
Definition: rz_reg.h:127
int offset
Offset into register profile in bits.
Definition: rz_reg.h:121
char * name[RZ_REG_NAME_LAST]
Definition: rz_reg.h:149
RzTypeParser * parser
Definition: rz_type.h:37
char * path
Definition: rz_type.h:176
Definition: sdbht.h:14
Definition: sdb.h:63
Definition: dis.h:43
int64_t counter
Definition: main.c:4
int pos
Definition: main.c:11
uv_timer_t timeout
Definition: main.c:9
uint64_t blocks
Definition: list.c:104
RZ_API void rz_syscall_item_free(RzSyscallItem *si)
Definition: syscall.c:325
RZ_API int rz_syscall_get_num(RzSyscall *s, const char *str)
Definition: syscall.c:376
RZ_API RzSyscallItem * rz_syscall_get(RzSyscall *s, int num, int swi)
Definition: syscall.c:345
RZ_API RzList * rz_syscall_list(RzSyscall *s)
Definition: syscall.c:415
RZ_API void rz_core_task_yield(RzCoreTaskScheduler *scheduler)
Definition: task.c:336
#define fail(test)
Definition: tests.h:29
RZ_API void rz_debug_trace_op(RzDebug *dbg, RzAnalysisOp *op)
Definition: trace.c:177
RZ_API bool rz_type_func_ret_set(RzTypeDB *typedb, const char *name, RZ_OWN RZ_NONNULL RzType *type)
Sets the new return type for the RzCallable.
Definition: function.c:348
RZ_API RZ_OWN RzList * rz_type_db_get_by_offset(const RzTypeDB *typedb, ut64 offset)
Returns the list of all structured types that have members matching the offset.
Definition: path.c:219
RZ_API void rz_type_free(RZ_NULLABLE RzType *type)
Frees the RzType.
Definition: type.c:1273
RZ_API RzBaseType * rz_type_db_get_enum(const RzTypeDB *typedb, RZ_NONNULL const char *name)
Returns the enum base type matching the specified name.
Definition: type.c:489
RZ_API RZ_OWN char * rz_type_as_string(const RzTypeDB *typedb, RZ_NONNULL const RzType *type)
Returns the type C representation.
Definition: type.c:817
Definition: dis.c:32
RZ_API RZ_BORROW RzAnalysisVar * rz_analysis_function_get_var(RzAnalysisFunction *fcn, char kind, int delta)
Definition: var.c:259
RZ_API void rz_analysis_function_delete_all_vars(RzAnalysisFunction *fcn)
Definition: var.c:220
RZ_API int rz_analysis_var_count(RzAnalysis *a, RzAnalysisFunction *fcn, int kind, int type)
Definition: var.c:574
RZ_API void rz_analysis_var_set_access(RzAnalysisVar *var, const char *reg, ut64 access_addr, int access_type, st64 stackptr)
Definition: var.c:441
RZ_API RzList * rz_analysis_var_list(RzAnalysis *a, RzAnalysisFunction *fcn, int kind)
Definition: var.c:1154
RZ_API void rz_analysis_function_delete_vars_by_kind(RzAnalysisFunction *fcn, RzAnalysisVarKind kind)
Definition: var.c:206
RZ_API RZ_BORROW RzAnalysisVar * rz_analysis_function_set_var(RzAnalysisFunction *fcn, int delta, char kind, RZ_BORROW RZ_NULLABLE const RzType *type, int size, bool isarg, RZ_NONNULL const char *name)
Definition: var.c:111
RZ_DEPRECATE RZ_API RzList * rz_analysis_var_all_list(RzAnalysis *analysis, RzAnalysisFunction *fcn)
Definition: var.c:1135
RZ_API RZ_BORROW RzAnalysisVar * rz_analysis_function_get_var_byname(RzAnalysisFunction *fcn, const char *name)
Definition: var.c:247
RZ_API void rz_analysis_var_set_type(RzAnalysisVar *var, RZ_OWN RzType *type, bool resolve_overlaps)
Definition: var.c:170
RZ_API void rz_analysis_var_global_set_type(RzAnalysisVarGlobal *glob, RZ_NONNULL RZ_BORROW RzType *type)
Set the type of the global variable.
Definition: var_global.c:302
RZ_API RZ_OWN RzAnalysisVarGlobal * rz_analysis_var_global_new(RZ_NONNULL const char *name, ut64 addr)
Create a new instance of global variable.
Definition: var_global.c:15
RZ_API RZ_BORROW RzAnalysisVarGlobal * rz_analysis_var_global_get_byname(RzAnalysis *analysis, RZ_NONNULL const char *name)
Get the instance of global variable by its name.
Definition: var_global.c:190
RZ_API void rz_analysis_var_global_free(RzAnalysisVarGlobal *glob)
Free the global variable instance.
Definition: var_global.c:79
RZ_API bool rz_analysis_var_global_delete_byname(RzAnalysis *analysis, RZ_NONNULL const char *name)
Delete and free the global variable by its name.
Definition: var_global.c:136
RZ_API bool rz_analysis_var_global_delete_byaddr_in(RzAnalysis *analysis, ut64 addr)
Same as rz_analysis_var_global_delete_byname in the address.
Definition: var_global.c:172
RZ_API RZ_OWN bool rz_analysis_var_global_add(RzAnalysis *analysis, RZ_NONNULL RzAnalysisVarGlobal *global_var)
Add the global variable into hashtable.
Definition: var_global.c:46
RZ_API bool rz_analysis_var_global_rename(RzAnalysis *analysis, RZ_NONNULL const char *old_name, RZ_NONNULL const char *newname)
Rename the global variable.
Definition: var_global.c:277
static int color
Definition: visual.c:20
static int obs
Definition: visual.c:14
RZ_API RzListInfo * rz_listinfo_new(const char *name, RzInterval pitv, RzInterval vitv, int perm, const char *extra)
Definition: visual.c:4020
RZ_API void rz_listinfo_free(RzListInfo *info)
Definition: visual.c:4032
static int level
Definition: vmenus.c:2424
static st64 delta
Definition: vmenus.c:2425
RZ_API void rz_analysis_list_vtables(RzAnalysis *analysis, RzOutputMode mode)
Definition: vtable.c:288
RZ_API bool rz_analysis_vtable_begin(RzAnalysis *analysis, RVTableContext *context)
Definition: vtable.c:41
ut64(WINAPI *w32_GetEnabledXStateFeatures)()
RZ_API RZ_OWN RzList * rz_analysis_xrefs_list(RzAnalysis *analysis)
Get list of all xrefs.
Definition: xrefs.c:206
RZ_API RzList * rz_analysis_xrefs_get_from(RzAnalysis *analysis, ut64 addr)
Definition: xrefs.c:187
RZ_API RzList * rz_analysis_xrefs_get_to(RzAnalysis *analysis, ut64 addr)
Definition: xrefs.c:173
RZ_API RzList * rz_analysis_function_get_xrefs_to(RzAnalysisFunction *fcn)
Definition: xrefs.c:302
RZ_API ut64 rz_analysis_xrefs_count(RzAnalysis *analysis)
Definition: xrefs.c:272
RZ_API bool rz_analysis_xrefs_init(RzAnalysis *analysis)
Definition: xrefs.c:245
RZ_API const char * rz_analysis_xrefs_type_tostring(RzAnalysisXRefType type)
Definition: xrefs.c:216
RZ_API bool rz_analysis_xrefs_set(RzAnalysis *analysis, ut64 from, ut64 to, RzAnalysisXRefType type)
Definition: xrefs.c:117
RZ_API bool rz_analysis_xref_del(RzAnalysis *analysis, ut64 from, ut64 to)
Definition: xrefs.c:163
RZ_API RzList * rz_analysis_function_get_xrefs_from(RzAnalysisFunction *fcn)
Definition: xrefs.c:297
static int sp
Definition: z80asm.c:91
static int verbose
Definition: z80asm.c:73
static int addr
Definition: z80asm.c:58
static bool input(void *ud, zip_uint8_t *data, zip_uint64_t length)
static int seek(char *argv[])