1 /**
2 * Author......: See docs/credits.txt
3 * License.....: MIT
4 */
5
6 #include "common.h"
7 #include "types.h"
8 #include "memory.h"
9 #include "convert.h"
10 #include "event.h"
11 #include "shared.h"
12 #include "filehandling.h"
13 #include "rp.h"
14 #include "rp_cpu.h"
15
16 static const char grp_op_nop[] =
17 {
18 RULE_OP_MANGLE_LREST,
19 RULE_OP_MANGLE_UREST,
20 RULE_OP_MANGLE_LREST_UFIRST,
21 RULE_OP_MANGLE_UREST_LFIRST,
22 RULE_OP_MANGLE_TREST,
23 RULE_OP_MANGLE_REVERSE,
24 RULE_OP_MANGLE_DUPEWORD,
25 RULE_OP_MANGLE_REFLECT,
26 RULE_OP_MANGLE_DELETE_FIRST,
27 RULE_OP_MANGLE_DELETE_LAST,
28 RULE_OP_MANGLE_ROTATE_LEFT,
29 RULE_OP_MANGLE_ROTATE_RIGHT,
30 RULE_OP_MANGLE_SWITCH_FIRST,
31 RULE_OP_MANGLE_SWITCH_LAST,
32 RULE_OP_MANGLE_DUPECHAR_ALL,
33 RULE_OP_MANGLE_TITLE,
34 };
35
36 static const char grp_op_pos_p0[] =
37 {
38 RULE_OP_MANGLE_TOGGLE_AT,
39 RULE_OP_MANGLE_DELETE_AT,
40 RULE_OP_MANGLE_TRUNCATE_AT,
41 RULE_OP_MANGLE_CHR_INCR,
42 RULE_OP_MANGLE_CHR_DECR,
43 RULE_OP_MANGLE_CHR_SHIFTL,
44 RULE_OP_MANGLE_CHR_SHIFTR,
45 RULE_OP_MANGLE_REPLACE_NP1,
46 RULE_OP_MANGLE_REPLACE_NM1
47 };
48
49 static const char grp_op_pos_p1[] =
50 {
51 RULE_OP_MANGLE_DUPEWORD_TIMES,
52 RULE_OP_MANGLE_DUPECHAR_FIRST,
53 RULE_OP_MANGLE_DUPECHAR_LAST,
54 RULE_OP_MANGLE_DUPEBLOCK_FIRST,
55 RULE_OP_MANGLE_DUPEBLOCK_LAST
56 };
57
58 static const char grp_op_chr[] =
59 {
60 RULE_OP_MANGLE_APPEND,
61 RULE_OP_MANGLE_PREPEND,
62 RULE_OP_MANGLE_PURGECHAR,
63 RULE_OP_MANGLE_TITLE_SEP
64 };
65
66 static const char grp_op_chr_chr[] =
67 {
68 RULE_OP_MANGLE_REPLACE
69 };
70
71 static const char grp_op_pos_chr[] =
72 {
73 RULE_OP_MANGLE_INSERT,
74 RULE_OP_MANGLE_OVERSTRIKE,
75 RULE_OP_MANGLE_TOGGLE_AT_SEP
76 };
77
78 static const char grp_op_pos_pos0[] =
79 {
80 RULE_OP_MANGLE_SWITCH_AT
81 };
82
83 static const char grp_op_pos_pos1[] =
84 {
85 RULE_OP_MANGLE_EXTRACT,
86 RULE_OP_MANGLE_OMIT
87 };
88
89 static const char grp_pos[] =
90 {
91 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B'
92 };
93
class_num(const u8 c)94 bool class_num (const u8 c)
95 {
96 return ((c >= '0') && (c <= '9'));
97 }
98
class_lower(const u8 c)99 bool class_lower (const u8 c)
100 {
101 return ((c >= 'a') && (c <= 'z'));
102 }
103
class_upper(const u8 c)104 bool class_upper (const u8 c)
105 {
106 return ((c >= 'A') && (c <= 'Z'));
107 }
108
class_alpha(const u8 c)109 bool class_alpha (const u8 c)
110 {
111 return (class_lower (c) || class_upper (c));
112 }
113
conv_ctoi(const u8 c)114 int conv_ctoi (const u8 c)
115 {
116 if (class_num (c)) return c - '0';
117 if (class_upper (c)) return c - 'A' + 10;
118
119 return -1;
120 }
121
conv_itoc(const u8 c)122 int conv_itoc (const u8 c)
123 {
124 if (c < 10) return c + '0';
125 if (c < 37) return c + 'A' - 10;
126
127 return -1;
128 }
129
generate_random_rule(char rule_buf[RP_RULE_SIZE],const u32 rp_gen_func_min,const u32 rp_gen_func_max,const rp_gen_ops_t * rp_gen_ops)130 int generate_random_rule (char rule_buf[RP_RULE_SIZE], const u32 rp_gen_func_min, const u32 rp_gen_func_max, const rp_gen_ops_t *rp_gen_ops)
131 {
132 // generate them
133
134 const u32 rp_gen_num = get_random_num (rp_gen_func_min, rp_gen_func_max);
135
136 u32 rule_pos = 0;
137
138 for (u32 j = 0; j < rp_gen_num; j++)
139 {
140 u32 r = 0;
141 u32 p1 = 0;
142 u32 p2 = 0;
143
144 const int group_num = get_random_num (0, rp_gen_ops->grp_op_alias_cnt);
145
146 const int group_num_alias = rp_gen_ops->grp_op_alias_buf[group_num];
147
148 switch (group_num_alias)
149 {
150 case 0:
151 r = get_random_num (0, rp_gen_ops->grp_op_nop_cnt);
152 rule_buf[rule_pos++] = rp_gen_ops->grp_op_nop_selection[r];
153 break;
154
155 case 1:
156 r = get_random_num (0, rp_gen_ops->grp_op_pos_p0_cnt);
157 rule_buf[rule_pos++] = rp_gen_ops->grp_op_pos_p0_selection[r];
158 p1 = get_random_num (0, sizeof (grp_pos));
159 rule_buf[rule_pos++] = grp_pos[p1];
160 break;
161
162 case 2:
163 r = get_random_num (0, rp_gen_ops->grp_op_pos_p1_cnt);
164 rule_buf[rule_pos++] = rp_gen_ops->grp_op_pos_p1_selection[r];
165 p1 = get_random_num (1, 6);
166 rule_buf[rule_pos++] = grp_pos[p1];
167 break;
168
169 case 3:
170 r = get_random_num (0, rp_gen_ops->grp_op_chr_cnt);
171 rule_buf[rule_pos++] = rp_gen_ops->grp_op_chr_selection[r];
172 p1 = get_random_num (0x20, 0x7e);
173 rule_buf[rule_pos++] = (char) p1;
174 break;
175
176 case 4:
177 r = get_random_num (0, rp_gen_ops->grp_op_chr_chr_cnt);
178 rule_buf[rule_pos++] = rp_gen_ops->grp_op_chr_chr_selection[r];
179 p1 = get_random_num (0x20, 0x7e);
180 rule_buf[rule_pos++] = (char) p1;
181 p2 = get_random_num (0x20, 0x7e);
182 while (p1 == p2)
183 p2 = get_random_num (0x20, 0x7e);
184 rule_buf[rule_pos++] = (char) p2;
185 break;
186
187 case 5:
188 r = get_random_num (0, rp_gen_ops->grp_op_pos_chr_cnt);
189 rule_buf[rule_pos++] = rp_gen_ops->grp_op_pos_chr_selection[r];
190 p1 = get_random_num (0, sizeof (grp_pos));
191 rule_buf[rule_pos++] = grp_pos[p1];
192 p2 = get_random_num (0x20, 0x7e);
193 rule_buf[rule_pos++] = (char) p2;
194 break;
195
196 case 6:
197 r = get_random_num (0, rp_gen_ops->grp_op_pos_pos0_cnt);
198 rule_buf[rule_pos++] = rp_gen_ops->grp_op_pos_pos0_selection[r];
199 p1 = get_random_num (0, sizeof (grp_pos));
200 rule_buf[rule_pos++] = grp_pos[p1];
201 p2 = get_random_num (0, sizeof (grp_pos));
202 while (p1 == p2)
203 p2 = get_random_num (0, sizeof (grp_pos));
204 rule_buf[rule_pos++] = grp_pos[p2];
205 break;
206
207 case 7:
208 r = get_random_num (0, rp_gen_ops->grp_op_pos_pos1_cnt);
209 rule_buf[rule_pos++] = rp_gen_ops->grp_op_pos_pos1_selection[r];
210 p1 = get_random_num (0, sizeof (grp_pos));
211 rule_buf[rule_pos++] = grp_pos[p1];
212 p2 = get_random_num (1, sizeof (grp_pos));
213 while (p1 == p2)
214 p2 = get_random_num (1, sizeof (grp_pos));
215 rule_buf[rule_pos++] = grp_pos[p2];
216 break;
217 }
218 }
219
220 return (rule_pos);
221 }
222
223 #define INCR_POS if (++rule_pos == rule_len) return (-1)
224
225 #define SET_NAME(rule,val) (rule)->cmds[rule_cnt] = ((val) & 0xff) << 0
226 #define SET_P0(rule,val) do { INCR_POS; if (is_hex_notation (rule_buf, rule_len, rule_pos) == true) { (rule)->cmds[rule_cnt] |= (hex_convert (rule_buf[rule_pos + 3] & 0xff) << 8) | (hex_convert (rule_buf[rule_pos + 2] & 0xff) << 12); rule_pos += 3; } else { (rule)->cmds[rule_cnt] |= ((val) & 0xff) << 8; } } while(0)
227 #define SET_P1(rule,val) do { INCR_POS; if (is_hex_notation (rule_buf, rule_len, rule_pos) == true) { (rule)->cmds[rule_cnt] |= (hex_convert (rule_buf[rule_pos + 3] & 0xff) << 16) | (hex_convert (rule_buf[rule_pos + 2] & 0xff) << 20); rule_pos += 3; } else { (rule)->cmds[rule_cnt] |= ((val) & 0xff) << 16; } } while(0)
228 #define GET_NAME(rule) rule_cmd = (((rule)->cmds[rule_cnt] >> 0) & 0xff)
229 #define GET_P0(rule) INCR_POS; rule_buf[rule_pos] = (((rule)->cmds[rule_cnt] >> 8) & 0xff)
230 #define GET_P1(rule) INCR_POS; rule_buf[rule_pos] = (((rule)->cmds[rule_cnt] >> 16) & 0xff)
231
232 #define SET_P0_CONV(rule,val) INCR_POS; (rule)->cmds[rule_cnt] |= ((conv_ctoi (val)) & 0xff) << 8
233 #define SET_P1_CONV(rule,val) INCR_POS; (rule)->cmds[rule_cnt] |= ((conv_ctoi (val)) & 0xff) << 16
234 #define GET_P0_CONV(rule) INCR_POS; rule_buf[rule_pos] = (char) conv_itoc (((rule)->cmds[rule_cnt] >> 8) & 0xff)
235 #define GET_P1_CONV(rule) INCR_POS; rule_buf[rule_pos] = (char) conv_itoc (((rule)->cmds[rule_cnt] >> 16) & 0xff)
236
is_hex_notation(const char * rule_buf,u32 rule_len,u32 rule_pos)237 bool is_hex_notation (const char *rule_buf, u32 rule_len, u32 rule_pos)
238 {
239 if ((rule_pos + 4) > rule_len) return false;
240
241 if (rule_buf[rule_pos + 0] != '\\') return false;
242 if (rule_buf[rule_pos + 1] != 'x') return false;
243
244 if (is_valid_hex_char (rule_buf[rule_pos + 2]) == false) return false;
245 if (is_valid_hex_char (rule_buf[rule_pos + 3]) == false) return false;
246
247 return true;
248 }
249
cpu_rule_to_kernel_rule(char * rule_buf,u32 rule_len,kernel_rule_t * rule)250 int cpu_rule_to_kernel_rule (char *rule_buf, u32 rule_len, kernel_rule_t *rule)
251 {
252 u32 rule_pos;
253 u32 rule_cnt;
254
255 for (rule_pos = 0, rule_cnt = 0; rule_pos < rule_len && rule_cnt < MAX_KERNEL_RULES; rule_pos++, rule_cnt++)
256 {
257 switch (rule_buf[rule_pos])
258 {
259 case ' ':
260 rule_cnt--;
261 break;
262
263 case RULE_OP_MANGLE_NOOP:
264 SET_NAME (rule, rule_buf[rule_pos]);
265 break;
266
267 case RULE_OP_MANGLE_LREST:
268 SET_NAME (rule, rule_buf[rule_pos]);
269 break;
270
271 case RULE_OP_MANGLE_UREST:
272 SET_NAME (rule, rule_buf[rule_pos]);
273 break;
274
275 case RULE_OP_MANGLE_LREST_UFIRST:
276 SET_NAME (rule, rule_buf[rule_pos]);
277 break;
278
279 case RULE_OP_MANGLE_UREST_LFIRST:
280 SET_NAME (rule, rule_buf[rule_pos]);
281 break;
282
283 case RULE_OP_MANGLE_TREST:
284 SET_NAME (rule, rule_buf[rule_pos]);
285 break;
286
287 case RULE_OP_MANGLE_TOGGLE_AT:
288 SET_NAME (rule, rule_buf[rule_pos]);
289 SET_P0_CONV (rule, rule_buf[rule_pos]);
290 break;
291
292 case RULE_OP_MANGLE_REVERSE:
293 SET_NAME (rule, rule_buf[rule_pos]);
294 break;
295
296 case RULE_OP_MANGLE_DUPEWORD:
297 SET_NAME (rule, rule_buf[rule_pos]);
298 break;
299
300 case RULE_OP_MANGLE_DUPEWORD_TIMES:
301 SET_NAME (rule, rule_buf[rule_pos]);
302 SET_P0_CONV (rule, rule_buf[rule_pos]);
303 break;
304
305 case RULE_OP_MANGLE_REFLECT:
306 SET_NAME (rule, rule_buf[rule_pos]);
307 break;
308
309 case RULE_OP_MANGLE_ROTATE_LEFT:
310 SET_NAME (rule, rule_buf[rule_pos]);
311 break;
312
313 case RULE_OP_MANGLE_ROTATE_RIGHT:
314 SET_NAME (rule, rule_buf[rule_pos]);
315 break;
316
317 case RULE_OP_MANGLE_APPEND:
318 SET_NAME (rule, rule_buf[rule_pos]);
319 SET_P0 (rule, rule_buf[rule_pos]);
320 break;
321
322 case RULE_OP_MANGLE_PREPEND:
323 SET_NAME (rule, rule_buf[rule_pos]);
324 SET_P0 (rule, rule_buf[rule_pos]);
325 break;
326
327 case RULE_OP_MANGLE_DELETE_FIRST:
328 SET_NAME (rule, rule_buf[rule_pos]);
329 break;
330
331 case RULE_OP_MANGLE_DELETE_LAST:
332 SET_NAME (rule, rule_buf[rule_pos]);
333 break;
334
335 case RULE_OP_MANGLE_DELETE_AT:
336 SET_NAME (rule, rule_buf[rule_pos]);
337 SET_P0_CONV (rule, rule_buf[rule_pos]);
338 break;
339
340 case RULE_OP_MANGLE_EXTRACT:
341 SET_NAME (rule, rule_buf[rule_pos]);
342 SET_P0_CONV (rule, rule_buf[rule_pos]);
343 SET_P1_CONV (rule, rule_buf[rule_pos]);
344 break;
345
346 case RULE_OP_MANGLE_OMIT:
347 SET_NAME (rule, rule_buf[rule_pos]);
348 SET_P0_CONV (rule, rule_buf[rule_pos]);
349 SET_P1_CONV (rule, rule_buf[rule_pos]);
350 break;
351
352 case RULE_OP_MANGLE_INSERT:
353 SET_NAME (rule, rule_buf[rule_pos]);
354 SET_P0_CONV (rule, rule_buf[rule_pos]);
355 SET_P1 (rule, rule_buf[rule_pos]);
356 break;
357
358 case RULE_OP_MANGLE_OVERSTRIKE:
359 SET_NAME (rule, rule_buf[rule_pos]);
360 SET_P0_CONV (rule, rule_buf[rule_pos]);
361 SET_P1 (rule, rule_buf[rule_pos]);
362 break;
363
364 case RULE_OP_MANGLE_TRUNCATE_AT:
365 SET_NAME (rule, rule_buf[rule_pos]);
366 SET_P0_CONV (rule, rule_buf[rule_pos]);
367 break;
368
369 case RULE_OP_MANGLE_REPLACE:
370 SET_NAME (rule, rule_buf[rule_pos]);
371 SET_P0 (rule, rule_buf[rule_pos]);
372 SET_P1 (rule, rule_buf[rule_pos]);
373 break;
374
375 case RULE_OP_MANGLE_PURGECHAR:
376 SET_NAME (rule, rule_buf[rule_pos]);
377 SET_P0 (rule, rule_buf[rule_pos]);
378 break;
379
380 case RULE_OP_MANGLE_TOGGLECASE_REC:
381 return -1;
382
383 case RULE_OP_MANGLE_DUPECHAR_FIRST:
384 SET_NAME (rule, rule_buf[rule_pos]);
385 SET_P0_CONV (rule, rule_buf[rule_pos]);
386 break;
387
388 case RULE_OP_MANGLE_DUPECHAR_LAST:
389 SET_NAME (rule, rule_buf[rule_pos]);
390 SET_P0_CONV (rule, rule_buf[rule_pos]);
391 break;
392
393 case RULE_OP_MANGLE_DUPECHAR_ALL:
394 SET_NAME (rule, rule_buf[rule_pos]);
395 break;
396
397 case RULE_OP_MANGLE_SWITCH_FIRST:
398 SET_NAME (rule, rule_buf[rule_pos]);
399 break;
400
401 case RULE_OP_MANGLE_SWITCH_LAST:
402 SET_NAME (rule, rule_buf[rule_pos]);
403 break;
404
405 case RULE_OP_MANGLE_SWITCH_AT:
406 SET_NAME (rule, rule_buf[rule_pos]);
407 SET_P0_CONV (rule, rule_buf[rule_pos]);
408 SET_P1_CONV (rule, rule_buf[rule_pos]);
409 break;
410
411 case RULE_OP_MANGLE_CHR_SHIFTL:
412 SET_NAME (rule, rule_buf[rule_pos]);
413 SET_P0_CONV (rule, rule_buf[rule_pos]);
414 break;
415
416 case RULE_OP_MANGLE_CHR_SHIFTR:
417 SET_NAME (rule, rule_buf[rule_pos]);
418 SET_P0_CONV (rule, rule_buf[rule_pos]);
419 break;
420
421 case RULE_OP_MANGLE_CHR_INCR:
422 SET_NAME (rule, rule_buf[rule_pos]);
423 SET_P0_CONV (rule, rule_buf[rule_pos]);
424 break;
425
426 case RULE_OP_MANGLE_CHR_DECR:
427 SET_NAME (rule, rule_buf[rule_pos]);
428 SET_P0_CONV (rule, rule_buf[rule_pos]);
429 break;
430
431 case RULE_OP_MANGLE_REPLACE_NP1:
432 SET_NAME (rule, rule_buf[rule_pos]);
433 SET_P0_CONV (rule, rule_buf[rule_pos]);
434 break;
435
436 case RULE_OP_MANGLE_REPLACE_NM1:
437 SET_NAME (rule, rule_buf[rule_pos]);
438 SET_P0_CONV (rule, rule_buf[rule_pos]);
439 break;
440
441 case RULE_OP_MANGLE_DUPEBLOCK_FIRST:
442 SET_NAME (rule, rule_buf[rule_pos]);
443 SET_P0_CONV (rule, rule_buf[rule_pos]);
444 break;
445
446 case RULE_OP_MANGLE_DUPEBLOCK_LAST:
447 SET_NAME (rule, rule_buf[rule_pos]);
448 SET_P0_CONV (rule, rule_buf[rule_pos]);
449 break;
450
451 case RULE_OP_MANGLE_TITLE:
452 SET_NAME (rule, rule_buf[rule_pos]);
453 break;
454
455 case RULE_OP_MANGLE_TITLE_SEP:
456 SET_NAME (rule, rule_buf[rule_pos]);
457 SET_P0 (rule, rule_buf[rule_pos]);
458 break;
459
460 case RULE_OP_MANGLE_TOGGLE_AT_SEP:
461 SET_NAME (rule, rule_buf[rule_pos]);
462 SET_P0_CONV (rule, rule_buf[rule_pos]);
463 SET_P1 (rule, rule_buf[rule_pos]);
464 break;
465
466 default:
467 return -1;
468 }
469 }
470
471 if (rule_pos < rule_len) return -1;
472
473 return 0;
474 }
475
kernel_rule_to_cpu_rule(char * rule_buf,kernel_rule_t * rule)476 int kernel_rule_to_cpu_rule (char *rule_buf, kernel_rule_t *rule)
477 {
478 u32 rule_cnt;
479 u32 rule_pos;
480 u32 rule_len = HCBUFSIZ_LARGE - 1; // maximum possible len
481
482 for (rule_cnt = 0, rule_pos = 0; rule_pos < rule_len && rule_cnt < MAX_KERNEL_RULES; rule_pos++, rule_cnt++)
483 {
484 char rule_cmd;
485
486 GET_NAME (rule);
487
488 if (rule_cnt > 0) rule_buf[rule_pos++] = ' ';
489
490 switch (rule_cmd)
491 {
492 case RULE_OP_MANGLE_NOOP:
493 rule_buf[rule_pos] = rule_cmd;
494 break;
495
496 case RULE_OP_MANGLE_LREST:
497 rule_buf[rule_pos] = rule_cmd;
498 break;
499
500 case RULE_OP_MANGLE_UREST:
501 rule_buf[rule_pos] = rule_cmd;
502 break;
503
504 case RULE_OP_MANGLE_LREST_UFIRST:
505 rule_buf[rule_pos] = rule_cmd;
506 break;
507
508 case RULE_OP_MANGLE_UREST_LFIRST:
509 rule_buf[rule_pos] = rule_cmd;
510 break;
511
512 case RULE_OP_MANGLE_TREST:
513 rule_buf[rule_pos] = rule_cmd;
514 break;
515
516 case RULE_OP_MANGLE_TOGGLE_AT:
517 rule_buf[rule_pos] = rule_cmd;
518 GET_P0_CONV (rule);
519 break;
520
521 case RULE_OP_MANGLE_REVERSE:
522 rule_buf[rule_pos] = rule_cmd;
523 break;
524
525 case RULE_OP_MANGLE_DUPEWORD:
526 rule_buf[rule_pos] = rule_cmd;
527 break;
528
529 case RULE_OP_MANGLE_DUPEWORD_TIMES:
530 rule_buf[rule_pos] = rule_cmd;
531 GET_P0_CONV (rule);
532 break;
533
534 case RULE_OP_MANGLE_REFLECT:
535 rule_buf[rule_pos] = rule_cmd;
536 break;
537
538 case RULE_OP_MANGLE_ROTATE_LEFT:
539 rule_buf[rule_pos] = rule_cmd;
540 break;
541
542 case RULE_OP_MANGLE_ROTATE_RIGHT:
543 rule_buf[rule_pos] = rule_cmd;
544 break;
545
546 case RULE_OP_MANGLE_APPEND:
547 rule_buf[rule_pos] = rule_cmd;
548 GET_P0 (rule);
549 break;
550
551 case RULE_OP_MANGLE_PREPEND:
552 rule_buf[rule_pos] = rule_cmd;
553 GET_P0 (rule);
554 break;
555
556 case RULE_OP_MANGLE_DELETE_FIRST:
557 rule_buf[rule_pos] = rule_cmd;
558 break;
559
560 case RULE_OP_MANGLE_DELETE_LAST:
561 rule_buf[rule_pos] = rule_cmd;
562 break;
563
564 case RULE_OP_MANGLE_DELETE_AT:
565 rule_buf[rule_pos] = rule_cmd;
566 GET_P0_CONV (rule);
567 break;
568
569 case RULE_OP_MANGLE_EXTRACT:
570 rule_buf[rule_pos] = rule_cmd;
571 GET_P0_CONV (rule);
572 GET_P1_CONV (rule);
573 break;
574
575 case RULE_OP_MANGLE_OMIT:
576 rule_buf[rule_pos] = rule_cmd;
577 GET_P0_CONV (rule);
578 GET_P1_CONV (rule);
579 break;
580
581 case RULE_OP_MANGLE_INSERT:
582 rule_buf[rule_pos] = rule_cmd;
583 GET_P0_CONV (rule);
584 GET_P1 (rule);
585 break;
586
587 case RULE_OP_MANGLE_OVERSTRIKE:
588 rule_buf[rule_pos] = rule_cmd;
589 GET_P0_CONV (rule);
590 GET_P1 (rule);
591 break;
592
593 case RULE_OP_MANGLE_TRUNCATE_AT:
594 rule_buf[rule_pos] = rule_cmd;
595 GET_P0_CONV (rule);
596 break;
597
598 case RULE_OP_MANGLE_REPLACE:
599 rule_buf[rule_pos] = rule_cmd;
600 GET_P0 (rule);
601 GET_P1 (rule);
602 break;
603
604 case RULE_OP_MANGLE_PURGECHAR:
605 rule_buf[rule_pos] = rule_cmd;
606 GET_P0 (rule);
607 break;
608
609 case RULE_OP_MANGLE_TOGGLECASE_REC:
610 return -1;
611
612 case RULE_OP_MANGLE_DUPECHAR_FIRST:
613 rule_buf[rule_pos] = rule_cmd;
614 GET_P0_CONV (rule);
615 break;
616
617 case RULE_OP_MANGLE_DUPECHAR_LAST:
618 rule_buf[rule_pos] = rule_cmd;
619 GET_P0_CONV (rule);
620 break;
621
622 case RULE_OP_MANGLE_DUPECHAR_ALL:
623 rule_buf[rule_pos] = rule_cmd;
624 break;
625
626 case RULE_OP_MANGLE_SWITCH_FIRST:
627 rule_buf[rule_pos] = rule_cmd;
628 break;
629
630 case RULE_OP_MANGLE_SWITCH_LAST:
631 rule_buf[rule_pos] = rule_cmd;
632 break;
633
634 case RULE_OP_MANGLE_SWITCH_AT:
635 rule_buf[rule_pos] = rule_cmd;
636 GET_P0_CONV (rule);
637 GET_P1_CONV (rule);
638 break;
639
640 case RULE_OP_MANGLE_CHR_SHIFTL:
641 rule_buf[rule_pos] = rule_cmd;
642 GET_P0_CONV (rule);
643 break;
644
645 case RULE_OP_MANGLE_CHR_SHIFTR:
646 rule_buf[rule_pos] = rule_cmd;
647 GET_P0_CONV (rule);
648 break;
649
650 case RULE_OP_MANGLE_CHR_INCR:
651 rule_buf[rule_pos] = rule_cmd;
652 GET_P0_CONV (rule);
653 break;
654
655 case RULE_OP_MANGLE_CHR_DECR:
656 rule_buf[rule_pos] = rule_cmd;
657 GET_P0_CONV (rule);
658 break;
659
660 case RULE_OP_MANGLE_REPLACE_NP1:
661 rule_buf[rule_pos] = rule_cmd;
662 GET_P0_CONV (rule);
663 break;
664
665 case RULE_OP_MANGLE_REPLACE_NM1:
666 rule_buf[rule_pos] = rule_cmd;
667 GET_P0_CONV (rule);
668 break;
669
670 case RULE_OP_MANGLE_DUPEBLOCK_FIRST:
671 rule_buf[rule_pos] = rule_cmd;
672 GET_P0_CONV (rule);
673 break;
674
675 case RULE_OP_MANGLE_DUPEBLOCK_LAST:
676 rule_buf[rule_pos] = rule_cmd;
677 GET_P0_CONV (rule);
678 break;
679
680 case RULE_OP_MANGLE_TITLE:
681 rule_buf[rule_pos] = rule_cmd;
682 break;
683
684 case RULE_OP_MANGLE_TITLE_SEP:
685 rule_buf[rule_pos] = rule_cmd;
686 GET_P0 (rule);
687 break;
688
689 case RULE_OP_MANGLE_TOGGLE_AT_SEP:
690 rule_buf[rule_pos] = rule_cmd;
691 GET_P0_CONV (rule);
692 GET_P1 (rule);
693 break;
694
695 case 0:
696 if (rule_pos == 0) return -1;
697 return rule_pos - 1;
698
699 default:
700 return -1;
701 }
702 }
703
704 return rule_pos;
705 }
706
kernel_rules_has_noop(const kernel_rule_t * kernel_rules_buf,const u32 kernel_rules_cnt)707 bool kernel_rules_has_noop (const kernel_rule_t *kernel_rules_buf, const u32 kernel_rules_cnt)
708 {
709 for (u32 kernel_rules_pos = 0; kernel_rules_pos < kernel_rules_cnt; kernel_rules_pos++)
710 {
711 if (kernel_rules_buf[kernel_rules_pos].cmds[0] != RULE_OP_MANGLE_NOOP) continue;
712 if (kernel_rules_buf[kernel_rules_pos].cmds[1] != 0) continue;
713
714 return true;
715 }
716
717 return false;
718 }
719
kernel_rules_load(hashcat_ctx_t * hashcat_ctx,kernel_rule_t ** out_buf,u32 * out_cnt)720 int kernel_rules_load (hashcat_ctx_t *hashcat_ctx, kernel_rule_t **out_buf, u32 *out_cnt)
721 {
722 const user_options_t *user_options = hashcat_ctx->user_options;
723
724 /**
725 * load rules
726 */
727
728 u32 *all_kernel_rules_cnt = NULL;
729
730 kernel_rule_t **all_kernel_rules_buf = NULL;
731
732 if (user_options->rp_files_cnt)
733 {
734 all_kernel_rules_cnt = (u32 *) hccalloc (user_options->rp_files_cnt, sizeof (u32));
735
736 all_kernel_rules_buf = (kernel_rule_t **) hccalloc (user_options->rp_files_cnt, sizeof (kernel_rule_t *));
737 }
738
739 char *rule_buf = (char *) hcmalloc (HCBUFSIZ_LARGE);
740
741 u32 rule_len = 0;
742
743 for (u32 i = 0; i < user_options->rp_files_cnt; i++)
744 {
745 u32 kernel_rules_avail = 0;
746
747 u32 kernel_rules_cnt = 0;
748
749 kernel_rule_t *kernel_rules_buf = NULL;
750
751 char *rp_file = user_options->rp_files[i];
752
753 HCFILE fp;
754
755 u32 rule_line = 0;
756
757 if (hc_fopen (&fp, rp_file, "rb") == false)
758 {
759 event_log_error (hashcat_ctx, "%s: %s", rp_file, strerror (errno));
760
761 hcfree (all_kernel_rules_cnt);
762 hcfree (all_kernel_rules_buf);
763
764 hcfree (rule_buf);
765
766 return -1;
767 }
768
769 while (!hc_feof (&fp))
770 {
771 rule_len = (u32) fgetl (&fp, rule_buf, HCBUFSIZ_LARGE);
772
773 rule_line++;
774
775 if (rule_len == 0) continue;
776
777 if (rule_buf[0] == '#') continue;
778
779 if (kernel_rules_avail == kernel_rules_cnt)
780 {
781 kernel_rules_buf = (kernel_rule_t *) hcrealloc (kernel_rules_buf, kernel_rules_avail * sizeof (kernel_rule_t), INCR_RULES * sizeof (kernel_rule_t));
782
783 kernel_rules_avail += INCR_RULES;
784 }
785
786 char in[RP_PASSWORD_SIZE];
787 char out[RP_PASSWORD_SIZE];
788
789 memset (in, 0, sizeof (in));
790 memset (out, 0, sizeof (out));
791
792 int result = _old_apply_rule (rule_buf, rule_len, in, 1, out);
793
794 if (result == -1)
795 {
796 event_log_warning (hashcat_ctx, "Skipping invalid or unsupported rule in file %s on line %u: %s", rp_file, rule_line, rule_buf);
797
798 continue;
799 }
800
801 if (cpu_rule_to_kernel_rule (rule_buf, rule_len, &kernel_rules_buf[kernel_rules_cnt]) == -1)
802 {
803 event_log_warning (hashcat_ctx, "Cannot convert rule for use on OpenCL device in file %s on line %u: %s", rp_file, rule_line, rule_buf);
804
805 memset (&kernel_rules_buf[kernel_rules_cnt], 0, sizeof (kernel_rule_t)); // needs to be cleared otherwise we could have some remaining data
806
807 continue;
808 }
809
810 kernel_rules_cnt++;
811 }
812
813 hc_fclose (&fp);
814
815 all_kernel_rules_cnt[i] = kernel_rules_cnt;
816 all_kernel_rules_buf[i] = kernel_rules_buf;
817 }
818
819 hcfree (rule_buf);
820
821 /**
822 * merge rules
823 */
824
825 u32 kernel_rules_cnt = 1;
826
827 u32 *repeats = (u32 *) hccalloc (user_options->rp_files_cnt + 1, sizeof (u32));
828
829 repeats[0] = kernel_rules_cnt;
830
831 for (u32 i = 0; i < user_options->rp_files_cnt; i++)
832 {
833 kernel_rules_cnt *= all_kernel_rules_cnt[i];
834
835 repeats[i + 1] = kernel_rules_cnt;
836 }
837
838 kernel_rule_t *kernel_rules_buf = (kernel_rule_t *) hccalloc (kernel_rules_cnt, sizeof (kernel_rule_t));
839
840 for (u32 i = 0; i < kernel_rules_cnt; i++)
841 {
842 u32 out_pos = 0;
843
844 kernel_rule_t *out = &kernel_rules_buf[i];
845
846 for (u32 j = 0; j < user_options->rp_files_cnt; j++)
847 {
848 u32 in_off = (i / repeats[j]) % all_kernel_rules_cnt[j];
849 u32 in_pos;
850
851 kernel_rule_t *in = &all_kernel_rules_buf[j][in_off];
852
853 for (in_pos = 0; in->cmds[in_pos]; in_pos++, out_pos++)
854 {
855 if (out_pos == RULES_MAX - 1)
856 {
857 // event_log_warning (hashcat_ctx, "Truncated chaining of rules %d and %d - maximum functions per rule exceeded.", i, in_off);
858
859 break;
860 }
861
862 out->cmds[out_pos] = in->cmds[in_pos];
863 }
864 }
865 }
866
867 hcfree (repeats);
868
869 hcfree (all_kernel_rules_cnt);
870 hcfree (all_kernel_rules_buf);
871
872 if (kernel_rules_cnt == 0)
873 {
874 event_log_error (hashcat_ctx, "No valid rules left.");
875
876 hcfree (kernel_rules_buf);
877
878 return -1;
879 }
880
881 *out_cnt = kernel_rules_cnt;
882 *out_buf = kernel_rules_buf;
883
884 return 0;
885 }
886
kernel_rules_generate(hashcat_ctx_t * hashcat_ctx,kernel_rule_t ** out_buf,u32 * out_cnt,const char * rp_gen_func_selection)887 int kernel_rules_generate (hashcat_ctx_t *hashcat_ctx, kernel_rule_t **out_buf, u32 *out_cnt, const char *rp_gen_func_selection)
888 {
889 const user_options_t *user_options = hashcat_ctx->user_options;
890
891 u32 kernel_rules_cnt = 0;
892 kernel_rule_t *kernel_rules_buf = (kernel_rule_t *) hccalloc (user_options->rp_gen, sizeof (kernel_rule_t));
893
894 // operator selection
895
896 rp_gen_ops_t rp_gen_ops;
897
898 rp_gen_ops.grp_op_nop_selection = hcmalloc (sizeof (grp_op_nop));
899 rp_gen_ops.grp_op_pos_p0_selection = hcmalloc (sizeof (grp_op_pos_p0));
900 rp_gen_ops.grp_op_pos_p1_selection = hcmalloc (sizeof (grp_op_pos_p1));
901 rp_gen_ops.grp_op_chr_selection = hcmalloc (sizeof (grp_op_chr));
902 rp_gen_ops.grp_op_chr_chr_selection = hcmalloc (sizeof (grp_op_chr_chr));
903 rp_gen_ops.grp_op_pos_chr_selection = hcmalloc (sizeof (grp_op_pos_chr));
904 rp_gen_ops.grp_op_pos_pos0_selection = hcmalloc (sizeof (grp_op_pos_pos0));
905 rp_gen_ops.grp_op_pos_pos1_selection = hcmalloc (sizeof (grp_op_pos_pos1));
906
907 rp_gen_ops.grp_op_nop_cnt = 0;
908 rp_gen_ops.grp_op_pos_p0_cnt = 0;
909 rp_gen_ops.grp_op_pos_p1_cnt = 0;
910 rp_gen_ops.grp_op_chr_cnt = 0;
911 rp_gen_ops.grp_op_chr_chr_cnt = 0;
912 rp_gen_ops.grp_op_pos_chr_cnt = 0;
913 rp_gen_ops.grp_op_pos_pos0_cnt = 0;
914 rp_gen_ops.grp_op_pos_pos1_cnt = 0;
915
916 rp_gen_ops.grp_op_alias_cnt = 0;
917
918 for (size_t i = 0; i < sizeof (grp_op_nop); i++)
919 {
920 if (rp_gen_func_selection == NULL)
921 {
922 rp_gen_ops.grp_op_nop_selection[rp_gen_ops.grp_op_nop_cnt] = grp_op_nop[i];
923
924 rp_gen_ops.grp_op_nop_cnt++;
925 }
926 else
927 {
928 if (strchr (rp_gen_func_selection, grp_op_nop[i]) == NULL) continue;
929
930 rp_gen_ops.grp_op_nop_selection[rp_gen_ops.grp_op_nop_cnt] = grp_op_nop[i];
931
932 rp_gen_ops.grp_op_nop_cnt++;
933 }
934 }
935
936 for (size_t i = 0; i < sizeof (grp_op_pos_p0); i++)
937 {
938 if (rp_gen_func_selection == NULL)
939 {
940 rp_gen_ops.grp_op_pos_p0_selection[rp_gen_ops.grp_op_pos_p0_cnt] = grp_op_nop[i];
941
942 rp_gen_ops.grp_op_pos_p0_cnt++;
943 }
944 else
945 {
946 if (strchr (rp_gen_func_selection, grp_op_pos_p0[i]) == NULL) continue;
947
948 rp_gen_ops.grp_op_pos_p0_selection[rp_gen_ops.grp_op_pos_p0_cnt] = grp_op_pos_p0[i];
949
950 rp_gen_ops.grp_op_pos_p0_cnt++;
951 }
952 }
953
954 for (size_t i = 0; i < sizeof (grp_op_pos_p1); i++)
955 {
956 if (rp_gen_func_selection == NULL)
957 {
958 rp_gen_ops.grp_op_pos_p1_selection[rp_gen_ops.grp_op_pos_p1_cnt] = grp_op_pos_p1[i];
959
960 rp_gen_ops.grp_op_pos_p1_cnt++;
961 }
962 else
963 {
964 if (strchr (rp_gen_func_selection, grp_op_pos_p1[i]) == NULL) continue;
965
966 rp_gen_ops.grp_op_pos_p1_selection[rp_gen_ops.grp_op_pos_p1_cnt] = grp_op_pos_p1[i];
967
968 rp_gen_ops.grp_op_pos_p1_cnt++;
969 }
970 }
971
972 for (size_t i = 0; i < sizeof (grp_op_chr); i++)
973 {
974 if (rp_gen_func_selection == NULL)
975 {
976 rp_gen_ops.grp_op_chr_selection[rp_gen_ops.grp_op_chr_cnt] = grp_op_chr[i];
977
978 rp_gen_ops.grp_op_chr_cnt++;
979 }
980 else
981 {
982 if (strchr (rp_gen_func_selection, grp_op_chr[i]) == NULL) continue;
983
984 rp_gen_ops.grp_op_chr_selection[rp_gen_ops.grp_op_chr_cnt] = grp_op_chr[i];
985
986 rp_gen_ops.grp_op_chr_cnt++;
987 }
988 }
989
990 for (size_t i = 0; i < sizeof (grp_op_chr_chr); i++)
991 {
992 if (rp_gen_func_selection == NULL)
993 {
994 rp_gen_ops.grp_op_chr_chr_selection[rp_gen_ops.grp_op_chr_chr_cnt] = grp_op_chr_chr[i];
995
996 rp_gen_ops.grp_op_chr_chr_cnt++;
997 }
998 else
999 {
1000 if (strchr (rp_gen_func_selection, grp_op_chr_chr[i]) == NULL) continue;
1001
1002 rp_gen_ops.grp_op_chr_chr_selection[rp_gen_ops.grp_op_chr_chr_cnt] = grp_op_chr_chr[i];
1003
1004 rp_gen_ops.grp_op_chr_chr_cnt++;
1005 }
1006 }
1007
1008 for (size_t i = 0; i < sizeof (grp_op_pos_chr); i++)
1009 {
1010 if (rp_gen_func_selection == NULL)
1011 {
1012 rp_gen_ops.grp_op_pos_chr_selection[rp_gen_ops.grp_op_pos_chr_cnt] = grp_op_pos_chr[i];
1013
1014 rp_gen_ops.grp_op_pos_chr_cnt++;
1015 }
1016 else
1017 {
1018 if (strchr (rp_gen_func_selection, grp_op_pos_chr[i]) == NULL) continue;
1019
1020 rp_gen_ops.grp_op_pos_chr_selection[rp_gen_ops.grp_op_pos_chr_cnt] = grp_op_pos_chr[i];
1021
1022 rp_gen_ops.grp_op_pos_chr_cnt++;
1023 }
1024 }
1025
1026 for (size_t i = 0; i < sizeof (grp_op_pos_pos0); i++)
1027 {
1028 if (rp_gen_func_selection == NULL)
1029 {
1030 rp_gen_ops.grp_op_pos_pos0_selection[rp_gen_ops.grp_op_pos_pos0_cnt] = grp_op_pos_pos0[i];
1031
1032 rp_gen_ops.grp_op_pos_pos0_cnt++;
1033 }
1034 else
1035 {
1036 if (strchr (rp_gen_func_selection, grp_op_pos_pos0[i]) == NULL) continue;
1037
1038 rp_gen_ops.grp_op_pos_pos0_selection[rp_gen_ops.grp_op_pos_pos0_cnt] = grp_op_pos_pos0[i];
1039
1040 rp_gen_ops.grp_op_pos_pos0_cnt++;
1041 }
1042 }
1043
1044 for (size_t i = 0; i < sizeof (grp_op_pos_pos1); i++)
1045 {
1046 if (rp_gen_func_selection == NULL)
1047 {
1048 rp_gen_ops.grp_op_pos_pos1_selection[rp_gen_ops.grp_op_pos_pos1_cnt] = grp_op_pos_pos1[i];
1049
1050 rp_gen_ops.grp_op_pos_pos1_cnt++;
1051 }
1052 else
1053 {
1054 if (strchr (rp_gen_func_selection, grp_op_pos_pos1[i]) == NULL) continue;
1055
1056 rp_gen_ops.grp_op_pos_pos1_selection[rp_gen_ops.grp_op_pos_pos1_cnt] = grp_op_pos_pos1[i];
1057
1058 rp_gen_ops.grp_op_pos_pos1_cnt++;
1059 }
1060 }
1061
1062 if (rp_gen_ops.grp_op_nop_cnt) { rp_gen_ops.grp_op_alias_buf[rp_gen_ops.grp_op_alias_cnt++] = 0; };
1063 if (rp_gen_ops.grp_op_pos_p0_cnt) { rp_gen_ops.grp_op_alias_buf[rp_gen_ops.grp_op_alias_cnt++] = 1; };
1064 if (rp_gen_ops.grp_op_pos_p1_cnt) { rp_gen_ops.grp_op_alias_buf[rp_gen_ops.grp_op_alias_cnt++] = 2; };
1065 if (rp_gen_ops.grp_op_chr_cnt) { rp_gen_ops.grp_op_alias_buf[rp_gen_ops.grp_op_alias_cnt++] = 3; };
1066 if (rp_gen_ops.grp_op_chr_chr_cnt) { rp_gen_ops.grp_op_alias_buf[rp_gen_ops.grp_op_alias_cnt++] = 4; };
1067 if (rp_gen_ops.grp_op_pos_chr_cnt) { rp_gen_ops.grp_op_alias_buf[rp_gen_ops.grp_op_alias_cnt++] = 5; };
1068 if (rp_gen_ops.grp_op_pos_pos0_cnt) { rp_gen_ops.grp_op_alias_buf[rp_gen_ops.grp_op_alias_cnt++] = 6; };
1069 if (rp_gen_ops.grp_op_pos_pos1_cnt) { rp_gen_ops.grp_op_alias_buf[rp_gen_ops.grp_op_alias_cnt++] = 7; };
1070
1071 char *rule_buf = (char *) hcmalloc (RP_RULE_SIZE);
1072
1073 for (kernel_rules_cnt = 0; kernel_rules_cnt < user_options->rp_gen; kernel_rules_cnt++)
1074 {
1075 memset (rule_buf, 0, RP_RULE_SIZE);
1076
1077 const int rule_len = generate_random_rule (rule_buf, user_options->rp_gen_func_min, user_options->rp_gen_func_max, &rp_gen_ops);
1078
1079 if (cpu_rule_to_kernel_rule (rule_buf, rule_len, &kernel_rules_buf[kernel_rules_cnt]) == -1) continue;
1080 }
1081
1082 hcfree (rule_buf);
1083
1084 hcfree (rp_gen_ops.grp_op_nop_selection);
1085 hcfree (rp_gen_ops.grp_op_pos_p0_selection);
1086 hcfree (rp_gen_ops.grp_op_pos_p1_selection);
1087 hcfree (rp_gen_ops.grp_op_chr_selection);
1088 hcfree (rp_gen_ops.grp_op_chr_chr_selection);
1089 hcfree (rp_gen_ops.grp_op_pos_chr_selection);
1090 hcfree (rp_gen_ops.grp_op_pos_pos0_selection);
1091 hcfree (rp_gen_ops.grp_op_pos_pos1_selection);
1092
1093 *out_cnt = kernel_rules_cnt;
1094 *out_buf = kernel_rules_buf;
1095
1096 return 0;
1097 }
1098