Rizin
unix-like reverse engineering framework and cli tools
cmd_search_rop.c
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2009-2016 Alexandru Caciulescu <alex.darredevil@gmail.com>
2 // SPDX-License-Identifier: LGPL-3.0-only
3 
4 #include <stddef.h>
5 
6 #include "rz_core.h"
7 #include "rz_io.h"
8 #include "rz_list.h"
9 #include "rz_types_base.h"
10 
11 static RzList *parse_list(const char *str) {
12  char *line, *data, *str_n;
13 
14  if (!str) {
15  return NULL;
16  }
17  str_n = strdup(str);
18  line = strtok(str_n, "\n");
19  data = strchr(line, '=');
20 
21  RzList *list = rz_str_split_duplist(data + 1, ",", false);
22 
23  free(str_n);
24  return list;
25 }
26 
27 static RzList *get_constants(const char *str) {
28  RzList *list;
29  char *p, *data;
30  if (!str) {
31  return NULL;
32  }
33 
34  data = strdup(str);
36  p = strtok(data, ",");
37  while (p) {
38  if (strtol(p, NULL, 0)) {
39  rz_list_append(list, (void *)strdup(p));
40  }
41  p = strtok(NULL, ",");
42  }
43  free(data);
44  return list;
45 }
46 
47 static bool isFlag(RzRegItem *reg) {
48  const char *type = rz_reg_get_type(reg->type);
49 
50  if (!strcmp(type, "flg"))
51  return true;
52  return false;
53 }
54 
55 // binary op
56 static bool simulate_op(const char *op, ut64 src1, ut64 src2, ut64 old_src1, ut64 old_src2, ut64 *result, int size) {
57  ut64 limit;
58  if (size == 64) {
59  limit = UT64_MAX;
60  } else {
61  limit = 1ULL << size;
62  }
63 
64  if (!strcmp(op, "^")) {
65  *result = src1 ^ src2;
66  return true;
67  }
68  if (!strcmp(op, "+")) {
69  *result = src1 + src2;
70  return true;
71  }
72  if (!strcmp(op, "-")) {
73  if (src2 > src1) {
74  *result = limit + (src1 - src2);
75  } else {
76  *result = src1 - src2;
77  }
78  return true;
79  }
80  if (!strcmp(op, "*")) {
81  *result = src1 * src2;
82  return true;
83  }
84  if (!strcmp(op, "|")) {
85  *result = src1 | src2;
86  return true;
87  }
88  if (!strcmp(op, "/")) {
89  *result = src1 / src2;
90  return true;
91  }
92  if (!strcmp(op, "%")) {
93  *result = src1 % src2;
94  return true;
95  }
96  if (!strcmp(op, "<<")) {
97  *result = src1 << src2;
98  return true;
99  }
100  if (!strcmp(op, ">>")) {
101  *result = src1 >> src2;
102  return true;
103  }
104  if (!strcmp(op, "&")) {
105  *result = src1 & src2;
106  return true;
107  }
108  if (!strcmp(op, "+=")) {
109  *result = old_src1 + src2;
110  return true;
111  }
112  if (!strcmp(op, "-=")) {
113  if (src2 > old_src1) {
114  *result = limit + (old_src1 - src2);
115  } else {
116  *result = old_src1 - src2;
117  }
118  return true;
119  }
120  if (!strcmp(op, "*=")) {
121  *result = old_src1 * src2;
122  return true;
123  }
124  if (!strcmp(op, "/=")) {
125  *result = old_src1 / src2;
126  return true;
127  }
128  if (!strcmp(op, "%=")) {
129  *result = old_src1 % src2;
130  return true;
131  }
132  if (!strcmp(op, "<<")) {
133  *result = src1 << src2;
134  return true;
135  }
136  if (!strcmp(op, ">>")) {
137  *result = src1 >> src2;
138  return true;
139  }
140  if (!strcmp(op, "&=")) {
141  *result = src1 & src2;
142  return true;
143  }
144  if (!strcmp(op, "^=")) {
145  *result = src1 ^ src2;
146  return true;
147  }
148  if (!strcmp(op, "|=")) {
149  *result = src1 | src2;
150  return true;
151  }
152  return false;
153 }
154 
155 // fill REGs with known values
156 static void fillRegisterValues(RzCore *core) {
157  RzListIter *iter_reg;
158  RzRegItem *reg_item;
159  int nr = 10;
160 
162  if (!regs) {
163  return;
164  }
165  rz_list_foreach (regs, iter_reg, reg_item) {
166  rz_reg_arena_pop(core->analysis->reg);
167  rz_reg_set_value(core->analysis->reg, reg_item, nr);
169  nr += 3;
170  }
171 }
172 
173 // split esil string in flags part and main instruction
174 // hacky, only tested for x86, TODO: portable version
175 // NOTE: esil_main and esil_flg are heap allocated and must be freed by the caller
176 static void esil_split_flg(char *esil_str, char **esil_main, char **esil_flg) {
177  char *split = strstr(esil_str, "f,=");
178  const int kCommaHits = 2;
179  int hits = 0;
180 
181  if (split) {
182  while (hits != kCommaHits) {
183  --split;
184  if (*split == ',') {
185  hits++;
186  }
187  }
188  *esil_flg = strdup(++split);
189  *esil_main = rz_str_ndup(esil_str, strlen(esil_str) - strlen(*esil_flg) - 1);
190  }
191 }
192 
193 #define FREE_ROP \
194  { \
195  RZ_FREE(out); \
196  RZ_FREE(esil_flg); \
197  RZ_FREE(esil_main); \
198  rz_list_free(ops_list); \
199  ops_list = NULL; \
200  rz_list_free(flg_read); \
201  flg_read = NULL; \
202  rz_list_free(flg_write); \
203  flg_write = NULL; \
204  rz_list_free(reg_read); \
205  reg_read = NULL; \
206  rz_list_free(reg_write); \
207  reg_write = NULL; \
208  rz_list_free(mem_read); \
209  mem_read = NULL; \
210  rz_list_free(mem_write); \
211  mem_write = NULL; \
212  }
213 
214 static char *rop_classify_constant(RzCore *core, RzList *ropList) {
215  char *esil_str, *constant;
216  char *ct = NULL, *esil_main = NULL, *esil_flg = NULL, *out = NULL;
217  RzListIter *iter_r, *iter_dst, *iter_const;
218  RzRegItem *item_dst;
219  const RzList *head;
220  RzList *constants;
221  RzList *ops_list = NULL, *flg_read = NULL, *flg_write = NULL,
222  *reg_read = NULL, *reg_write = NULL, *mem_read = NULL,
223  *mem_write = NULL;
224  const bool romem = rz_config_get_i(core->config, "esil.romem");
225  const bool stats = rz_config_get_i(core->config, "esil.stats");
226 
227  if (!romem || !stats) {
228  // eprintf ("Error: esil.romem and esil.stats must be set TRUE");
229  return NULL;
230  }
231 
232  rz_list_foreach (ropList, iter_r, esil_str) {
233  constants = get_constants(esil_str);
234  // if there are no constants in the instruction continue
235  if (rz_list_empty(constants)) {
236  continue;
237  }
238  // init regs with known values
239  fillRegisterValues(core);
241  if (!head) {
242  ct = NULL;
243  goto continue_error;
244  }
245  esil_split_flg(esil_str, &esil_main, &esil_flg);
246  cmd_analysis_esil(core, esil_main ? esil_main : esil_str);
247  out = sdb_querys(core->analysis->esil->stats, NULL, 0, "*");
248  if (!out) {
249  goto continue_error;
250  }
251  ops_list = parse_list(strstr(out, "ops.list"));
252  flg_read = parse_list(strstr(out, "flg.read"));
253  flg_write = parse_list(strstr(out, "flg.write"));
254  reg_read = parse_list(strstr(out, "reg.read"));
255  reg_write = parse_list(strstr(out, "reg.write"));
256  mem_read = parse_list(strstr(out, "mem.read"));
257  mem_write = parse_list(strstr(out, "mem.write"));
258  if (!rz_list_find(ops_list, "=", (RzListComparator)strcmp)) {
259  goto continue_error;
260  }
262  if (!head) {
263  goto out_error;
264  }
265  rz_list_foreach (head, iter_dst, item_dst) {
266  ut64 diff_dst, value_dst;
267  if (!rz_list_find(reg_write, item_dst->name,
268  (RzListComparator)strcmp)) {
269  continue;
270  }
271 
272  value_dst = rz_reg_get_value(core->analysis->reg, item_dst);
273  rz_reg_arena_swap(core->analysis->reg, false);
274  diff_dst = rz_reg_get_value(core->analysis->reg, item_dst);
275  rz_reg_arena_swap(core->analysis->reg, false);
276  // restore initial value
277  rz_reg_set_value(core->analysis->reg, item_dst, diff_dst);
278 
279  if (value_dst != diff_dst) {
280  rz_list_foreach (constants, iter_const, constant) {
281  if (value_dst == rz_num_get(NULL, constant)) {
282  ct = rz_str_appendf(ct, "%s <-- 0x%" PFMT64x ";", item_dst->name, value_dst);
283  }
284  }
285  }
286  }
287  continue_error:
288  // coverity may complain here but as long as the pointer is set back to
289  // NULL is safe that is why is used RZ_FREE
290  FREE_ROP;
291  rz_list_free(constants);
292  }
293  return ct;
294 out_error:
295  FREE_ROP;
296  rz_list_free(constants);
297  return NULL;
298 }
299 
300 static char *rop_classify_mov(RzCore *core, RzList *ropList) {
301  char *esil_str;
302  char *mov = NULL, *esil_main = NULL, *esil_flg = NULL, *out = NULL;
303  RzListIter *iter_src, *iter_r, *iter_dst;
304  RzRegItem *item_src, *item_dst;
305  const RzList *head;
306  RzList *ops_list = NULL, *flg_read = NULL, *flg_write = NULL,
307  *reg_read = NULL, *reg_write = NULL, *mem_read = NULL,
308  *mem_write = NULL;
309  const bool romem = rz_config_get_i(core->config, "esil.romem");
310  const bool stats = rz_config_get_i(core->config, "esil.stats");
311 
312  if (!romem || !stats) {
313  // eprintf ("Error: esil.romem and esil.stats must be set TRUE");
314  return NULL;
315  }
316 
317  rz_list_foreach (ropList, iter_r, esil_str) {
318  // init regs with known values
319  fillRegisterValues(core);
321  if (!head) {
322  goto out_error;
323  }
324  esil_split_flg(esil_str, &esil_main, &esil_flg);
325  cmd_analysis_esil(core, esil_main ? esil_main : esil_str);
326  out = sdb_querys(core->analysis->esil->stats, NULL, 0, "*");
327  if (out) {
328  ops_list = parse_list(strstr(out, "ops.list"));
329  flg_read = parse_list(strstr(out, "flg.read"));
330  flg_write = parse_list(strstr(out, "flg.write"));
331  reg_read = parse_list(strstr(out, "reg.read"));
332  reg_write = parse_list(strstr(out, "reg.write"));
333  mem_read = parse_list(strstr(out, "mem.read"));
334  mem_write = parse_list(strstr(out, "mem.write"));
335  } else {
336  goto continue_error;
337  }
338 
339  if (!rz_list_find(ops_list, "=", (RzListComparator)strcmp)) {
340  goto continue_error;
341  }
342 
344  if (!head) {
345  goto out_error;
346  }
347  rz_list_foreach (head, iter_dst, item_dst) {
348  ut64 diff_dst, value_dst;
349  if (!rz_list_find(reg_write, item_dst->name,
350  (RzListComparator)strcmp)) {
351  continue;
352  }
353 
354  // you never mov into flags
355  if (isFlag(item_dst)) {
356  continue;
357  }
358 
359  value_dst = rz_reg_get_value(core->analysis->reg, item_dst);
360  rz_reg_arena_swap(core->analysis->reg, false);
361  diff_dst = rz_reg_get_value(core->analysis->reg, item_dst);
362  rz_reg_arena_swap(core->analysis->reg, false);
363  rz_list_foreach (head, iter_src, item_src) {
364  ut64 diff_src, value_src;
365  if (!rz_list_find(reg_read, item_src->name,
366  (RzListComparator)strcmp)) {
367  continue;
368  }
369  // you never mov from flags
370  if (item_src == item_dst || isFlag(item_src)) {
371  continue;
372  }
373  value_src = rz_reg_get_value(core->analysis->reg, item_src);
374  rz_reg_arena_swap(core->analysis->reg, false);
375  diff_src = rz_reg_get_value(core->analysis->reg, item_src);
376  rz_reg_arena_swap(core->analysis->reg, false);
377  // restore initial value
378  rz_reg_set_value(core->analysis->reg, item_src, diff_src);
379  if (value_dst == value_src && value_dst != diff_dst) {
380  mov = rz_str_appendf(mov, "%s <-- %s;",
381  item_dst->name, item_src->name);
382  }
383  }
384  }
385  continue_error:
386  FREE_ROP;
387  }
388  return mov;
389 out_error:
390  FREE_ROP;
391  return NULL;
392 }
393 
394 static char *rop_classify_arithmetic(RzCore *core, RzList *ropList) {
395  char *esil_str, *op;
396  char *arithmetic = NULL, *esil_flg = NULL, *esil_main = NULL,
397  *out = NULL;
398  RzListIter *iter_src1, *iter_src2, *iter_r, *iter_dst, *iter_ops;
399  RzRegItem *item_src1, *item_src2, *item_dst;
400  const RzList *head;
401  RzList *ops_list = NULL, *flg_read = NULL, *flg_write = NULL,
402  *reg_read = NULL, *reg_write = NULL, *mem_read = NULL,
403  *mem_write = NULL;
404  const bool romem = rz_config_get_i(core->config, "esil.romem");
405  const bool stats = rz_config_get_i(core->config, "esil.stats");
406  ut64 *op_result = RZ_NEW0(ut64);
407  ut64 *op_result_r = RZ_NEW0(ut64);
408 
409  if (!romem || !stats) {
410  // eprintf ("Error: esil.romem and esil.stats must be set TRUE");
411  free(op_result);
412  free(op_result_r);
413  return NULL;
414  }
415 
416  rz_list_foreach (ropList, iter_r, esil_str) {
417  // init regs with known values
418  fillRegisterValues(core);
420  if (!head) {
421  goto out_error;
422  }
423  esil_split_flg(esil_str, &esil_main, &esil_flg);
424  if (esil_main) {
425  cmd_analysis_esil(core, esil_main);
426  } else {
427  cmd_analysis_esil(core, esil_str);
428  }
429  out = sdb_querys(core->analysis->esil->stats, NULL, 0, "*");
430  // rz_cons_println (out);
431  if (!out) {
432  goto continue_error;
433  }
434  ops_list = parse_list(strstr(out, "ops.list"));
435  flg_read = parse_list(strstr(out, "flg.read"));
436  flg_write = parse_list(strstr(out, "flg.write"));
437  reg_read = parse_list(strstr(out, "reg.read"));
438  reg_write = parse_list(strstr(out, "reg.write"));
439  mem_read = parse_list(strstr(out, "mem.read"));
440  mem_write = parse_list(strstr(out, "mem.write"));
441 
442  rz_list_foreach (ops_list, iter_ops, op) {
443  rz_list_foreach (head, iter_src1, item_src1) {
444  ut64 value_src1, diff_src1;
445 
446  value_src1 = rz_reg_get_value(core->analysis->reg, item_src1);
447  rz_reg_arena_swap(core->analysis->reg, false);
448  diff_src1 = rz_reg_get_value(core->analysis->reg, item_src1);
449  rz_reg_arena_swap(core->analysis->reg, false);
450  if (!rz_list_find(reg_read, item_src1->name,
451  (RzListComparator)strcmp)) {
452  continue;
453  }
454 
455  rz_list_foreach (head, iter_src2, item_src2) {
456  ut64 value_src2, diff_src2;
457  value_src2 = rz_reg_get_value(core->analysis->reg, item_src2);
458  rz_reg_arena_swap(core->analysis->reg, false);
459  diff_src2 = rz_reg_get_value(core->analysis->reg, item_src2);
460 
461  if (!rz_list_find(reg_read, item_src2->name,
462  (RzListComparator)strcmp)) {
463  continue;
464  }
465  // TODO check condition
466  if (iter_src1 == iter_src2) {
467  continue;
468  }
469 
470  rz_list_foreach (head, iter_dst, item_dst) {
471  ut64 value_dst;
472  bool redundant = false, simulate, simulate_r;
473 
474  value_dst = rz_reg_get_value(core->analysis->reg, item_dst);
475  rz_reg_arena_swap(core->analysis->reg, false);
476  if (!rz_list_find(reg_write, item_dst->name,
477  (RzListComparator)strcmp)) {
478  continue;
479  }
480  // don't check flags for arithmetic
481  if (isFlag(item_dst)) {
482  continue;
483  }
484  simulate = simulate_op(op, value_src1, value_src2, diff_src1, diff_src2, op_result, item_dst->size);
485  simulate_r = simulate_op(op, value_src2, value_src1, diff_src2, diff_src1, op_result_r, item_dst->size);
486  if (/*value_src1 != 0 && value_src2 != 0 && */ simulate && value_dst == *op_result) {
487  // rz_cons_println ("Debug: FOUND ONE !");
488  char *tmp = rz_str_newf("%s <-- %s %s %s;", item_dst->name, item_src1->name, op, item_src2->name);
489  if (arithmetic && !strstr(arithmetic, tmp)) {
491  } else if (!arithmetic) {
493  }
494  free(tmp);
495  } else if (!redundant /*&& value_src1 != 0 && value_src2 != 0*/ && simulate_r && value_dst == *op_result_r) {
496  // rz_cons_println ("Debug: FOUND ONE reversed!");
497  char *tmp = rz_str_newf("%s <-- %s %s %s;", item_dst->name, item_src2->name, op, item_src1->name);
498  if (arithmetic && !strstr(arithmetic, tmp)) {
500  } else if (!arithmetic) {
502  }
503  free(tmp);
504  }
505  }
506  }
507  }
508  }
509  continue_error:
510  FREE_ROP;
511  }
512  free(op_result);
513  free(op_result_r);
514  return arithmetic;
515 out_error:
516  FREE_ROP;
517  free(op_result);
518  free(op_result_r);
519  return NULL;
520 }
521 
522 static char *rop_classify_arithmetic_const(RzCore *core, RzList *ropList) {
523  char *esil_str, *op, *constant;
524  char *arithmetic = NULL, *esil_flg = NULL, *esil_main = NULL;
525  RzListIter *iter_src1, *iter_r, *iter_dst, *iter_ops, *iter_const;
526  RzRegItem *item_src1, *item_dst;
527  const RzList *head;
528  RzList *constants;
529  RzList *ops_list = NULL, *flg_read = NULL, *flg_write = NULL, *reg_read = NULL,
530  *reg_write = NULL, *mem_read = NULL, *mem_write = NULL;
531  const bool romem = rz_config_get_i(core->config, "esil.romem");
532  const bool stats = rz_config_get_i(core->config, "esil.stats");
533  ut64 *op_result = RZ_NEW0(ut64);
534  ut64 *op_result_r = RZ_NEW0(ut64);
535 
536  if (!romem || !stats) {
537  // eprintf ("Error: esil.romem and esil.stats must be set TRUE");
538  RZ_FREE(op_result);
539  RZ_FREE(op_result_r);
540  return NULL;
541  }
542 
543  rz_list_foreach (ropList, iter_r, esil_str) {
544  constants = get_constants(esil_str);
545  // if there are no constants in the instruction continue
546  if (rz_list_empty(constants)) {
547  continue;
548  }
549  // init regs with known values
550  fillRegisterValues(core);
552  if (!head) {
553  arithmetic = NULL;
554  continue;
555  }
556  esil_split_flg(esil_str, &esil_main, &esil_flg);
557  if (esil_main) {
558  cmd_analysis_esil(core, esil_main);
559  } else {
560  cmd_analysis_esil(core, esil_str);
561  }
562  char *out = sdb_querys(core->analysis->esil->stats, NULL, 0, "*");
563  // rz_cons_println (out);
564  if (out) {
565  ops_list = parse_list(strstr(out, "ops.list"));
566  flg_read = parse_list(strstr(out, "flg.read"));
567  flg_write = parse_list(strstr(out, "flg.write"));
568  reg_read = parse_list(strstr(out, "reg.read"));
569  reg_write = parse_list(strstr(out, "reg.write"));
570  mem_read = parse_list(strstr(out, "mem.read"));
571  mem_write = parse_list(strstr(out, "mem.write"));
572  } else {
573  RZ_FREE(op_result);
574  RZ_FREE(op_result_r);
575  goto continue_error;
576  }
577 
578  rz_list_foreach (ops_list, iter_ops, op) {
579  rz_list_foreach (head, iter_src1, item_src1) {
580  ut64 value_src1, diff_src1;
581  value_src1 = rz_reg_get_value(core->analysis->reg, item_src1);
582  rz_reg_arena_swap(core->analysis->reg, false);
583  diff_src1 = rz_reg_get_value(core->analysis->reg, item_src1);
584  rz_reg_arena_swap(core->analysis->reg, false);
585 
586  if (!rz_list_find(reg_read, item_src1->name,
587  (RzListComparator)strcmp)) {
588  continue;
589  }
590  rz_list_foreach (head, iter_dst, item_dst) {
591  ut64 value_dst, diff_dst;
592  bool redundant = false, simulate, simulate_r;
593  value_dst = rz_reg_get_value(core->analysis->reg, item_dst);
594  rz_reg_arena_swap(core->analysis->reg, false);
595  diff_dst = rz_reg_get_value(core->analysis->reg, item_dst);
596  rz_reg_arena_swap(core->analysis->reg, false);
597  if (!rz_list_find(reg_write, item_dst->name,
598  (RzListComparator)strcmp)) {
599  continue;
600  }
601  // don't check flags for arithmetic
602  if (isFlag(item_dst)) {
603  continue;
604  }
605  if (value_dst != diff_dst) {
606  rz_list_foreach (constants, iter_const, constant) {
607  ut64 value_ct = rz_num_get(NULL, constant);
608  simulate = simulate_op(op, value_src1, value_ct,
609  diff_src1, value_ct, op_result,
610  item_dst->size);
611  simulate_r = simulate_op(op, value_ct, value_src1,
612  value_ct, diff_src1, op_result_r,
613  item_dst->size);
614  if (simulate && op_result && value_dst == *op_result) {
615  char *tmp = rz_str_newf("%s <-- %s %s %s;", item_dst->name, item_src1->name, op, constant);
616  if (arithmetic && !strstr(arithmetic, tmp)) {
618  } else if (!arithmetic) {
620  }
621  free(tmp);
622  redundant = true;
623  } else if (!redundant && simulate_r && value_dst == *op_result_r) {
624  char *tmp = rz_str_newf("%s <-- %s %s %s;", item_dst->name, constant, op, item_src1->name);
625  if (arithmetic && !strstr(arithmetic, tmp)) {
627  } else if (!arithmetic) {
629  }
630  free(tmp);
631  }
632  }
633  }
634  }
635  }
636  }
637  continue_error:
638  FREE_ROP;
639  rz_list_free(constants);
640  }
641  free(op_result);
642  free(op_result_r);
643  return arithmetic;
644 }
645 
646 static int rop_classify_nops(RzCore *core, RzList *ropList) {
647  char *esil_str;
648  int changes = 1;
649  RzListIter *iter_r;
650  const bool romem = rz_config_get_i(core->config, "esil.romem");
651  const bool stats = rz_config_get_i(core->config, "esil.stats");
652 
653  if (!romem || !stats) {
654  // eprintf ("Error: esil.romem and esil.stats must be set TRUE\n");
655  return -2;
656  }
657 
658  rz_list_foreach (ropList, iter_r, esil_str) {
659  fillRegisterValues(core);
660 
661  // rz_cons_printf ("Emulating nop:%s\n", esil_str);
662  cmd_analysis_esil(core, esil_str);
663  char *out = sdb_querys(core->analysis->esil->stats, NULL, 0, "*");
664  // rz_cons_println (out);
665  if (out) {
666  free(out);
667  return 0;
668  }
669  // directly say NOP
670  continue;
671  }
672 
673  return changes;
674 }
675 
676 static void rop_classify(RzCore *core, Sdb *db, RzList *ropList, const char *key, unsigned int size) {
677  int nop = 0;
678  rop_classify_nops(core, ropList);
679  char *mov, *ct, *arithm, *arithm_ct, *str;
680  Sdb *db_nop = sdb_ns(db, "nop", true);
681  Sdb *db_mov = sdb_ns(db, "mov", true);
682  Sdb *db_ct = sdb_ns(db, "const", true);
683  Sdb *db_aritm = sdb_ns(db, "arithm", true);
684  Sdb *db_aritm_ct = sdb_ns(db, "arithm_ct", true);
685 
686  if (!db_nop || !db_mov || !db_ct || !db_aritm || !db_aritm_ct) {
687  eprintf("Error: Could not create SDB 'rop' sub-namespaces\n");
688  return;
689  }
690  nop = rop_classify_nops(core, ropList);
691  mov = rop_classify_mov(core, ropList);
692  ct = rop_classify_constant(core, ropList);
693  arithm = rop_classify_arithmetic(core, ropList);
694  arithm_ct = rop_classify_arithmetic_const(core, ropList);
695  str = rz_str_newf("0x%u", size);
696 
697  if (nop == 1) {
698  char *str_nop = rz_str_newf("%s NOP", str);
699  sdb_set(db_nop, key, str_nop, 0);
700  free(str_nop);
701  } else {
702  if (mov) {
703  char *str_mov = rz_str_newf("%s MOV { %s }", str, mov);
704  sdb_set(db_mov, key, str_mov, 0);
705  free(str_mov);
706  free(mov);
707  }
708  if (ct) {
709  char *str_ct = rz_str_newf("%s LOAD_CONST { %s }", str, ct);
710  sdb_set(db_ct, key, str_ct, 0);
711  free(str_ct);
712  free(ct);
713  }
714  if (arithm) {
715  char *str_arithm = rz_str_newf("%s ARITHMETIC { %s }", str, arithm);
716  sdb_set(db_aritm, key, str_arithm, 0);
717  free(str_arithm);
718  free(arithm);
719  }
720  if (arithm_ct) {
721  char *str_arithm_ct = rz_str_newf("%s ARITHMETIC_CONST { %s }", str, arithm_ct);
722  sdb_set(db_aritm_ct, key, str_arithm_ct, 0);
723  free(str_arithm_ct);
724  free(arithm_ct);
725  }
726  }
727 
728  free(str);
729 }
ut8 op
Definition: 6502dis.c:13
static char * regs[]
Definition: analysis_sh.c:203
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
RZ_API void rz_reg_arena_swap(RzReg *reg, int copy)
Definition: arena.c:196
static RzILOpEffect * mov(cs_insn *insn, bool is_thumb)
Definition: arm_il32.c:351
static ut32 arithmetic(ArmOp *op, int k)
Definition: armass64.c:933
const lzma_allocator const uint8_t size_t uint8_t * out
Definition: block.h:528
static int mem_read(struct mem_file *fh, void *buffer, int bytes)
Definition: cabd_memory.c:59
static int mem_write(struct mem_file *fh, void *buffer, int bytes)
Definition: cabd_memory.c:68
static void cmd_analysis_esil(RzCore *core, const char *input)
static RzList * get_constants(const char *str)
#define FREE_ROP
static char * rop_classify_mov(RzCore *core, RzList *ropList)
static bool isFlag(RzRegItem *reg)
static void rop_classify(RzCore *core, Sdb *db, RzList *ropList, const char *key, unsigned int size)
static void fillRegisterValues(RzCore *core)
static char * rop_classify_arithmetic(RzCore *core, RzList *ropList)
static char * rop_classify_constant(RzCore *core, RzList *ropList)
static char * rop_classify_arithmetic_const(RzCore *core, RzList *ropList)
static void esil_split_flg(char *esil_str, char **esil_main, char **esil_flg)
static int rop_classify_nops(RzCore *core, RzList *ropList)
static bool simulate_op(const char *op, ut64 src1, ut64 src2, ut64 old_src1, ut64 old_src2, ut64 *result, int size)
static RzList * parse_list(const char *str)
RZ_API ut64 rz_config_get_i(RzConfig *cfg, RZ_NONNULL const char *name)
Definition: config.c:119
#define NULL
Definition: cris-opc.c:27
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void static offset struct stat static buf void long static basep static whence static length const void static len key
Definition: sflib.h:118
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
voidpf void uLong size
Definition: ioapi.h:138
#define reg(n)
void * p
Definition: libc.cpp:67
static void list(RzEgg *egg)
Definition: rz-gg.c:52
RZ_API RZ_BORROW RzListIter * rz_list_find(RZ_NONNULL const RzList *list, const void *p, RZ_NONNULL RzListComparator cmp)
Returns RzListIter element which matches via the RzListComparator.
Definition: list.c:620
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_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
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 uint32_t const uint8_t uint32_t uint32_t limit
Definition: memcmplen.h:45
int type
Definition: mipsasm.c:17
line
Definition: setup.py:34
RZ_API Sdb * sdb_ns(Sdb *s, const char *name, int create)
Definition: ns.c:186
RZ_API const char * rz_reg_get_type(int idx)
Definition: reg.c:68
RZ_API const RzList * rz_reg_get_list(RzReg *reg, int type)
Definition: reg.c:389
#define eprintf(x, y...)
Definition: rlcc.c:7
RZ_API bool rz_reg_set_value(RzReg *reg, RzRegItem *item, ut64 value)
Definition: rvalue.c:186
RZ_API ut64 rz_reg_get_value(RzReg *reg, RzRegItem *item)
Definition: rvalue.c:114
int(* RzListComparator)(const void *value, const void *list_data)
Definition: rz_list.h:33
RZ_API ut64 rz_num_get(RzNum *num, const char *str)
Definition: unum.c:172
@ RZ_REG_TYPE_GPR
Definition: rz_reg.h:21
RZ_API char * rz_str_appendf(char *ptr, const char *fmt,...) RZ_PRINTF_CHECK(2
RZ_API char * rz_str_newf(const char *fmt,...) RZ_PRINTF_CHECK(1
RZ_API char * rz_str_append(char *ptr, const char *string)
Definition: str.c:1063
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 RzList * rz_str_split_duplist(const char *str, const char *c, bool trim)
Split the string str according to the substring c and returns a RzList with the result.
Definition: str.c:3464
#define RZ_NEW0(x)
Definition: rz_types.h:284
#define RZ_FREE(x)
Definition: rz_types.h:369
#define PFMT64x
Definition: rz_types.h:393
#define UT64_MAX
Definition: rz_types_base.h:86
RZ_API int sdb_set(Sdb *s, const char *key, const char *val, ut32 cas)
Definition: sdb.c:611
struct rz_analysis_esil_t * esil
Definition: rz_analysis.h:584
RzAnalysis * analysis
Definition: rz_core.h:322
RzConfig * config
Definition: rz_core.h:300
int size
in bits> 8,16,32,64 ... 128/256
Definition: rz_reg.h:120
char * name
Definition: rz_reg.h:118
Definition: sdb.h:63
Definition: dis.c:32
ut64(WINAPI *w32_GetEnabledXStateFeatures)()