Skip to content

Commit 002e473

Browse files
Merge pull request #26 from AFLplusplus/afl4
Afl4
2 parents 71ed0d2 + eb765dd commit 002e473

File tree

9 files changed

+352
-100
lines changed

9 files changed

+352
-100
lines changed

accel/tcg/cpu-exec.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -629,7 +629,7 @@ void afl_forkserver(CPUState *cpu) {
629629
status |= (FS_OPT_SET_MAPSIZE(MAP_SIZE) | FS_OPT_MAPSIZE);
630630
if (lkm_snapshot) status |= FS_OPT_SNAPSHOT;
631631
if (sharedmem_fuzzing != 0) status |= FS_OPT_SHDMEM_FUZZ;
632-
if (status) status |= (FS_OPT_ENABLED);
632+
if (status) status |= (FS_OPT_ENABLED | FS_OPT_NEWCMPLOG);
633633
if (getenv("AFL_DEBUG"))
634634
fprintf(stderr, "Debug: Sending status %08x\n", status);
635635
memcpy(tmp, &status, 4);

accel/tcg/tcg-runtime.c

Lines changed: 73 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@
3434

3535
#include "qemuafl/common.h"
3636

37+
uint32_t afl_hash_ip(uint64_t);
38+
3739
void HELPER(afl_entry_routine)(CPUArchState *env) {
3840

3941
afl_forkserver(env_cpu(env));
@@ -117,13 +119,23 @@ void HELPER(afl_cmplog_8)(target_ulong cur_loc, target_ulong arg1,
117119
target_ulong arg2) {
118120

119121
register uintptr_t k = (uintptr_t)cur_loc;
122+
u32 hits = 0;
120123

121-
__afl_cmp_map->headers[k].type = CMP_TYPE_INS;
124+
if (__afl_cmp_map->headers[k].type != CMP_TYPE_INS)
125+
__afl_cmp_map->headers[k].hits = 0;
122126

123-
u32 hits = __afl_cmp_map->headers[k].hits;
124-
__afl_cmp_map->headers[k].hits = hits + 1;
127+
if (__afl_cmp_map->headers[k].hits == 0) {
128+
129+
__afl_cmp_map->headers[k].type = CMP_TYPE_INS;
130+
__afl_cmp_map->headers[k].shape = 0;
131+
132+
} else {
125133

126-
__afl_cmp_map->headers[k].shape = 0;
134+
hits = __afl_cmp_map->headers[k].hits;
135+
136+
}
137+
138+
__afl_cmp_map->headers[k].hits = hits + 1;
127139

128140
hits &= CMP_MAP_H - 1;
129141
__afl_cmp_map->log[k][hits].v0 = arg1;
@@ -135,13 +147,23 @@ void HELPER(afl_cmplog_16)(target_ulong cur_loc, target_ulong arg1,
135147
target_ulong arg2) {
136148

137149
register uintptr_t k = (uintptr_t)cur_loc;
150+
u32 hits = 0;
138151

139-
__afl_cmp_map->headers[k].type = CMP_TYPE_INS;
152+
if (__afl_cmp_map->headers[k].type != CMP_TYPE_INS)
153+
__afl_cmp_map->headers[k].hits = 0;
140154

141-
u32 hits = __afl_cmp_map->headers[k].hits;
142-
__afl_cmp_map->headers[k].hits = hits + 1;
155+
if (__afl_cmp_map->headers[k].hits == 0) {
156+
157+
__afl_cmp_map->headers[k].type = CMP_TYPE_INS;
158+
__afl_cmp_map->headers[k].shape = 1;
143159

144-
__afl_cmp_map->headers[k].shape = 1;
160+
} else {
161+
162+
hits = __afl_cmp_map->headers[k].hits;
163+
164+
}
165+
166+
__afl_cmp_map->headers[k].hits = hits + 1;
145167

146168
hits &= CMP_MAP_H - 1;
147169
__afl_cmp_map->log[k][hits].v0 = arg1;
@@ -153,13 +175,23 @@ void HELPER(afl_cmplog_32)(target_ulong cur_loc, target_ulong arg1,
153175
target_ulong arg2) {
154176

155177
register uintptr_t k = (uintptr_t)cur_loc;
178+
u32 hits = 0;
156179

157-
__afl_cmp_map->headers[k].type = CMP_TYPE_INS;
180+
if (__afl_cmp_map->headers[k].type != CMP_TYPE_INS)
181+
__afl_cmp_map->headers[k].hits = 0;
158182

159-
u32 hits = __afl_cmp_map->headers[k].hits;
160-
__afl_cmp_map->headers[k].hits = hits + 1;
183+
if (__afl_cmp_map->headers[k].hits == 0) {
161184

162-
__afl_cmp_map->headers[k].shape = 3;
185+
__afl_cmp_map->headers[k].type = CMP_TYPE_INS;
186+
__afl_cmp_map->headers[k].shape = 3;
187+
188+
} else {
189+
190+
hits = __afl_cmp_map->headers[k].hits;
191+
192+
}
193+
194+
__afl_cmp_map->headers[k].hits = hits + 1;
163195

164196
hits &= CMP_MAP_H - 1;
165197
__afl_cmp_map->log[k][hits].v0 = arg1;
@@ -171,13 +203,23 @@ void HELPER(afl_cmplog_64)(target_ulong cur_loc, target_ulong arg1,
171203
target_ulong arg2) {
172204

173205
register uintptr_t k = (uintptr_t)cur_loc;
206+
u32 hits = 0;
174207

175-
__afl_cmp_map->headers[k].type = CMP_TYPE_INS;
208+
if (__afl_cmp_map->headers[k].type != CMP_TYPE_INS)
209+
__afl_cmp_map->headers[k].hits = 0;
176210

177-
u32 hits = __afl_cmp_map->headers[k].hits;
178-
__afl_cmp_map->headers[k].hits = hits + 1;
211+
if (__afl_cmp_map->headers[k].hits == 0) {
212+
213+
__afl_cmp_map->headers[k].type = CMP_TYPE_INS;
214+
__afl_cmp_map->headers[k].shape = 7;
179215

180-
__afl_cmp_map->headers[k].shape = 7;
216+
} else {
217+
218+
hits = __afl_cmp_map->headers[k].hits;
219+
220+
}
221+
222+
__afl_cmp_map->headers[k].hits = hits + 1;
181223

182224
hits &= CMP_MAP_H - 1;
183225
__afl_cmp_map->log[k][hits].v0 = arg1;
@@ -242,21 +284,28 @@ void HELPER(afl_cmplog_rtn)(CPUArchState *env) {
242284
uintptr_t k = 0;
243285
#endif
244286

245-
k = (k >> 4) ^ (k << 8);
246-
k &= CMP_MAP_W - 1;
287+
k = (uintptr_t)(afl_hash_ip((uint64_t)k));
288+
k &= (CMP_MAP_W - 1);
247289

248-
__afl_cmp_map->headers[k].type = CMP_TYPE_RTN;
290+
u32 hits = 0;
249291

250-
u32 hits = __afl_cmp_map->headers[k].hits;
251-
__afl_cmp_map->headers[k].hits = hits + 1;
292+
if (__afl_cmp_map->headers[k].type != CMP_TYPE_RTN) {
293+
__afl_cmp_map->headers[k].type = CMP_TYPE_RTN;
294+
__afl_cmp_map->headers[k].hits = 0;
295+
__afl_cmp_map->headers[k].shape = 30;
296+
} else {
297+
hits = __afl_cmp_map->headers[k].hits;
298+
}
252299

253-
__afl_cmp_map->headers[k].shape = 31;
300+
__afl_cmp_map->headers[k].hits += 1;
254301

255302
hits &= CMP_MAP_RTN_H - 1;
303+
((struct cmpfn_operands *)__afl_cmp_map->log[k])[hits].v0_len = 31;
304+
((struct cmpfn_operands *)__afl_cmp_map->log[k])[hits].v1_len = 31;
256305
__builtin_memcpy(((struct cmpfn_operands *)__afl_cmp_map->log[k])[hits].v0,
257-
ptr1, 32);
306+
ptr1, 31);
258307
__builtin_memcpy(((struct cmpfn_operands *)__afl_cmp_map->log[k])[hits].v1,
259-
ptr2, 32);
308+
ptr2, 31);
260309

261310
}
262311

accel/tcg/translate-all.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@
6565

6666
#include "qemuafl/common.h"
6767
#include "tcg/tcg-op.h"
68+
#include "qemuafl/imported/afl_hash.h"
6869

6970
#include <math.h>
7071

@@ -106,7 +107,8 @@ static void afl_gen_trace(target_ulong cur_loc) {
106107

107108
// cur_loc = (cur_loc >> 4) ^ (cur_loc << 8);
108109
// cur_loc &= MAP_SIZE - 1;
109-
cur_loc = pc_hash(cur_loc) & (MAP_SIZE -1);
110+
cur_loc = (uintptr_t)(afl_hash_ip((uint64_t)cur_loc));
111+
cur_loc &= (MAP_SIZE - 1);
110112

111113
/* Implement probabilistic instrumentation by looking at scrambled block
112114
address. This keeps the instrumented locations stable across runs. */

qemuafl/cpu-translate.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@
3535
#include "tcg/tcg.h"
3636
#include "tcg/tcg-op.h"
3737

38+
uint32_t afl_hash_ip(uint64_t);
39+
3840
#if TARGET_LONG_BITS == 64
3941
#define _DEFAULT_MO MO_64
4042
#else
@@ -48,8 +50,8 @@ static void afl_gen_compcov(target_ulong cur_loc, TCGv arg1, TCGv arg2,
4850

4951
if (__afl_cmp_map) {
5052

51-
cur_loc = (cur_loc >> 4) ^ (cur_loc << 8);
52-
cur_loc &= CMP_MAP_W - 1;
53+
cur_loc = (uintptr_t)(afl_hash_ip((uint64_t)cur_loc));
54+
cur_loc &= (CMP_MAP_W - 1);
5355

5456
TCGv cur_loc_v = tcg_const_tl(cur_loc);
5557

@@ -78,8 +80,8 @@ static void afl_gen_compcov(target_ulong cur_loc, TCGv arg1, TCGv arg2,
7880

7981
if (!is_imm && afl_compcov_level < 2) return;
8082

81-
cur_loc = (cur_loc >> 4) ^ (cur_loc << 8);
82-
cur_loc &= MAP_SIZE - 7;
83+
cur_loc = (uintptr_t)(afl_hash_ip((uint64_t)cur_loc));
84+
cur_loc &= (MAP_SIZE - 1);
8385

8486
TCGv cur_loc_v = tcg_const_tl(cur_loc);
8587

qemuafl/imported/afl_hash.h

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
2+
#ifndef _AFL_HASH_H
3+
4+
#define _AFL_HASH_H
5+
6+
/* This is an exerpt of xxhash/XXH3 to prevent colliding with xxhash that is
7+
in QEMU */
8+
9+
#include <stdio.h>
10+
#include <limits.h>
11+
#include <stdint.h>
12+
13+
uint32_t afl_hash_ip(uint64_t ip);
14+
uint64_t AFL_readLE64(const void *memPtr);
15+
uint64_t AFL_rrmxmx(uint64_t h64, uint64_t len);
16+
17+
#define AFL_rotl64(x, r) (((x) << (r)) | ((x) >> (64 - (r))))
18+
19+
inline uint64_t AFL_readLE64(const void *memPtr) {
20+
21+
const uint8_t *bytePtr = (const uint8_t *)memPtr;
22+
return bytePtr[0] | ((uint64_t)bytePtr[1] << 8) | ((uint64_t)bytePtr[2] << 16) |
23+
((uint64_t)bytePtr[3] << 24) | ((uint64_t)bytePtr[4] << 32) |
24+
((uint64_t)bytePtr[5] << 40) | ((uint64_t)bytePtr[6] << 48) |
25+
((uint64_t)bytePtr[7] << 56);
26+
27+
}
28+
29+
inline uint64_t AFL_rrmxmx(uint64_t h64, uint64_t len) {
30+
31+
/* this mix is inspired by Pelle Evensen's rrmxmx */
32+
h64 ^= AFL_rotl64(h64, 49) ^ AFL_rotl64(h64, 24);
33+
h64 *= 0x9FB21C651E98DF25ULL;
34+
h64 ^= (h64 >> 35) + len;
35+
h64 *= 0x9FB21C651E98DF25ULL;
36+
return h64 ^ (h64 >> 28);
37+
38+
}
39+
40+
inline uint32_t afl_hash_ip(uint64_t ip) {
41+
42+
const uint8_t secret[] = {
43+
44+
0xb8, 0xfe, 0x6c, 0x39, 0x23, 0xa4, 0x4b, 0xbe, 0x7c, 0x01, 0x81, 0x2c,
45+
0xf7, 0x21, 0xad, 0x1c, 0xde, 0xd4, 0x6d, 0xe9, 0x83, 0x90, 0x97, 0xdb,
46+
0x72, 0x40, 0xa4, 0xa4, 0xb7, 0xb3, 0x67, 0x1f, 0xcb, 0x79, 0xe6, 0x4e,
47+
0xcc, 0xc0, 0xe5, 0x78, 0x82, 0x5a, 0xd0, 0x7d, 0xcc, 0xff, 0x72, 0x21,
48+
0xb8, 0x08, 0x46, 0x74, 0xf7, 0x43, 0x24, 0x8e, 0xe0, 0x35, 0x90, 0xe6,
49+
0x81, 0x3a, 0x26, 0x4c, 0x3c, 0x28, 0x52, 0xbb, 0x91, 0xc3, 0x00, 0xcb,
50+
0x88, 0xd0, 0x65, 0x8b, 0x1b, 0x53, 0x2e, 0xa3, 0x71, 0x64, 0x48, 0x97,
51+
0xa2, 0x0d, 0xf9, 0x4e, 0x38, 0x19, 0xef, 0x46, 0xa9, 0xde, 0xac, 0xd8,
52+
0xa8, 0xfa, 0x76, 0x3f, 0xe3, 0x9c, 0x34, 0x3f, 0xf9, 0xdc, 0xbb, 0xc7,
53+
0xc7, 0x0b, 0x4f, 0x1d, 0x8a, 0x51, 0xe0, 0x4b, 0xcd, 0xb4, 0x59, 0x31,
54+
0xc8, 0x9f, 0x7e, 0xc9, 0xd9, 0x78, 0x73, 0x64, 0xea, 0xc5, 0xac, 0x83,
55+
0x34, 0xd3, 0xeb, 0xc3, 0xc5, 0x81, 0xa0, 0xff, 0xfa, 0x13, 0x63, 0xeb,
56+
0x17, 0x0d, 0xdd, 0x51, 0xb7, 0xf0, 0xda, 0x49, 0xd3, 0x16, 0x55, 0x26,
57+
0x29, 0xd4, 0x68, 0x9e, 0x2b, 0x16, 0xbe, 0x58, 0x7d, 0x47, 0xa1, 0xfc,
58+
0x8f, 0xf8, 0xb8, 0xd1, 0x7a, 0xd0, 0x31, 0xce, 0x45, 0xcb, 0x3a, 0x8f,
59+
0x95, 0x16, 0x04, 0x28, 0xaf, 0xd7, 0xfb, 0xca, 0xbb, 0x4b, 0x40, 0x7e,
60+
61+
};
62+
63+
uint32_t const input1 = (uint32_t)(ip & 0xffffffff);
64+
uint32_t const input2 = (uint32_t)(ip >> 32);
65+
uint64_t const bitflip = (AFL_readLE64(secret + 8) ^ AFL_readLE64(secret + 16));
66+
uint64_t const input64 = input2 + (((uint64_t)input1) << 32);
67+
uint64_t const keyed = input64 ^ bitflip;
68+
return AFL_rrmxmx(keyed, 8);
69+
70+
}
71+
72+
#endif

qemuafl/imported/cmplog.h

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
you may not use this file except in compliance with the License.
1919
You may obtain a copy of the License at:
2020
21-
http://www.apache.org/licenses/LICENSE-2.0
21+
https://www.apache.org/licenses/LICENSE-2.0
2222
2323
Shared code to handle the shared memory. This is used by the fuzzer
2424
as well the other components like afl-tmin, afl-showmap, etc...
@@ -29,42 +29,47 @@
2929
#define _AFL_CMPLOG_H
3030

3131
#include "config.h"
32-
//#include "forkserver.h"
32+
33+
#define CMPLOG_LVL_MAX 3
3334

3435
#define CMP_MAP_W 65536
35-
#define CMP_MAP_H 256
36+
#define CMP_MAP_H 32
3637
#define CMP_MAP_RTN_H (CMP_MAP_H / 4)
3738

3839
#define SHAPE_BYTES(x) (x + 1)
3940

40-
#define CMP_TYPE_INS 0
41-
#define CMP_TYPE_RTN 1
41+
#define CMP_TYPE_INS 1
42+
#define CMP_TYPE_RTN 2
4243

4344
struct cmp_header {
4445

45-
unsigned hits : 20;
46-
47-
unsigned cnt : 20;
48-
unsigned id : 16;
49-
50-
unsigned shape : 5; // from 0 to 31
51-
unsigned type : 1;
46+
unsigned hits : 24;
47+
unsigned id : 24;
48+
unsigned shape : 5;
49+
unsigned type : 2;
50+
unsigned attribute : 4;
51+
unsigned overflow : 1;
52+
unsigned reserved : 4;
5253

5354
} __attribute__((packed));
5455

5556
struct cmp_operands {
5657

5758
u64 v0;
5859
u64 v1;
60+
u64 v0_128;
61+
u64 v1_128;
5962

60-
};
63+
} __attribute__((packed));
6164

6265
struct cmpfn_operands {
6366

64-
u8 v0[32];
65-
u8 v1[32];
67+
u8 v0[31];
68+
u8 v0_len;
69+
u8 v1[31];
70+
u8 v1_len;
6671

67-
};
72+
} __attribute__((packed));
6873

6974
typedef struct cmp_operands cmp_map_list[CMP_MAP_H];
7075

@@ -77,7 +82,8 @@ struct cmp_map {
7782

7883
/* Execs the child */
7984

80-
//void cmplog_exec_child(afl_forkserver_t *fsrv, char **argv);
85+
struct afl_forkserver;
86+
void cmplog_exec_child(struct afl_forkserver *fsrv, char **argv);
8187

8288
#endif
8389

0 commit comments

Comments
 (0)