Rizin
unix-like reverse engineering framework and cli tools
rz-sign.c
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2021 RizinOrg <info@rizin.re>
2 // SPDX-FileCopyrightText: 2021 deroad <wargio@libero.it>
3 // SPDX-License-Identifier: LGPL-3.0-only
4 #include <rz_main.h>
5 #include <rz_core.h>
6 
12 };
13 
14 static void rz_sign_show_help(void) {
15  printf("Usage: rz-sign [options] [file]\n"
16  " -h this help message\n"
17  " -a [-a] add extra 'a' to analysis command (available only with -o option)\n"
18  " -e [k=v] set an evaluable config variable (available only with -o option)\n"
19  " -c [output.pat] [input.sig] parses a FLIRT signature and converts it to its other format\n"
20  " -o [output.sig] [input.bin] performs an analysis on the binary and generates the FLIRT signature.\n"
21  " -d [flirt.sig] parses a FLIRT signature and dump its content\n"
22  " -q quiet mode\n"
23  " -v show version information\n"
24  "Examples:\n"
25  " rz-sign -d signature.sig\n"
26  " rz-sign -c new_signature.pat old_signature.sig\n"
27  " rz-sign -o libc.sig libc.so.6\n");
28 }
29 
30 static void perform_analysis(RzCore *core, size_t complexity) {
31  const char *cmd = NULL;
32  switch (complexity) {
33  case 0: cmd = "aa"; break;
34  case 1: cmd = "aaa"; break;
35  default: cmd = "aaaa"; break;
36  }
37  rz_core_cmd0(core, cmd);
38 }
39 
40 RZ_API int rz_main_rz_sign(int argc, const char **argv) {
41  RzListIter *it;
42  const char *input_file = NULL;
43  const char *output_file = NULL;
44  char *config = NULL;
45  RzCore *core = NULL;
46  RzList *evars = NULL;
47  bool quiet = false;
48  RzGetopt opt;
49  int ret = 0;
50  ut32 n_nodes = 0;
51 
52  int c, option = RZ_SIGN_OPT_NONE;
53  size_t complexity = 0;
54 
55  evars = rz_list_newf(free);
56  if (!evars) {
57  RZ_LOG_ERROR("rz-sign: cannot allocate RzList\n");
58  return -1;
59  }
60 
61  rz_getopt_init(&opt, argc, argv, "aqhdc:o:e:v");
62  while ((c = rz_getopt_next(&opt)) != -1) {
63  switch (c) {
64  case 'a':
65  complexity++;
66  break;
67  case 'c':
68  if (option != RZ_SIGN_OPT_NONE) {
69  RZ_LOG_ERROR("rz-sign: cannot combine option -%c with previous options\n", c);
70  ret = -1;
71  goto rz_sign_end;
72  }
74  output_file = opt.arg;
75  break;
76  case 'o':
77  if (option != RZ_SIGN_OPT_NONE) {
78  RZ_LOG_ERROR("rz-sign: cannot combine option -%c with previous options\n", c);
79  ret = -1;
80  goto rz_sign_end;
81  }
83  output_file = opt.arg;
84  break;
85  case 'd':
86  if (option != RZ_SIGN_OPT_NONE) {
87  RZ_LOG_ERROR("rz-sign: cannot combine option -%c with previous options\n", c);
88  ret = -1;
89  goto rz_sign_end;
90  }
92  break;
93  case 'e':
94  if (!(config = rz_str_new(opt.arg)) || !rz_list_append(evars, config)) {
95  free(config);
96  RZ_LOG_ERROR("rz-sign: cannot add evaluable config variable '%s' to RzList\n", opt.arg);
97  ret = -1;
98  goto rz_sign_end;
99  }
100  break;
101  case 'q':
102  quiet = true;
103  break;
104  case 'v':
105  return rz_main_version_print("rz-sign");
106  case 'h':
108  goto rz_sign_end;
109  default:
110  RZ_LOG_ERROR("rz-sign: invalid option -%c\n", c);
112  ret = -1;
113  goto rz_sign_end;
114  }
115  }
116 
117  if (opt.ind >= argc) {
118  RZ_LOG_ERROR("rz-sign: input file was not provided\n");
120  ret = -1;
121  goto rz_sign_end;
122  }
123 
124  input_file = argv[opt.ind];
125 
126  if (option == RZ_SIGN_OPT_CREATE_FLIRT && complexity > 2) {
127  RZ_LOG_ERROR("rz-sign: Invalid analysis complexity (too many -a defined, max -aa)\n");
129  ret = -1;
130  goto rz_sign_end;
131  }
132 
133  core = rz_core_new();
134  if (!core) {
135  RZ_LOG_ERROR("rz-sign: Cannot allocate RzCore\n");
136  ret = -1;
137  goto rz_sign_end;
138  }
139  rz_config_set_b(core->config, "scr.interactive", false);
140  rz_config_set_b(core->config, "analysis.apply.signature", false);
141  rz_cons_reset();
143 
144  rz_core_loadlibs(core, RZ_CORE_LOADLIBS_ALL);
145 
146  if (!rz_core_file_open(core, input_file, 0, 0)) {
147  RZ_LOG_ERROR("rz-sign: Could not open file %s\n", input_file);
148  ret = -1;
149  goto rz_sign_end;
150  }
151 
152  (void)rz_core_bin_load(core, NULL, UT64_MAX);
153  (void)rz_core_bin_update_arch_bits(core);
154 
155  // quiet mode
156  if (quiet) {
157  rz_config_set_b(core->config, "scr.prompt", false);
158  rz_config_set_i(core->config, "scr.color", COLOR_MODE_DISABLED);
159  }
160 
161  // set all evars
162  rz_list_foreach (evars, it, config) {
163  if (!rz_config_eval(core->config, config)) {
164  RZ_LOG_ERROR("rz-sign: invalid option '%s'\n", config);
165  ret = -1;
166  goto rz_sign_end;
167  }
168  }
169 
170  switch (option) {
172  // convert a flirt file from .pat to .sig or viceversa
173  if (!rz_core_flirt_convert_file(core, input_file, output_file)) {
174  ret = -1;
175  } else if (!quiet) {
176  rz_cons_printf("rz-sign: %s was converted to %s.\n", input_file, output_file);
177  }
178  break;
180  // run analysis to find functions
181  perform_analysis(core, complexity);
182  // create flirt file
183  if (!rz_core_flirt_create_file(core, output_file, &n_nodes)) {
184  ret = -1;
185  } else if (!quiet) {
186  rz_cons_printf("rz-sign: written %u signatures to %s.\n", n_nodes, output_file);
187  }
188  break;
190  if (!rz_core_flirt_dump_file(input_file)) {
191  ret = -1;
192  }
193  break;
194  default:
195  RZ_LOG_ERROR("rz-sign: missing option, please set -c or -d or -o\n");
196  ret = -1;
197  break;
198  }
199  rz_cons_flush();
200 
201 rz_sign_end:
202  rz_list_free(evars);
203  rz_core_free(core);
204  return ret;
205 }
RZ_API int rz_core_bin_update_arch_bits(RzCore *r)
Definition: cbin.c:4503
RZ_API RZ_BORROW RzCoreFile * rz_core_file_open(RZ_NONNULL RzCore *r, RZ_NONNULL const char *file, int flags, ut64 loadaddr)
Tries to open the file as is, otherwise tries as is a compilation of files.
Definition: cfile.c:1182
RZ_API bool rz_core_bin_load(RZ_NONNULL RzCore *r, RZ_NULLABLE const char *filenameuri, ut64 baddr)
Definition: cfile.c:942
RZ_API int rz_core_cmd0(RzCore *core, const char *cmd)
Definition: cmd.c:5428
RZ_API bool rz_config_eval(RZ_NONNULL RzConfig *cfg, RZ_NONNULL const char *str)
Sets the configuration variable and its value passed as argument.
Definition: config.c:575
RZ_API RzConfigNode * rz_config_set_i(RzConfig *cfg, RZ_NONNULL const char *name, const ut64 i)
Definition: config.c:419
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_set_interactive(bool x)
Definition: cons.c:1724
RZ_API int rz_cons_printf(const char *format,...)
Definition: cons.c:1202
RZ_API void rz_cons_flush(void)
Definition: cons.c:959
RZ_API void rz_cons_reset(void)
Definition: cons.c:804
#define RZ_API
#define NULL
Definition: cris-opc.c:27
_Use_decl_annotations_ int __cdecl printf(const char *const _Format,...)
Definition: cs_driver.c:93
RZ_API bool rz_core_flirt_convert_file(RZ_NONNULL RzCore *core, RZ_NONNULL const char *input_file, RZ_NONNULL const char *output_file)
converts a FLIRT file to the other format.
Definition: csign.c:510
RZ_API bool rz_core_flirt_create_file(RZ_NONNULL RzCore *core, RZ_NONNULL const char *output_file, RZ_NULLABLE ut32 *written_nodes)
Generates a new FLIRT file from a given RzCore structure.
Definition: csign.c:431
RZ_API bool rz_core_flirt_dump_file(RZ_NONNULL const char *flirt_file)
Dumps the contents of a FLIRT file.
Definition: csign.c:372
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
uint32_t ut32
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
RZ_API void rz_core_free(RzCore *c)
Definition: core.c:2683
RZ_API RzCore * rz_core_new(void)
Definition: core.c:866
rz_sign_option
Definition: rz-sign.c:7
@ RZ_SIGN_OPT_DUMP_FLIRT
Definition: rz-sign.c:11
@ RZ_SIGN_OPT_CONVERT_FLIRT
Definition: rz-sign.c:9
@ RZ_SIGN_OPT_CREATE_FLIRT
Definition: rz-sign.c:10
@ RZ_SIGN_OPT_NONE
Definition: rz-sign.c:8
static void rz_sign_show_help(void)
Definition: rz-sign.c:14
static void perform_analysis(RzCore *core, size_t complexity)
Definition: rz-sign.c:30
RZ_API int rz_main_rz_sign(int argc, const char **argv)
Definition: rz-sign.c:40
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 int rz_core_loadlibs(RzCore *core, int where)
Definition: libs.c:119
static static fork const void static count static fd const char const char static newpath char char argv
Definition: sflib.h:40
@ COLOR_MODE_DISABLED
Definition: rz_cons.h:442
RZ_API void rz_getopt_init(RzGetopt *go, int argc, const char **argv, const char *ostr)
Definition: getopt.c:17
RZ_API int rz_getopt_next(RzGetopt *opt)
Definition: getopt.c:29
#define RZ_LOG_ERROR(fmtstr,...)
Definition: rz_log.h:58
RZ_API int rz_main_version_print(const char *program)
Definition: main.c:49
RZ_API char * rz_str_new(const char *str)
Definition: str.c:865
#define UT64_MAX
Definition: rz_types_base.h:86
#define c(i)
Definition: sha256.c:43
Definition: getopt.h:84
RzConfig * config
Definition: rz_core.h:300
const char * arg
Definition: rz_getopt.h:15