xref: /aosp_15_r20/external/AFLplusplus/src/afl-fuzz-redqueen.c (revision 08b48e0b10e97b33e7b60c5b6e2243bd915777f2)
1 /*
2    american fuzzy lop++ - redqueen implementation on top of cmplog
3    ---------------------------------------------------------------
4 
5    Originally written by Michal Zalewski
6 
7    Forkserver design by Jann Horn <[email protected]>
8 
9    Now maintained by by Marc Heuse <[email protected]>,
10                         Heiko Eißfeldt <[email protected]> and
11                         Andrea Fioraldi <[email protected]>
12 
13    Copyright 2016, 2017 Google Inc. All rights reserved.
14    Copyright 2019-2024 AFLplusplus Project. All rights reserved.
15 
16    Licensed under the Apache License, Version 2.0 (the "License");
17    you may not use this file except in compliance with the License.
18    You may obtain a copy of the License at:
19 
20      https://www.apache.org/licenses/LICENSE-2.0
21 
22    Shared code to handle the shared memory. This is used by the fuzzer
23    as well the other components like afl-tmin, afl-showmap, etc...
24 
25  */
26 
27 #include <limits.h>
28 #include "afl-fuzz.h"
29 #include "cmplog.h"
30 
31 // #define _DEBUG
32 // #define CMPLOG_INTROSPECTION
33 
34 // CMP attribute enum
35 enum {
36 
37   IS_EQUAL = 1,    // arithemtic equal comparison
38   IS_GREATER = 2,  // arithmetic greater comparison
39   IS_LESSER = 4,   // arithmetic lesser comparison
40   IS_FP = 8,       // is a floating point, not an integer
41   /* --- below are internal settings, not from target cmplog */
42   IS_FP_MOD = 16,    // arithemtic changed floating point
43   IS_INT_MOD = 32,   // arithmetic changed integer
44   IS_TRANSFORM = 64  // transformed integer
45 
46 };
47 
48 // add to dictionary enum
49 // DEFAULT = 1, notTXT = 2, FOUND = 4, notSAME = 8
50 enum {
51 
52   DICT_ADD_NEVER = 0,
53   DICT_ADD_NOTFOUND_SAME_TXT = 1,
54   DICT_ADD_NOTFOUND_SAME = 3,
55   DICT_ADD_FOUND_SAME_TXT = 5,
56   DICT_ADD_FOUND_SAME = 7,
57   DICT_ADD_NOTFOUND_TXT = 9,
58   DICT_ADD_NOTFOUND = 11,
59   DICT_ADD_FOUND_TXT = 13,
60   DICT_ADD_FOUND = 15,
61   DICT_ADD_ANY = DICT_ADD_FOUND
62 
63 };
64 
65 // CMPLOG LVL
66 enum {
67 
68   LVL1 = 1,  // Integer solving
69   LVL2 = 2,  // unused except for setting the queue entry
70   LVL3 = 4   // expensive tranformations
71 
72 };
73 
74 #define DICT_ADD_STRATEGY DICT_ADD_FOUND_SAME
75 
76 struct range {
77 
78   u32           start;
79   u32           end;
80   struct range *next;
81   struct range *prev;
82   u8            ok;
83 
84 };
85 
86 static u32 hshape;
87 static u64 screen_update;
88 static u64 last_update;
89 
add_range(struct range * ranges,u32 start,u32 end)90 static struct range *add_range(struct range *ranges, u32 start, u32 end) {
91 
92   struct range *r = ck_alloc_nozero(sizeof(struct range));
93   r->start = start;
94   r->end = end;
95   r->next = ranges;
96   r->ok = 0;
97   if (likely(ranges)) ranges->prev = r;
98   return r;
99 
100 }
101 
pop_biggest_range(struct range ** ranges)102 static struct range *pop_biggest_range(struct range **ranges) {
103 
104   struct range *r = *ranges;
105   struct range *rmax = NULL;
106   u32           max_size = 0;
107 
108   while (r) {
109 
110     if (!r->ok) {
111 
112       u32 s = 1 + r->end - r->start;
113 
114       if (s >= max_size) {
115 
116         max_size = s;
117         rmax = r;
118 
119       }
120 
121     }
122 
123     r = r->next;
124 
125   }
126 
127   return rmax;
128 
129 }
130 
131 #ifdef _DEBUG
dump(char * txt,u8 * buf,u32 len)132 static void dump(char *txt, u8 *buf, u32 len) {
133 
134   u32 i;
135   fprintf(stderr, "DUMP %s %016llx ", txt, hash64(buf, len, HASH_CONST));
136   for (i = 0; i < len; i++)
137     fprintf(stderr, "%02x", buf[i]);
138   fprintf(stderr, "\n");
139 
140 }
141 
142 /*
143 static void dump_file(char *path, char *name, u32 counter, u8 *buf, u32 len) {
144 
145   char fn[4096];
146   if (!path) path = ".";
147   snprintf(fn, sizeof(fn), "%s/%s%d", path, name, counter);
148   int fd = open(fn, O_RDWR | O_CREAT | O_TRUNC, 0644);
149   if (fd >= 0) {
150 
151     write(fd, buf, len);
152     close(fd);
153 
154   }
155 
156 }
157 
158 */
159 
160 #endif
161 
get_exec_checksum(afl_state_t * afl,u8 * buf,u32 len,u64 * cksum)162 static u8 get_exec_checksum(afl_state_t *afl, u8 *buf, u32 len, u64 *cksum) {
163 
164   if (unlikely(common_fuzz_stuff(afl, buf, len))) { return 1; }
165 
166   *cksum = hash64(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST);
167 
168   return 0;
169 
170 }
171 
172 /* replace everything with different values */
random_replace(afl_state_t * afl,u8 * buf,u32 len)173 static void random_replace(afl_state_t *afl, u8 *buf, u32 len) {
174 
175   for (u32 i = 0; i < len; i++) {
176 
177     u8 c;
178 
179     do {
180 
181       c = rand_below(afl, 256);
182 
183     } while (c == buf[i]);
184 
185     buf[i] = c;
186 
187   }
188 
189 }
190 
191 /* replace everything with different values but stay in the same type */
type_replace(afl_state_t * afl,u8 * buf,u32 len)192 static void type_replace(afl_state_t *afl, u8 *buf, u32 len) {
193 
194   u32 i;
195   u8  c;
196   for (i = 0; i < len; ++i) {
197 
198     // wont help for UTF or non-latin charsets
199     do {
200 
201       switch (buf[i]) {
202 
203         case 'A' ... 'F':
204           c = 'A' + rand_below(afl, 1 + 'F' - 'A');
205           break;
206         case 'a' ... 'f':
207           c = 'a' + rand_below(afl, 1 + 'f' - 'a');
208           break;
209         case '0':
210           c = '1';
211           break;
212         case '1':
213           c = '0';
214           break;
215         case '2' ... '9':
216           c = '2' + rand_below(afl, 1 + '9' - '2');
217           break;
218         case 'G' ... 'Z':
219           c = 'G' + rand_below(afl, 1 + 'Z' - 'G');
220           break;
221         case 'g' ... 'z':
222           c = 'g' + rand_below(afl, 1 + 'z' - 'g');
223           break;
224         case '!' ... '*':
225           c = '!' + rand_below(afl, 1 + '*' - '!');
226           break;
227         case ',' ... '.':
228           c = ',' + rand_below(afl, 1 + '.' - ',');
229           break;
230         case ':' ... '@':
231           c = ':' + rand_below(afl, 1 + '@' - ':');
232           break;
233         case '[' ... '`':
234           c = '[' + rand_below(afl, 1 + '`' - '[');
235           break;
236         case '{' ... '~':
237           c = '{' + rand_below(afl, 1 + '~' - '{');
238           break;
239         case '+':
240           c = '/';
241           break;
242         case '/':
243           c = '+';
244           break;
245         case ' ':
246           c = '\t';
247           break;
248         case '\t':
249           c = ' ';
250           break;
251         case '\r':
252           c = '\n';
253           break;
254         case '\n':
255           c = '\r';
256           break;
257         case 0:
258           c = 1;
259           break;
260         case 1:
261           c = 0;
262           break;
263         case 0xff:
264           c = 0;
265           break;
266         default:
267           if (buf[i] < 32) {
268 
269             c = (buf[i] ^ 0x1f);
270 
271           } else {
272 
273             c = (buf[i] ^ 0x7f);  // we keep the highest bit
274 
275           }
276 
277       }
278 
279     } while (c == buf[i]);
280 
281     buf[i] = c;
282 
283   }
284 
285 }
286 
colorization(afl_state_t * afl,u8 * buf,u32 len,struct tainted ** taints)287 static u8 colorization(afl_state_t *afl, u8 *buf, u32 len,
288                        struct tainted **taints) {
289 
290   struct range   *ranges = add_range(NULL, 0, len - 1), *rng;
291   struct tainted *taint = NULL;
292   u8             *backup = ck_alloc_nozero(len);
293   u8             *changed = ck_alloc_nozero(len);
294 
295 #if defined(_DEBUG) || defined(CMPLOG_INTROSPECTION)
296   u64 start_time = get_cur_time();
297 #endif
298 
299   u64 orig_hit_cnt, new_hit_cnt, exec_cksum;
300   orig_hit_cnt = afl->queued_items + afl->saved_crashes;
301 
302   afl->stage_name = "colorization";
303   afl->stage_short = "colorization";
304   afl->stage_max = (len << 1);
305   afl->stage_cur = 0;
306 
307   // in colorization we do not classify counts, hence we have to calculate
308   // the original checksum.
309   if (unlikely(get_exec_checksum(afl, buf, len, &exec_cksum))) {
310 
311     goto checksum_fail;
312 
313   }
314 
315   memcpy(backup, buf, len);
316   memcpy(changed, buf, len);
317   if (afl->cmplog_random_colorization) {
318 
319     random_replace(afl, changed, len);
320 
321   } else {
322 
323     type_replace(afl, changed, len);
324 
325   }
326 
327   while ((rng = pop_biggest_range(&ranges)) != NULL &&
328          afl->stage_cur < afl->stage_max) {
329 
330     u32 s = 1 + rng->end - rng->start;
331 
332     memcpy(buf + rng->start, changed + rng->start, s);
333 
334     u64 cksum = 0;
335     u64 start_us = get_cur_time_us();
336     if (unlikely(get_exec_checksum(afl, buf, len, &cksum))) {
337 
338       goto checksum_fail;
339 
340     }
341 
342     u64 stop_us = get_cur_time_us();
343 
344     /* Discard if the mutations change the path or if it is too decremental
345       in speed - how could the same path have a much different speed
346       though ...*/
347     if (cksum != exec_cksum ||
348         (unlikely(stop_us - start_us > 3 * afl->queue_cur->exec_us) &&
349          likely(!afl->fixed_seed))) {
350 
351       memcpy(buf + rng->start, backup + rng->start, s);
352 
353       if (s > 1) {  // to not add 0 size ranges
354 
355         ranges = add_range(ranges, rng->start, rng->start - 1 + s / 2);
356         ranges = add_range(ranges, rng->start + s / 2, rng->end);
357 
358       }
359 
360       if (ranges == rng) {
361 
362         ranges = rng->next;
363         if (ranges) { ranges->prev = NULL; }
364 
365       } else if (rng->next) {
366 
367         rng->prev->next = rng->next;
368         rng->next->prev = rng->prev;
369 
370       } else {
371 
372         if (rng->prev) { rng->prev->next = NULL; }
373 
374       }
375 
376       free(rng);
377 
378     } else {
379 
380       rng->ok = 1;
381 
382     }
383 
384     if (unlikely(++afl->stage_cur % screen_update == 0)) { show_stats(afl); };
385 
386   }
387 
388   rng = ranges;
389   while (rng) {
390 
391     rng = rng->next;
392 
393   }
394 
395   u32 i = 1;
396   u32 positions = 0;
397   while (i) {
398 
399   restart:
400     i = 0;
401     struct range *r = NULL;
402     u32           pos = (u32)-1;
403     rng = ranges;
404 
405     while (rng) {
406 
407       if (rng->ok == 1 && rng->start < pos) {
408 
409         if (taint && taint->pos + taint->len == rng->start) {
410 
411           taint->len += (1 + rng->end - rng->start);
412           positions += (1 + rng->end - rng->start);
413           rng->ok = 2;
414           goto restart;
415 
416         } else {
417 
418           r = rng;
419           pos = rng->start;
420 
421         }
422 
423       }
424 
425       rng = rng->next;
426 
427     }
428 
429     if (r) {
430 
431       struct tainted *t = ck_alloc_nozero(sizeof(struct tainted));
432       t->pos = r->start;
433       t->len = 1 + r->end - r->start;
434       positions += (1 + r->end - r->start);
435       if (likely(taint)) { taint->prev = t; }
436       t->next = taint;
437       t->prev = NULL;
438       taint = t;
439       r->ok = 2;
440       i = 1;
441 
442     }
443 
444   }
445 
446   /* temporary: clean ranges */
447   while (ranges) {
448 
449     rng = ranges;
450     ranges = rng->next;
451     ck_free(rng);
452     rng = NULL;
453 
454   }
455 
456   new_hit_cnt = afl->queued_items + afl->saved_crashes;
457 
458 #if defined(_DEBUG) || defined(CMPLOG_INTROSPECTION)
459   FILE *f = stderr;
460   #ifndef _DEBUG
461   if (afl->not_on_tty) {
462 
463     char fn[4096];
464     snprintf(fn, sizeof(fn), "%s/introspection_cmplog.txt", afl->out_dir);
465     f = fopen(fn, "a");
466 
467   }
468 
469   #endif
470 
471   if (f) {
472 
473     fprintf(
474         f,
475         "Colorization: fname=%s len=%u ms=%llu result=%u execs=%u found=%llu "
476         "taint=%u ascii=%u auto_extra_before=%u\n",
477         afl->queue_cur->fname, len, get_cur_time() - start_time,
478         afl->queue_cur->colorized, afl->stage_cur, new_hit_cnt - orig_hit_cnt,
479         positions, afl->queue_cur->is_ascii ? 1 : 0, afl->a_extras_cnt);
480 
481   #ifndef _DEBUG
482     if (afl->not_on_tty) { fclose(f); }
483   #endif
484 
485   }
486 
487 #endif
488 
489   if (taint) {
490 
491     if (afl->colorize_success && afl->cmplog_lvl < 3 &&
492         (positions > CMPLOG_POSITIONS_MAX && len / positions == 1 &&
493          afl->active_items / afl->colorize_success > CMPLOG_CORPUS_PERCENT)) {
494 
495 #ifdef _DEBUG
496       fprintf(stderr, "Colorization unsatisfactory\n");
497 #endif
498 
499       *taints = NULL;
500 
501       struct tainted *t;
502       while (taint) {
503 
504         t = taint->next;
505         ck_free(taint);
506         taint = t;
507 
508       }
509 
510     } else {
511 
512       *taints = taint;
513       ++afl->colorize_success;
514 
515     }
516 
517   }
518 
519   afl->stage_finds[STAGE_COLORIZATION] += new_hit_cnt - orig_hit_cnt;
520   afl->stage_cycles[STAGE_COLORIZATION] += afl->stage_cur;
521   ck_free(backup);
522   ck_free(changed);
523 
524   return 0;
525 
526 checksum_fail:
527   while (ranges) {
528 
529     rng = ranges;
530     ranges = rng->next;
531     ck_free(rng);
532     rng = NULL;
533 
534   }
535 
536   ck_free(backup);
537   ck_free(changed);
538 
539   return 1;
540 
541 }
542 
543 ///// Input to State replacement
544 
its_fuzz(afl_state_t * afl,u8 * buf,u32 len,u8 * status)545 static u8 its_fuzz(afl_state_t *afl, u8 *buf, u32 len, u8 *status) {
546 
547   u64 orig_hit_cnt, new_hit_cnt;
548 
549   orig_hit_cnt = afl->queued_items + afl->saved_crashes;
550 
551 #ifdef _DEBUG
552   dump("DATA", buf, len);
553 #endif
554 
555   if (unlikely(common_fuzz_stuff(afl, buf, len))) { return 1; }
556 
557   new_hit_cnt = afl->queued_items + afl->saved_crashes;
558 
559   if (unlikely(new_hit_cnt != orig_hit_cnt)) {
560 
561 #ifdef _DEBUG
562     fprintf(stderr, "NEW FIND\n");
563 #endif
564     *status = 1;
565 
566   } else {
567 
568     *status = 2;
569 
570   }
571 
572   return 0;
573 
574 }
575 
strntoll(const char * str,size_t sz,char ** end,int base,long long * out)576 static int strntoll(const char *str, size_t sz, char **end, int base,
577                     long long *out) {
578 
579   char        buf[64];
580   long long   ret;
581   const char *beg = str;
582 
583   if (!str || !sz) { return 1; }
584 
585   for (; beg && sz && *beg == ' '; beg++, sz--) {};
586 
587   if (!sz) return 1;
588   if (sz >= sizeof(buf)) sz = sizeof(buf) - 1;
589 
590   memcpy(buf, beg, sz);
591   buf[sz] = '\0';
592   ret = strtoll(buf, end, base);
593   if ((ret == LLONG_MIN || ret == LLONG_MAX) && errno == ERANGE) return 1;
594   if (end) *end = (char *)beg + (*end - buf);
595   *out = ret;
596 
597   return 0;
598 
599 }
600 
strntoull(const char * str,size_t sz,char ** end,int base,unsigned long long * out)601 static int strntoull(const char *str, size_t sz, char **end, int base,
602                      unsigned long long *out) {
603 
604   char               buf[64];
605   unsigned long long ret;
606   const char        *beg = str;
607 
608   if (!str || !sz) { return 1; }
609 
610   for (; beg && sz && *beg == ' '; beg++, sz--)
611     ;
612 
613   if (!sz) return 1;
614   if (sz >= sizeof(buf)) sz = sizeof(buf) - 1;
615 
616   memcpy(buf, beg, sz);
617   buf[sz] = '\0';
618   ret = strtoull(buf, end, base);
619   if (ret == ULLONG_MAX && errno == ERANGE) return 1;
620   if (end) *end = (char *)beg + (*end - buf);
621   *out = ret;
622 
623   return 0;
624 
625 }
626 
627 static u8 hex_table_up[16] = {'0', '1', '2', '3', '4', '5', '6', '7',
628                               '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
629 static u8 hex_table_low[16] = {'0', '1', '2', '3', '4', '5', '6', '7',
630                                '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
631 static u8 hex_table[] = {0, 1, 2, 3,  4,  5,  6,  7,  8,  9,  0,  0,  0, 0,
632                          0, 0, 0, 10, 11, 12, 13, 14, 15, 0,  0,  0,  0, 0,
633                          0, 0, 0, 0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 0,
634                          0, 0, 0, 0,  0,  0,  0,  10, 11, 12, 13, 14, 15};
635 
636 // tests 2 bytes at location
is_hex(const char * str)637 static int is_hex(const char *str) {
638 
639   u32 i;
640 
641   for (i = 0; i < 2; i++) {
642 
643     switch (str[i]) {
644 
645       case '0' ... '9':
646       case 'A' ... 'F':
647       case 'a' ... 'f':
648         break;
649       default:
650         return 0;
651 
652     }
653 
654   }
655 
656   return 1;
657 
658 }
659 
660 // tests 4 bytes at location
is_base64(const char * str)661 static int is_base64(const char *str) {
662 
663   u32 i;
664 
665   for (i = 0; i < 4; i++) {
666 
667     switch (str[i]) {
668 
669       case '0' ... '9':
670       case 'A' ... 'Z':
671       case 'a' ... 'z':
672       case '+':
673       case '/':
674       case '=':
675         break;
676       default:
677         return 0;
678 
679     }
680 
681   }
682 
683   return 1;
684 
685 }
686 
687 static u8 base64_encode_table[] =
688     "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
689 static u8 base64_decode_table[] = {
690 
691     62, 0,  0,  0,  63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 0,
692     0,  0,  0,  0,  0,  0,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9,
693     10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
694     0,  0,  0,  0,  0,  0,  26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
695     36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51};
696 
from_base64(u8 * src,u8 * dst,u32 dst_len)697 static u32 from_base64(u8 *src, u8 *dst, u32 dst_len) {
698 
699   u32 i, j, v;
700   u32 len = ((dst_len / 3) << 2);
701   u32 ret = 0;
702 
703   for (i = 0, j = 0; i < len; i += 4, j += 3) {
704 
705     v = base64_decode_table[src[i] - 43];
706     v = (v << 6) | base64_decode_table[src[i + 1] - 43];
707     v = src[i + 2] == '=' ? v << 6
708                           : (v << 6) | base64_decode_table[src[i + 2] - 43];
709     v = src[i + 3] == '=' ? v << 6
710                           : (v << 6) | base64_decode_table[src[i + 3] - 43];
711 
712     dst[j] = (v >> 16) & 0xFF;
713     ++ret;
714 
715     if (src[i + 2] != '=') {
716 
717       dst[j + 1] = (v >> 8) & 0xFF;
718       ++ret;
719 
720     }
721 
722     if (src[i + 3] != '=') {
723 
724       dst[j + 2] = v & 0xFF;
725       ++ret;
726 
727     }
728 
729   }
730 
731   return ret;
732 
733 }
734 
to_base64(u8 * src,u8 * dst,u32 dst_len)735 static u32 to_base64(u8 *src, u8 *dst, u32 dst_len) {
736 
737   u32 i, j, v;
738   //  u32 len = (dst_len >> 2) * 3;
739   u32 len = (dst_len / 3) * 4;
740   if (dst_len % 3) len += 4;
741 
742   for (i = 0, j = 0; j < len; i += 3, j += 4) {
743 
744     v = src[i];
745     v = i + 1 < len ? v << 8 | src[i + 1] : v << 8;
746     v = i + 2 < len ? v << 8 | src[i + 2] : v << 8;
747 
748     dst[j] = base64_encode_table[(v >> 18) & 0x3F];
749     dst[j + 1] = base64_encode_table[(v >> 12) & 0x3F];
750 
751     if (i + 1 < dst_len) {
752 
753       dst[j + 2] = base64_encode_table[(v >> 6) & 0x3F];
754 
755     } else {
756 
757       dst[j + 2] = '=';
758 
759     }
760 
761     if (i + 2 < dst_len) {
762 
763       dst[j + 3] = base64_encode_table[v & 0x3F];
764 
765     } else {
766 
767       dst[j + 3] = '=';
768 
769     }
770 
771   }
772 
773   dst[len] = 0;
774   return len;
775 
776 }
777 
778 #ifdef WORD_SIZE_64
779 static u8 cmp_extend_encodingN(afl_state_t *afl, struct cmp_header *h,
780                                u128 pattern, u128 repl, u128 o_pattern,
781                                u128 changed_val, u8 attr, u32 idx,
782                                u32 taint_len, u8 *orig_buf, u8 *buf, u8 *cbuf,
783                                u32 len, u8 do_reverse, u8 lvl, u8 *status);
784 #endif
cmp_extend_encoding(afl_state_t * afl,struct cmp_header * h,u64 pattern,u64 repl,u64 o_pattern,u64 changed_val,u8 attr,u32 idx,u32 taint_len,u8 * orig_buf,u8 * buf,u8 * cbuf,u32 len,u8 do_reverse,u8 lvl,u8 * status)785 static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h,
786                               u64 pattern, u64 repl, u64 o_pattern,
787                               u64 changed_val, u8 attr, u32 idx, u32 taint_len,
788                               u8 *orig_buf, u8 *buf, u8 *cbuf, u32 len,
789                               u8 do_reverse, u8 lvl, u8 *status) {
790 
791   u64 *buf_64 = (u64 *)&buf[idx];
792   u32 *buf_32 = (u32 *)&buf[idx];
793   u16 *buf_16 = (u16 *)&buf[idx];
794   u8  *buf_8 = &buf[idx];
795   u64 *o_buf_64 = (u64 *)&orig_buf[idx];
796   u32 *o_buf_32 = (u32 *)&orig_buf[idx];
797   u16 *o_buf_16 = (u16 *)&orig_buf[idx];
798   u8  *o_buf_8 = &orig_buf[idx];
799 
800   u32 its_len = MIN(len - idx, taint_len);
801 
802   if (unlikely(afl->fsrv.total_execs - last_update > screen_update)) {
803 
804     show_stats(afl);
805     last_update = afl->fsrv.total_execs;
806 
807   }
808 
809   /*
810   fprintf(stderr,
811           "Encode: %llx->%llx into %llx(<-%llx) at idx=%u "
812           "taint_len=%u shape=%u attr=%u\n",
813           o_pattern, pattern, repl, changed_val, idx, taint_len,
814           hshape, attr);
815   */
816 
817   u8 bytes;
818 
819   switch (hshape) {
820 
821     case 0:
822     case 1:
823       bytes = 1;
824       break;
825     case 2:
826       bytes = 2;
827       break;
828     case 3:
829     case 4:
830       bytes = 4;
831       break;
832     default:
833       bytes = 8;
834 
835   }
836 
837   // necessary for preventing heap access overflow
838   bytes = MIN(bytes, len - idx);
839 
840   //  reverse atoi()/strnu?toll() is expensive, so we only to it in lvl 3
841   if (afl->cmplog_enable_transform && (lvl & LVL3)) {
842 
843     u8                *endptr;
844     u8                 use_num = 0, use_unum = 0;
845     unsigned long long unum = 0;
846     long long          num = 0;
847 
848     // if (afl->queue_cur->is_ascii) {
849 
850     // we first check if our input are ascii numbers that are transformed to
851     // an integer and used for comparison:
852 
853     endptr = buf_8;
854     if (strntoll(buf_8, len - idx, (char **)&endptr, 0, &num)) {
855 
856       if (!strntoull(buf_8, len - idx, (char **)&endptr, 0, &unum)) {
857 
858         use_unum = 1;
859 
860       }
861 
862     } else {
863 
864       use_num = 1;
865 
866     }
867 
868     //}
869 
870 #ifdef _DEBUG
871     if (idx == 0)
872       fprintf(stderr,
873               "ASCII is=%u use_num=%u>%lld use_unum=%u>%llu idx=%u "
874               "pattern=0x%llx\n",
875               afl->queue_cur->is_ascii, use_num, num, use_unum, unum, idx,
876               pattern);
877 #endif
878 
879     // atoi("AAA") == 0 so !num means we have to investigate
880     if (use_num && ((u64)num == pattern || !num)) {
881 
882       u8     tmp_buf[32];
883       size_t num_len = snprintf(tmp_buf, sizeof(tmp_buf), "%lld", repl);
884       size_t old_len = endptr - buf_8;
885 
886       u8 *new_buf = afl_realloc((void **)&afl->out_scratch_buf, len + num_len);
887       if (unlikely(!new_buf)) { PFATAL("alloc"); }
888 
889       memcpy(new_buf, buf, idx);
890       memcpy(new_buf + idx, tmp_buf, num_len);
891       memcpy(new_buf + idx + num_len, buf_8 + old_len, len - idx - old_len);
892 
893       if (new_buf[idx + num_len] >= '0' && new_buf[idx + num_len] <= '9') {
894 
895         new_buf[idx + num_len] = ' ';
896 
897       }
898 
899       if (unlikely(its_fuzz(afl, new_buf, len, status))) { return 1; }
900 
901     } else if (use_unum && (unum == pattern || !unum)) {
902 
903       u8     tmp_buf[32];
904       size_t num_len = snprintf(tmp_buf, sizeof(tmp_buf), "%llu", repl);
905       size_t old_len = endptr - buf_8;
906 
907       u8 *new_buf = afl_realloc((void **)&afl->out_scratch_buf, len + num_len);
908       if (unlikely(!new_buf)) { PFATAL("alloc"); }
909 
910       memcpy(new_buf, buf, idx);
911       memcpy(new_buf + idx, tmp_buf, num_len);
912       memcpy(new_buf + idx + num_len, buf_8 + old_len, len - idx - old_len);
913 
914       if (new_buf[idx + num_len] >= '0' && new_buf[idx + num_len] <= '9') {
915 
916         new_buf[idx + num_len] = ' ';
917 
918       }
919 
920       if (unlikely(its_fuzz(afl, new_buf, len, status))) { return 1; }
921 
922     }
923 
924     // Try to identify transform magic
925     if (pattern != o_pattern && repl == changed_val && attr <= IS_EQUAL) {
926 
927       u64 b_val, o_b_val, mask;
928       switch (bytes) {
929 
930         case 0:                        // cannot happen
931           b_val = o_b_val = mask = 0;  // keep the linters happy
932           break;
933         case 1: {
934 
935           u8 *ptr = (u8 *)&buf[idx];
936           u8 *o_ptr = (u8 *)&orig_buf[idx];
937           b_val = (u64)(*ptr);
938           o_b_val = (u64)(*o_ptr % 0x100);
939           mask = 0xff;
940           break;
941 
942         }
943 
944         case 2:
945         case 3: {
946 
947           u16 *ptr = (u16 *)&buf[idx];
948           u16 *o_ptr = (u16 *)&orig_buf[idx];
949           b_val = (u64)(*ptr);
950           o_b_val = (u64)(*o_ptr);
951           mask = 0xffff;
952           break;
953 
954         }
955 
956         case 4:
957         case 5:
958         case 6:
959         case 7: {
960 
961           u32 *ptr = (u32 *)&buf[idx];
962           u32 *o_ptr = (u32 *)&orig_buf[idx];
963           b_val = (u64)(*ptr);
964           o_b_val = (u64)(*o_ptr);
965           mask = 0xffffffff;
966           break;
967 
968         }
969 
970         default: {
971 
972           u64 *ptr = (u64 *)&buf[idx];
973           u64 *o_ptr = (u64 *)&orig_buf[idx];
974           b_val = (u64)(*ptr);
975           o_b_val = (u64)(*o_ptr);
976           mask = 0xffffffffffffffff;
977 
978         }
979 
980       }
981 
982       // test for arithmetic, eg. "if ((user_val - 0x1111) == 0x1234) ..."
983       s64 diff = pattern - b_val;
984       s64 o_diff = o_pattern - o_b_val;
985       /*
986              fprintf(stderr, "DIFF1 idx=%03u shape=%02u %llx-%llx=%lx\n", idx,
987                        hshape, o_pattern, o_b_val, o_diff);
988                fprintf(stderr, "DIFF1 %016llx %llx-%llx=%lx\n", repl, pattern,
989                        b_val, diff);
990       */
991       if (diff == o_diff && diff) {
992 
993         // this could be an arithmetic transformation
994 
995         u64 new_repl = (u64)((s64)repl - diff);
996         // fprintf(stderr, "SAME DIFF %llx->%llx\n", repl, new_repl);
997 
998         if (unlikely(cmp_extend_encoding(
999                 afl, h, pattern, new_repl, o_pattern, repl, IS_TRANSFORM, idx,
1000                 taint_len, orig_buf, buf, cbuf, len, 1, lvl, status))) {
1001 
1002           return 1;
1003 
1004         }
1005 
1006         // if (*status == 1) { fprintf(stderr, "FOUND!\n"); }
1007 
1008       }
1009 
1010       // test for XOR, eg. "if ((user_val ^ 0xabcd) == 0x1234) ..."
1011       if (*status != 1) {
1012 
1013         diff = pattern ^ b_val;
1014         s64 o_diff = o_pattern ^ o_b_val;
1015 
1016         /* fprintf(stderr, "DIFF2 idx=%03u shape=%02u %llx-%llx=%lx\n",
1017                    idx, hshape, o_pattern, o_b_val, o_diff);
1018            fprintf(stderr,
1019                    "DIFF2 %016llx %llx-%llx=%lx\n", repl, pattern, b_val, diff);
1020         */
1021         if (diff == o_diff && diff) {
1022 
1023           // this could be a XOR transformation
1024 
1025           u64 new_repl = (u64)((s64)repl ^ diff);
1026           // fprintf(stderr, "SAME DIFF %llx->%llx\n", repl, new_repl);
1027 
1028           if (unlikely(cmp_extend_encoding(
1029                   afl, h, pattern, new_repl, o_pattern, repl, IS_TRANSFORM, idx,
1030                   taint_len, orig_buf, buf, cbuf, len, 1, lvl, status))) {
1031 
1032             return 1;
1033 
1034           }
1035 
1036           // if (*status == 1) { fprintf(stderr, "FOUND!\n"); }
1037 
1038         }
1039 
1040       }
1041 
1042       // test for to lowercase, eg. "new_val = (user_val | 0x2020) ..."
1043       if (*status != 1) {
1044 
1045         if ((b_val | (0x2020202020202020 & mask)) == (pattern & mask)) {
1046 
1047           diff = 1;
1048 
1049         } else {
1050 
1051           diff = 0;
1052 
1053         }
1054 
1055         if ((o_b_val | (0x2020202020202020 & mask)) == (o_pattern & mask)) {
1056 
1057           o_diff = 1;
1058 
1059         } else {
1060 
1061           o_diff = 0;
1062 
1063         }
1064 
1065         /* fprintf(stderr, "DIFF3 idx=%03u shape=%02u %llx-%llx=%lx\n",
1066                    idx, hshape, o_pattern, o_b_val, o_diff);
1067            fprintf(stderr,
1068                    "DIFF3 %016llx %llx-%llx=%lx\n", repl, pattern, b_val, diff);
1069         */
1070         if (o_diff && diff) {
1071 
1072           // this could be a lower to upper
1073 
1074           u64 new_repl = (repl & (0x5f5f5f5f5f5f5f5f & mask));
1075           // fprintf(stderr, "SAME DIFF %llx->%llx\n", repl, new_repl);
1076 
1077           if (unlikely(cmp_extend_encoding(
1078                   afl, h, pattern, new_repl, o_pattern, repl, IS_TRANSFORM, idx,
1079                   taint_len, orig_buf, buf, cbuf, len, 1, lvl, status))) {
1080 
1081             return 1;
1082 
1083           }
1084 
1085           // if (*status == 1) { fprintf(stderr, "FOUND!\n"); }
1086 
1087         }
1088 
1089       }
1090 
1091       // test for to uppercase, eg. "new_val = (user_val | 0x5f5f) ..."
1092       if (*status != 1) {
1093 
1094         if ((b_val & (0x5f5f5f5f5f5f5f5f & mask)) == (pattern & mask)) {
1095 
1096           diff = 1;
1097 
1098         } else {
1099 
1100           diff = 0;
1101 
1102         }
1103 
1104         if ((o_b_val & (0x5f5f5f5f5f5f5f5f & mask)) == (o_pattern & mask)) {
1105 
1106           o_diff = 1;
1107 
1108         } else {
1109 
1110           o_diff = 0;
1111 
1112         }
1113 
1114         /* fprintf(stderr, "DIFF4 idx=%03u shape=%02u %llx-%llx=%lx\n",
1115                    idx, hshape, o_pattern, o_b_val, o_diff);
1116            fprintf(stderr,
1117                    "DIFF4 %016llx %llx-%llx=%lx\n", repl, pattern, b_val, diff);
1118         */
1119         if (o_diff && diff) {
1120 
1121           // this could be a lower to upper
1122 
1123           u64 new_repl = (repl | (0x2020202020202020 & mask));
1124           // fprintf(stderr, "SAME DIFF %llx->%llx\n", repl, new_repl);
1125 
1126           if (unlikely(cmp_extend_encoding(
1127                   afl, h, pattern, new_repl, o_pattern, repl, IS_TRANSFORM, idx,
1128                   taint_len, orig_buf, buf, cbuf, len, 1, lvl, status))) {
1129 
1130             return 1;
1131 
1132           }
1133 
1134           // if (*status == 1) { fprintf(stderr, "FOUND!\n"); }
1135 
1136         }
1137 
1138       }
1139 
1140       *status = 0;
1141 
1142     }
1143 
1144   }
1145 
1146   // #endif
1147 
1148   // we only allow this for ascii2integer (above) so leave if this is the case
1149   if (unlikely(pattern == o_pattern)) { return 0; }
1150 
1151   if ((lvl & LVL1) || attr >= IS_FP_MOD) {
1152 
1153     if (hshape >= 8 && *status != 1) {
1154 
1155       // if (its_len >= 8)
1156       //   fprintf(stderr,
1157       //           "TestU64: %u>=8 (idx=%u attr=%u) %llx==%llx"
1158       //           " %llx==%llx <= %llx<-%llx\n",
1159       //           its_len, idx, attr, *buf_64, pattern, *o_buf_64, o_pattern,
1160       //           repl, changed_val);
1161 
1162       // if this is an fcmp (attr & 8 == 8) then do not compare the patterns -
1163       // due to a bug in llvm dynamic float bitcasts do not work :(
1164       // the value 16 means this is a +- 1.0 test case
1165       if (its_len >= 8 && ((*buf_64 == pattern && *o_buf_64 == o_pattern) ||
1166                            attr >= IS_FP_MOD)) {
1167 
1168         u64 tmp_64 = *buf_64;
1169         *buf_64 = repl;
1170         if (unlikely(its_fuzz(afl, buf, len, status))) { return 1; }
1171 #ifdef CMPLOG_COMBINE
1172         if (*status == 1) { memcpy(cbuf + idx, buf_64, 8); }
1173 #endif
1174         *buf_64 = tmp_64;
1175 
1176         // fprintf(stderr, "Status=%u\n", *status);
1177 
1178       }
1179 
1180       // reverse encoding
1181       if (do_reverse && *status != 1) {
1182 
1183         if (unlikely(cmp_extend_encoding(afl, h, SWAP64(pattern), SWAP64(repl),
1184                                          SWAP64(o_pattern), SWAP64(changed_val),
1185                                          attr, idx, taint_len, orig_buf, buf,
1186                                          cbuf, len, 0, lvl, status))) {
1187 
1188           return 1;
1189 
1190         }
1191 
1192       }
1193 
1194     }
1195 
1196     if (hshape >= 4 && *status != 1) {
1197 
1198       // if (its_len >= 4 && (attr <= 1 || attr >= 8))
1199       //   fprintf(stderr,
1200       //           "TestU32: %u>=4 (idx=%u attr=%u) %x==%x"
1201       //           " %x==%x <= %x<-%x\n",
1202       //           its_len, idx, attr, *buf_32, (u32)pattern, *o_buf_32,
1203       //           (u32)o_pattern, (u32)repl, (u32)changed_val);
1204 
1205       if (its_len >= 4 &&
1206           ((*buf_32 == (u32)pattern && *o_buf_32 == (u32)o_pattern) ||
1207            attr >= IS_FP_MOD)) {
1208 
1209         u32 tmp_32 = *buf_32;
1210         *buf_32 = (u32)repl;
1211         if (unlikely(its_fuzz(afl, buf, len, status))) { return 1; }
1212 #ifdef CMPLOG_COMBINE
1213         if (*status == 1) { memcpy(cbuf + idx, buf_32, 4); }
1214 #endif
1215         *buf_32 = tmp_32;
1216 
1217         // fprintf(stderr, "Status=%u\n", *status);
1218 
1219       }
1220 
1221       // reverse encoding
1222       if (do_reverse && *status != 1) {
1223 
1224         if (unlikely(cmp_extend_encoding(afl, h, SWAP32(pattern), SWAP32(repl),
1225                                          SWAP32(o_pattern), SWAP32(changed_val),
1226                                          attr, idx, taint_len, orig_buf, buf,
1227                                          cbuf, len, 0, lvl, status))) {
1228 
1229           return 1;
1230 
1231         }
1232 
1233       }
1234 
1235     }
1236 
1237     if (hshape >= 2 && *status != 1) {
1238 
1239       if (its_len >= 2 &&
1240           ((*buf_16 == (u16)pattern && *o_buf_16 == (u16)o_pattern) ||
1241            attr >= IS_FP_MOD)) {
1242 
1243         u16 tmp_16 = *buf_16;
1244         *buf_16 = (u16)repl;
1245         if (unlikely(its_fuzz(afl, buf, len, status))) { return 1; }
1246 #ifdef CMPLOG_COMBINE
1247         if (*status == 1) { memcpy(cbuf + idx, buf_16, 2); }
1248 #endif
1249         *buf_16 = tmp_16;
1250 
1251       }
1252 
1253       // reverse encoding
1254       if (do_reverse && *status != 1) {
1255 
1256         if (unlikely(cmp_extend_encoding(afl, h, SWAP16(pattern), SWAP16(repl),
1257                                          SWAP16(o_pattern), SWAP16(changed_val),
1258                                          attr, idx, taint_len, orig_buf, buf,
1259                                          cbuf, len, 0, lvl, status))) {
1260 
1261           return 1;
1262 
1263         }
1264 
1265       }
1266 
1267     }
1268 
1269     if (*status != 1) {  // u8
1270 
1271       // if (its_len >= 1)
1272       //   fprintf(stderr,
1273       //           "TestU8: %u>=1 (idx=%u attr=%u) %x==%x %x==%x <= %x<-%x\n",
1274       //           its_len, idx, attr, *buf_8, (u8)pattern, *o_buf_8,
1275       //           (u8)o_pattern, (u8)repl, (u8)changed_val);
1276 
1277       if (its_len >= 1 &&
1278           ((*buf_8 == (u8)pattern && *o_buf_8 == (u8)o_pattern) ||
1279            attr >= IS_FP_MOD)) {
1280 
1281         u8 tmp_8 = *buf_8;
1282         *buf_8 = (u8)repl;
1283         if (unlikely(its_fuzz(afl, buf, len, status))) { return 1; }
1284 #ifdef CMPLOG_COMBINE
1285         if (*status == 1) { cbuf[idx] = *buf_8; }
1286 #endif
1287         *buf_8 = tmp_8;
1288 
1289       }
1290 
1291     }
1292 
1293   }
1294 
1295   // If 'S' is set for cmplog mode then we try a scale encoding of the value.
1296   // Currently we can only handle bytes up to 1 << 55 on 32 bit and 1 << 119
1297   // on 64 bit systems.
1298   // Caveat: This implementation here works only on little endian systems.
1299 
1300   if (attr < IS_FP && (afl->cmplog_enable_scale || lvl >= LVL3) &&
1301       repl == changed_val) {
1302 
1303     u8  do_call = 1;
1304     u64 new_val = repl << 2;
1305     u32 ilen = 0;
1306 
1307     if (changed_val <= 255) {
1308 
1309       ilen = 1;
1310 
1311     } else if (new_val <= 65535) {
1312 
1313       new_val += 1;  // two byte mode
1314       ilen = 2;
1315 
1316     } else if (new_val <= 4294967295) {
1317 
1318       new_val += 2;  // four byte mode
1319       ilen = 4;
1320 
1321     } else {
1322 
1323 #ifndef WORD_SIZE_64
1324       if (repl <= 0x00ffffffffffffff) {
1325 
1326         new_val = repl << 8;
1327         u8  scale_len = 0;
1328         u64 tmp_val = repl;
1329         while (tmp_val) {
1330 
1331           tmp_val >>= 8;
1332           ++scale_len;
1333 
1334         }  // scale_len will be >= 4;
1335 
1336         if (scale_len >= 4) {
1337 
1338           scale_len -= 4;
1339 
1340         } else {
1341 
1342           scale_len = 0;
1343 
1344         };
1345 
1346         new_val += (scale_len << 2) + 3;
1347         ilen = scale_len + 5;
1348 
1349       } else {
1350 
1351         do_call = 0;
1352 
1353       }
1354 
1355 #else
1356       {
1357 
1358         u128 new_vall = ((u128)repl) << 8;
1359         u8   scale_len = 0;
1360         u128 tmp_val = (u128)repl;
1361 
1362         while (tmp_val) {
1363 
1364           tmp_val >>= 8;
1365           ++scale_len;
1366 
1367         }  // scale_len will be >= 4;
1368 
1369         if (scale_len >= 4) {
1370 
1371           scale_len -= 4;
1372 
1373         } else {
1374 
1375           scale_len = 0;
1376 
1377         };
1378 
1379         new_vall += (scale_len << 2) + 3;
1380         ilen = scale_len + 5;
1381 
1382         if (ilen <= its_len && ilen > 1) {
1383 
1384           u8 tmpbuf[32];
1385           memcpy(tmpbuf, buf + idx, ilen);
1386           memcpy(buf + idx, (char *)&new_vall, ilen);
1387 
1388           if (unlikely(its_fuzz(afl, buf, len, status))) { return 1; }
1389   #ifdef CMPLOG_COMBINE
1390           if (*status == 1) { memcpy(cbuf + idx, (char *)&new_vall, ilen); }
1391   #endif
1392           memcpy(buf + idx, tmpbuf, ilen);
1393 
1394         };
1395 
1396         do_call = 0;
1397 
1398       }
1399 
1400 #endif
1401 
1402     }
1403 
1404     if (do_call) {
1405 
1406       if (ilen <= its_len && ilen > 1) {
1407 
1408         u8 tmpbuf[32];
1409         memcpy(tmpbuf, buf + idx, ilen);
1410         memcpy(buf + idx, (char *)&new_val, ilen);
1411 
1412         if (unlikely(its_fuzz(afl, buf, len, status))) { return 1; }
1413 #ifdef CMPLOG_COMBINE
1414         if (*status == 1) { memcpy(cbuf + idx, (char *)&new_val, ilen); }
1415 #endif
1416         memcpy(buf + idx, tmpbuf, ilen);
1417 
1418       };
1419 
1420     }
1421 
1422   }
1423 
1424   // here we add and subtract 1 from the value, but only if it is not an
1425   // == or != comparison
1426   // Bits: 1 = Equal, 2 = Greater, 4 = Lesser, 8 = Float
1427   //       16 = modified float, 32 = modified integer (modified = wont match
1428   //                                                   in original buffer)
1429 
1430   if (!afl->cmplog_enable_arith || lvl < LVL3 || attr == IS_TRANSFORM) {
1431 
1432     return 0;
1433 
1434   }
1435 
1436   if (!(attr & (IS_GREATER | IS_LESSER)) || hshape < 4) { return 0; }
1437 
1438   // transform >= to < and <= to >
1439   if ((attr & IS_EQUAL) && (attr & (IS_GREATER | IS_LESSER))) {
1440 
1441     if (attr & 2) {
1442 
1443       attr += 2;
1444 
1445     } else {
1446 
1447       attr -= 2;
1448 
1449     }
1450 
1451   }
1452 
1453   // lesser/greater FP comparison
1454   if (attr >= IS_FP && attr < IS_FP_MOD) {
1455 
1456     u64 repl_new;
1457 
1458     if (attr & IS_GREATER) {
1459 
1460       if (hshape == 4 && its_len >= 4) {
1461 
1462         float *f = (float *)&repl;
1463         float  g = *f;
1464         g += 1.0;
1465         u32 *r = (u32 *)&g;
1466         repl_new = (u32)*r;
1467 
1468       } else if (hshape == 8 && its_len >= 8) {
1469 
1470         double *f = (double *)&repl;
1471         double  g = *f;
1472         g += 1.0;
1473 
1474         u64 *r = (u64 *)&g;
1475         repl_new = *r;
1476 
1477       } else {
1478 
1479         return 0;
1480 
1481       }
1482 
1483       changed_val = repl_new;
1484 
1485       if (unlikely(cmp_extend_encoding(
1486               afl, h, pattern, repl_new, o_pattern, changed_val, 16, idx,
1487               taint_len, orig_buf, buf, cbuf, len, 1, lvl, status))) {
1488 
1489         return 1;
1490 
1491       }
1492 
1493     } else {
1494 
1495       if (hshape == 4) {
1496 
1497         float *f = (float *)&repl;
1498         float  g = *f;
1499         g -= 1.0;
1500         u32 *r = (u32 *)&g;
1501         repl_new = (u32)*r;
1502 
1503       } else if (hshape == 8) {
1504 
1505         double *f = (double *)&repl;
1506         double  g = *f;
1507         g -= 1.0;
1508         u64 *r = (u64 *)&g;
1509         repl_new = *r;
1510 
1511       } else {
1512 
1513         return 0;
1514 
1515       }
1516 
1517       changed_val = repl_new;
1518 
1519       if (unlikely(cmp_extend_encoding(
1520               afl, h, pattern, repl_new, o_pattern, changed_val, 16, idx,
1521               taint_len, orig_buf, buf, cbuf, len, 1, lvl, status))) {
1522 
1523         return 1;
1524 
1525       }
1526 
1527     }
1528 
1529     // transform double to float, llvm likes to do that internally ...
1530     if (hshape == 8 && its_len >= 4) {
1531 
1532       double *f = (double *)&repl;
1533       float   g = (float)*f;
1534       repl_new = 0;
1535 #if (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
1536       memcpy((char *)&repl_new, (char *)&g, 4);
1537 #else
1538       memcpy(((char *)&repl_new) + 4, (char *)&g, 4);
1539 #endif
1540       changed_val = repl_new;
1541       hshape = 4;  // modify shape
1542 
1543       // fprintf(stderr, "DOUBLE2FLOAT %llx\n", repl_new);
1544 
1545       if (unlikely(cmp_extend_encoding(
1546               afl, h, pattern, repl_new, o_pattern, changed_val, 16, idx,
1547               taint_len, orig_buf, buf, cbuf, len, 1, lvl, status))) {
1548 
1549         hshape = 8;  // recover shape
1550         return 1;
1551 
1552       }
1553 
1554       hshape = 8;  // recover shape
1555 
1556     }
1557 
1558   }
1559 
1560   else if (attr < IS_FP) {
1561 
1562     // lesser/greater integer comparison
1563 
1564     u64 repl_new;
1565 
1566     if (attr & IS_GREATER) {
1567 
1568       repl_new = repl + 1;
1569       changed_val = repl_new;
1570       if (unlikely(cmp_extend_encoding(
1571               afl, h, pattern, repl_new, o_pattern, changed_val, 32, idx,
1572               taint_len, orig_buf, buf, cbuf, len, 1, lvl, status))) {
1573 
1574         return 1;
1575 
1576       }
1577 
1578     } else {
1579 
1580       repl_new = repl - 1;
1581       changed_val = repl_new;
1582       if (unlikely(cmp_extend_encoding(
1583               afl, h, pattern, repl_new, o_pattern, changed_val, 32, idx,
1584               taint_len, orig_buf, buf, cbuf, len, 1, lvl, status))) {
1585 
1586         return 1;
1587 
1588       }
1589 
1590     }
1591 
1592   }
1593 
1594   // #endif                                           /*
1595   //  CMPLOG_SOLVE_ARITHMETIC
1596 
1597   return 0;
1598 
1599 }
1600 
1601 #ifdef WORD_SIZE_64
1602 
cmp_extend_encodingN(afl_state_t * afl,struct cmp_header * h,u128 pattern,u128 repl,u128 o_pattern,u128 changed_val,u8 attr,u32 idx,u32 taint_len,u8 * orig_buf,u8 * buf,u8 * cbuf,u32 len,u8 do_reverse,u8 lvl,u8 * status)1603 static u8 cmp_extend_encodingN(afl_state_t *afl, struct cmp_header *h,
1604                                u128 pattern, u128 repl, u128 o_pattern,
1605                                u128 changed_val, u8 attr, u32 idx,
1606                                u32 taint_len, u8 *orig_buf, u8 *buf, u8 *cbuf,
1607                                u32 len, u8 do_reverse, u8 lvl, u8 *status) {
1608 
1609   if (unlikely(afl->fsrv.total_execs - last_update > screen_update)) {
1610 
1611     show_stats(afl);
1612     last_update = afl->fsrv.total_execs;
1613 
1614   }
1615 
1616   u8 *ptr = (u8 *)&buf[idx];
1617   u8 *o_ptr = (u8 *)&orig_buf[idx];
1618   u8 *p = (u8 *)&pattern;
1619   u8 *o_p = (u8 *)&o_pattern;
1620   u8 *r = (u8 *)&repl;
1621   u8  backup[16];
1622   u32 its_len = MIN(len - idx, taint_len);
1623   #if (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
1624   size_t off = 0;
1625   #else
1626   size_t off = 16 - hshape;
1627   #endif
1628 
1629   if (its_len >= hshape) {
1630 
1631   #ifdef _DEBUG
1632     fprintf(stderr, "TestUN: %u>=%u (len=%u idx=%u attr=%u off=%lu) (%u) ",
1633             its_len, hshape, len, idx, attr, off, do_reverse);
1634     u32 i;
1635     u8 *o_r = (u8 *)&changed_val;
1636     for (i = 0; i < hshape; i++)
1637       fprintf(stderr, "%02x", ptr[i]);
1638     fprintf(stderr, "==");
1639     for (i = 0; i < hshape; i++)
1640       fprintf(stderr, "%02x", p[off + i]);
1641     fprintf(stderr, " ");
1642     for (i = 0; i < hshape; i++)
1643       fprintf(stderr, "%02x", o_ptr[i]);
1644     fprintf(stderr, "==");
1645     for (i = 0; i < hshape; i++)
1646       fprintf(stderr, "%02x", o_p[off + i]);
1647     fprintf(stderr, " <= ");
1648     for (i = 0; i < hshape; i++)
1649       fprintf(stderr, "%02x", r[off + i]);
1650     fprintf(stderr, "<-");
1651     for (i = 0; i < hshape; i++)
1652       fprintf(stderr, "%02x", o_r[off + i]);
1653     fprintf(stderr, "\n");
1654   #endif
1655 
1656     if (!memcmp(ptr, p + off, hshape) && !memcmp(o_ptr, o_p + off, hshape)) {
1657 
1658       memcpy(backup, ptr, hshape);
1659       memcpy(ptr, r + off, hshape);
1660 
1661       if (unlikely(its_fuzz(afl, buf, len, status))) { return 1; }
1662 
1663   #ifdef CMPLOG_COMBINE
1664       if (*status == 1) { memcpy(cbuf + idx, r, hshape); }
1665   #endif
1666 
1667       memcpy(ptr, backup, hshape);
1668 
1669   #ifdef _DEBUG
1670       fprintf(stderr, "Status=%u\n", *status);
1671   #endif
1672 
1673     }
1674 
1675     // reverse encoding
1676     if (do_reverse && *status != 1) {
1677 
1678       if (unlikely(cmp_extend_encodingN(
1679               afl, h, SWAPN(pattern, (hshape << 3)), SWAPN(repl, (hshape << 3)),
1680               SWAPN(o_pattern, (hshape << 3)),
1681               SWAPN(changed_val, (hshape << 3)), attr, idx, taint_len, orig_buf,
1682               buf, cbuf, len, 0, lvl, status))) {
1683 
1684         return 1;
1685 
1686       }
1687 
1688     }
1689 
1690     // Scale encoding only works on little endian systems
1691 
1692     if (attr < IS_FP && attr < 32 &&
1693         (afl->cmplog_enable_scale || lvl >= LVL3)) {
1694 
1695       u128 new_val = repl << 2;
1696       u128 max_scale = (u128)1 << 120;
1697       u32  ilen = 0;
1698       u8   do_call = 1;
1699 
1700       if (new_val <= 255) {
1701 
1702         ilen = 1;
1703 
1704       } else if (new_val <= 65535) {
1705 
1706         new_val += 1;  // two byte mode
1707         ilen = 2;
1708 
1709       } else if (new_val <= 4294967295) {
1710 
1711         new_val += 2;  // four byte mode
1712         ilen = 4;
1713 
1714       } else if (repl < max_scale) {
1715 
1716         new_val = (u128)repl << 8;
1717         u8   scale_len = 0;
1718         u128 tmp_val = (u128)repl;
1719         while (tmp_val) {
1720 
1721           tmp_val >>= 8;
1722           ++scale_len;
1723 
1724         }  // scale_len will be >= 4;
1725 
1726         if (scale_len >= 4) {
1727 
1728           scale_len -= 4;
1729 
1730         } else {
1731 
1732           scale_len = 0;
1733 
1734         };
1735 
1736         new_val += (scale_len << 2) + 3;
1737         ilen = scale_len + 5;
1738 
1739       } else {
1740 
1741         do_call = 0;
1742 
1743       }
1744 
1745       if (do_call && ilen <= its_len) {
1746 
1747         u8 tmpbuf[32];
1748         memcpy(tmpbuf, buf + idx, ilen);
1749         memcpy(buf + idx, (char *)&new_val, ilen);
1750 
1751         if (unlikely(its_fuzz(afl, buf, len, status))) { return 1; }
1752   #ifdef CMPLOG_COMBINE
1753         if (*status == 1) { memcpy(cbuf + idx, (char *)&new_val, ilen); }
1754   #endif
1755         memcpy(buf + idx, tmpbuf, ilen);
1756 
1757       };
1758 
1759     }
1760 
1761   }
1762 
1763   return 0;
1764 
1765 }
1766 
1767 #endif
1768 
try_to_add_to_dict(afl_state_t * afl,u64 v,u8 shape)1769 static void try_to_add_to_dict(afl_state_t *afl, u64 v, u8 shape) {
1770 
1771   u8 *b = (u8 *)&v;
1772 
1773   u32 k;
1774   u8  cons_ff = 0, cons_0 = 0;
1775   for (k = 0; k < shape; ++k) {
1776 
1777     if (b[k] == 0) {
1778 
1779       ++cons_0;
1780 
1781     } else if (b[k] == 0xff) {
1782 
1783       ++cons_ff;
1784 
1785     } else {
1786 
1787       cons_0 = cons_ff = 0;
1788 
1789     }
1790 
1791     if (cons_0 > 1 || cons_ff > 1) { return; }
1792 
1793   }
1794 
1795   maybe_add_auto(afl, (u8 *)&v, shape);
1796 
1797   u64 rev;
1798   switch (shape) {
1799 
1800     case 1:
1801       break;
1802     case 2:
1803       rev = SWAP16((u16)v);
1804       maybe_add_auto(afl, (u8 *)&rev, shape);
1805       break;
1806     case 4:
1807       rev = SWAP32((u32)v);
1808       maybe_add_auto(afl, (u8 *)&rev, shape);
1809       break;
1810     case 8:
1811       rev = SWAP64(v);
1812       maybe_add_auto(afl, (u8 *)&rev, shape);
1813       break;
1814 
1815   }
1816 
1817 }
1818 
1819 #ifdef WORD_SIZE_64
try_to_add_to_dictN(afl_state_t * afl,u128 v,u8 size)1820 static void try_to_add_to_dictN(afl_state_t *afl, u128 v, u8 size) {
1821 
1822   u8 *b = (u8 *)&v;
1823 
1824   u32 k;
1825   u8  cons_ff = 0, cons_0 = 0;
1826   #if (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
1827   u32 off = 0;
1828   for (k = 0; k < size; ++k) {
1829 
1830   #else
1831   u32 off = 16 - size;
1832   for (k = 16 - size; k < 16; ++k) {
1833 
1834   #endif
1835     if (b[k] == 0) {
1836 
1837       ++cons_0;
1838 
1839     } else if (b[k] == 0xff) {
1840 
1841       ++cons_ff;
1842 
1843     } else {
1844 
1845       cons_0 = cons_ff = 0;
1846 
1847     }
1848 
1849     if (cons_0 > 1 || cons_ff > 1) { return; }
1850 
1851   }
1852 
1853   maybe_add_auto(afl, (u8 *)&v + off, size);
1854   u128 rev = SWAPN(v, size);
1855   maybe_add_auto(afl, (u8 *)&rev + off, size);
1856 
1857 }
1858 
1859 #endif
1860 
1861 #define SWAPA(_x) ((_x & 0xf8) + ((_x & 7) ^ 0x07))
1862 
1863 static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf,
1864                    u32 len, u32 lvl, struct tainted *taint) {
1865 
1866   struct cmp_header *h = &afl->shm.cmp_map->headers[key];
1867   struct tainted    *t;
1868   u32                i, j, idx, taint_len, loggeds;
1869   u32                have_taint = 1;
1870   u8                 status = 0, found_one = 0;
1871 
1872   /* loop cmps are useless, detect and ignore them */
1873 #ifdef WORD_SIZE_64
1874   u32  is_n = 0;
1875   u128 s128_v0 = 0, s128_v1 = 0, orig_s128_v0 = 0, orig_s128_v1 = 0;
1876 #endif
1877   u64 s_v0, s_v1;
1878   u8  s_v0_fixed = 1, s_v1_fixed = 1;
1879   u8  s_v0_inc = 1, s_v1_inc = 1;
1880   u8  s_v0_dec = 1, s_v1_dec = 1;
1881 
1882   hshape = SHAPE_BYTES(h->shape);
1883 
1884   if (h->hits > CMP_MAP_H) {
1885 
1886     loggeds = CMP_MAP_H;
1887 
1888   } else {
1889 
1890     loggeds = h->hits;
1891 
1892   }
1893 
1894 #ifdef WORD_SIZE_64
1895   switch (hshape) {
1896 
1897     case 1:
1898     case 2:
1899     case 4:
1900     case 8:
1901       break;
1902     default:
1903       is_n = 1;
1904 
1905   }
1906 
1907 #endif
1908 
1909   if (hshape < 2) { return 0; }
1910 
1911   for (i = 0; i < loggeds; ++i) {
1912 
1913     struct cmp_operands *o = &afl->shm.cmp_map->log[key][i];
1914 
1915     // loop detection code
1916     if (i == 0) {
1917 
1918       s_v0 = o->v0;
1919       s_v1 = o->v1;
1920 
1921     } else {
1922 
1923       if (s_v0 != o->v0) { s_v0_fixed = 0; }
1924       if (s_v1 != o->v1) { s_v1_fixed = 0; }
1925       if (s_v0 + 1 != o->v0) { s_v0_inc = 0; }
1926       if (s_v1 + 1 != o->v1) { s_v1_inc = 0; }
1927       if (s_v0 - 1 != o->v0) { s_v0_dec = 0; }
1928       if (s_v1 - 1 != o->v1) { s_v1_dec = 0; }
1929       s_v0 = o->v0;
1930       s_v1 = o->v1;
1931 
1932     }
1933 
1934     struct cmp_operands *orig_o = &afl->orig_cmp_map->log[key][i];
1935 
1936     // opt not in the paper
1937     for (j = 0; j < i; ++j) {
1938 
1939       if (afl->shm.cmp_map->log[key][j].v0 == o->v0 &&
1940           afl->shm.cmp_map->log[key][j].v1 == o->v1) {
1941 
1942         goto cmp_fuzz_next_iter;
1943 
1944       }
1945 
1946     }
1947 
1948 #ifdef _DEBUG
1949     fprintf(stderr, "Handling: %llx->%llx vs %llx->%llx attr=%u shape=%u\n",
1950             orig_o->v0, o->v0, orig_o->v1, o->v1, h->attribute, hshape);
1951 #endif
1952 
1953     t = taint;
1954     while (t->next) {
1955 
1956       t = t->next;
1957 
1958     }
1959 
1960 #ifdef WORD_SIZE_64
1961     if (unlikely(is_n)) {
1962 
1963       s128_v0 = ((u128)o->v0) + (((u128)o->v0_128) << 64);
1964       s128_v1 = ((u128)o->v1) + (((u128)o->v1_128) << 64);
1965       orig_s128_v0 = ((u128)orig_o->v0) + (((u128)orig_o->v0_128) << 64);
1966       orig_s128_v1 = ((u128)orig_o->v1) + (((u128)orig_o->v1_128) << 64);
1967 
1968     }
1969 
1970 #endif
1971 
1972     for (idx = 0; idx < len; ++idx) {
1973 
1974       if (have_taint) {
1975 
1976         if (!t || idx < t->pos) {
1977 
1978           continue;
1979 
1980         } else {
1981 
1982           taint_len = t->pos + t->len - idx;
1983 
1984           if (idx == t->pos + t->len - 1) { t = t->prev; }
1985 
1986         }
1987 
1988       } else {
1989 
1990         taint_len = len - idx;
1991 
1992       }
1993 
1994       status = 0;
1995 
1996 #ifdef WORD_SIZE_64
1997       if (is_n) {  // _ExtInt special case including u128
1998 
1999         if (s128_v0 != orig_s128_v0 && orig_s128_v0 != orig_s128_v1) {
2000 
2001           if (unlikely(cmp_extend_encodingN(
2002                   afl, h, s128_v0, s128_v1, orig_s128_v0, orig_s128_v1,
2003                   h->attribute, idx, taint_len, orig_buf, buf, cbuf, len, 1,
2004                   lvl, &status))) {
2005 
2006             return 1;
2007 
2008           }
2009 
2010         }
2011 
2012         if (status == 1) {
2013 
2014           found_one = 1;
2015           break;
2016 
2017         }
2018 
2019         if (s128_v1 != orig_s128_v1 && orig_s128_v1 != orig_s128_v0) {
2020 
2021           if (unlikely(cmp_extend_encodingN(
2022                   afl, h, s128_v1, s128_v0, orig_s128_v1, orig_s128_v0,
2023                   SWAPA(h->attribute), idx, taint_len, orig_buf, buf, cbuf, len,
2024                   1, lvl, &status))) {
2025 
2026             return 1;
2027 
2028           }
2029 
2030         }
2031 
2032         if (status == 1) {
2033 
2034           found_one = 1;
2035           break;
2036 
2037         }
2038 
2039       }
2040 
2041 #endif
2042 
2043 #ifdef _DEBUG
2044       if (o->v0 != orig_o->v0 || o->v1 != orig_o->v1)
2045         fprintf(stderr, "key=%u idx=%u o0=%llu v0=%llu o1=%llu v1=%llu\n", key,
2046                 idx, orig_o->v0, o->v0, orig_o->v1, o->v1);
2047 #endif
2048 
2049       // even for u128 and _ExtInt we do cmp_extend_encoding() because
2050       // if we got here their own special trials failed and it might just be
2051       // a cast from e.g. u64 to u128 from the input data.
2052 
2053       if ((o->v0 != orig_o->v0 || lvl >= LVL3) && orig_o->v0 != orig_o->v1) {
2054 
2055         if (unlikely(cmp_extend_encoding(
2056                 afl, h, o->v0, o->v1, orig_o->v0, orig_o->v1, h->attribute, idx,
2057                 taint_len, orig_buf, buf, cbuf, len, 1, lvl, &status))) {
2058 
2059           return 1;
2060 
2061         }
2062 
2063       }
2064 
2065       if (status == 1) {
2066 
2067         found_one = 1;
2068         break;
2069 
2070       }
2071 
2072       status = 0;
2073       if ((o->v1 != orig_o->v1 || lvl >= LVL3) && orig_o->v0 != orig_o->v1) {
2074 
2075         if (unlikely(cmp_extend_encoding(afl, h, o->v1, o->v0, orig_o->v1,
2076                                          orig_o->v0, SWAPA(h->attribute), idx,
2077                                          taint_len, orig_buf, buf, cbuf, len, 1,
2078                                          lvl, &status))) {
2079 
2080           return 1;
2081 
2082         }
2083 
2084       }
2085 
2086       if (status == 1) {
2087 
2088         found_one = 1;
2089         break;
2090 
2091       }
2092 
2093     }
2094 
2095 #ifdef _DEBUG
2096     fprintf(stderr,
2097             "END: %llx->%llx vs %llx->%llx attr=%u i=%u found=%u "
2098             "isN=%u size=%u\n",
2099             orig_o->v0, o->v0, orig_o->v1, o->v1, h->attribute, i, found_one,
2100             is_n, hshape);
2101 #endif
2102 
2103     // we only learn 16 bit +
2104     if (hshape > 1) {
2105 
2106       if (!found_one || afl->queue_cur->is_ascii) {
2107 
2108 #ifdef WORD_SIZE_64
2109         if (unlikely(is_n)) {
2110 
2111           if (!found_one ||
2112               check_if_text_buf((u8 *)&s128_v0, SHAPE_BYTES(h->shape)) ==
2113                   SHAPE_BYTES(h->shape))
2114             try_to_add_to_dictN(afl, s128_v0, SHAPE_BYTES(h->shape));
2115           if (!found_one ||
2116               check_if_text_buf((u8 *)&s128_v1, SHAPE_BYTES(h->shape)) ==
2117                   SHAPE_BYTES(h->shape))
2118             try_to_add_to_dictN(afl, s128_v1, SHAPE_BYTES(h->shape));
2119 
2120         } else
2121 
2122 #endif
2123         {
2124 
2125           if (!memcmp((u8 *)&o->v0, (u8 *)&orig_o->v0, SHAPE_BYTES(h->shape)) &&
2126               (!found_one ||
2127                check_if_text_buf((u8 *)&o->v0, SHAPE_BYTES(h->shape)) ==
2128                    SHAPE_BYTES(h->shape)))
2129             try_to_add_to_dict(afl, o->v0, SHAPE_BYTES(h->shape));
2130           if (!memcmp((u8 *)&o->v1, (u8 *)&orig_o->v1, SHAPE_BYTES(h->shape)) &&
2131               (!found_one ||
2132                check_if_text_buf((u8 *)&o->v1, SHAPE_BYTES(h->shape)) ==
2133                    SHAPE_BYTES(h->shape)))
2134             try_to_add_to_dict(afl, o->v1, SHAPE_BYTES(h->shape));
2135 
2136         }
2137 
2138       }
2139 
2140     }
2141 
2142   cmp_fuzz_next_iter:
2143     afl->stage_cur++;
2144 
2145   }
2146 
2147   if (loggeds > 3 && ((s_v0_fixed && s_v1_inc) || (s_v1_fixed && s_v0_inc) ||
2148                       (s_v0_fixed && s_v1_dec) || (s_v1_fixed && s_v0_dec))) {
2149 
2150     afl->pass_stats[key].total = afl->pass_stats[key].faileds = 0xff;
2151 
2152   }
2153 
2154   if (!found_one && afl->pass_stats[key].faileds < 0xff) {
2155 
2156     afl->pass_stats[key].faileds++;
2157 
2158   }
2159 
2160   if (afl->pass_stats[key].total < 0xff) { afl->pass_stats[key].total++; }
2161 
2162   return 0;
2163 
2164 }
2165 
2166 static u8 rtn_extend_encoding(afl_state_t *afl, u8 entry,
2167                               struct cmpfn_operands *o,
2168                               struct cmpfn_operands *orig_o, u32 idx,
2169                               u32 taint_len, u8 *orig_buf, u8 *buf, u8 *cbuf,
2170                               u32 len, u8 lvl, u8 *status) {
2171 
2172 #ifndef CMPLOG_COMBINE
2173   (void)(cbuf);
2174 #endif
2175   // #ifndef CMPLOG_SOLVE_TRANSFORM
2176   //   (void)(changed_val);
2177   // #endif
2178 
2179   if (unlikely(afl->fsrv.total_execs - last_update > screen_update)) {
2180 
2181     show_stats(afl);
2182     last_update = afl->fsrv.total_execs;
2183 
2184   }
2185 
2186   u8 *pattern, *repl, *o_pattern, *changed_val;
2187   u8  l0, l1, ol0, ol1;
2188 
2189   if (entry == 0) {
2190 
2191     pattern = o->v0;
2192     repl = o->v1;
2193     o_pattern = orig_o->v0;
2194     changed_val = orig_o->v1;
2195     l0 = o->v0_len;
2196     ol0 = orig_o->v0_len;
2197     l1 = o->v1_len;
2198     ol1 = orig_o->v1_len;
2199 
2200   } else {
2201 
2202     pattern = o->v1;
2203     repl = o->v0;
2204     o_pattern = orig_o->v1;
2205     changed_val = orig_o->v0;
2206     l0 = o->v1_len;
2207     ol0 = orig_o->v1_len;
2208     l1 = o->v0_len;
2209     ol1 = orig_o->v0_len;
2210 
2211   }
2212 
2213   if (l0 >= 0x80 || ol0 >= 0x80) {
2214 
2215     if (l0 >= 0x80) { l0 -= 0x80; }
2216     if (l1 >= 0x80) { l1 -= 0x80; }
2217     if (ol0 >= 0x80) { ol0 -= 0x80; }
2218     if (ol1 >= 0x80) { ol1 -= 0x80; }
2219 
2220   }
2221 
2222   if (l0 == 0 || l1 == 0 || ol0 == 0 || ol1 == 0 || l0 > 31 || l1 > 31 ||
2223       ol0 > 31 || ol1 > 31) {
2224 
2225     l0 = ol0 = hshape;
2226 
2227   }
2228 
2229   u8  lmax = MAX(l0, ol0);
2230   u8  save[40];
2231   u32 saved_idx = idx, pre, from = 0, to = 0, i, j;
2232   u32 its_len = MIN(MIN(lmax, hshape), len - idx);
2233   its_len = MIN(its_len, taint_len);
2234   u32 saved_its_len = its_len;
2235 
2236   // fprintf(stderr, "its_len=%u repl=%s\n", its_len, repl);
2237 
2238   if (its_len <= 1) { return 0; }
2239 
2240   if (lvl & LVL3) {
2241 
2242     if (memcmp(changed_val, repl, its_len) != 0) { return 0; }
2243 
2244     u32 max_to = MIN(4U, idx);
2245     if (!(lvl & LVL1) && max_to) { from = 1; }
2246     to = max_to;
2247 
2248   }
2249 
2250   memcpy(save, &buf[saved_idx - to], its_len + to);
2251   (void)(j);
2252 
2253 #ifdef _DEBUG
2254   if (idx == 0) {
2255 
2256     fprintf(stderr, "RTN T idx=%u lvl=%02x is_txt=%u shape=%u/%u ", idx, lvl,
2257             o->v0_len >= 0x80 ? 1 : 0, hshape, l0);
2258     for (j = 0; j < 8; j++)
2259       fprintf(stderr, "%02x", orig_buf[idx + j]);
2260     fprintf(stderr, " -> ");
2261     for (j = 0; j < 8; j++)
2262       fprintf(stderr, "%02x", o_pattern[j]);
2263     fprintf(stderr, " <= ");
2264     for (j = 0; j < 8; j++)
2265       fprintf(stderr, "%02x", repl[j]);
2266     fprintf(stderr, "\n");
2267     fprintf(stderr, "                ");
2268     for (j = 0; j < 8; j++)
2269       fprintf(stderr, "%02x", buf[idx + j]);
2270     fprintf(stderr, " -> ");
2271     for (j = 0; j < 8; j++)
2272       fprintf(stderr, "%02x", pattern[j]);
2273     fprintf(stderr, " <= ");
2274     for (j = 0; j < 8; j++)
2275       fprintf(stderr, "%02x", changed_val[j]);
2276     fprintf(stderr, "\n");
2277 
2278   }
2279 
2280 #endif
2281 
2282   // Try to match the replace value up to 4 bytes before the current idx.
2283   // This allows matching of eg.:
2284   //   if (memcmp(user_val, "TEST") == 0)
2285   //     if (memcmp(user_val, "TEST-VALUE") == 0) ...
2286   // We only do this in lvl 3, otherwise we only do direct matching
2287 
2288   // fprintf(stderr, "XXXX FROMB64 saved_idx=%u its_len=%u from=%u to=%u FROMHEX
2289   // repl=%s\n", saved_idx, saved_its_len, from, to, repl);
2290 
2291   for (pre = from; pre <= to; pre++) {
2292 
2293     if (*status != 1 && (!pre || !memcmp(buf + saved_idx - pre, repl, pre))) {
2294 
2295       idx = saved_idx - pre;
2296       its_len = saved_its_len + pre;
2297 
2298       for (i = 0; i < its_len; ++i) {
2299 
2300         if ((pattern[i] != buf[idx + i] || o_pattern[i] != orig_buf[idx + i]) ||
2301             *status == 1) {
2302 
2303           break;
2304 
2305         }
2306 
2307         buf[idx + i] = repl[i];
2308 
2309         if (unlikely(its_fuzz(afl, buf, len, status))) { return 1; }
2310 
2311 #ifdef CMPLOG_COMBINE
2312         if (*status == 1) { memcpy(cbuf + idx, &buf[idx], i); }
2313 #endif
2314 
2315       }
2316 
2317       memcpy(&buf[idx], save + to - pre, i);
2318 
2319     }
2320 
2321   }
2322 
2323   if (*status == 1) return 0;
2324 
2325   // transform solving
2326 
2327   if (afl->cmplog_enable_transform && (lvl & LVL3)) {
2328 
2329     u32 toupper = 0, tolower = 0, xor = 0, arith = 0, tohex = 0, fromhex = 0;
2330     u32 tob64 = 0, fromb64 = 0;
2331     u32 from_0 = 0, from_x = 0, from_X = 0, from_slash = 0, from_up = 0;
2332     u32 to_0 = 0, to_x = 0, to_slash = 0, to_up = 0;
2333     u8  xor_val[32], arith_val[32], tmp[48];
2334 
2335     idx = saved_idx;
2336     its_len = saved_its_len;
2337 
2338     memcpy(save, &buf[idx], its_len);
2339 
2340     for (i = 0; i < its_len; ++i) {
2341 
2342       xor_val[i] = pattern[i] ^ buf[idx + i];
2343       arith_val[i] = pattern[i] - buf[idx + i];
2344 
2345       if (i == 0) {
2346 
2347         if (orig_buf[idx] == '0') {
2348 
2349           from_0 = 1;
2350 
2351         } else if (orig_buf[idx] == '\\') {
2352 
2353           from_slash = 1;
2354 
2355         }
2356 
2357         if (repl[0] == '0') {
2358 
2359           to_0 = 1;
2360 
2361         } else if (repl[0] == '\\') {
2362 
2363           to_slash = 1;
2364 
2365         }
2366 
2367       } else if (i == 1) {
2368 
2369         if (orig_buf[idx + 1] == 'x') {
2370 
2371           from_x = 1;
2372 
2373         } else if (orig_buf[idx + 1] == 'X') {
2374 
2375           from_X = from_x = 1;
2376 
2377         }
2378 
2379         if (repl[1] == 'x' || repl[1] == 'X') { to_x = 1; }
2380 
2381       }
2382 
2383       if (afl->cmplog_enable_xtreme_transform && i < 16 &&
2384           is_hex(repl + (i << 1))) {
2385 
2386         ++tohex;
2387 
2388         if (!to_up) {
2389 
2390           if (repl[i << 1] >= 'A' && repl[i << 1] <= 'F')
2391             to_up = 1;
2392           else if (repl[i << 1] >= 'a' && repl[i << 1] <= 'f')
2393             to_up = 2;
2394           if (repl[(i << 1) + 1] >= 'A' && repl[(i << 1) + 1] <= 'F')
2395             to_up = 1;
2396           else if (repl[(i << 1) + 1] >= 'a' && repl[(i << 1) + 1] <= 'f')
2397             to_up = 2;
2398 
2399         }
2400 
2401       }
2402 
2403       if (afl->cmplog_enable_xtreme_transform && (i % 2) == 1) {
2404 
2405         if (len > idx + i + 1 && is_hex(orig_buf + idx + i - 1)) {
2406 
2407           fromhex += 2;
2408 
2409           if (!from_up) {
2410 
2411             if (orig_buf[idx + i] >= 'A' && orig_buf[idx + i] <= 'F')
2412               from_up = 1;
2413             else if (orig_buf[idx + i] >= 'a' && orig_buf[idx + i] <= 'f')
2414               from_up = 2;
2415             if (orig_buf[idx + i - 1] >= 'A' && orig_buf[idx + i - 1] <= 'F')
2416               from_up = 1;
2417             else if (orig_buf[idx + i - 1] >= 'a' &&
2418                      orig_buf[idx + i - 1] <= 'f')
2419               from_up = 2;
2420 
2421           }
2422 
2423         }
2424 
2425       }
2426 
2427       if (afl->cmplog_enable_xtreme_transform) {
2428 
2429         if (i % 3 == 2 && i < 24) {
2430 
2431           if (is_base64(repl + ((i / 3) << 2))) tob64 += 3;
2432 
2433         }
2434 
2435         // fprintf(stderr, "X FROMB64 idx=%u i=%u repl=%s\n", saved_idx, i,
2436         // repl);
2437         if (i % 4 == 3 && i < 24) {
2438 
2439           if (is_base64(orig_buf + idx + i - 3)) fromb64 += 4;
2440 
2441         }
2442 
2443       }
2444 
2445       if ((o_pattern[i] ^ orig_buf[idx + i]) == xor_val[i] && xor_val[i]) {
2446 
2447         ++xor;
2448 
2449       }
2450 
2451       if ((o_pattern[i] - orig_buf[idx + i]) == arith_val[i] && arith_val[i]) {
2452 
2453         ++arith;
2454 
2455       }
2456 
2457       if ((buf[idx + i] | 0x20) == pattern[i] &&
2458           (orig_buf[idx + i] | 0x20) == o_pattern[i]) {
2459 
2460         ++tolower;
2461 
2462       }
2463 
2464       if ((buf[idx + i] & 0x5a) == pattern[i] &&
2465           (orig_buf[idx + i] & 0x5a) == o_pattern[i]) {
2466 
2467         ++toupper;
2468 
2469       }
2470 
2471 #ifdef _DEBUG
2472       if (idx == 0) {
2473 
2474         fprintf(stderr, "RTN Z %s %s %s %s repl=%s\n", buf, pattern, orig_buf,
2475                 o_pattern, repl);
2476         fprintf(
2477             stderr,
2478             "RTN Z idx=%u len=%u loop=%u xor=%u arith=%u tolower=%u toupper=%u "
2479             "tohex=%u fromhex=%u to_0=%u to_slash=%u to_x=%u "
2480             "from_0=%u from_slash=%u from_x=%u\n",
2481             idx, its_len, i, xor, arith, tolower, toupper, tohex, fromhex, to_0,
2482             to_slash, to_x, from_0, from_slash, from_x);
2483         if (afl->cmplog_enable_xtreme_transform) {
2484 
2485           fprintf(stderr, "RTN Z idx=%u loop=%u tob64=%u from64=%u\n", idx, i,
2486                   tob64, fromb64);
2487 
2488         }
2489 
2490       }
2491 
2492 #endif
2493 
2494       if (afl->cmplog_enable_xtreme_transform) {
2495 
2496         // input is base64 and converted to binary? convert repl to base64!
2497         // fprintf(stderr, "FROMB64 idx=%u i=%u %% 4 == 3 && i < 24 &&
2498         // fromb64=%u > i, repl=%s\n", saved_idx, i, fromb64, repl);
2499         if ((i % 4) == 3 && i < 24 && fromb64 > i) {
2500 
2501           for (u32 hlen = i; hlen + saved_idx < len && hlen <= its_len;
2502                ++hlen) {
2503 
2504             u32 res = to_base64(repl, tmp, hlen);
2505             // fprintf(stderr, "FROMB64 GOGO! idx=%u repl=%s tmp[%u]=%s
2506             // hlen=%u\n", saved_idx, repl, res, tmp, hlen);
2507             if (res + saved_idx < len) {
2508 
2509               memcpy(buf + idx, tmp, res);
2510               if (unlikely(its_fuzz(afl, buf, len, status))) { return 1; }
2511               // fprintf(stderr, "RTN ATTEMPT FROMB64 idx=%u fromb64 %u %s %s
2512               // result %u\n",       saved_idx,      fromb64,      tmp, repl,
2513               // *status);
2514 
2515             }
2516 
2517           }
2518 
2519         }
2520 
2521         // input is converted to base64? decode repl with base64!
2522         if ((i % 3) == 2 && i < 24 && tob64 > i) {
2523 
2524           u32 olen = from_base64(repl, tmp, i + 1);
2525           memcpy(buf + idx, tmp, olen);
2526           if (unlikely(its_fuzz(afl, buf, len, status))) { return 1; }
2527           // fprintf(stderr, "RTN ATTEMPT tob64 %u idx=%u result %u\n", tob64,
2528           // idx, *status);
2529 
2530         }
2531 
2532       }
2533 
2534       // input is converted to hex? convert repl to binary!
2535       if (afl->cmplog_enable_xtreme_transform && i < 16 && tohex > i) {
2536 
2537         u32 off;
2538         if (to_slash + to_x + to_0 == 2) {
2539 
2540           off = 2;
2541 
2542         } else {
2543 
2544           off = 0;
2545 
2546         }
2547 
2548         for (j = 0; j <= i; j++)
2549           tmp[j] = (hex_table[repl[off + (j << 1)] - '0'] << 4) +
2550                    hex_table[repl[off + (j << 1) + 1] - '0'];
2551 
2552         memcpy(buf + idx, tmp, i + 1);
2553         if (unlikely(its_fuzz(afl, buf, len, status))) { return 1; }
2554         // fprintf(stderr, "RTN ATTEMPT tohex %u result %u\n", tohex,
2555         // *status);
2556 
2557       }
2558 
2559       // input is hex and converted to binary? convert repl to hex!
2560       if (afl->cmplog_enable_xtreme_transform && (i % 2) == 1 && i < 16 &&
2561           fromhex && fromhex + from_slash + from_x + from_0 > i) {
2562 
2563         u8 off = 0;
2564         if (from_slash && from_x) {
2565 
2566           tmp[0] = '\\';
2567           if (from_X) {
2568 
2569             tmp[1] = 'X';
2570 
2571           } else {
2572 
2573             tmp[1] = 'x';
2574 
2575           }
2576 
2577           off = 2;
2578 
2579         } else if (from_0 && from_x) {
2580 
2581           tmp[0] = '0';
2582           if (from_X) {
2583 
2584             tmp[1] = 'X';
2585 
2586           } else {
2587 
2588             tmp[1] = 'x';
2589 
2590           }
2591 
2592           off = 2;
2593 
2594         }
2595 
2596         for (u32 hlen = i; hlen <= (i << 1) && hlen + idx < len; hlen += i) {
2597 
2598           if (to_up == 1) {
2599 
2600             for (j = 0; j <= (hlen >> 1); j++) {
2601 
2602               tmp[off + (j << 1)] = hex_table_up[repl[j] >> 4];
2603               tmp[off + (j << 1) + 1] = hex_table_up[repl[j] % 16];
2604 
2605             }
2606 
2607           } else {
2608 
2609             for (j = 0; j <= (hlen >> 1); j++) {
2610 
2611               tmp[off + (j << 1)] = hex_table_low[repl[j] >> 4];
2612               tmp[off + (j << 1) + 1] = hex_table_low[repl[j] % 16];
2613 
2614             }
2615 
2616           }
2617 
2618           memcpy(buf + idx, tmp, hlen + 1 + off);
2619           if (unlikely(its_fuzz(afl, buf, len, status))) { return 1; }
2620           tmp[hlen + 1 + off] = 0;
2621           // fprintf(stderr, "RTN ATTEMPT idx=%u len=%u fromhex %u %s %s result
2622           // %u\n", idx, len, fromhex, tmp, repl, *status);
2623           memcpy(buf + idx, save, hlen + 1 + off);
2624 
2625         }
2626 
2627       }
2628 
2629       if (xor > i) {
2630 
2631         for (j = 0; j <= i; j++)
2632           buf[idx + j] = repl[j] ^ xor_val[j];
2633         if (unlikely(its_fuzz(afl, buf, len, status))) { return 1; }
2634         // fprintf(stderr, "RTN ATTEMPT xor %u result %u\n", xor, *status);
2635 
2636       }
2637 
2638       if (arith > i && *status != 1) {
2639 
2640         for (j = 0; j <= i; j++)
2641           buf[idx + j] = repl[j] - arith_val[j];
2642         if (unlikely(its_fuzz(afl, buf, len, status))) { return 1; }
2643         // fprintf(stderr, "RTN ATTEMPT arith %u result %u\n", arith,
2644         // *status);
2645 
2646       }
2647 
2648       if (toupper > i && *status != 1) {
2649 
2650         for (j = 0; j <= i; j++)
2651           buf[idx + j] = repl[j] | 0x20;
2652         if (unlikely(its_fuzz(afl, buf, len, status))) { return 1; }
2653         // fprintf(stderr, "RTN ATTEMPT toupper %u result %u\n", toupper,
2654         // *status);
2655 
2656       }
2657 
2658       if (tolower > i && *status != 1) {
2659 
2660         for (j = 0; j <= i; j++)
2661           buf[idx + j] = repl[j] & 0x5f;
2662         if (unlikely(its_fuzz(afl, buf, len, status))) { return 1; }
2663         // fprintf(stderr, "RTN ATTEMPT tolower %u result %u\n", tolower,
2664         // *status);
2665 
2666       }
2667 
2668 #ifdef CMPLOG_COMBINE
2669       if (*status == 1) { memcpy(cbuf + idx, &buf[idx], i + 1); }
2670 #endif
2671 
2672       if ((i >= 7 &&
2673            (i >= xor&&i >= arith &&i >= tolower &&i >= toupper &&i > tohex &&i >
2674                 (fromhex + from_0 + from_x + from_slash + 1) &&
2675             (afl->cmplog_enable_xtreme_transform && i > tob64 + 3 &&
2676              i > fromb64 + 4))) ||
2677           repl[i] != changed_val[i] || *status == 1) {
2678 
2679         break;
2680 
2681       }
2682 
2683     }
2684 
2685     memcpy(&buf[idx], save, i);
2686 
2687   }
2688 
2689   return 0;
2690 
2691 }
2692 
2693 static u8 rtn_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf,
2694                    u32 len, u8 lvl, struct tainted *taint) {
2695 
2696   struct tainted    *t;
2697   struct cmp_header *h = &afl->shm.cmp_map->headers[key];
2698   u32                i, idx, have_taint = 1, taint_len, loggeds;
2699   u8                 status = 0, found_one = 0;
2700 
2701   hshape = SHAPE_BYTES(h->shape);
2702 
2703   if (hshape < 2) { return 0; }
2704 
2705   if (h->hits > CMP_MAP_RTN_H) {
2706 
2707     loggeds = CMP_MAP_RTN_H;
2708 
2709   } else {
2710 
2711     loggeds = h->hits;
2712 
2713   }
2714 
2715   for (i = 0; i < loggeds; ++i) {
2716 
2717     struct cmpfn_operands *o =
2718         &((struct cmpfn_operands *)afl->shm.cmp_map->log[key])[i];
2719 
2720     struct cmpfn_operands *orig_o =
2721         &((struct cmpfn_operands *)afl->orig_cmp_map->log[key])[i];
2722 
2723     /*
2724         // opt not in the paper
2725         for (j = 0; j < i; ++j) {
2726 
2727           if (!memcmp(&((struct cmpfn_operands *)afl->shm.cmp_map->log[key])[j],
2728        o, sizeof(struct cmpfn_operands))) {
2729 
2730             goto rtn_fuzz_next_iter;
2731 
2732           }
2733 
2734         }
2735 
2736     */
2737 
2738 #ifdef _DEBUG
2739     u32                j;
2740     struct cmp_header *hh = &afl->orig_cmp_map->headers[key];
2741     fprintf(stderr, "RTN N hits=%u id=%u shape=%u attr=%u v0=", h->hits, h->id,
2742             hshape, h->attribute);
2743     for (j = 0; j < 8; j++)
2744       fprintf(stderr, "%02x", o->v0[j]);
2745     fprintf(stderr, " v1=");
2746     for (j = 0; j < 8; j++)
2747       fprintf(stderr, "%02x", o->v1[j]);
2748     fprintf(stderr, "\nRTN O hits=%u id=%u shape=%u attr=%u o0=", hh->hits,
2749             hh->id, hshape, hh->attribute);
2750     for (j = 0; j < 8; j++)
2751       fprintf(stderr, "%02x", orig_o->v0[j]);
2752     fprintf(stderr, " o1=");
2753     for (j = 0; j < 8; j++)
2754       fprintf(stderr, "%02x", orig_o->v1[j]);
2755     fprintf(stderr, "\n");
2756 #endif
2757 
2758     t = taint;
2759     while (t->next) {
2760 
2761       t = t->next;
2762 
2763     }
2764 
2765     for (idx = 0; idx < len; ++idx) {
2766 
2767       if (have_taint) {
2768 
2769         if (!t || idx < t->pos) {
2770 
2771           continue;
2772 
2773         } else {
2774 
2775           taint_len = t->pos + t->len - idx;
2776 
2777           if (idx == t->pos + t->len - 1) { t = t->prev; }
2778 
2779         }
2780 
2781       } else {
2782 
2783         taint_len = len - idx;
2784 
2785       }
2786 
2787       status = 0;
2788 
2789 #ifdef _DEBUG
2790       u32 w;
2791       fprintf(stderr, "key=%u idx=%u len=%u o0=", key, idx, hshape);
2792       for (w = 0; w < hshape; ++w)
2793         fprintf(stderr, "%02x", orig_o->v0[w]);
2794       fprintf(stderr, " v0=");
2795       for (w = 0; w < hshape; ++w)
2796         fprintf(stderr, "%02x", o->v0[w]);
2797       fprintf(stderr, " o1=");
2798       for (w = 0; w < hshape; ++w)
2799         fprintf(stderr, "%02x", orig_o->v1[w]);
2800       fprintf(stderr, " v1=");
2801       for (w = 0; w < hshape; ++w)
2802         fprintf(stderr, "%02x", o->v1[w]);
2803       fprintf(stderr, "\n");
2804 #endif
2805 
2806       if (unlikely(rtn_extend_encoding(afl, 0, o, orig_o, idx, taint_len,
2807                                        orig_buf, buf, cbuf, len, lvl,
2808                                        &status))) {
2809 
2810         return 1;
2811 
2812       }
2813 
2814       if (status == 1) {
2815 
2816         found_one = 1;
2817         break;
2818 
2819       }
2820 
2821       status = 0;
2822 
2823       if (unlikely(rtn_extend_encoding(afl, 1, o, orig_o, idx, taint_len,
2824                                        orig_buf, buf, cbuf, len, lvl,
2825                                        &status))) {
2826 
2827         return 1;
2828 
2829       }
2830 
2831       if (status == 1) {
2832 
2833         found_one = 1;
2834         break;
2835 
2836       }
2837 
2838     }
2839 
2840     //  if (unlikely(!afl->pass_stats[key].total)) {
2841 
2842     if ((!found_one && (lvl & LVL1)) || afl->queue_cur->is_ascii) {
2843 
2844       // if (unlikely(!afl->pass_stats[key].total)) {
2845 
2846       u32 shape_len = SHAPE_BYTES(h->shape);
2847       u32 v0_len = shape_len, v1_len = shape_len;
2848       if (afl->queue_cur->is_ascii ||
2849           check_if_text_buf((u8 *)&o->v0, shape_len) == shape_len) {
2850 
2851         if (strlen(o->v0)) v0_len = strlen(o->v0);
2852 
2853       }
2854 
2855       if (afl->queue_cur->is_ascii ||
2856           check_if_text_buf((u8 *)&o->v1, shape_len) == shape_len) {
2857 
2858         if (strlen(o->v1)) v1_len = strlen(o->v1);
2859 
2860       }
2861 
2862       // fprintf(stderr, "SHOULD: found:%u ascii:%u text?%u:%u %u:%s %u:%s \n",
2863       // found_one, afl->queue_cur->is_ascii, check_if_text_buf((u8 *)&o->v0,
2864       // shape_len), check_if_text_buf((u8 *)&o->v1, shape_len), v0_len,
2865       // o->v0, v1_len, o->v1);
2866 
2867       // Note that this check differs from the line 1901, for RTN we are more
2868       // opportunistic for adding to the dictionary than cmps
2869       if (!memcmp(o->v0, orig_o->v0, v0_len) ||
2870           (!found_one || check_if_text_buf((u8 *)&o->v0, v0_len) == v0_len))
2871         maybe_add_auto(afl, o->v0, v0_len);
2872       if (!memcmp(o->v1, orig_o->v1, v1_len) ||
2873           (!found_one || check_if_text_buf((u8 *)&o->v1, v1_len) == v1_len))
2874         maybe_add_auto(afl, o->v1, v1_len);
2875 
2876       //}
2877 
2878     }
2879 
2880     // rtn_fuzz_next_iter:
2881     afl->stage_cur++;
2882 
2883   }
2884 
2885   if (!found_one && afl->pass_stats[key].faileds < 0xff) {
2886 
2887     afl->pass_stats[key].faileds++;
2888 
2889   }
2890 
2891   if (afl->pass_stats[key].total < 0xff) { afl->pass_stats[key].total++; }
2892 
2893   return 0;
2894 
2895 }
2896 
2897 ///// Input to State stage
2898 
2899 // afl->queue_cur->exec_cksum
2900 u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len) {
2901 
2902   u8 r = 1;
2903   if (unlikely(!afl->pass_stats)) {
2904 
2905     afl->pass_stats = ck_alloc(sizeof(struct afl_pass_stat) * CMP_MAP_W);
2906 
2907   }
2908 
2909   struct tainted *taint = NULL;
2910   if (likely(afl->queue_cur->exec_us)) {
2911 
2912     if (likely((100000 / 2) >= afl->queue_cur->exec_us)) {
2913 
2914       screen_update = 100000 / afl->queue_cur->exec_us;
2915 
2916     } else {
2917 
2918       screen_update = 1;
2919 
2920     }
2921 
2922   } else {
2923 
2924     screen_update = 100000;
2925 
2926   }
2927 
2928   if (!afl->queue_cur->taint || !afl->queue_cur->cmplog_colorinput) {
2929 
2930     if (unlikely(colorization(afl, buf, len, &taint))) { return 1; }
2931 
2932     // no taint? still try, create a dummy to prevent again colorization
2933     if (!taint) {
2934 
2935 #ifdef _DEBUG
2936       fprintf(stderr, "TAINT FAILED\n");
2937 #endif
2938       afl->queue_cur->colorized = CMPLOG_LVL_MAX;
2939       return 0;
2940 
2941     }
2942 
2943 #ifdef _DEBUG
2944     else if (taint->pos == 0 && taint->len == len) {
2945 
2946       fprintf(stderr, "TAINT FULL\n");
2947 
2948     }
2949 
2950 #endif
2951 
2952   } else {
2953 
2954     buf = afl->queue_cur->cmplog_colorinput;
2955     taint = afl->queue_cur->taint;
2956 
2957   }
2958 
2959   struct tainted *t = taint;
2960 
2961   while (t) {
2962 
2963 #ifdef _DEBUG
2964     fprintf(stderr, "T: idx=%u len=%u\n", t->pos, t->len);
2965 #endif
2966     t = t->next;
2967 
2968   }
2969 
2970 #if defined(_DEBUG) || defined(CMPLOG_INTROSPECTION)
2971   u64 start_time = get_cur_time();
2972   u32 cmp_locations = 0;
2973 #endif
2974 
2975   // Generate the cmplog data
2976 
2977   // manually clear the full cmp_map
2978   memset(afl->shm.cmp_map, 0, sizeof(struct cmp_map));
2979   if (unlikely(common_fuzz_cmplog_stuff(afl, orig_buf, len))) {
2980 
2981     afl->queue_cur->colorized = CMPLOG_LVL_MAX;
2982     while (taint) {
2983 
2984       t = taint->next;
2985       ck_free(taint);
2986       taint = t;
2987 
2988     }
2989 
2990     return 1;
2991 
2992   }
2993 
2994   if (unlikely(!afl->orig_cmp_map)) {
2995 
2996     afl->orig_cmp_map = ck_alloc_nozero(sizeof(struct cmp_map));
2997 
2998   }
2999 
3000   memcpy(afl->orig_cmp_map, afl->shm.cmp_map, sizeof(struct cmp_map));
3001   memset(afl->shm.cmp_map->headers, 0, sizeof(struct cmp_header) * CMP_MAP_W);
3002   if (unlikely(common_fuzz_cmplog_stuff(afl, buf, len))) {
3003 
3004     afl->queue_cur->colorized = CMPLOG_LVL_MAX;
3005     while (taint) {
3006 
3007       t = taint->next;
3008       ck_free(taint);
3009       taint = t;
3010 
3011     }
3012 
3013     return 1;
3014 
3015   }
3016 
3017 #ifdef _DEBUG
3018   dump("ORIG", orig_buf, len);
3019   dump("NEW ", buf, len);
3020 #endif
3021 
3022   // Start insertion loop
3023 
3024   u64 orig_hit_cnt, new_hit_cnt;
3025   u64 orig_execs = afl->fsrv.total_execs;
3026   orig_hit_cnt = afl->queued_items + afl->saved_crashes;
3027 
3028   afl->stage_name = "input-to-state";
3029   afl->stage_short = "its";
3030   afl->stage_max = 0;
3031   afl->stage_cur = 0;
3032 
3033   u32 lvl = (afl->queue_cur->colorized ? 0 : LVL1) +
3034             (afl->cmplog_lvl == CMPLOG_LVL_MAX ? LVL3 : 0);
3035 
3036 #ifdef CMPLOG_COMBINE
3037   u8 *cbuf = afl_realloc((void **)&afl->in_scratch_buf, len + 128);
3038   memcpy(cbuf, orig_buf, len);
3039   u8 *virgin_backup = afl_realloc((void **)&afl->ex_buf, afl->shm.map_size);
3040   memcpy(virgin_backup, afl->virgin_bits, afl->shm.map_size);
3041 #else
3042   u8 *cbuf = NULL;
3043 #endif
3044 
3045   u32 k;
3046   for (k = 0; k < CMP_MAP_W; ++k) {
3047 
3048     if (!afl->shm.cmp_map->headers[k].hits) { continue; }
3049 
3050     if (afl->pass_stats[k].faileds >= CMPLOG_FAIL_MAX ||
3051         afl->pass_stats[k].total >= CMPLOG_FAIL_MAX) {
3052 
3053 #ifdef _DEBUG
3054       fprintf(stderr, "DISABLED %u\n", k);
3055 #endif
3056 
3057       afl->shm.cmp_map->headers[k].hits = 0;  // ignore this cmp
3058 
3059     }
3060 
3061     if (afl->shm.cmp_map->headers[k].type == CMP_TYPE_INS) {
3062 
3063       // fprintf(stderr, "INS %u\n", k);
3064       afl->stage_max +=
3065           MIN((u32)(afl->shm.cmp_map->headers[k].hits), (u32)CMP_MAP_H);
3066 
3067     } else {
3068 
3069       // fprintf(stderr, "RTN %u\n", k);
3070       afl->stage_max +=
3071           MIN((u32)(afl->shm.cmp_map->headers[k].hits), (u32)CMP_MAP_RTN_H);
3072 
3073     }
3074 
3075   }
3076 
3077   for (k = 0; k < CMP_MAP_W; ++k) {
3078 
3079     if (!afl->shm.cmp_map->headers[k].hits) { continue; }
3080 
3081 #if defined(_DEBUG) || defined(CMPLOG_INTROSPECTION)
3082     ++cmp_locations;
3083 #endif
3084 
3085     if (afl->shm.cmp_map->headers[k].type == CMP_TYPE_INS) {
3086 
3087       if (unlikely(cmp_fuzz(afl, k, orig_buf, buf, cbuf, len, lvl, taint))) {
3088 
3089         goto exit_its;
3090 
3091       }
3092 
3093     } else if ((lvl & LVL1) || ((lvl & LVL3) && afl->cmplog_enable_transform)) {
3094 
3095       if (unlikely(rtn_fuzz(afl, k, orig_buf, buf, cbuf, len, lvl, taint))) {
3096 
3097         goto exit_its;
3098 
3099       }
3100 
3101     }
3102 
3103   }
3104 
3105   r = 0;
3106 
3107 exit_its:
3108 
3109   if (afl->cmplog_lvl == CMPLOG_LVL_MAX) {
3110 
3111     afl->queue_cur->colorized = CMPLOG_LVL_MAX;
3112 
3113     if (afl->queue_cur->cmplog_colorinput) {
3114 
3115       ck_free(afl->queue_cur->cmplog_colorinput);
3116 
3117     }
3118 
3119     while (taint) {
3120 
3121       t = taint->next;
3122       ck_free(taint);
3123       taint = t;
3124 
3125     }
3126 
3127     afl->queue_cur->taint = NULL;
3128 
3129   } else {
3130 
3131     afl->queue_cur->colorized = LVL2;
3132 
3133     if (!afl->queue_cur->taint) { afl->queue_cur->taint = taint; }
3134 
3135     if (!afl->queue_cur->cmplog_colorinput) {
3136 
3137       afl->queue_cur->cmplog_colorinput = ck_alloc_nozero(len);
3138       memcpy(afl->queue_cur->cmplog_colorinput, buf, len);
3139       memcpy(buf, orig_buf, len);
3140 
3141     }
3142 
3143   }
3144 
3145 #ifdef CMPLOG_COMBINE
3146   if (afl->queued_items + afl->saved_crashes > orig_hit_cnt + 1) {
3147 
3148     // copy the current virgin bits so we can recover the information
3149     u8 *virgin_save = afl_realloc((void **)&afl->eff_buf, afl->shm.map_size);
3150     memcpy(virgin_save, afl->virgin_bits, afl->shm.map_size);
3151     // reset virgin bits to the backup previous to redqueen
3152     memcpy(afl->virgin_bits, virgin_backup, afl->shm.map_size);
3153 
3154     u8 status = 0;
3155     its_fuzz(afl, cbuf, len, &status);
3156 
3157   // now combine with the saved virgin bits
3158   #ifdef WORD_SIZE_64
3159     u64 *v = (u64 *)afl->virgin_bits;
3160     u64 *s = (u64 *)virgin_save;
3161     u32  i;
3162     for (i = 0; i < (afl->shm.map_size >> 3); i++) {
3163 
3164       v[i] &= s[i];
3165 
3166     }
3167 
3168   #else
3169     u32 *v = (u32 *)afl->virgin_bits;
3170     u32 *s = (u32 *)virgin_save;
3171     u32  i;
3172     for (i = 0; i < (afl->shm.map_size >> 2); i++) {
3173 
3174       v[i] &= s[i];
3175 
3176     }
3177 
3178   #endif
3179 
3180   #ifdef _DEBUG
3181     dump("COMB", cbuf, len);
3182     if (status == 1) {
3183 
3184       fprintf(stderr, "NEW CMPLOG_COMBINED\n");
3185 
3186     } else {
3187 
3188       fprintf(stderr, "NO new combined\n");
3189 
3190     }
3191 
3192   #endif
3193 
3194   }
3195 
3196 #endif
3197 
3198   new_hit_cnt = afl->queued_items + afl->saved_crashes;
3199   afl->stage_finds[STAGE_ITS] += new_hit_cnt - orig_hit_cnt;
3200   afl->stage_cycles[STAGE_ITS] += afl->fsrv.total_execs - orig_execs;
3201 
3202 #if defined(_DEBUG) || defined(CMPLOG_INTROSPECTION)
3203   FILE *f = stderr;
3204   #ifndef _DEBUG
3205   if (afl->not_on_tty) {
3206 
3207     char fn[4096];
3208     snprintf(fn, sizeof(fn), "%s/introspection_cmplog.txt", afl->out_dir);
3209     f = fopen(fn, "a");
3210 
3211   }
3212 
3213   #endif
3214 
3215   if (f) {
3216 
3217     fprintf(f,
3218             "Cmplog: fname=%s len=%u ms=%llu result=%u finds=%llu entries=%u "
3219             "auto_extra_after=%u\n",
3220             afl->queue_cur->fname, len, get_cur_time() - start_time, r,
3221             new_hit_cnt - orig_hit_cnt, cmp_locations, afl->a_extras_cnt);
3222 
3223   #ifndef _DEBUG
3224     if (afl->not_on_tty) { fclose(f); }
3225   #endif
3226 
3227   }
3228 
3229 #endif
3230 
3231   return r;
3232 
3233 }
3234 
3235