Rizin
unix-like reverse engineering framework and cli tools
keyword.c
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2010-2015 pancake <pancake@nopcode.org>
2 // SPDX-License-Identifier: LGPL-3.0-only
3 
4 #include <rz_search.h>
5 
6 static int ignoreMask(const ut8 *bm, int len) {
7  int i;
8  for (i = 0; i < len; i++) {
9  if (bm[i] != 0xff) {
10  return 0;
11  }
12  }
13  return 1;
14 }
15 
16 RZ_API RzSearchKeyword *rz_search_keyword_new(const ut8 *kwbuf, int kwlen, const ut8 *bmbuf, int bmlen, const char *data) {
17  RzSearchKeyword *kw;
18  if (kwlen < 1 || bmlen < 0) {
19  return NULL;
20  }
22  if (!kw) {
23  return NULL;
24  }
26  kw->data = (void *)data;
27  kw->keyword_length = kwlen;
28  kw->bin_keyword = malloc(kwlen);
29  if (!kw->bin_keyword) {
31  return NULL;
32  }
33  memcpy(kw->bin_keyword, kwbuf, kwlen);
34  if (bmbuf && bmlen > 0 && !ignoreMask(bmbuf, bmlen)) {
35  kw->bin_binmask = malloc(bmlen);
36  if (!kw->bin_binmask) {
38  return NULL;
39  }
40  memcpy(kw->bin_binmask, bmbuf, bmlen);
41  kw->binmask_length = bmlen;
42  } else {
43  kw->bin_binmask = NULL;
44  kw->binmask_length = 0;
45  }
46  return kw;
47 }
48 
50  if (!kw) {
51  return;
52  }
53  free(kw->bin_binmask);
54  free(kw->bin_keyword);
55  free(kw);
56 }
57 
58 RZ_API RzSearchKeyword *rz_search_keyword_new_str(const char *kwbuf, const char *bmstr, const char *data, int ignore_case) {
59  RzSearchKeyword *kw;
60  ut8 *bmbuf = NULL;
61  int bmlen = 0;
62 
63  if (bmstr) {
64  bmbuf = malloc(strlen(bmstr) + 1);
65  if (!bmbuf) {
66  return NULL;
67  }
68  bmlen = rz_hex_str2bin(bmstr, bmbuf);
69  if (bmlen < 1) {
70  RZ_FREE(bmbuf);
71  }
72  }
73  kw = rz_search_keyword_new((ut8 *)kwbuf, strlen(kwbuf), bmbuf, bmlen, data);
74  if (kw) {
75  kw->icase = ignore_case;
77  }
78  free(bmbuf);
79  return kw;
80 }
81 
82 RZ_API RzSearchKeyword *rz_search_keyword_new_wide(const char *kwbuf, const char *bmstr, const char *data, int ignore_case) {
83  RzSearchKeyword *kw;
84  int len;
85  const char *p2;
86  char *p, *str;
87  ut8 *bmbuf = NULL;
88  int bmlen = 0;
89 
90  if (bmstr) {
91  bmbuf = malloc(strlen(bmstr) + 1);
92  if (!bmbuf) {
93  return NULL;
94  }
95  bmlen = rz_hex_str2bin(bmstr, bmbuf);
96  if (bmlen < 1) {
97  RZ_FREE(bmbuf);
98  }
99  }
100 
101  len = strlen(kwbuf);
102  str = malloc((len + 1) * 2);
103  for (p2 = kwbuf, p = str; *p2;) {
104  RzRune ch;
105  int num_utf8_bytes = rz_utf8_decode((const ut8 *)p2, kwbuf + len - p2, &ch);
106  if (num_utf8_bytes < 1) {
107  eprintf("WARNING: Malformed UTF8 at pos %td\n", p2 - kwbuf);
108  p[0] = *p2;
109  p[1] = 0;
110  p2++;
111  p += 2;
112  continue;
113  }
114  if (ignore_case && ch <= 0xff) {
115  ch = tolower(ch);
116  }
117  int num_wide_bytes = rz_utf16le_encode((ut8 *)p, ch);
118  rz_warn_if_fail(num_wide_bytes != 0);
119  p2 += num_utf8_bytes;
120  p += num_wide_bytes;
121  }
122 
123  kw = rz_search_keyword_new((ut8 *)str, p - str, bmbuf, bmlen, data);
124  free(str);
125  if (kw) {
126  kw->icase = ignore_case;
127  }
128  free(bmbuf);
129  return kw;
130 }
131 
132 RZ_API RzSearchKeyword *rz_search_keyword_new_hex(const char *kwstr, const char *bmstr, const char *data) {
133  RzSearchKeyword *kw;
134  ut8 *kwbuf, *bmbuf;
135  int kwlen, bmlen = 0;
136 
137  if (!kwstr) {
138  return NULL;
139  }
140 
141  kwbuf = malloc(strlen(kwstr) + 1);
142  if (!kwbuf) {
143  return NULL;
144  }
145 
146  kwlen = rz_hex_str2bin(kwstr, kwbuf);
147  if (kwlen < 1) {
148  free(kwbuf);
149  return NULL;
150  }
151 
152  bmbuf = NULL;
153  if (bmstr && *bmstr) {
154  bmbuf = malloc(strlen(bmstr) + 1);
155  if (!bmbuf) {
156  free(kwbuf);
157  return NULL;
158  }
159  bmlen = rz_hex_str2bin(bmstr, bmbuf);
160  if (bmlen < 1) {
161  free(bmbuf);
162  free(kwbuf);
163  return NULL;
164  }
165  }
166 
167  kw = rz_search_keyword_new(kwbuf, kwlen, bmbuf, bmlen, data);
168  free(kwbuf);
169  free(bmbuf);
170  return kw;
171 }
172 
173 RZ_API RzSearchKeyword *rz_search_keyword_new_hexmask(const char *kwstr, const char *data) {
174  RzSearchKeyword *ks = NULL;
175  ut8 *kw, *bm;
176  if (kwstr != NULL) {
177  int len = strlen(kwstr);
178  kw = malloc(len + 4);
179  bm = malloc(len + 4);
180  if (kw != NULL && bm != NULL) {
181  len = rz_hex_str2binmask(kwstr, (ut8 *)kw, (ut8 *)bm);
182  if (len < 0) {
183  len = -len - 1;
184  }
185  if (len > 0) {
186  ks = rz_search_keyword_new(kw, len, bm, len, data);
187  }
188  }
189  free(kw);
190  free(bm);
191  }
192  return ks;
193 }
194 
195 /* Validate a regexp in the canonical format /<regexp>/<options> */
196 RZ_API RzSearchKeyword *rz_search_keyword_new_regexp(const char *str, const char *data) {
197  RzSearchKeyword *kw;
198  int i = 0, start, length;
199 
200  while (isspace((const unsigned char)str[i])) {
201  i++;
202  }
203 
204  if (str[i++] != '/') {
205  return NULL;
206  }
207 
208  /* Find the fist non backslash-escaped slash */
209  int specials = 0;
210  for (start = i; str[i]; i++) {
211  if (str[i] == '/' && str[i - 1] != '\\') {
212  break;
213  } else if (str[i - 1] == '\\' && isalpha(str[i])) {
214  specials++;
215  }
216  }
217 
218  if (str[i++] != '/') {
219  return NULL;
220  }
221 
222  length = i - start - 1;
223  if ((length > 128) || (length < 1)) {
224  return NULL;
225  }
226 
227  kw = RZ_NEW0(RzSearchKeyword);
228  if (!kw) {
229  return NULL;
230  }
231 
232  kw->bin_keyword = malloc(length + 1);
233  if (!kw->bin_keyword) {
235  return NULL;
236  }
237 
238  kw->bin_keyword[length] = 0;
239  memcpy(kw->bin_keyword, str + start, length);
240  kw->keyword_length = length - specials;
242  kw->data = (void *)data;
243 
244  /* Parse the options */
245  for (; str[i]; i++) {
246  switch (str[i]) {
247  case 'i':
248  kw->icase = true;
249  break;
250  default:
252  return NULL;
253  }
254  }
255 
256  return kw;
257 }
size_t len
Definition: 6502dis.c:15
lzma_index ** i
Definition: index.h:629
#define RZ_API
#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 static semflg const void static shmflg const struct timespec struct timespec static rem const char static group const void start
Definition: sflib.h:133
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void static offset struct stat static buf void long static basep static whence static length const void static len static semflg const void static shmflg const struct timespec struct timespec static rem const char static group const void length
Definition: sflib.h:133
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
static int ignoreMask(const ut8 *bm, int len)
Definition: keyword.c:6
RZ_API RzSearchKeyword * rz_search_keyword_new_str(const char *kwbuf, const char *bmstr, const char *data, int ignore_case)
Definition: keyword.c:58
RZ_API RzSearchKeyword * rz_search_keyword_new_wide(const char *kwbuf, const char *bmstr, const char *data, int ignore_case)
Definition: keyword.c:82
RZ_API RzSearchKeyword * rz_search_keyword_new_hex(const char *kwstr, const char *bmstr, const char *data)
Definition: keyword.c:132
RZ_API void rz_search_keyword_free(RzSearchKeyword *kw)
Definition: keyword.c:49
RZ_API RzSearchKeyword * rz_search_keyword_new_regexp(const char *str, const char *data)
Definition: keyword.c:196
RZ_API RzSearchKeyword * rz_search_keyword_new(const ut8 *kwbuf, int kwlen, const ut8 *bmbuf, int bmlen, const char *data)
Definition: keyword.c:16
RZ_API RzSearchKeyword * rz_search_keyword_new_hexmask(const char *kwstr, const char *data)
Definition: keyword.c:173
uint8_t ut8
Definition: lh5801.h:11
void * p
Definition: libc.cpp:67
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
void * malloc(size_t size)
Definition: malloc.c:123
#define eprintf(x, y...)
Definition: rlcc.c:7
#define rz_warn_if_fail(expr)
Definition: rz_assert.h:35
RZ_API int rz_hex_str2bin(const char *in, ut8 *out)
Convert an input string in into the binary form in out.
Definition: hex.c:444
RZ_API int rz_hex_str2binmask(const char *in, ut8 *out, ut8 *mask)
Definition: hex.c:490
#define RZ_SEARCH_KEYWORD_TYPE_STRING
Definition: rz_search.h:32
#define RZ_SEARCH_KEYWORD_TYPE_BINARY
Definition: rz_search.h:31
#define RZ_NEW0(x)
Definition: rz_types.h:284
#define RZ_FREE(x)
Definition: rz_types.h:369
RZ_API int rz_utf16le_encode(ut8 *ptr, RzRune ch)
Definition: utf16.c:46
RZ_API int rz_utf8_decode(const ut8 *ptr, int ptrlen, RzRune *ch)
Definition: utf8.c:492
ut32 RzRune
Definition: rz_utf8.h:13
#define isspace(c)
Definition: safe-ctype.h:141
#define tolower(c)
Definition: safe-ctype.h:149
#define isalpha(c)
Definition: safe-ctype.h:125
int ignore_case
Definition: zipcmp.c:234