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