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