Rizin
unix-like reverse engineering framework and cli tools
flirt.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-FileCopyrightText: 2014-2016 jfrankowski <jody.frankowski@gmail.com>
4 // SPDX-License-Identifier: LGPL-3.0-only
5 /* credits to IDA for the flirt tech */
6 /* original cpp code from Rheax <rheaxmascot@gmail.com> */
7 /* thanks LemonBoy for the improved research on rheax original work */
8 /* more information on flirt https://www.hex-rays.com/products/ida/tech/flirt/in_depth.shtml */
9 
10 /*
11  Flirt file format
12  =================
13  High level layout:
14  After the v5 header, there might be two more header fields depending of the version.
15  If version == 6 or version == 7, there is one more header field.
16  If version == 8 or version == 9, there is two more header field.
17  See idasig_v* structs for their description.
18  Next there is the non null terminated library name of library_name_len length.
19  Next see Parsing below.
20 
21  Endianness:
22  All multi bytes values are stored in little endian form in the headers.
23  For the rest of the file they are stored in big endian form.
24 
25  Parsing:
26  - described headers
27  - library name, not null terminated, length of library_name_len.
28 
29  parse_tree (cf. parse_tree):
30  - read number of initial root nodes: 1 byte if strictly inferior to 127 otherwise 2 bytes,
31  stored in big endian mode, and the most significant bit isn't used. cf. read_multiple_bytes().
32  if 0, this is a leaf, goto leaf (cf. parse_leaf). else continue parsing (cf. parse_tree).
33 
34  - for number of root node do:
35  - read node length, one unsigned byte (the pattern size in this node) (cf. read_node_length)
36  - read node variant mask (bit array) (cf. read_node_variant_mask):
37  if node length < 0x10 read up to two bytes. cf. read_max_2_bytes
38  if node length < 0x20 read up to five bytes. cf. read_multiple_bytes
39  - read non-variant bytes (cf. read_node_bytes)
40  - goto parse_tree
41 
42  leaf (cf. parse_leaf):
43  - read crc length, 1 byte
44  - read crc value, 2 bytes
45  module:
46  - read total module length:
47  if version >= 9 read up to five bytes, cf. read_multiple_bytes
48  else read up to two bytes, cf. read_max_2_bytes
49  - read module public functions (cf. read_module_public_functions):
50  same crc:
51  public function name:
52  - read function offset:
53  if version >= 9 read up to five bytes, cf. read_multiple_bytes
54  else read up to two bytes, cf. read_max_2_bytes
55  - if current byte < 0x20, read it : this is a function flag, see IDASIG_FUNCTION* defines
56  - read function name until current byte < 0x20
57  - read parsing flag, 1 byte
58  - if flag & IDASIG_PARSE_MORE_PUBLIC_NAMES: goto public function name
59  - if flag & IDASIG_PARSE_READ_TAIL_BYTES, read tail bytes, cf. read_module_tail_bytes:
60  - if version >= 8: read number of tail bytes, else suppose one
61  - for number of tail bytes do:
62  - read tail byte offset:
63  if version >= 9 read up to five bytes, cf. read_multiple_bytes
64  else read up to two bytes, cf. read_max_2_bytes
65  - read tail byte value, one byte
66 
67  - if flag & IDASIG_PARSE_READ_REFERENCED_FUNCTIONS, read referenced functions, cf. read_module_referenced_functions:
68  - if version >= 8: read number of referenced functions, else suppose one
69  - for number of referenced functions do:
70  - read referenced function offset:
71  if version >= 9 read up to five bytes, cf. read_multiple_bytes
72  else read up to two bytes, cf. read_max_2_bytes
73  - read referenced function name length, one byte:
74  - if name length == 0, read length up to five bytes, cf. read_multiple_bytes
75  - for name length, read name chars:
76  - if name is null terminated, it means the offset is negative
77 
78  - if flag & IDASIG_PARSE_MORE_MODULES_WITH_SAME_CRC, goto same crc, read function with same crc
79  - if flag & IDASIG_PARSE_MORE_MODULES, goto module, to read another module
80 
81 
82  More Information
83  -----------------
84  Function flags:
85  - local functions ((l) with dumpsig) which are static ones.
86  - collision functions ((!) with dumpsig) are the result of an unresolved collision.
87 
88  Tail bytes:
89  When two modules have the same pattern, and same crc, flirt tries to identify
90  a byte which is different in all the same modules.
91  Their offset is from the first byte after the crc.
92  They appear as "(XXXX: XX)" in dumpsig output
93 
94  Referenced functions:
95  When two modules have the same pattern, and same crc, and are identical in
96  non-variant bytes, they only differ by the functions they call. These functions are
97  "referenced functions". They need to be identified first before the module can be
98  identified.
99  The offset is from the start of the function to the referenced function name.
100  They appear as "(REF XXXX: NAME)" in dumpsig output
101  */
102 
103 #include <rz_lib.h>
104 #include <rz_flirt.h>
105 #define MAX_WBITS 15
106 
107 #if 0
108 #define sig_dbg(...) eprintf(__VA_ARGS__)
109 static void sig_dbg_buffer(const char *name, const ut8 *buffer, ut32 b_size) {
110  sig_dbg("%s ", name);
111  for (ut32 i = 0; i < b_size; ++i) {
112  sig_dbg(i == 0 ? "%02X" : ":%02X", buffer[i]);
113  }
114  sig_dbg("\n");
115 }
116 #else
117 #define sig_dbg(...)
118 #define sig_dbg_buffer(n, b, s)
119 #endif
120 
121 #define rz_buf_append_le_bits(buffer, tmp, value, bits) \
122  rz_write_le##bits(tmp, value); \
123  rz_buf_append_bytes(buffer, tmp, sizeof(ut##bits))
124 
125 #define rz_buf_append_be_bits(buffer, tmp, value, bits) \
126  rz_write_be##bits(tmp, value); \
127  rz_buf_append_bytes(buffer, tmp, sizeof(ut##bits))
128 
129 /*feature flags*/
130 #define IDASIG_FEATURE_NONE 0x00
131 #define IDASIG_FEATURE_STARTUP 0x01
132 #define IDASIG_FEATURE_CTYPE_CRC 0x02
133 #define IDASIG_FEATURE_2BYTE_CTYPE 0x04
134 #define IDASIG_FEATURE_ALT_CTYPE_CRC 0x08
135 #define IDASIG_FEATURE_COMPRESSED 0x10
136 
137 /*parsing flags*/
138 #define IDASIG_PARSE_MORE_PUBLIC_NAMES 0x01
139 #define IDASIG_PARSE_READ_TAIL_BYTES 0x02
140 #define IDASIG_PARSE_READ_REFERENCED_FUNCTIONS 0x04
141 #define IDASIG_PARSE_MORE_MODULES_WITH_SAME_CRC 0x08
142 #define IDASIG_PARSE_MORE_MODULES 0x10
143 
144 /*functions flags*/
145 #define IDASIG_FUNCTION_LOCAL 0x02 // describes a static function
146 #define IDASIG_FUNCTION_UNRESOLVED_COLLISION 0x08 // describes a collision that wasn't resolved
147 
148 typedef struct idasig_v5_t {
149  /* newer header only add fields, that's why we'll always read a v5 header first */
150  ut8 magic[6]; /* should be set to IDASGN */
151  ut8 version; /*from 5 to 9*/
159  ut8 ctype[12]; // XXX: how to use it
163 
164 typedef struct idasig_v6_v7_t {
167 
168 typedef struct idasig_v8_v9_t {
171 
172 typedef struct idasig_v10_t {
175 
176 typedef struct parse_status_t {
178  bool eof;
179  bool error;
182 
183 #define is_status_err_or_eof(p) (p->eof || p->error)
184 
185 /* newer header only add fields, that's why we'll always read a v5 header first */
186 /*
187  arch : target architecture
188  file_types : files where we expect to find the functions (exe, coff, ...)
189  os_types : os where we expect to find the functions
190  app_types : applications in which we expect to find the functions
191  features : signature file features
192  old_n_functions : number of functions
193  crc16 : certainly crc16 of the tree
194  ctype[12] : unknown field
195  library_name_len : length of the library name, which is right after the header
196  ctypes_crc16 : unknown field
197  n_functions : number of functions
198  pattern_size : number of the leading pattern bytes
199  */
200 
201 // This is from flair tools flair/crc16.cpp
202 // CRC-HDLC & CRC-16/X-25 produces the same but in LE format.
203 #define POLY 0x8408
204 ut16 flirt_crc16(const ut8 *data_p, size_t length) {
205  ut8 i;
206  ut32 data;
207  ut32 crc = 0xFFFF;
208 
209  if (length == 0) {
210  return 0;
211  }
212  do {
213  data = *data_p++;
214  for (i = 0; i < 8; i++) {
215  if ((crc ^ data) & 1) {
216  crc = (crc >> 1) ^ POLY;
217  } else {
218  crc >>= 1;
219  }
220  data >>= 1;
221  }
222  } while (--length > 0);
223 
224  crc = ~crc;
225  data = crc;
226  crc = (crc << 8) | ((data >> 8) & 0xff);
227  return (ut16)(crc);
228 }
229 
231  ut8 r = 0;
232  int length;
233 
234  if (b->eof || b->error) {
235  return 0;
236  }
237  if ((length = rz_buf_read(b->buffer, &r, 1)) != 1) {
238  if (length == -1) {
239  b->error = true;
240  }
241  if (length == 0) {
242  b->eof = true;
243  }
244  return 0;
245  }
246  return r;
247 }
248 
250  ut16 r = (read_byte(b) << 8);
251  r += read_byte(b);
252  return r;
253 }
254 
256  ut32 r = ((ut32)(read_short(b)) << 16);
257  r += read_short(b);
258  return r;
259 }
260 
262  ut16 r = read_byte(b);
263  return (r & 0x80)
264  ? ((r & 0x7f) << 8) + read_byte(b)
265  : r;
266 }
267 
269  ut32 r = read_byte(b);
270  if ((r & 0x80) != 0x80) {
271  return r;
272  }
273  if ((r & 0xc0) != 0xc0) {
274  return ((r & 0x7f) << 8) + read_byte(b);
275  }
276  if ((r & 0xe0) != 0xe0) {
277  r = ((r & 0x3f) << 24) + (read_byte(b) << 16);
278  r += read_short(b);
279  return r;
280  }
281  return read_word(b);
282 }
283 
285  if (!module) {
286  return;
287  }
288  rz_list_free(module->public_functions);
289  rz_list_free(module->tail_bytes);
290  rz_list_free(module->referenced_functions);
291  free(module);
292 }
293 
300  if (!node) {
301  return;
302  }
303  free(node->pattern_mask);
304  free(node->pattern_bytes);
305  rz_list_free(node->module_list);
306  rz_list_free(node->child_list);
307  free(node);
308 }
309 
316  if (!info) {
317  return;
318  }
319  if (info->type == RZ_FLIRT_FILE_TYPE_SIG) {
320  free(info->u.sig.name);
321  }
322  memset(info, 0, sizeof(RzFlirtInfo));
323 }
324 
336 static bool is_pattern_matching(ut32 p_size, const ut8 *pattern, const ut8 *mask, const ut8 *b, ut32 b_size) {
337  if (b_size < p_size) {
338  return false;
339  }
340  for (ut32 i = 0; i < p_size; i++) {
341  if (mask[i] == 0xFF && pattern[i] != b[i]) {
342  return false;
343  }
344  }
345  return true;
346 }
347 
359 static int module_match_buffer(RzAnalysis *analysis, const RzFlirtModule *module, ut8 *b, ut64 address, ut32 buf_size) {
360  RzFlirtFunction *flirt_func;
361  RzAnalysisFunction *next_module_function;
362  RzListIter *tail_byte_it, *flirt_func_it;
363  RzFlirtTailByte *tail_byte;
364  ut32 name_index = 0;
365 
366  if (32 + module->crc_length < buf_size &&
367  module->crc16 != flirt_crc16(b + 32, module->crc_length)) {
368  return false;
369  }
370  if (module->tail_bytes) {
371  rz_list_foreach (module->tail_bytes, tail_byte_it, tail_byte) {
372  if (32 + module->crc_length + tail_byte->offset < buf_size &&
373  b[32 + module->crc_length + tail_byte->offset] != tail_byte->value) {
374  return false;
375  }
376  }
377  }
378 
379  rz_list_foreach (module->public_functions, flirt_func_it, flirt_func) {
380  // Once the first module function is found, we need to go through the module->public_functions
381  // list to identify the others. See flirt doc for more information
382 
383  next_module_function = rz_analysis_get_function_at((RzAnalysis *)analysis, address + flirt_func->offset);
384  if (next_module_function) {
385  ut32 next_module_function_size;
386 
387  // get function size from flirt signature
388  ut64 flirt_fcn_size = module->length - flirt_func->offset;
389  RzFlirtFunction *next_flirt_func;
390  RzListIter *next_flirt_func_it = flirt_func_it->n;
391  while (next_flirt_func_it) {
392  next_flirt_func = next_flirt_func_it->data;
393  if (!next_flirt_func->is_local && !next_flirt_func->negative_offset) {
394  flirt_fcn_size = next_flirt_func->offset - flirt_func->offset;
395  break;
396  }
397  next_flirt_func_it = next_flirt_func_it->n;
398  }
399  // resize function if needed
400  next_module_function_size = rz_analysis_function_linear_size(next_module_function);
401  if (next_module_function_size < flirt_fcn_size) {
402  RzListIter *iter;
403  RzListIter *iter_tmp;
404  RzAnalysisFunction *fcn;
405  rz_list_foreach_safe (analysis->fcns, iter, iter_tmp, fcn) {
406  if (fcn != next_module_function &&
407  fcn->addr >= next_module_function->addr + next_module_function_size &&
408  fcn->addr < next_module_function->addr + flirt_fcn_size) {
409  RzListIter *iter_bb;
410  RzAnalysisBlock *block;
411  rz_list_foreach (fcn->bbs, iter_bb, block) {
412  rz_analysis_function_add_block(next_module_function, block);
413  }
414  next_module_function->ninstr += fcn->ninstr;
416  }
417  }
418  rz_analysis_function_resize(next_module_function, flirt_fcn_size);
419  next_module_function_size = rz_analysis_function_linear_size(next_module_function);
420  rz_analysis_trim_jmprefs((RzAnalysis *)analysis, next_module_function);
421  }
422 
423  // filter name
424  rz_name_filter(flirt_func->name, -1, true);
425 
426  // verify that the name is unique
427  char *name = rz_str_newf("flirt.%s", flirt_func->name);
428  if (!name) {
429  RZ_LOG_ERROR("FLIRT: cannot allocate string buffer for name\n");
430  return false;
431  }
432 
433  while (!rz_analysis_function_rename(next_module_function, name)) {
434  free(name);
435  name_index++;
436  name = rz_str_newf("flirt.%s_%u", flirt_func->name, name_index);
437  if (!name) {
438  RZ_LOG_ERROR("FLIRT: cannot allocate string buffer for name\n");
439  return false;
440  }
441  }
442 
443  // remove old flag
444  RzFlagItem *fit = analysis->flb.get_at_by_spaces(analysis->flb.f, next_module_function->addr, "fcn.", "func.", NULL);
445  if (fit) {
446  analysis->flb.unset(analysis->flb.f, fit);
447  }
448 
449  // set new flag
450  analysis->flb.set(analysis->flb.f, name, next_module_function->addr, next_module_function_size);
451  RZ_LOG_DEBUG("FLIRT: Found %s\n", next_module_function->name);
452  free(name);
453  }
454  }
455  return true;
456 }
457 
458 static int node_match_buffer(RzAnalysis *analysis, const RzFlirtNode *node, ut8 *b, ut64 address, ut32 buf_size, ut32 buf_idx) {
459  RzListIter *node_child_it, *module_it;
460  RzFlirtNode *child;
462 
463  if (is_pattern_matching(node->length, node->pattern_bytes, node->pattern_mask, b + buf_idx, buf_size - buf_idx)) {
464  if (node->child_list) {
465  rz_list_foreach (node->child_list, node_child_it, child) {
466  if (node_match_buffer(analysis, child, b, address, buf_size, buf_idx + node->length)) {
467  return true;
468  }
469  }
470  } else if (node->module_list) {
471  rz_list_foreach (node->module_list, module_it, module) {
472  if (module_match_buffer(analysis, module, b, address, buf_size)) {
473  return true;
474  }
475  }
476  }
477  }
478 
479  return false;
480 }
481 
490 static bool node_match_functions(RzAnalysis *analysis, const RzFlirtNode *root_node) {
491  bool ret = true;
492 
493  if (rz_list_length(analysis->fcns) == 0) {
494  RZ_LOG_ERROR("FLIRT: There are no analyzed functions. Have you run 'aa'?\n");
495  return ret;
496  }
497 
498  analysis->flb.push_fs(analysis->flb.f, "flirt");
499  RzListIter *it_func;
500  RzAnalysisFunction *func;
501  rz_list_foreach (analysis->fcns, it_func, func) {
502  if (func->type != RZ_ANALYSIS_FCN_TYPE_FCN && func->type != RZ_ANALYSIS_FCN_TYPE_LOC) { // scan only for unknown functions
503  continue;
504  }
505 
506  ut64 func_size = rz_analysis_function_linear_size(func);
507  ut8 *func_buf = malloc(func_size);
508  if (!func_buf) {
509  ret = false;
510  break;
511  }
512  if (!analysis->iob.read_at(analysis->iob.io, func->addr, func_buf, (int)func_size)) {
513  RZ_LOG_ERROR("FLIRT: Couldn't read function %s at 0x%" PFMT64x "\n", func->name, func->addr);
514  RZ_FREE(func_buf);
515  ret = false;
516  break;
517  }
518  RzListIter *node_child_it;
519  RzFlirtNode *child;
520  rz_list_foreach (root_node->child_list, node_child_it, child) {
521  if (node_match_buffer(analysis, child, func_buf, func->addr, func_size, 0)) {
522  break;
523  }
524  }
525  RZ_FREE(func_buf);
526  }
527  analysis->flb.pop_fs(analysis->flb.f);
528 
529  return ret;
530 }
531 
533  /* parses a module tail bytes */
534  /* returns false on parsing error */
535  int i;
536  ut32 number_of_tail_bytes;
537  RzFlirtTailByte *tail_byte = NULL;
538  if (!(module->tail_bytes = rz_list_newf((RzListFree)free))) {
539  RZ_LOG_ERROR("FLIRT: failed to allocate tail bytes list.\n");
540  goto err_exit;
541  }
542 
543  if (b->version == 8 || b->version == 9) {
544  // this counter was introduced in version 8 and kept in version 9
545  number_of_tail_bytes = read_max_2_bytes(b);
546  if (is_status_err_or_eof(b)) {
547  RZ_LOG_ERROR("FLIRT: failed to read referenced function count because EOF (version 8 or 9).\n");
548  goto err_exit;
549  }
550  } else if (b->version > 9) {
551  // this counter was changed from version 10
552  number_of_tail_bytes = read_multiple_bytes(b);
553  if (is_status_err_or_eof(b)) {
554  RZ_LOG_ERROR("FLIRT: failed to read referenced function count because EOF (version > 9).\n");
555  goto err_exit;
556  }
557  } else { // suppose there's only one
558  number_of_tail_bytes = 1;
559  }
560 
561  for (i = 0; i < number_of_tail_bytes; i++) {
562  tail_byte = RZ_NEW0(RzFlirtTailByte);
563  if (!tail_byte) {
564  return false;
565  }
566  if (b->version >= 9) {
567  /*/!\ XXX don't trust ./zipsig output because it will write a version 9 header, but keep the old version offsets*/
568  tail_byte->offset = read_multiple_bytes(b);
569  if (is_status_err_or_eof(b)) {
570  RZ_LOG_ERROR("FLIRT: failed to read tail byte offset because EOF (version >= 9).\n");
571  goto err_exit;
572  }
573  } else {
574  tail_byte->offset = read_max_2_bytes(b);
575  if (is_status_err_or_eof(b)) {
576  RZ_LOG_ERROR("FLIRT: failed to read tail byte offset because EOF.\n");
577  goto err_exit;
578  }
579  }
580  tail_byte->value = read_byte(b);
581  if (is_status_err_or_eof(b)) {
582  RZ_LOG_ERROR("FLIRT: failed to read tail byte value because EOF.\n");
583  goto err_exit;
584  }
585  rz_list_append(module->tail_bytes, tail_byte);
586  sig_dbg("dbg: read tail byte: %04X: %02X\n", tail_byte->offset, tail_byte->value);
587  }
588 
589  return true;
590 
591 err_exit:
592  free(tail_byte);
593  rz_list_free(module->tail_bytes);
594  return false;
595 }
596 
598  /* parses a module referenced functions */
599  /* returns false on parsing error */
600  ut32 i, j;
601  ut32 number_of_referenced_functions;
602  ut32 ref_function_name_length;
603  RzFlirtFunction *ref_function = NULL;
604 
605  module->referenced_functions = rz_list_newf((RzListFree)free);
606 
607  if (b->version == 8 || b->version == 9) {
608  // this counter was introduced in version 8 and kept in version 9
609  number_of_referenced_functions = read_max_2_bytes(b);
610  if (is_status_err_or_eof(b)) {
611  RZ_LOG_ERROR("FLIRT: failed to read referenced function count because EOF (version 8 or 9).\n");
612  goto err_exit;
613  }
614  } else if (b->version > 9) {
615  // this counter was changed from version 10
616  number_of_referenced_functions = read_multiple_bytes(b);
617  if (is_status_err_or_eof(b)) {
618  RZ_LOG_ERROR("FLIRT: failed to read referenced function count because EOF (version > 9).\n");
619  goto err_exit;
620  }
621  } else { // suppose there's only one
622  number_of_referenced_functions = 1;
623  }
624  sig_dbg("dbg: n refs: %02X\n", number_of_referenced_functions);
625 
626  for (i = 0; i < number_of_referenced_functions; i++) {
627  ref_function = RZ_NEW0(RzFlirtFunction);
628  if (!ref_function) {
629  RZ_LOG_ERROR("FLIRT: failed to allocate RzFlirtFunction.\n");
630  goto err_exit;
631  }
632  if (b->version >= 9) {
633  ref_function->offset = read_multiple_bytes(b);
634  if (is_status_err_or_eof(b)) {
635  RZ_LOG_ERROR("FLIRT: failed to read referenced function offset because EOF (version >= 9).\n");
636  goto err_exit;
637  }
638  } else {
639  ref_function->offset = read_max_2_bytes(b);
640  if (is_status_err_or_eof(b)) {
641  RZ_LOG_ERROR("FLIRT: failed to read referenced function offset because EOF.\n");
642  goto err_exit;
643  }
644  }
645  ref_function_name_length = read_byte(b);
646  if (is_status_err_or_eof(b)) {
647  RZ_LOG_ERROR("FLIRT: failed to read referenced function name length because EOF.\n");
648  goto err_exit;
649  }
650  if (!ref_function_name_length) {
651  // not sure why it's not read_multiple_bytes() in the first place
652  ref_function_name_length = read_multiple_bytes(b); // XXX might be read_max_2_bytes, need more data
653  if (is_status_err_or_eof(b)) {
654  RZ_LOG_ERROR("FLIRT: failed to read referenced function name length because EOF (2).\n");
655  goto err_exit;
656  }
657  }
658  if (ref_function_name_length >= RZ_FLIRT_NAME_MAX) {
659  RZ_LOG_ERROR("FLIRT: invalid referenced function name length (%u >= %u).\n", ref_function_name_length, RZ_FLIRT_NAME_MAX);
660  goto err_exit;
661  }
662  sig_dbg("dbg: REF length %02X\n", ref_function_name_length);
663  for (j = 0; j < ref_function_name_length; j++) {
664  ref_function->name[j] = read_byte(b);
665  if (is_status_err_or_eof(b)) {
666  RZ_LOG_ERROR("FLIRT: failed to read referenced function name[%u] because EOF.\n", j);
667  goto err_exit;
668  }
669  }
670  if (!ref_function->name[ref_function_name_length]) {
671  // if the last byte of the name is 0, it means the offset is negative
672  ref_function->negative_offset = true;
673  } else {
674  ref_function->name[ref_function_name_length] = '\0';
675  }
676  rz_list_append(module->referenced_functions, ref_function);
677  sig_dbg("dbg: (REF: %04X: %s)\n", ref_function->offset, ref_function->name);
678  }
679 
680  return true;
681 
682 err_exit:
683  free(ref_function);
684  return false;
685 }
686 
688  /* Reads and set the public functions names and offsets associated within a module */
689  /* returns false on parsing error */
690  int i;
691  ut32 offset = 0;
692  ut8 current_byte;
693  RzFlirtFunction *function = NULL;
694 
695  module->public_functions = rz_list_newf((RzListFree)free);
696 
697  do {
698  function = RZ_NEW0(RzFlirtFunction);
699  if (b->version >= 9) { // seems like version 9 introduced some larger offsets
700  offset += read_multiple_bytes(b); // offsets are dependent of the previous ones
701  if (is_status_err_or_eof(b)) {
702  RZ_LOG_ERROR("FLIRT: failed to read public function offset because EOF (version >= 9).\n");
703  goto err_exit;
704  }
705  } else {
706  offset += read_max_2_bytes(b); // offsets are dependent of the previous ones
707  if (is_status_err_or_eof(b)) {
708  RZ_LOG_ERROR("FLIRT: failed to read public function offset because EOF.\n");
709  goto err_exit;
710  }
711  }
712  function->offset = offset;
713 
714  current_byte = read_byte(b);
715  if (is_status_err_or_eof(b)) {
716  RZ_LOG_ERROR("FLIRT: failed to read public function flags because EOF.\n");
717  goto err_exit;
718  }
719  if (current_byte < 0x20) {
720  if (current_byte & IDASIG_FUNCTION_LOCAL) { // static function
721  function->is_local = true;
722  }
723  if (current_byte & IDASIG_FUNCTION_UNRESOLVED_COLLISION) {
724  // unresolved collision (happens in *.exc while creating .sig from .pat)
725  function->is_collision = true;
726  }
727  current_byte = read_byte(b);
728  if (is_status_err_or_eof(b)) {
729  RZ_LOG_ERROR("FLIRT: failed to read public function current byte because EOF.\n");
730  goto err_exit;
731  }
732  }
733 
734  for (i = 0; current_byte >= 0x20 && i < RZ_FLIRT_NAME_MAX; i++) {
735  function->name[i] = current_byte;
736  current_byte = read_byte(b);
737  if (is_status_err_or_eof(b)) {
738  RZ_LOG_ERROR("FLIRT: failed to read public function name[%u] because EOF.\n", i);
739  goto err_exit;
740  }
741  }
742 
743  if (i == RZ_FLIRT_NAME_MAX) {
744  RZ_LOG_WARN("FLIRT: public function name is too long\n");
745  function->name[RZ_FLIRT_NAME_MAX - 1] = '\0';
746  } else {
747  function->name[i] = '\0';
748  }
749 
750  sig_dbg("dbg: %04X: %s \n", function->offset, function->name);
751  *flags = current_byte;
752  rz_list_append(module->public_functions, function);
754 
755  return true;
756 
757 err_exit:
758  free(function);
759  return false;
760 }
761 
763  /* parses a signature leaf: modules with same leading pattern */
764  /* returns false on parsing error */
765  ut8 flags, crc_length;
766  ut16 crc16;
768 
770  do { // loop for all modules having the same prefix
771 
772  crc_length = read_byte(b);
773  if (is_status_err_or_eof(b)) {
774  RZ_LOG_ERROR("FLIRT: failed to read crc16 length.\n");
775  goto err_exit;
776  }
777  crc16 = read_short(b);
778  if (is_status_err_or_eof(b)) {
779  RZ_LOG_ERROR("FLIRT: failed to read crc16.\n");
780  goto err_exit;
781  }
782  sig_dbg("dbg: crc_len: %02X crc16: %04X\n", crc_length, crc16);
783 
784  do { // loop for all modules having the same crc
786  if (!module) {
787  RZ_LOG_ERROR("FLIRT: failed to allocate RzFlirtModule.\n");
788  goto err_exit;
789  }
790 
791  module->crc_length = crc_length;
792  module->crc16 = crc16;
793 
794  if (b->version >= 9) { // seems like version 9 introduced some larger length
795  /*/!\ XXX don't trust ./zipsig output because it will write a version 9 header, but keep the old version offsets*/
796  module->length = read_multiple_bytes(b); // should be < 0x8000
797  if (is_status_err_or_eof(b)) {
798  RZ_LOG_ERROR("FLIRT: failed to read module length because EOF (version >= 9).\n");
799  goto err_exit;
800  }
801  } else {
802  module->length = read_max_2_bytes(b); // should be < 0x8000
803  if (is_status_err_or_eof(b)) {
804  RZ_LOG_ERROR("FLIRT: failed to read module length because EOF.\n");
805  goto err_exit;
806  }
807  }
808  sig_dbg("dbg: module_length: %04X\n", module->length);
809 
811  goto err_exit;
812  }
813 
814  if (flags & IDASIG_PARSE_READ_TAIL_BYTES) { // we need to read some tail bytes because in this leaf we have functions with same crc
816  goto err_exit;
817  }
818  }
819  if (flags & IDASIG_PARSE_READ_REFERENCED_FUNCTIONS) { // we need to read some referenced functions
821  goto err_exit;
822  }
823  }
824 
827  } while (flags & IDASIG_PARSE_MORE_MODULES); // same prefix but different crc
828 
829  return true;
830 
831 err_exit:
833  return false;
834 }
835 
837  node->length = read_byte(b);
838  if (is_status_err_or_eof(b)) {
839  return false;
840  }
841  sig_dbg("dbg: node length: %02X\n", node->length);
842  return true;
843 }
844 
846  /* Reads and sets a node's variant bytes mask. This mask is then used to */
847  /* read the non-variant bytes following. */
848  /* returns false on parsing error */
849  if (node->length < 0x10) {
851  if (is_status_err_or_eof(b)) {
852  return false;
853  }
854  } else if (node->length <= 0x20) {
856  if (is_status_err_or_eof(b)) {
857  return false;
858  }
859  } else if (node->length <= 0x40) { // it shouldn't be more than 64 bytes
861  if (is_status_err_or_eof(b)) {
862  return false;
863  }
864  }
865 
866  sig_dbg("dbg: variant_mask %08llx\n", node->variant_mask);
867  return true;
868 }
869 
870 static bool read_node_bytes(RzFlirtNode *node, ParseStatus *b) {
871  /* Reads the node bytes, and also sets the variant bytes in pattern_mask */
872  /* returns false on parsing error */
873  int i;
874  ut64 current_mask_bit = 0;
875  if ((int)node->length < 0) {
876  return false;
877  }
878  current_mask_bit = 1ULL << (node->length - 1);
879  if (!(node->pattern_bytes = malloc(node->length))) {
880  return false;
881  }
882  if (!(node->pattern_mask = malloc(node->length))) {
883  return false;
884  }
885  for (i = 0; i < node->length; i++, current_mask_bit >>= 1) {
886  if (node->variant_mask & current_mask_bit) {
887  node->pattern_bytes[i] = 0;
888  node->pattern_mask[i] = 0;
889  } else {
890  node->pattern_bytes[i] = read_byte(b);
891  node->pattern_mask[i] = 0xFF;
892  if (is_status_err_or_eof(b)) {
893  return false;
894  }
895  }
896  }
897  sig_dbg_buffer("bytes", node->pattern_bytes, node->length);
898  sig_dbg_buffer("mask ", node->pattern_mask, node->length);
899  return true;
900 }
901 
902 static ut8 parse_tree(ParseStatus *b, RzFlirtNode *root_node) {
903  /* parse a signature pattern tree or sub-tree */
904  /* returns false on parsing error */
905  RzFlirtNode *node = NULL;
906  int i, tree_nodes = read_multiple_bytes(b); // confirmed it's not read_byte(), XXX could it be read_max_2_bytes() ???
907  if (is_status_err_or_eof(b)) {
908  RZ_LOG_ERROR("FLIRT: failed to read tree node number because EOF.\n");
909  return false;
910  }
911  sig_dbg("dbg: tree_nodes %02x\n", tree_nodes);
912  if (tree_nodes == 0) { // if there's no tree nodes remaining, that means we are on the leaf
913  return parse_leaf(b, root_node);
914  }
916 
917  for (i = 0; i < tree_nodes; i++) {
918  if (!(node = RZ_NEW0(RzFlirtNode))) {
919  RZ_LOG_ERROR("FLIRT: failed to allocate child tree node.\n");
920  goto err_exit;
921  }
922  if (!read_node_length(node, b) || node->length > 0x40) {
923  RZ_LOG_ERROR("FLIRT: failed to read pattern mask length (length %u).\n", node->length);
924  goto err_exit;
925  }
926  if (!read_node_variant_mask(node, b)) {
927  RZ_LOG_ERROR("FLIRT: failed to read variant mask.\n");
928  goto err_exit;
929  }
930  if (!read_node_bytes(node, b)) {
931  RZ_LOG_ERROR("FLIRT: failed to read pattern.\n");
932  goto err_exit;
933  }
934  if (!parse_tree(b, node)) {
935  goto err_exit; // parse child nodes
936  }
937  rz_list_append(root_node->child_list, node);
938  }
939  return true;
940 err_exit:
942  return false;
943 }
944 
947  if (rz_buf_read(buf, header->magic, sizeof(header->magic)) != sizeof(header->magic)) {
948  return false;
949  }
950  if (rz_buf_read(buf, &header->version, sizeof(header->version)) != sizeof(header->version)) {
951  return false;
952  }
953  if (rz_buf_read(buf, &header->arch, sizeof(header->arch)) != sizeof(header->arch)) {
954  return false;
955  }
956  if (!rz_buf_read_le32(buf, &header->file_types)) {
957  return false;
958  }
959  if (!rz_buf_read_le16(buf, &header->os_types)) {
960  return false;
961  }
962  if (!rz_buf_read_le16(buf, &header->app_types)) {
963  return false;
964  }
965  if (!rz_buf_read_le16(buf, &header->features)) {
966  return false;
967  }
968  if (!rz_buf_read_le16(buf, &header->old_n_functions)) {
969  return false;
970  }
971  if (!rz_buf_read_le16(buf, &header->crc16)) {
972  return false;
973  }
974  if (rz_buf_read(buf, header->ctype, sizeof(header->ctype)) != sizeof(header->ctype)) {
975  return false;
976  }
977  if (rz_buf_read(buf, (unsigned char *)&header->library_name_len, sizeof(header->library_name_len)) != sizeof(header->library_name_len)) {
978  return false;
979  }
980  if (!rz_buf_read_le16(buf, &header->ctypes_crc16)) {
981  return false;
982  }
983 
984  return true;
985 }
986 
988  if (!rz_buf_read_le32(buf, &header->n_functions)) {
989  RZ_LOG_ERROR("FLIRT: invalid sig file (EOF in v6/v7 header).\n");
990  return false;
991  }
992 
993  return true;
994 }
995 
997  if (!rz_buf_read_le16(buf, &header->pattern_size)) {
998  RZ_LOG_ERROR("FLIRT: invalid sig file (EOF in v8/v9 header).\n");
999  return false;
1000  }
1001 
1002  return true;
1003 }
1004 
1006  if (!rz_buf_read_le16(buf, &header->unknown)) {
1007  RZ_LOG_ERROR("FLIRT: invalid sig file (EOF in v10 header).\n");
1008  return false;
1009  }
1010 
1011  return true;
1012 }
1013 
1022  ut8 ret = 0;
1023 
1025  if (!header) {
1026  goto exit;
1027  }
1028 
1029  if (rz_buf_read(buffer, header->magic, sizeof(header->magic)) != sizeof(header->magic)) {
1030  RZ_LOG_ERROR("FLIRT: invalid sig file (EOF in v5 header magic).\n");
1031  goto exit;
1032  }
1033 
1034  if (memcmp((const char *)header->magic, "IDASGN", 6)) {
1035  RZ_LOG_ERROR("FLIRT: invalid sig magic.\n");
1036  goto exit;
1037  }
1038 
1039  if (rz_buf_read(buffer, &header->version, sizeof(header->version)) != sizeof(header->version)) {
1040  RZ_LOG_ERROR("FLIRT: invalid sig file (EOF in v5 header version).\n");
1041  goto exit;
1042  }
1043 
1044  ret = header->version;
1045 
1046 exit:
1047  free(header);
1048  return ret;
1049 }
1050 
1063  rz_return_val_if_fail(flirt_buf && info, false);
1064 
1065  bool res = false;
1066  ut8 *name = NULL;
1067  idasig_v5_t v5 = { 0 };
1068  idasig_v6_v7_t v6_v7 = { 0 };
1069  idasig_v8_v9_t v8_v9 = { 0 };
1070  idasig_v10_t v10 = { 0 };
1071 
1072  if (!parse_v5_header(flirt_buf, &v5)) {
1073  RZ_LOG_ERROR("FLIRT: invalid sig header.\n");
1074  goto exit;
1075  }
1076 
1077  if (memcmp((const char *)v5.magic, "IDASGN", 6)) {
1078  RZ_LOG_ERROR("FLIRT: invalid sig magic.\n");
1079  goto exit;
1080  }
1081 
1082  if (v5.version < 5 || v5.version > 10) {
1083  RZ_LOG_ERROR("FLIRT: Unsupported flirt signature version\n");
1084  goto exit;
1085  }
1086 
1087  if (v5.version >= 6 && !parse_v6_v7_header(flirt_buf, &v6_v7)) {
1088  goto exit;
1089  }
1090 
1091  if (v5.version >= 8 && !parse_v8_v9_header(flirt_buf, &v8_v9)) {
1092  goto exit;
1093  }
1094 
1095  if (v5.version >= 10 && !parse_v10_header(flirt_buf, &v10)) {
1096  goto exit;
1097  }
1098 
1099  name = malloc(v5.library_name_len + 1);
1100  if (!name) {
1101  RZ_LOG_ERROR("FLIRT: failed to allocate library name\n");
1102  goto exit;
1103  }
1104 
1105  if (rz_buf_read(flirt_buf, name, v5.library_name_len) != v5.library_name_len) {
1106  RZ_LOG_ERROR("FLIRT: failed to read library name\n");
1107  goto exit;
1108  }
1109 
1110  name[v5.library_name_len] = '\0';
1111 
1113  info->u.sig.version = v5.version;
1114  info->u.sig.architecture = v5.arch;
1115  info->u.sig.n_modules = v5.version < 6 ? v5.old_n_functions : v6_v7.n_functions;
1116  info->u.sig.name = (char *)name;
1117  name = NULL;
1118  res = true;
1119 
1120 exit:
1121  free(name);
1122  return res;
1123 }
1124 
1137  rz_return_val_if_fail(flirt_buf && expected_arch <= RZ_FLIRT_SIG_ARCH_ANY, NULL);
1138 
1139  ut8 *name = NULL;
1140  ut8 *buf = NULL, *decompressed_buf = NULL;
1141  RzBuffer *rz_buf = NULL;
1142  int size, decompressed_size;
1143  RzFlirtNode *node = NULL;
1144  RzFlirtNode *ret = NULL;
1145  idasig_v5_t *header = NULL;
1146  idasig_v6_v7_t *v6_v7 = NULL;
1147  idasig_v8_v9_t *v8_v9 = NULL;
1148  idasig_v10_t *v10 = NULL;
1149 
1150  ParseStatus ps = { 0 };
1151 
1152  if (!(ps.version = flirt_parse_version(flirt_buf))) {
1153  goto exit;
1154  }
1155 
1156  if (ps.version < 5 || ps.version > 10) {
1157  RZ_LOG_ERROR("FLIRT: Unsupported flirt signature version\n");
1158  goto exit;
1159  }
1160 
1161  if (!(header = RZ_NEW0(idasig_v5_t))) {
1162  goto exit;
1163  }
1164 
1165  parse_v5_header(flirt_buf, header);
1166 
1167  if (expected_arch != RZ_FLIRT_SIG_ARCH_ANY && header->arch != expected_arch) {
1168  RZ_LOG_ERROR("FLIRT: the binary architecture did not match the .sig one.\n");
1169  goto exit;
1170  }
1171 
1172  if (ps.version >= 6) {
1173  if (!(v6_v7 = RZ_NEW0(idasig_v6_v7_t))) {
1174  goto exit;
1175  }
1176  if (!parse_v6_v7_header(flirt_buf, v6_v7)) {
1177  goto exit;
1178  }
1179 
1180  if (ps.version >= 8) {
1181  if (!(v8_v9 = RZ_NEW0(idasig_v8_v9_t))) {
1182  goto exit;
1183  }
1184  if (!parse_v8_v9_header(flirt_buf, v8_v9)) {
1185  goto exit;
1186  }
1187 
1188  if (ps.version >= 10) {
1189  if (!(v10 = RZ_NEW0(idasig_v10_t))) {
1190  goto exit;
1191  }
1192  if (!parse_v10_header(flirt_buf, v10)) {
1193  goto exit;
1194  }
1195  }
1196  }
1197  }
1198 
1199  name = malloc(header->library_name_len + 1);
1200  if (!name) {
1201  RZ_LOG_ERROR("FLIRT: failed to allocate library name\n");
1202  goto exit;
1203  }
1204 
1205  if (rz_buf_read(flirt_buf, name, header->library_name_len) != header->library_name_len) {
1206  RZ_LOG_ERROR("FLIRT: failed to read library name\n");
1207  goto exit;
1208  }
1209 
1210  name[header->library_name_len] = '\0';
1211 
1212  size = rz_buf_size(flirt_buf) - rz_buf_tell(flirt_buf);
1213  buf = malloc(size);
1214  if (!buf) {
1215  RZ_LOG_ERROR("FLIRT: failed to allocate buffer for signature body\n");
1216  goto exit;
1217  }
1218 
1219  if (rz_buf_read(flirt_buf, buf, size) != size) {
1220  RZ_LOG_ERROR("FLIRT: failed to read signature body\n");
1221  goto exit;
1222  }
1223 
1224  if (header->features & IDASIG_FEATURE_COMPRESSED) {
1225  if (ps.version >= 5 && ps.version < 7) {
1226  if (!(decompressed_buf = rz_inflate_ignore_header(buf, size, NULL, &decompressed_size))) {
1227  RZ_LOG_ERROR("FLIRT: Failed to decompress buffer.\n");
1228  goto exit;
1229  }
1230  } else if (ps.version >= 7) {
1231  if (!(decompressed_buf = rz_inflate(buf, size, NULL, &decompressed_size))) {
1232  RZ_LOG_ERROR("FLIRT: Failed to decompress buffer.\n");
1233  goto exit;
1234  }
1235  } else {
1236  RZ_LOG_ERROR("FLIRT: Sorry we do not support compressed signatures with version %d.\n", ps.version);
1237  goto exit;
1238  }
1239 
1240  RZ_FREE(buf);
1241  buf = decompressed_buf;
1242  size = decompressed_size;
1243  }
1244  rz_buf = rz_buf_new_with_pointers(buf, size, false);
1245  if (!rz_buf) {
1246  RZ_LOG_ERROR("FLIRT: failed to allocate new RzBuffer\n");
1247  goto exit;
1248  }
1249  ps.buffer = rz_buf;
1250 
1251  if (!(node = RZ_NEW0(RzFlirtNode))) {
1252  RZ_LOG_ERROR("FLIRT: failed to allocate root RzFlirtNode\n");
1253  goto exit;
1254  }
1255 
1256  if (parse_tree(&ps, node)) {
1257  ret = node;
1258  } else {
1259  free(node);
1260  }
1261 
1262  if (info && ret) {
1264  info->u.sig.version = ps.version;
1265  info->u.sig.architecture = header->arch;
1266  info->u.sig.n_modules = rz_sign_flirt_node_count_nodes(ret);
1267  info->u.sig.name = (char *)name;
1268  name = NULL;
1269  }
1270 
1271 exit:
1272  free(buf);
1273  rz_buf_free(rz_buf);
1274  free(header);
1275  free(v6_v7);
1276  free(v8_v9);
1277  free(v10);
1278  free(name);
1279  return ret;
1280 }
1281 
1289 RZ_API bool rz_sign_flirt_apply(RZ_NONNULL RzAnalysis *analysis, RZ_NONNULL const char *flirt_file, ut8 expected_arch) {
1290  rz_return_val_if_fail(analysis && RZ_STR_ISNOTEMPTY(flirt_file), false);
1291  RzBuffer *flirt_buf = NULL;
1292  RzFlirtNode *node = NULL;
1293 
1294  if (expected_arch > RZ_FLIRT_SIG_ARCH_ANY) {
1295  RZ_LOG_ERROR("FLIRT: unknown architecture %u\n", expected_arch);
1296  return false;
1297  }
1298 
1299  const char *extension = rz_str_lchr(flirt_file, '.');
1300  if (RZ_STR_ISEMPTY(extension) || (strcmp(extension, ".sig") != 0 && strcmp(extension, ".pat") != 0)) {
1301  RZ_LOG_ERROR("FLIRT: unknown extension '%s'\n", extension);
1302  return false;
1303  }
1304 
1305  if (!(flirt_buf = rz_buf_new_slurp(flirt_file))) {
1306  RZ_LOG_ERROR("FLIRT: Can't open %s\n", flirt_file);
1307  return false;
1308  }
1309 
1310  if (!strcmp(extension, ".pat")) {
1312  } else {
1313  node = rz_sign_flirt_parse_compressed_pattern_from_buffer(flirt_buf, expected_arch, NULL);
1314  }
1315 
1316  rz_buf_free(flirt_buf);
1317  if (node) {
1318  if (!node_match_functions(analysis, node)) {
1319  RZ_LOG_ERROR("FLIRT: Error while scanning the file %s\n", flirt_file);
1320  }
1322  return true;
1323  }
1324  RZ_LOG_ERROR("FLIRT: We encountered an error while parsing the file %s. Sorry.\n", flirt_file);
1325  return false;
1326 }
1327 
1335  rz_return_val_if_fail(node, 0);
1336  ut32 count = 0;
1337  RzListIter *it;
1338  RzFlirtNode *child;
1339  rz_list_foreach (node->child_list, it, child) {
1341  }
1342  if (rz_list_length(node->module_list) > 0) {
1343  count += 1;
1344  }
1345  return count;
1346 }
1347 
1348 static inline bool rz_write_vle16(RzBuffer *buffer, ut16 val) {
1349  ut8 tmp[10];
1350  ut32 n_bytes = 0;
1351  if (val > 0x7FFF) {
1352  RZ_LOG_ERROR("FLIRT: the variable length value is too big\n");
1353  return false;
1354  } else if (val > 0x7F) {
1355  // 16 bit value with max value 0x1FFF
1356  n_bytes = 2;
1357  tmp[0] = 0x80 | (val >> 8);
1358  tmp[1] = val & 0xFF;
1359  } else {
1360  // 8 bit value with max value 0x1F
1361  n_bytes = 1;
1362  tmp[0] = val;
1363  }
1364  rz_buf_append_bytes(buffer, tmp, n_bytes);
1365  return true;
1366 }
1367 
1368 static inline bool rz_write_vle32(RzBuffer *buffer, ut32 val) {
1369  ut8 tmp[10];
1370  ut32 n_bytes = 0;
1371 
1372  if (val > 0x1FFFFFFF) {
1373  n_bytes = 5;
1374  tmp[0] = 0xFF; // includes the 0xE0 mask
1375  tmp[1] = (val >> 24) & 0xFF;
1376  tmp[2] = (val >> 16) & 0xFF;
1377  tmp[3] = (val >> 8) & 0xFF;
1378  tmp[4] = val & 0xFF;
1379  } else if (val > 0x3FFF) {
1380  n_bytes = 4;
1381  tmp[0] = 0xC0 | ((val >> 24) & 0x3F);
1382  tmp[1] = (val >> 16) & 0xFF;
1383  tmp[2] = (val >> 8) & 0xFF;
1384  tmp[3] = val & 0xFF;
1385  } else if (val > 0x7F) {
1386  n_bytes = 2;
1387  tmp[0] = 0x80 | ((val >> 8) & 0x3F);
1388  tmp[1] = val & 0xFF;
1389  } else {
1390  n_bytes = 1;
1391  tmp[0] = val;
1392  }
1393 
1394  rz_buf_append_bytes(buffer, tmp, n_bytes);
1395  return true;
1396 }
1397 
1398 static inline bool rz_write_vle64(RzBuffer *buffer, ut64 val) {
1399  return rz_write_vle32(buffer, (val >> 32) & UT32_MAX) && rz_write_vle32(buffer, val & UT32_MAX);
1400 }
1401 
1403  return module->referenced_functions && rz_list_length(module->referenced_functions) > 0;
1404 }
1405 
1407  if (version < 9) {
1408  return rz_write_vle16(buffer, value);
1409  }
1410  return rz_write_vle32(buffer, value);
1411 }
1412 
1414  ut8 tmp[4];
1415  size_t value = 0;
1416  ut32 base_offset = 0;
1417  RzListIter *it;
1418  RzFlirtFunction *func;
1419  RzFlirtTailByte *byte;
1420  bool has_ref = flirt_has_references(module);
1421 
1422  if (first) {
1423  rz_buf_append_le_bits(buffer, tmp, module->crc_length, 8);
1424 
1425  rz_buf_append_be_bits(buffer, tmp, module->crc16, 16);
1426  }
1427  rz_write_vle32(buffer, module->length);
1428 
1429  if (has_ref) {
1431  }
1432  if (rz_list_length(module->tail_bytes) > 0) {
1434  }
1435 
1436  rz_list_foreach (module->public_functions, it, func) {
1437  if (value > 0) {
1440  }
1441  rz_write_vle32(buffer, func->offset - base_offset);
1442  base_offset = func->offset;
1443  tmp[0] = 0;
1444  if (func->is_local) {
1445  tmp[0] |= IDASIG_FUNCTION_LOCAL;
1446  }
1447  if (func->is_collision) {
1449  }
1450  if (tmp[0]) {
1452  }
1454  value++;
1455  }
1456 
1457  if (value > 0) {
1459  }
1460 
1461  value = rz_list_length(module->tail_bytes);
1462  if (value) {
1463  if (version >= 8) {
1464  // n of tail bytes.
1466  }
1467  value = 0;
1468  rz_list_foreach (module->tail_bytes, it, byte) {
1469  if (version < 8 && value > 1) {
1470  RZ_LOG_WARN("FLIRT: the number of tail bytes (%u) is > 1 when version %u does allow only 1\n", rz_list_length(module->tail_bytes), version);
1471  break;
1472  }
1473  value++;
1474 
1476  rz_buf_append_le_bits(buffer, tmp, byte->value, 8);
1477  }
1478  }
1479 
1480  if (has_ref) {
1481  // on sig files, it is not allowed to have multiple references.
1482  tmp[0] = 1;
1484 
1485  value = 0;
1486  rz_list_foreach (module->referenced_functions, it, func) {
1487  if (value > 0) {
1488  break;
1489  }
1490  value++;
1491 
1493 
1494  ut32 length = strlen(func->name);
1495  if (length > 0x7F) {
1496  tmp[0] = 0; // when name length is > 0x7F the length is preceeded by a 0x00
1498  }
1501  }
1502  }
1503 
1504  return true;
1505 }
1506 
1508  if (node->length > 64) {
1509  RZ_LOG_ERROR("FLIRT: pattern mask size is > 64.\n");
1510  return false;
1511  }
1512 
1513  RzListIter *it;
1514  RzFlirtNode *child;
1516 
1517  ut32 n_childs = rz_list_length(node->child_list);
1518  rz_write_vle32(buffer, n_childs);
1519 
1520  if (n_childs < 1) {
1521  // leaf
1522  ut8 flags = 0;
1523 
1524  RzFlirtModule *last = rz_list_last(node->module_list);
1525  rz_list_foreach (node->module_list, it, module) {
1526  bool already_found = !(flags & IDASIG_PARSE_MORE_MODULES_WITH_SAME_CRC);
1527  if (last != module) {
1529  if (next && next->crc16 == module->crc16) {
1531  } else {
1533  }
1534  } else {
1535  flags = 0;
1536  }
1537  if (!flirt_write_module(module, buffer, flags, version, already_found)) {
1538  return false;
1539  }
1540  }
1541  return true;
1542  }
1543 
1544  // tree
1545  rz_list_foreach (node->child_list, it, child) {
1546  // pattern mask size
1547  ut8 plen = child->length;
1548  rz_buf_append_bytes(buffer, &plen, 1);
1549  if (child->length < 0x10) {
1551  } else if (child->length <= 0x20) {
1553  } else if (child->length <= 0x40) {
1555  } else {
1556  RZ_LOG_ERROR("FLIRT: pattern mask size cannot be > 64 bits\n");
1557  return false;
1558  }
1559  for (ut32 i = 0; i < child->length; i++) {
1560  if (child->pattern_mask[i] != 0xFF) {
1561  continue;
1562  }
1563  rz_buf_append_bytes(buffer, &child->pattern_bytes[i], 1);
1564  }
1565  if (!flirt_write_node(child, buffer, version)) {
1566  return false;
1567  }
1568  }
1569 
1570  return true;
1571 }
1572 
1581  rz_return_val_if_fail(node && buffer && options, false);
1582  RzBuffer *body = buffer;
1583 
1584  if (options->version < 5 || options->version > 10) {
1585  RZ_LOG_ERROR("FLIRT: unsupported sig type version %u\n", options->version);
1586  return false;
1587  } else if (options->arch >= RZ_FLIRT_SIG_ARCH_ANY) {
1588  RZ_LOG_ERROR("FLIRT: unsupported architecture %u\n", options->arch);
1589  return false;
1590  } else if (RZ_STR_ISEMPTY(options->libname)) {
1591  RZ_LOG_ERROR("FLIRT: library name is empty\n");
1592  return false;
1593  }
1594 
1595  size_t library_name_len = strlen(options->libname);
1596  if (library_name_len > RZ_FLIRT_LIBRARY_NAME_MAX) {
1597  RZ_LOG_ERROR("FLIRT: library name is too big. max size is %u\n", RZ_FLIRT_LIBRARY_NAME_MAX);
1598  return false;
1599  }
1600 
1601  if (options->deflate) {
1602  if (options->version < 7) {
1603  RZ_LOG_ERROR("FLIRT: cannot deflate body due FLIRT version being < 7\n");
1604  return false;
1605  }
1606 
1607  body = rz_buf_new_empty(0);
1608  if (!body) {
1609  RZ_LOG_ERROR("FLIRT: cannot allocate body buffer\n");
1610  return false;
1611  }
1612  }
1613 
1614  ut8 tmp[32];
1615  ut32 n_functions = rz_sign_flirt_node_count_nodes(node);
1616 
1617  // magic
1618  rz_buf_append_string(buffer, "IDASGN");
1619 
1620  // version
1621  rz_buf_append_le_bits(buffer, tmp, options->version, 8);
1622 
1623  // arch
1625 
1626  // file_types (little endian)
1627  rz_buf_append_le_bits(buffer, tmp, options->file, 32);
1628 
1629  // os_types (little endian)
1631 
1632  // app_types (little endian)
1634 
1635  // features (little endian)
1637 
1638  // n_functions (little endian) - used only in v5.
1639  rz_buf_append_le_bits(buffer, tmp, options->version >= 6 ? 0 : n_functions, 16);
1640 
1641  // crc16 (little endian)
1642  rz_buf_append_le_bits(buffer, tmp, 0, 16);
1643 
1644  // ctype (little endian)
1645  memset(tmp, 0, 12);
1647 
1648  // library_name_len (max 255)
1649  rz_buf_append_le_bits(buffer, tmp, library_name_len, 8);
1650 
1651  // crc16_ctypes (little endian)
1653 
1654  if (options->version >= 6) {
1655  // n_functions (little endian)
1656  rz_buf_append_le_bits(buffer, tmp, n_functions, 32);
1657  }
1658 
1659  if (options->version >= 8) {
1660  // pattern_size (little endian) - we always use 32 bytes prelude
1661  rz_buf_append_le_bits(buffer, tmp, 32, 16);
1662  }
1663 
1664  if (options->version >= 10) {
1665  // unknown (little endian)
1666  rz_buf_append_le_bits(buffer, tmp, 0, 16);
1667  }
1668 
1669  // library name
1670  rz_buf_append_string(buffer, options->libname);
1671 
1672  if (!flirt_write_node(node, body, options->version)) {
1673  rz_buf_free(body);
1674  return false;
1675  }
1676 
1677  bool ret = true;
1678  if (options->deflate) {
1679  ut64 block_size = 1ull << 20; // 1 Mb
1680  if (!rz_deflatew_buf(body, buffer, block_size, NULL, 15)) {
1681  RZ_LOG_ERROR("FLIRT: cannot deflate body\n");
1682  ret = false;
1683  }
1684  rz_buf_free(body);
1685  }
1686  return ret;
1687 }
RZ_API void rz_analysis_function_add_block(RzAnalysisFunction *fcn, RzAnalysisBlock *bb)
Definition: function.c:264
RZ_API RzAnalysisFunction * rz_analysis_get_function_at(RzAnalysis *analysis, ut64 addr)
Definition: function.c:184
RZ_API ut64 rz_analysis_function_linear_size(RzAnalysisFunction *fcn)
Definition: function.c:318
RZ_API bool rz_analysis_function_rename(RzAnalysisFunction *fcn, const char *name)
Definition: function.c:240
RZ_API bool rz_analysis_function_delete(RzAnalysisFunction *fcn)
Definition: function.c:180
#define mask()
lzma_index ** i
Definition: index.h:629
ut16 val
Definition: armass64_const.h:6
RzBinInfo * info(RzBinFile *bf)
Definition: bin_ne.c:86
struct buffer buffer
static int value
Definition: cmd_api.c:93
#define RZ_API
#define NULL
Definition: cris-opc.c:27
#define r
Definition: crypto_rc6.c:12
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void count
Definition: sflib.h:98
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void static offset struct stat static buf void long static basep static whence static length const void static len static semflg const void static shmflg const struct timespec struct timespec static rem const char static group const void length
Definition: sflib.h:133
static int buf_size
Definition: debug_qnx.c:35
uint16_t ut16
uint32_t ut32
RZ_API int rz_analysis_function_resize(RzAnalysisFunction *fcn, int newsize)
Definition: fcn.c:90
RZ_API void rz_analysis_trim_jmprefs(RzAnalysis *analysis, RzAnalysisFunction *fcn)
Definition: fcn.c:1578
RZ_API void rz_sign_flirt_node_free(RZ_NULLABLE RzFlirtNode *node)
Frees an RzFlirtNode struct.
Definition: flirt.c:299
static ut8 read_module_public_functions(RzFlirtModule *module, ParseStatus *b, ut8 *flags)
Definition: flirt.c:687
static bool rz_write_vle16(RzBuffer *buffer, ut16 val)
Definition: flirt.c:1348
struct idasig_v10_t idasig_v10_t
static bool node_match_functions(RzAnalysis *analysis, const RzFlirtNode *root_node)
Tries to find matching functions between the signature infos in root_node and the analyzed functions ...
Definition: flirt.c:490
RZ_API RZ_OWN bool rz_sign_flirt_parse_header_compressed_pattern_from_buffer(RZ_NONNULL RzBuffer *flirt_buf, RZ_NONNULL RzFlirtInfo *info)
Parses the RzBuffer containing a FLIRT structure and returns an RzFlirtInfo.
Definition: flirt.c:1062
static int parse_v10_header(RzBuffer *buf, idasig_v10_t *header)
Definition: flirt.c:1005
#define IDASIG_FUNCTION_UNRESOLVED_COLLISION
Definition: flirt.c:146
static bool read_node_variant_mask(RzFlirtNode *node, ParseStatus *b)
Definition: flirt.c:845
static bool read_node_bytes(RzFlirtNode *node, ParseStatus *b)
Definition: flirt.c:870
RZ_API void rz_sign_flirt_info_fini(RZ_NULLABLE RzFlirtInfo *info)
Frees an RzFlirtInfo struct elements without freeing the pointer.
Definition: flirt.c:315
void module_free(RzFlirtModule *module)
Definition: flirt.c:284
static bool rz_write_versioned_vle(RzBuffer *buffer, ut32 value, ut8 version)
Definition: flirt.c:1406
struct idasig_v6_v7_t idasig_v6_v7_t
static bool flirt_has_references(RZ_NONNULL const RzFlirtModule *module)
Definition: flirt.c:1402
static bool rz_write_vle64(RzBuffer *buffer, ut64 val)
Definition: flirt.c:1398
RZ_API ut32 rz_sign_flirt_node_count_nodes(RZ_NONNULL const RzFlirtNode *node)
Counts the number of FLIRT signatures in the node.
Definition: flirt.c:1334
struct parse_status_t ParseStatus
#define IDASIG_PARSE_MORE_MODULES
Definition: flirt.c:142
static bool flirt_write_module(RZ_NONNULL const RzFlirtModule *module, RZ_NONNULL RzBuffer *buffer, ut8 flags, ut8 version, bool first)
Definition: flirt.c:1413
struct idasig_v8_v9_t idasig_v8_v9_t
static ut8 read_module_tail_bytes(RzFlirtModule *module, ParseStatus *b)
Definition: flirt.c:532
static ut8 read_byte(ParseStatus *b)
Definition: flirt.c:230
RZ_API bool rz_sign_flirt_apply(RZ_NONNULL RzAnalysis *analysis, RZ_NONNULL const char *flirt_file, ut8 expected_arch)
Parses the FLIRT file and applies the signatures.
Definition: flirt.c:1289
static bool flirt_write_node(RZ_NONNULL const RzFlirtNode *node, RZ_NONNULL RzBuffer *buffer, ut8 version)
Definition: flirt.c:1507
static int node_match_buffer(RzAnalysis *analysis, const RzFlirtNode *node, ut8 *b, ut64 address, ut32 buf_size, ut32 buf_idx)
Definition: flirt.c:458
static ut8 read_module_referenced_functions(RzFlirtModule *module, ParseStatus *b)
Definition: flirt.c:597
static ut16 read_max_2_bytes(ParseStatus *b)
Definition: flirt.c:261
static ut32 read_word(ParseStatus *b)
Definition: flirt.c:255
static ut16 read_short(ParseStatus *b)
Definition: flirt.c:249
#define rz_buf_append_le_bits(buffer, tmp, value, bits)
Definition: flirt.c:121
#define POLY
Definition: flirt.c:203
static int module_match_buffer(RzAnalysis *analysis, const RzFlirtModule *module, ut8 *b, ut64 address, ut32 buf_size)
Checks if the module matches the buffer and renames the matched functions.
Definition: flirt.c:359
RZ_API RZ_OWN RzFlirtNode * rz_sign_flirt_parse_compressed_pattern_from_buffer(RZ_NONNULL RzBuffer *flirt_buf, ut8 expected_arch, RZ_NULLABLE RzFlirtInfo *info)
Parses the RzBuffer containing a FLIRT structure and returns an RzFlirtNode.
Definition: flirt.c:1136
static ut8 parse_tree(ParseStatus *b, RzFlirtNode *root_node)
Definition: flirt.c:902
static bool is_pattern_matching(ut32 p_size, const ut8 *pattern, const ut8 *mask, const ut8 *b, ut32 b_size)
Checks if a pattern does match the buffer data.
Definition: flirt.c:336
struct idasig_v5_t idasig_v5_t
static bool read_node_length(RzFlirtNode *node, ParseStatus *b)
Definition: flirt.c:836
static ut32 read_multiple_bytes(ParseStatus *b)
Definition: flirt.c:268
ut16 flirt_crc16(const ut8 *data_p, size_t length)
Definition: flirt.c:204
RZ_API bool rz_sign_flirt_write_compressed_pattern_to_buffer(RZ_NONNULL const RzFlirtNode *node, RZ_NONNULL RzBuffer *buffer, RzFlirtCompressedOptions *options)
Writes in the the RzBuffer the FLIRT signatures in compressed format.
Definition: flirt.c:1580
#define rz_buf_append_be_bits(buffer, tmp, value, bits)
Definition: flirt.c:125
#define is_status_err_or_eof(p)
Definition: flirt.c:183
static bool rz_write_vle32(RzBuffer *buffer, ut32 val)
Definition: flirt.c:1368
static int parse_v6_v7_header(RzBuffer *buf, idasig_v6_v7_t *header)
Definition: flirt.c:987
#define IDASIG_PARSE_READ_REFERENCED_FUNCTIONS
Definition: flirt.c:140
#define IDASIG_FEATURE_NONE
Definition: flirt.c:130
static ut8 flirt_parse_version(RzBuffer *buffer)
Returns the FLIRT file version read from the RzBuffer This function returns the FLIRT file version,...
Definition: flirt.c:1021
static int parse_v8_v9_header(RzBuffer *buf, idasig_v8_v9_t *header)
Definition: flirt.c:996
static bool parse_v5_header(RzBuffer *buf, idasig_v5_t *header)
Definition: flirt.c:945
#define IDASIG_FUNCTION_LOCAL
Definition: flirt.c:145
#define sig_dbg_buffer(n, b, s)
Definition: flirt.c:118
#define sig_dbg(...)
Definition: flirt.c:117
#define IDASIG_FEATURE_COMPRESSED
Definition: flirt.c:135
#define IDASIG_PARSE_MORE_MODULES_WITH_SAME_CRC
Definition: flirt.c:141
#define IDASIG_PARSE_READ_TAIL_BYTES
Definition: flirt.c:139
#define IDASIG_PARSE_MORE_PUBLIC_NAMES
Definition: flirt.c:138
static ut8 parse_leaf(ParseStatus *b, RzFlirtNode *node)
Definition: flirt.c:762
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
voidpf void uLong size
Definition: ioapi.h:138
voidpf uLong offset
Definition: ioapi.h:144
voidpf void * buf
Definition: ioapi.h:138
uint8_t ut8
Definition: lh5801.h:11
return memset(p, 0, total)
RZ_API RZ_BORROW void * rz_list_iter_get_next_data(RzListIter *list)
returns the value stored in the next RzList iterator
Definition: list.c:29
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 void * rz_list_last(RZ_NONNULL const RzList *list)
Returns the last element of the list.
Definition: list.c:86
RZ_API ut32 rz_list_length(RZ_NONNULL const RzList *list)
Returns the length of the list.
Definition: list.c:109
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
void * malloc(size_t size)
Definition: malloc.c:123
static const char struct stat static buf struct stat static buf static vhangup int options
Definition: sflib.h:145
#define header(is_bt, len_min, ret_op)
@ RZ_ANALYSIS_FCN_TYPE_LOC
Definition: rz_analysis.h:194
@ RZ_ANALYSIS_FCN_TYPE_FCN
Definition: rz_analysis.h:193
#define rz_return_val_if_fail(expr, val)
Definition: rz_assert.h:108
RZ_API ut64 rz_buf_tell(RZ_NONNULL RzBuffer *b)
Return the current cursor position.
Definition: buf.c:1238
RZ_API bool rz_buf_append_bytes(RZ_NONNULL RzBuffer *b, RZ_NONNULL const ut8 *buf, ut64 len)
Append an array of bytes to the buffer.
Definition: buf.c:732
RZ_API st64 rz_buf_seek(RZ_NONNULL RzBuffer *b, st64 addr, int whence)
Modify the current cursor position in the buffer.
Definition: buf.c:1166
RZ_API RZ_OWN RzBuffer * rz_buf_new_slurp(const char *file)
Creates a new buffer from a file.
Definition: buf.c:384
RZ_API st64 rz_buf_append_string(RZ_NONNULL RzBuffer *b, RZ_NONNULL const char *str)
Append a string to the buffer.
Definition: buf.c:962
RZ_API RZ_OWN RzBuffer * rz_buf_new_with_pointers(const ut8 *bytes, ut64 len, bool steal)
Creates a new buffer with a bytes array.
Definition: buf.c:552
#define rz_buf_read_le16(b, result)
Read a big endian or little endian (ut16, ut32, ut64) at the specified offset in the buffer and shift...
Definition: rz_buf.h:266
#define RZ_BUF_SET
Definition: rz_buf.h:14
#define rz_buf_read_le32(b, result)
Definition: rz_buf.h:267
RZ_API void rz_buf_free(RzBuffer *b)
Free all internal data hold by the buffer and the buffer.
Definition: buf.c:1253
RZ_API RZ_OWN RzBuffer * rz_buf_new_empty(ut64 len)
Creates a new empty buffer with a predefined size;.
Definition: buf.c:285
RZ_API st64 rz_buf_read(RZ_NONNULL RzBuffer *b, RZ_NONNULL RZ_OUT ut8 *buf, ut64 len)
RZ_API ut64 rz_buf_size(RZ_NONNULL RzBuffer *b)
Return the size of the buffer.
Definition: buf.c:1225
RZ_API bool rz_deflatew_buf(RZ_NONNULL RzBuffer *src, RZ_NONNULL RzBuffer *dst, ut64 block_size, ut8 *src_consumed, int wbits)
Definition: compression.c:327
RZ_API ut8 * rz_inflate_ignore_header(RZ_NONNULL const ut8 *src, int srcLen, int *srcConsumed, int *dstLen)
inflate zlib compressed or gzipped. The input must be a raw stream with no header or trailer.
Definition: compression.c:28
RZ_API ut8 * rz_inflate(RZ_NONNULL const ut8 *src, int srcLen, int *srcConsumed, int *dstLen)
inflate zlib compressed or gzipped, automatically accepts either the zlib or gzip format,...
Definition: compression.c:18
RZ_API RZ_OWN RzFlirtNode * rz_sign_flirt_parse_string_pattern_from_buffer(RZ_NONNULL RzBuffer *flirt_buf, ut32 optimization, RZ_NULLABLE RzFlirtInfo *info)
Parses the RzBuffer containing a FLIRT signature in string format and returns an RzFlirtNode.
Definition: pat.c:356
@ RZ_FLIRT_NODE_OPTIMIZE_MAX
optimize the tree structure and drops the tail bytes
Definition: rz_flirt.h:188
#define RZ_FLIRT_LIBRARY_NAME_MAX
Definition: rz_flirt.h:18
@ RZ_FLIRT_SIG_ARCH_ANY
Definition: rz_flirt.h:99
@ RZ_FLIRT_FILE_TYPE_SIG
.sig compressed pattern file
Definition: rz_flirt.h:193
#define RZ_FLIRT_NAME_MAX
Definition: rz_flirt.h:17
void(* RzListFree)(void *ptr)
Definition: rz_list.h:11
#define RZ_LOG_WARN(fmtstr,...)
Definition: rz_log.h:56
#define RZ_LOG_DEBUG(fmtstr,...)
Definition: rz_log.h:49
#define RZ_LOG_ERROR(fmtstr,...)
Definition: rz_log.h:58
RZ_API bool rz_name_filter(char *name, int len, bool strict)
Definition: name.c:43
#define RZ_STR_ISNOTEMPTY(x)
Definition: rz_str.h:68
RZ_API const char * rz_str_lchr(const char *str, char chr)
Definition: str.c:669
RZ_API char * rz_str_newf(const char *fmt,...) RZ_PRINTF_CHECK(1
#define RZ_STR_ISEMPTY(x)
Definition: rz_str.h:67
#define RZ_NULLABLE
Definition: rz_types.h:65
#define RZ_OWN
Definition: rz_types.h:62
#define RZ_NEW0(x)
Definition: rz_types.h:284
#define RZ_NONNULL
Definition: rz_types.h:64
#define RZ_FREE(x)
Definition: rz_types.h:369
#define PFMT64x
Definition: rz_types.h:393
#define UT32_MAX
Definition: rz_types_base.h:99
#define UT16_MAX
static struct sockaddr static addrlen static backlog const void static flags void flags
Definition: sfsocketcall.h:123
#define b(i)
Definition: sha256.c:42
Definition: buffer.h:15
ut16 unknown
Definition: flirt.c:173
ut8 magic[6]
Definition: flirt.c:150
ut8 ctype[12]
Definition: flirt.c:159
ut8 arch
Definition: flirt.c:152
ut16 ctypes_crc16
Definition: flirt.c:161
ut8 library_name_len
Definition: flirt.c:160
ut16 os_types
Definition: flirt.c:154
ut16 crc16
Definition: flirt.c:158
ut16 app_types
Definition: flirt.c:155
ut8 version
Definition: flirt.c:151
ut16 old_n_functions
Definition: flirt.c:157
ut16 features
Definition: flirt.c:156
ut32 file_types
Definition: flirt.c:153
ut32 n_functions
Definition: flirt.c:165
ut16 pattern_size
Definition: flirt.c:169
Definition: sftypes.h:77
Definition: z80asm.h:102
ut8 version
Definition: flirt.c:180
bool error
Definition: flirt.c:179
RzBuffer * buffer
Definition: flirt.c:177
bool eof
Definition: flirt.c:178
RzList * fcns
Definition: rz_analysis.h:565
RzFlagBind flb
Definition: rz_analysis.h:575
RzIOBind iob
Definition: rz_analysis.h:574
char * type
Definition: rz_bin.h:211
RzFlagGetAtBySpaces get_at_by_spaces
Definition: rz_flag.h:82
RzFlagSet set
Definition: rz_flag.h:84
RzFlagPopSpace pop_fs
Definition: rz_flag.h:90
RzFlag * f
Definition: rz_flag.h:78
RzFlagPushSpace push_fs
Definition: rz_flag.h:89
RzFlagUnset unset
Definition: rz_flag.h:85
char name[RZ_FLIRT_NAME_MAX]
Definition: rz_flirt.h:158
RzList * child_list
Definition: rz_flirt.h:177
RzList * module_list
Definition: rz_flirt.h:178
ut8 * pattern_mask
Definition: rz_flirt.h:182
ut8 * pattern_bytes
Definition: rz_flirt.h:181
ut64 variant_mask
Definition: rz_flirt.h:180
RzIOReadAt read_at
Definition: rz_io.h:240
RzIO * io
Definition: rz_io.h:232
struct rz_list_iter_t * n
Definition: rz_list.h:15
void * data
Definition: rz_list.h:14
ut64(WINAPI *w32_GetEnabledXStateFeatures)()