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