mirror of
https://github.com/AFLplusplus/AFLplusplus.git
synced 2025-06-24 06:42:42 +00:00
Compare commits
596 Commits
Author | SHA1 | Date | |
---|---|---|---|
4f53803dfe | |||
ed06b3bc9f | |||
3081f589cc | |||
5d08f33a5f | |||
46cbe22feb | |||
6cba007c76 | |||
1461f3a0ee | |||
03d306a97f | |||
0278eb5351 | |||
8e88ef02ad | |||
ad2eaf54ad | |||
a287076ac0 | |||
c352943aa5 | |||
bd3900c084 | |||
48002fe146 | |||
31c8a052a6 | |||
46b87a6d62 | |||
b4208dde94 | |||
4a492d5d8e | |||
945309c316 | |||
41de569353 | |||
7aecf14c07 | |||
7b24f4a329 | |||
ebb919f771 | |||
b43f37456f | |||
701e89bbcd | |||
e3fae3e9b0 | |||
464ec516d5 | |||
3af042d5bf | |||
c1e4b8f7f6 | |||
79deeb46dd | |||
9cf260ca1f | |||
82752fe38d | |||
d11ade56e2 | |||
665d32a0dc | |||
e1bd9fc6ac | |||
2c6f2c970d | |||
0e3157375b | |||
f39cf57eac | |||
e62999c95f | |||
0b22665391 | |||
5777ceaf23 | |||
21916a7f60 | |||
6c83a9ccc1 | |||
bc9fda61a3 | |||
4e0b8beba8 | |||
1448eab8ec | |||
55aec64038 | |||
42fc9acf5b | |||
cdbd86a112 | |||
1aa58a1972 | |||
d0587a3ac4 | |||
d1fd072b79 | |||
c282156451 | |||
a9bda37d18 | |||
577b286508 | |||
009f663e2c | |||
1efb7c8a8b | |||
7f614be3a5 | |||
04d2476b32 | |||
c1d9a4fab9 | |||
8a060a4b68 | |||
a11488b9dc | |||
4cc9232485 | |||
20c46c0ed6 | |||
b3d16f7b8c | |||
c0837409bd | |||
78b7e14c73 | |||
f9a8b60b3b | |||
4a1cf0b9af | |||
c1e40c5fb7 | |||
d6a2edb42a | |||
5e8e233755 | |||
31ed850c4b | |||
994ac55878 | |||
cb5a61d8a1 | |||
146e535f7b | |||
b88f132975 | |||
12271064f8 | |||
55b67f1372 | |||
d21fb1a558 | |||
2e6c74f9b9 | |||
2a4281ce8d | |||
9cd702e75d | |||
8b35dd49be | |||
703fd0b610 | |||
db172473b5 | |||
5b44067e9c | |||
8531928fa4 | |||
804c98a1e8 | |||
1792ce2825 | |||
1d6cd5dd19 | |||
7e9abf1bba | |||
6a28502191 | |||
fc7c95e9f4 | |||
4086b93ad7 | |||
837a9693ab | |||
60d3ecab63 | |||
d0f39849c2 | |||
8820bf4758 | |||
75d8c47a6b | |||
3ec794c806 | |||
bf46ff8823 | |||
6f61fca15a | |||
b8cb35fa8c | |||
dfc9b3dba0 | |||
ab5f95e17a | |||
fe66a95d96 | |||
72a24e6439 | |||
088dd6476c | |||
30df52cd8c | |||
74d262c7b5 | |||
d7c99007ff | |||
bdb5622bd4 | |||
cf2ddf437b | |||
2b7aae66b6 | |||
598a3c6b5e | |||
0978283915 | |||
f27cbdb793 | |||
1689a8e053 | |||
6edc3b51ba | |||
93fb1d1a24 | |||
bf7a6d69cf | |||
6ddd5ecf4a | |||
e2099114aa | |||
db84f75a81 | |||
9111035495 | |||
d78a8698e4 | |||
7b2f983bf3 | |||
1910b0ad42 | |||
9a04df5d97 | |||
4f03f380ea | |||
e3b08d430c | |||
4f35c30371 | |||
9df9064549 | |||
256bc6ab42 | |||
614c5127ca | |||
5bb894f1ee | |||
8d72f41e20 | |||
b928303dd0 | |||
76b26ac2c6 | |||
dd16be405a | |||
2e57d86576 | |||
4369d6209f | |||
26ae4124f3 | |||
25945d51a4 | |||
db23931e7c | |||
6e37f9b237 | |||
2f2ddbbd79 | |||
ba7c012427 | |||
5bfe0c1a15 | |||
bb72cc752a | |||
8c4ecd90a8 | |||
c0d53a1aa7 | |||
31a1fbae33 | |||
09f1854cd1 | |||
4a6b751b93 | |||
bbcb3dd53e | |||
eac53afe7b | |||
19ca7b3761 | |||
55a2362348 | |||
8afb60d2f9 | |||
69a596c089 | |||
ccb952dde8 | |||
7c380a6612 | |||
88e2affe73 | |||
3f26818d97 | |||
bd83eb0f42 | |||
c5acf3f137 | |||
ea42feb06a | |||
a09720665d | |||
6f394842be | |||
02f4f75526 | |||
43f462c91b | |||
77bad3ad23 | |||
835a4b6497 | |||
d1a7b6988c | |||
365129d811 | |||
b840ac91dc | |||
dcd2f9ac77 | |||
37d9afc5cc | |||
62b3a1e800 | |||
9c54be6cf1 | |||
53409530b3 | |||
43014cd465 | |||
e27e3622d4 | |||
b169629dbd | |||
8fbeeb1439 | |||
2a489f844b | |||
a161aac7c1 | |||
a7f928ac31 | |||
50ae95cee4 | |||
f6bfa96a96 | |||
e86dcc9f18 | |||
9d33580aac | |||
77cfd504cf | |||
f7bbd467b5 | |||
8993ba4305 | |||
ba7313b521 | |||
e2d30641be | |||
2248773566 | |||
5f43d0ad42 | |||
af47531745 | |||
e80bd2d30c | |||
ac5815d994 | |||
540d741df0 | |||
ecb5854be0 | |||
25b650f59d | |||
ed6f19d3d8 | |||
aecd157244 | |||
43a98b0ec2 | |||
3b00cee858 | |||
2fbc0aefb1 | |||
2276a2f5c3 | |||
8fcca6fb41 | |||
b8568034f0 | |||
3ebf41ba34 | |||
304e84502d | |||
a6e42d98d9 | |||
de176a10bc | |||
e3183f7cda | |||
b5e0fff6b9 | |||
36db3428ab | |||
e7da8b9d6b | |||
c134df30db | |||
b5e6c2d6e2 | |||
b6f8509234 | |||
d45cd63583 | |||
0c9b460cc4 | |||
dd762726dc | |||
e68d57feec | |||
0c9d8e5929 | |||
75c3fa91dc | |||
a37c7e1246 | |||
392dcd57c6 | |||
1369cf7176 | |||
eccd0985a0 | |||
0617b8898a | |||
fbcdeb8439 | |||
6ed0a2b4aa | |||
8e50c0c103 | |||
f2cd5e1d8e | |||
9f6b012fbf | |||
ec0b83f127 | |||
0c81982e67 | |||
5014b86c3c | |||
44b5e1f488 | |||
31652eeb2a | |||
4bb4d4ad00 | |||
5331eca5d9 | |||
74e264a20a | |||
f0937f96d4 | |||
92cbdb9f45 | |||
fe36ceaa55 | |||
0618bfd4ae | |||
bdfd38771a | |||
477063e9ee | |||
e46c106b89 | |||
69630338ff | |||
112759cd39 | |||
f8767c397b | |||
e8d098335b | |||
12a87cfacb | |||
2806d6be2f | |||
2d9b793dbb | |||
7f02f0da61 | |||
bc2ccf464f | |||
b8536ced09 | |||
1db82f3303 | |||
fd713413e8 | |||
2d4a4ba73f | |||
348f980f21 | |||
ca55858aa7 | |||
e639521b01 | |||
894339c5d7 | |||
e13dc9b7e6 | |||
5fb657f569 | |||
d2700c7525 | |||
4cf358b589 | |||
5e708b23c6 | |||
9419e39fdf | |||
c202d80dea | |||
eecbdd99e1 | |||
64293cdc82 | |||
f8a5f1cd9e | |||
a3125c38f4 | |||
224add0222 | |||
19636f748c | |||
7aa5e1c443 | |||
93279db71b | |||
5bf760510e | |||
03dc80afc4 | |||
fda3106fd9 | |||
9721a77204 | |||
92a8c2804f | |||
e1521fa8eb | |||
4e3cd8ac3f | |||
31a8beb449 | |||
e7d871c8bf | |||
56d5aa3101 | |||
c6a2a4046e | |||
6dd5e931fc | |||
635140ba43 | |||
497f341eac | |||
068aa13c6b | |||
ba7ae6c59d | |||
6ae95271be | |||
a2e0163cc1 | |||
1db3b81d2e | |||
0a16ea7487 | |||
a26bb0b0f2 | |||
7d3530a22e | |||
a87ea96913 | |||
81609a0f42 | |||
938edab25f | |||
29c9870658 | |||
b6c4f3775a | |||
5ee5564ae2 | |||
ab36756061 | |||
831b8f35d5 | |||
0cf78b7748 | |||
0892a2245e | |||
622474e9e4 | |||
0cabc12f91 | |||
b282ce999d | |||
24b9d74e70 | |||
c03f2897d0 | |||
90fbf59bf1 | |||
93c7cbd496 | |||
db60555c1b | |||
45117a3384 | |||
4d4880b428 | |||
ac6ccd53df | |||
4ec376bd6a | |||
3c0448305b | |||
a6029a10cc | |||
26eaf53a83 | |||
5d623a27ed | |||
69e554b941 | |||
7340374a7c | |||
67d356b73f | |||
da18f1f722 | |||
58abcceff5 | |||
ad0d0c77fb | |||
2c3f761ede | |||
70c60cfba7 | |||
f3b6d64ad3 | |||
43e9a13921 | |||
526dbe8f16 | |||
951a0e5225 | |||
458b939bc4 | |||
476aca5b67 | |||
96bf0f8323 | |||
58206a3180 | |||
f138ab8ac6 | |||
50839cf6e9 | |||
626a4434ed | |||
d84cc73d13 | |||
6b049536f1 | |||
1d17210d9f | |||
1582aa9da2 | |||
e01307a993 | |||
beb9f95359 | |||
c49a4c7027 | |||
b08df87f5c | |||
72226d6f89 | |||
40adc34413 | |||
eeae114b76 | |||
48a862c503 | |||
29544e4d2b | |||
420a90ff75 | |||
45603367bf | |||
f7ea0f569f | |||
2bf92848ff | |||
ad65cfb400 | |||
5ffc8c7076 | |||
8943ba0249 | |||
b02adf6b3f | |||
6ef5d7c135 | |||
9ece2e3f2c | |||
4b2cdaf47c | |||
9b5b71b61b | |||
59465bd249 | |||
ed50f37c79 | |||
a96bda82f9 | |||
1860f6e594 | |||
c9ad3acc9b | |||
93c7a42453 | |||
ee07fc9f6d | |||
443edcd771 | |||
6650ef4274 | |||
b85174fc8d | |||
08f6d59f50 | |||
2ed2ac80bc | |||
2300088446 | |||
306a917956 | |||
0ea53ea5b5 | |||
092260e9f9 | |||
52e19d35fa | |||
bf17953353 | |||
e46fac6063 | |||
6062668679 | |||
acc178e5dd | |||
31adb57fd7 | |||
7652406c12 | |||
a607adb7a3 | |||
036a79268b | |||
335b2d4542 | |||
603136efa0 | |||
1e01ccc8fd | |||
9f6d27ddce | |||
8fcd404352 | |||
b2b887d04d | |||
849994dedd | |||
1286d1906f | |||
fae760fc9e | |||
01f442d810 | |||
eaedf2e62f | |||
07e0b39126 | |||
98238ed763 | |||
340d6aa97c | |||
5ae4a7ae02 | |||
80158de3e8 | |||
730713193a | |||
fea76dff23 | |||
808022d3e0 | |||
eee78077e2 | |||
ca91d3fbc0 | |||
ad4a776fc6 | |||
ebdb71aeb0 | |||
6dc58750cf | |||
1b84448be3 | |||
61ceef64b1 | |||
5404eef7be | |||
6fed799957 | |||
dd88069711 | |||
07bc202e0a | |||
f2b7357ff3 | |||
3cbaefd247 | |||
037a14f621 | |||
88e41f01c8 | |||
369fce9c85 | |||
eaf4a29930 | |||
48070e0148 | |||
c23bbddde9 | |||
038fef962c | |||
42c663e7c7 | |||
956fa95d77 | |||
ea0ea88ed3 | |||
e0e8645d6c | |||
a2100f32e0 | |||
25a6c2c006 | |||
7f8347b12e | |||
8e4bd0314e | |||
a7fd84e186 | |||
e405e721fa | |||
49d4fa4346 | |||
375aca2997 | |||
9f8eea5467 | |||
58aa181d01 | |||
f49e391022 | |||
698f1e272b | |||
023fc19ce0 | |||
40df85d1e6 | |||
47e7d243f7 | |||
6d209ce045 | |||
34a3060b0f | |||
c77709cdd9 | |||
27338fcef1 | |||
9fab7e892d | |||
dc151caa18 | |||
e1d7f4af35 | |||
d85722a4f6 | |||
775861ea94 | |||
602eceed8b | |||
68dc4829b3 | |||
a25f27de28 | |||
ed1a6f8a57 | |||
a9292626a6 | |||
1e7485dcee | |||
ba3a039e45 | |||
58871777ae | |||
f98dc8abe8 | |||
bd13d32437 | |||
028d4c8c64 | |||
79080355ac | |||
ba28f5fbfa | |||
5ba66a8860 | |||
06f0982f0f | |||
eda770fd32 | |||
37d2039211 | |||
d8e8d34c4e | |||
96ada75bd9 | |||
87596105ef | |||
ac639012fb | |||
a84b7c7820 | |||
5549212d9e | |||
eb52f1cc08 | |||
236fb9b145 | |||
e5d305ad42 | |||
76a033431d | |||
7793692590 | |||
97ba817aa7 | |||
6e6d91b6b0 | |||
123ec5d136 | |||
5da5d6e0df | |||
c33de47120 | |||
643df2b538 | |||
970e0b14ce | |||
3768933c92 | |||
da5d3d63e2 | |||
ccad11f7eb | |||
0d164e4c18 | |||
644e069450 | |||
75af391408 | |||
9604fe922e | |||
d5b6c0f773 | |||
12ab9ebd32 | |||
4859b583ad | |||
e6eee685ce | |||
ceb7e44e6f | |||
1ffb1b6b2a | |||
d668010bed | |||
58b80b68bc | |||
44a7696169 | |||
2f9eeef60c | |||
b0a912a838 | |||
4d493452a4 | |||
d88c97ad28 | |||
ba28c4982b | |||
8746b3e310 | |||
a5db79e4d6 | |||
d5812786f3 | |||
227c1a7002 | |||
8fedf49984 | |||
243c6640a8 | |||
33a129e00c | |||
9cefc4d3d4 | |||
3046c80cd5 | |||
ab0823cd3b | |||
de561b730a | |||
a518c4d75c | |||
660b697ed9 | |||
cefc9a00bf | |||
0c054f520e | |||
e731a1c1ab | |||
523ce154c3 | |||
04219f9857 | |||
136febaf68 | |||
046473acd5 | |||
8412b17d79 | |||
e9621db61c | |||
68d883d428 | |||
46ef6a54e1 | |||
355dcf6320 | |||
a4017406dc | |||
b99bbf671b | |||
9d3c25ac81 | |||
4e9c6050d0 | |||
f75778adfb | |||
db65dc5a0b | |||
bb6d9cddd7 | |||
ee7d69b817 | |||
aad9ac2b33 | |||
358cd1b062 | |||
0aeee03e47 | |||
9d305acbf3 | |||
5f492da717 | |||
c5b4e26052 | |||
1a60e35a2a | |||
2260a065f4 | |||
1eb54c4c3e | |||
c39596c8bf | |||
88cbaeb3e1 | |||
25f9c1f4fb | |||
934a02f7f6 | |||
98a2a334de | |||
1fc1b32db2 | |||
b01ef97569 | |||
c3197dfeb7 | |||
a9e6998b82 | |||
dcb5bc3fa5 | |||
daaefcddc0 | |||
3c0cfd82bc | |||
df0638ab87 | |||
27d05f3c21 | |||
86d76b52ac | |||
c38dedbecd | |||
2f74feaf99 | |||
806a76afae | |||
f822cdeb74 | |||
7fabe5052b | |||
353ae3682a | |||
ca0c9f6d17 | |||
629edb1e78 | |||
8012b555a8 |
@ -24,7 +24,7 @@ import importlib.metadata
|
||||
|
||||
# string_re = re.compile('(\\"(\\\\.|[^"\\\\])*\\")') # TODO: for future use
|
||||
|
||||
CURRENT_LLVM = os.getenv('LLVM_VERSION', 17)
|
||||
CURRENT_LLVM = os.getenv('LLVM_VERSION', 18)
|
||||
CLANG_FORMAT_BIN = os.getenv("CLANG_FORMAT_BIN", "")
|
||||
|
||||
|
||||
|
52
.github/workflows/ci.yml
vendored
52
.github/workflows/ci.yml
vendored
@ -20,39 +20,39 @@ jobs:
|
||||
AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES: 1
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: update
|
||||
run: sudo apt-get update && sudo apt-get upgrade -y
|
||||
- name: debug
|
||||
run: apt-cache search plugin-dev | grep gcc-; echo; apt-cache search clang-format- | grep clang-format-
|
||||
- name: update
|
||||
run: sudo apt-get update
|
||||
# && sudo apt-get upgrade -y
|
||||
- name: install packages
|
||||
#run: sudo apt-get install -y -m -f --install-suggests build-essential git libtool libtool-bin automake bison libglib2.0-0 clang llvm-dev libc++-dev findutils libcmocka-dev python3-dev python3-setuptools ninja-build python3-pip
|
||||
run: sudo apt-get install -y -m -f build-essential git libtool libtool-bin automake flex bison libglib2.0-0 clang llvm-dev libc++-dev findutils libcmocka-dev python3-dev python3-setuptools ninja-build python3-pip
|
||||
run: sudo apt-get install -y -m -f build-essential gcc-10 g++-10 git libtool libtool-bin automake flex bison libglib2.0-0 clang-12 llvm-12-dev libc++-dev findutils libcmocka-dev python3-dev python3-setuptools ninja-build python3-pip gcc-10-plugin-dev
|
||||
- name: compiler installed
|
||||
run: gcc -v; echo; clang -v
|
||||
- name: install gcc plugin
|
||||
run: sudo apt-get install -y -m -f --install-suggests $(readlink /usr/bin/gcc)-plugin-dev
|
||||
- name: build afl++
|
||||
run: make distrib ASAN_BUILD=1 NO_NYX=1
|
||||
run: export NO_NYX=1; export ASAN_BUILD=1; export LLVM_CONFIG=llvm-config-12; make ASAN_BUILD=1 NO_NYX=1 LLVM_CONFIG=llvm-config-12 distrib
|
||||
- name: run tests
|
||||
run: sudo -E ./afl-system-config; make tests
|
||||
# macos:
|
||||
# runs-on: macOS-latest
|
||||
# env:
|
||||
# AFL_MAP_SIZE: 65536
|
||||
# AFL_SKIP_CPUFREQ: 1
|
||||
# AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES: 1
|
||||
# steps:
|
||||
# - uses: actions/checkout@v3
|
||||
# - name: install
|
||||
# run: brew install make gcc llvm
|
||||
# - name: fix install
|
||||
# run: cd /usr/local/bin; ln -s gcc-11 gcc; ln -s g++-11 g++; which gcc; gcc -v
|
||||
# - name: build
|
||||
# run: export PATH=/usr/local/Cellar/llvm/*/":$PATH"; export CC=/usr/local/Cellar/llvm/*/bin/clang; export CXX="$CC"++; export LLVM_CONFIG=/usr/local/Cellar/llvm/*/bin/llvm-config; sudo -E ./afl-system-config; gmake ASAN_BUILD=1
|
||||
# - name: frida
|
||||
# run: export CC=/usr/local/Cellar/llvm/*/bin/clang; export CXX="$CC"++; cd frida_mode; gmake
|
||||
# - name: run tests
|
||||
# run: sudo -E ./afl-system-config; export CC=/usr/local/Cellar/llvm/*/bin/clang; export CXX="$CC"++; export PATH=/usr/local/Cellar/llvm/*/":/usr/local/bin:$PATH"; export LLVM_CONFIG=/usr/local/Cellar/llvm/*/bin/llvm-config; gmake tests
|
||||
# - name: force frida test for MacOS
|
||||
# run: export AFL_PATH=`pwd`; /usr/local/bin/gcc -o test-instr test-instr.c; mkdir in; echo > in/in; AFL_NO_UI=1 ./afl-fuzz -O -i in -o out -V 5 -- ./test-instr
|
||||
macos:
|
||||
runs-on: macOS-latest
|
||||
env:
|
||||
AFL_MAP_SIZE: 65536
|
||||
AFL_SKIP_CPUFREQ: 1
|
||||
AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES: 1
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: install
|
||||
run: brew install make gcc llvm
|
||||
# - name: fix install
|
||||
# run: cd /usr/local/bin; ln -s gcc-11 gcc; ln -s g++-11 g++; which gcc; gcc -v
|
||||
# - name: build
|
||||
# run: export PATH=/usr/local/Cellar/llvm/*/":$PATH"; export CC=/usr/local/Cellar/llvm/*/bin/clang; export CXX="$CC"++; export LLVM_CONFIG=/usr/local/Cellar/llvm/*/bin/llvm-config; sudo -E ./afl-system-config; gmake ASAN_BUILD=1 afl-fuzz
|
||||
- name: build
|
||||
run: sudo -E ./afl-system-config; gmake ASAN_BUILD=1 afl-fuzz
|
||||
# - name: frida
|
||||
# run: export CC=/usr/local/Cellar/llvm/*/bin/clang; export CXX="$CC"++; cd frida_mode; gmake
|
||||
# - name: run tests
|
||||
# run: sudo -E ./afl-system-config; export CC=/usr/local/Cellar/llvm/*/bin/clang; export CXX="$CC"++; export PATH=/usr/local/Cellar/llvm/*/":/usr/local/bin:$PATH"; export LLVM_CONFIG=/usr/local/Cellar/llvm/*/bin/llvm-config; gmake tests
|
||||
# - name: force frida test for MacOS
|
||||
# run: export AFL_PATH=`pwd`; /usr/local/bin/gcc -o test-instr test-instr.c; mkdir in; echo > in/in; AFL_NO_UI=1 ./afl-fuzz -O -i in -o out -V 5 -- ./test-instr
|
||||
|
8
.gitignore
vendored
8
.gitignore
vendored
@ -6,6 +6,7 @@
|
||||
*.pyc
|
||||
*.so
|
||||
*.swp
|
||||
.DS_Store
|
||||
.sync_tmp
|
||||
.test
|
||||
.test2
|
||||
@ -99,10 +100,17 @@ unicorn_mode/samples/*/\.test-*
|
||||
utils/afl_network_proxy/afl-network-client
|
||||
utils/afl_network_proxy/afl-network-server
|
||||
utils/afl_proxy/afl-proxy
|
||||
utils/bench/hash
|
||||
utils/optimin/build
|
||||
utils/optimin/optimin
|
||||
utils/persistent_mode/persistent_demo
|
||||
utils/persistent_mode/persistent_demo_new
|
||||
utils/persistent_mode/persistent_demo_new_compat
|
||||
utils/persistent_mode/test-instr
|
||||
utils/replay_record/persistent_demo_replay
|
||||
utils/replay_record/persistent_demo_replay_compat
|
||||
utils/replay_record/persistent_demo_replay_argparse
|
||||
utils/plot_ui/afl-plot-ui
|
||||
vuln_prog
|
||||
argv_fuzz_demo
|
||||
argv_fuzz_persistent_demo
|
6
.gitmodules
vendored
6
.gitmodules
vendored
@ -19,9 +19,9 @@
|
||||
[submodule "nyx_mode/libnyx"]
|
||||
path = nyx_mode/libnyx
|
||||
url = https://github.com/nyx-fuzz/libnyx.git
|
||||
[submodule "nyx_mode/QEMU-Nyx"]
|
||||
path = nyx_mode/QEMU-Nyx
|
||||
url = https://github.com/nyx-fuzz/qemu-nyx.git
|
||||
[submodule "nyx_mode/packer"]
|
||||
path = nyx_mode/packer
|
||||
url = https://github.com/nyx-fuzz/packer.git
|
||||
[submodule "nyx_mode/QEMU-Nyx"]
|
||||
path = nyx_mode/QEMU-Nyx
|
||||
url = https://github.com/nyx-fuzz/QEMU-Nyx
|
||||
|
@ -27,5 +27,5 @@ keywords:
|
||||
- qemu
|
||||
- llvm
|
||||
- unicorn-emulator
|
||||
- securiy
|
||||
- security
|
||||
license: AGPL-3.0-or-later
|
||||
|
@ -34,6 +34,7 @@ file in one the following folders:
|
||||
* [docs/](docs/) (this is where you can find most of our docs content)
|
||||
* [frida_mode/](frida_mode/)
|
||||
* [instrumentation/](instrumentation/)
|
||||
* [nyx_mode/](nyx_mode/)
|
||||
* [qemu_mode/](qemu_mode/)
|
||||
* [unicorn_mode/](unicorn_mode/)
|
||||
|
||||
@ -47,7 +48,7 @@ When working on the docs, please keep the following guidelines in mind:
|
||||
* Don't: fuzzing-network-service.md
|
||||
* Use a maximum of 80 characters per line to make reading in a console easier.
|
||||
* Make all pull requests against `dev`, see
|
||||
[#how-to-submit-a-pull-request-to-afl](#how-to-submit-a-pull-request-to-afl).
|
||||
[#how-to-submit-a-pull-request](#how-to-submit-a-pull-request).
|
||||
|
||||
And finally, here are some best practices for writing docs content:
|
||||
|
||||
@ -56,4 +57,4 @@ And finally, here are some best practices for writing docs content:
|
||||
* Use bulleted lists to present similar content in a way that makes it easy to
|
||||
scan.
|
||||
* Use numbered lists for procedures or prioritizing.
|
||||
* Link to related content, for example, prerequisites or in-depth discussions.
|
||||
* Link to related content, for example, prerequisites or in-depth discussions.
|
||||
|
@ -16,8 +16,8 @@ ENV NO_CORESIGHT=1
|
||||
ENV NO_NYX=1
|
||||
|
||||
### Only change these if you know what you are doing:
|
||||
# LLVM 15 does not look good so we stay at 14 to still have LTO
|
||||
ENV LLVM_VERSION=14
|
||||
# Current recommended LLVM version is 16
|
||||
ENV LLVM_VERSION=16
|
||||
# GCC 12 is producing compile errors for some targets so we stay at GCC 11
|
||||
ENV GCC_VERSION=11
|
||||
|
||||
@ -88,7 +88,7 @@ ARG TEST_BUILD
|
||||
|
||||
RUN sed -i.bak 's/^ -/ /g' GNUmakefile && \
|
||||
make clean && make distrib && \
|
||||
([ "${TEST_BUILD}" ] || (make install && make clean)) && \
|
||||
([ "${TEST_BUILD}" ] || (make install)) && \
|
||||
mv GNUmakefile.bak GNUmakefile
|
||||
|
||||
RUN echo "set encoding=utf-8" > /root/.vimrc && \
|
||||
|
162
GNUmakefile
162
GNUmakefile
@ -19,21 +19,21 @@
|
||||
# so use a variable for '#'
|
||||
HASH=\#
|
||||
|
||||
PREFIX ?= /usr/local
|
||||
BIN_PATH = $(PREFIX)/bin
|
||||
HELPER_PATH = $(PREFIX)/lib/afl
|
||||
DOC_PATH = $(PREFIX)/share/doc/afl
|
||||
MISC_PATH = $(PREFIX)/share/afl
|
||||
MAN_PATH = $(PREFIX)/share/man/man8
|
||||
PREFIX ?= /usr/local
|
||||
BIN_PATH = $(PREFIX)/bin
|
||||
HELPER_PATH = $(PREFIX)/lib/afl
|
||||
DOC_PATH = $(PREFIX)/share/doc/afl
|
||||
MISC_PATH = $(PREFIX)/share/afl
|
||||
MAN_PATH = $(PREFIX)/share/man/man8
|
||||
INCLUDE_PATH = $(PREFIX)/include/afl
|
||||
|
||||
PROGNAME = afl
|
||||
VERSION = $(shell grep '^$(HASH)define VERSION ' ../config.h | cut -d '"' -f2)
|
||||
|
||||
# PROGS intentionally omit afl-as, which gets installed elsewhere.
|
||||
|
||||
PROGS = afl-fuzz afl-showmap afl-tmin afl-gotcpu afl-analyze
|
||||
SH_PROGS = afl-plot afl-cmin afl-cmin.bash afl-whatsup afl-addseeds afl-system-config afl-persistent-config afl-cc
|
||||
MANPAGES=$(foreach p, $(PROGS) $(SH_PROGS), $(p).8) afl-as.8
|
||||
HEADERS = include/afl-fuzz.h include/afl-mutations.h include/afl-persistent-replay.h include/afl-prealloc.h include/afl-record-compat.h include/alloc-inl.h include/android-ashmem.h include/cmplog.h include/common.h include/config.h include/coverage-32.h include/coverage-64.h include/debug.h include/envs.h include/forkserver.h include/hash.h include/list.h include/sharedmem.h include/snapshot-inl.h include/t1ha.h include/t1ha0_ia32aes_b.h include/t1ha_bits.h include/t1ha_selfcheck.h include/types.h include/xxhash.h
|
||||
MANPAGES=$(foreach p, $(PROGS) $(SH_PROGS), $(p).8)
|
||||
ASAN_OPTIONS=detect_leaks=0
|
||||
|
||||
SYS = $(shell uname -s)
|
||||
@ -52,7 +52,7 @@ endif
|
||||
ifdef ASAN_BUILD
|
||||
$(info Compiling ASAN version of binaries)
|
||||
override CFLAGS += $(ASAN_CFLAGS)
|
||||
LDFLAGS += $(ASAN_LDFLAGS)
|
||||
override LDFLAGS += $(ASAN_LDFLAGS)
|
||||
endif
|
||||
ifdef UBSAN_BUILD
|
||||
$(info Compiling UBSAN version of binaries)
|
||||
@ -66,6 +66,10 @@ ifdef MSAN_BUILD
|
||||
override LDFLAGS += -fsanitize=memory
|
||||
endif
|
||||
|
||||
ifdef CODE_COVERAGE
|
||||
override CFLAGS += -D__AFL_CODE_COVERAGE=1
|
||||
endif
|
||||
|
||||
ifeq "$(findstring android, $(shell $(CC) --version 2>/dev/null))" ""
|
||||
ifeq "$(shell echo 'int main() {return 0; }' | $(CC) $(CFLAGS) -Werror -x c - -flto=full -o .test 2>/dev/null && echo 1 || echo 0 ; rm -f .test )" "1"
|
||||
CFLAGS_FLTO ?= -flto=full
|
||||
@ -80,38 +84,44 @@ else
|
||||
endif
|
||||
endif
|
||||
|
||||
#ifeq "$(shell echo 'int main() {return 0; }' | $(CC) -fno-move-loop-invariants -fdisable-tree-cunrolli -x c - -o .test 2>/dev/null && echo 1 || echo 0 ; rm -f .test )" "1"
|
||||
# SPECIAL_PERFORMANCE += -fno-move-loop-invariants -fdisable-tree-cunrolli
|
||||
#endif
|
||||
|
||||
#ifeq "$(shell echo 'int main() {return 0; }' | $(CC) $(CFLAGS) -Werror -x c - -march=native -o .test 2>/dev/null && echo 1 || echo 0 ; rm -f .test )" "1"
|
||||
# ifndef SOURCE_DATE_EPOCH
|
||||
# HAVE_MARCHNATIVE = 1
|
||||
# CFLAGS_OPT += -march=native
|
||||
# endif
|
||||
#endif
|
||||
ifdef PERFORMANCE
|
||||
SPECIAL_PERFORMANCE := -D_AFL_SPECIAL_PERFORMANCE
|
||||
ifeq "$(SYS)" "Linux"
|
||||
ifeq "$(shell grep avx2 /proc/cpuinfo)" ""
|
||||
else
|
||||
SPECIAL_PERFORMANCE += -mavx2 -D_HAVE_AVX2
|
||||
endif
|
||||
endif
|
||||
ifeq "$(shell echo 'int main() {return 0; }' | $(CC) $(CFLAGS) -Werror -x c - -march=native -o .test 2>/dev/null && echo 1 || echo 0 ; rm -f .test )" "1"
|
||||
HAVE_MARCHNATIVE = 1
|
||||
SPECIAL_PERFORMANCE += -march=native
|
||||
endif
|
||||
$(info SPECIAL_PERFORMANCE=$(SPECIAL_PERFORMANCE))
|
||||
else
|
||||
SPECIAL_PERFORMANCE :=
|
||||
endif
|
||||
|
||||
ifneq "$(SYS)" "Darwin"
|
||||
#ifeq "$(HAVE_MARCHNATIVE)" "1"
|
||||
# SPECIAL_PERFORMANCE += -march=native
|
||||
#endif
|
||||
#ifeq "$(HAVE_MARCHNATIVE)" "1"
|
||||
# SPECIAL_PERFORMANCE += -march=native
|
||||
#endif
|
||||
#ifndef DEBUG
|
||||
# CFLAGS_OPT += -D_FORTIFY_SOURCE=1
|
||||
# override CFLAGS_OPT += -D_FORTIFY_SOURCE=1
|
||||
#endif
|
||||
else
|
||||
# On some odd MacOS system configurations, the Xcode sdk path is not set correctly
|
||||
SDK_LD = -L$(shell xcrun --show-sdk-path)/usr/lib
|
||||
LDFLAGS += $(SDK_LD)
|
||||
override LDFLAGS += $(SDK_LD)
|
||||
endif
|
||||
|
||||
COMPILER_TYPE=$(shell $(CC) --version|grep "Free Software Foundation")
|
||||
ifneq "$(COMPILER_TYPE)" ""
|
||||
#$(info gcc is being used)
|
||||
CFLAGS_OPT += -Wno-error=format-truncation -Wno-format-truncation
|
||||
override CFLAGS_OPT += -Wno-format-truncation
|
||||
endif
|
||||
|
||||
ifeq "$(SYS)" "SunOS"
|
||||
LDFLAGS = -lkstat -lrt -lsocket -lnsl
|
||||
override LDFLAGS = -lkstat -lrt -lsocket -lnsl
|
||||
endif
|
||||
|
||||
ifdef STATIC
|
||||
@ -121,8 +131,8 @@ ifdef STATIC
|
||||
PYFLAGS=
|
||||
PYTHON_INCLUDE = /
|
||||
|
||||
CFLAGS_OPT += -static
|
||||
LDFLAGS += -lm -lpthread -lz -lutil
|
||||
override CFLAGS_OPT += -static
|
||||
override LDFLAGS += -lm -lpthread -lz -lutil
|
||||
endif
|
||||
|
||||
ifdef PROFILING
|
||||
@ -315,10 +325,12 @@ ifdef TEST_MMAP
|
||||
endif
|
||||
|
||||
.PHONY: all
|
||||
all: test_x86 test_shm test_python ready $(PROGS) afl-as llvm gcc_plugin test_build all_done
|
||||
all: test_x86 test_shm test_python ready $(PROGS) llvm gcc_plugin test_build all_done
|
||||
-$(MAKE) -C utils/aflpp_driver
|
||||
@echo
|
||||
@echo
|
||||
@echo
|
||||
@echo
|
||||
@echo Build Summary:
|
||||
@test -e afl-fuzz && echo "[+] afl-fuzz and supporting tools successfully built" || echo "[-] afl-fuzz could not be built, please set CC to a working compiler"
|
||||
@test -e afl-llvm-pass.so && echo "[+] LLVM basic mode successfully built" || echo "[-] LLVM mode could not be built, please install at least llvm-11 and clang-11 or newer, see docs/INSTALL.md"
|
||||
@ -327,6 +339,7 @@ all: test_x86 test_shm test_python ready $(PROGS) afl-as llvm gcc_plugin test_bu
|
||||
ifneq "$(SYS)" "Darwin"
|
||||
@test -e afl-gcc-pass.so && echo "[+] gcc_mode successfully built" || echo "[-] gcc_mode could not be built, it is optional, install gcc-VERSION-plugin-dev to enable this"
|
||||
endif
|
||||
@test -e afl-cc || echo "[-] AFL++ instrumentation compilers could not be built! Install llvm-VERSION-dev or gcc-VERSION-plugin-dev, see docs/INSTALL.md!"
|
||||
@echo
|
||||
|
||||
.PHONY: llvm
|
||||
@ -385,6 +398,7 @@ help:
|
||||
@echo
|
||||
@echo Known build environment options:
|
||||
@echo "=========================================="
|
||||
@echo "PERFORMANCE - compile with performance options that make the binary not transferable to other systems. Recommended!"
|
||||
@echo STATIC - compile AFL++ static
|
||||
@echo "CODE_COVERAGE - compile the target for code coverage (see docs/instrumentation/README.llvm.md)"
|
||||
@echo ASAN_BUILD - compiles AFL++ with memory sanitizer for debug purposes
|
||||
@ -395,7 +409,7 @@ help:
|
||||
@echo INTROSPECTION - compile afl-fuzz with mutation introspection
|
||||
@echo NO_PYTHON - disable python support
|
||||
@echo NO_SPLICING - disables splicing mutation in afl-fuzz, not recommended for normal fuzzing
|
||||
@echo NO_UTF - do not use UTF-8 for line rendering in status screen (fallback to G1 box drawing, of vanilla AFL)
|
||||
@echo "NO_UTF - do not use UTF-8 for line rendering in status screen (fallback to G1 box drawing, of vanilla AFL)"
|
||||
@echo NO_NYX - disable building nyx mode dependencies
|
||||
@echo "NO_CORESIGHT - disable building coresight (arm64 only)"
|
||||
@echo NO_UNICORN_ARM64 - disable building unicorn on arm64
|
||||
@ -430,6 +444,14 @@ test_shm:
|
||||
@echo "[-] shmat seems not to be working, switching to mmap implementation"
|
||||
endif
|
||||
|
||||
ifeq "$(shell echo '$(HASH)include <zlib.h>@int main() {return 0; }' | tr @ '\n' | $(CC) $(CFLAGS) -Werror -x c - -lz -o .test 2>/dev/null && echo 1 || echo 0 ; rm -f .test )" "1"
|
||||
override SPECIAL_PERFORMANCE += -DHAVE_ZLIB
|
||||
override LDFLAGS += -lz
|
||||
$(info [+] ZLIB detected)
|
||||
else
|
||||
$(info [!] Warning: no ZLIB detected)
|
||||
endif
|
||||
|
||||
.PHONY: test_python
|
||||
ifeq "$(PYTHON_OK)" "1"
|
||||
test_python:
|
||||
@ -444,36 +466,32 @@ endif
|
||||
ready:
|
||||
@echo "[+] Everything seems to be working, ready to compile. ($(shell $(CC) --version 2>&1|head -n 1))"
|
||||
|
||||
afl-as: src/afl-as.c include/afl-as.h $(COMM_HDR) | test_x86
|
||||
$(CC) $(CFLAGS) src/$@.c -o $@ $(LDFLAGS)
|
||||
@ln -sf afl-as as
|
||||
|
||||
src/afl-performance.o : $(COMM_HDR) src/afl-performance.c include/hash.h
|
||||
$(CC) $(CFLAGS) $(CFLAGS_OPT) -Iinclude -c src/afl-performance.c -o src/afl-performance.o
|
||||
$(CC) $(CFLAGS) $(CFLAGS_OPT) $(SPECIAL_PERFORMANCE) -Iinclude -c src/afl-performance.c -o src/afl-performance.o
|
||||
|
||||
src/afl-common.o : $(COMM_HDR) src/afl-common.c include/common.h
|
||||
$(CC) $(CFLAGS) $(CFLAGS_FLTO) -c src/afl-common.c -o src/afl-common.o
|
||||
$(CC) $(CFLAGS) $(CFLAGS_FLTO) $(SPECIAL_PERFORMANCE) -c src/afl-common.c -o src/afl-common.o
|
||||
|
||||
src/afl-forkserver.o : $(COMM_HDR) src/afl-forkserver.c include/forkserver.h
|
||||
$(CC) $(CFLAGS) $(CFLAGS_FLTO) -c src/afl-forkserver.c -o src/afl-forkserver.o
|
||||
$(CC) $(CFLAGS) $(CFLAGS_FLTO) $(SPECIAL_PERFORMANCE) -c src/afl-forkserver.c -o src/afl-forkserver.o
|
||||
|
||||
src/afl-sharedmem.o : $(COMM_HDR) src/afl-sharedmem.c include/sharedmem.h
|
||||
$(CC) $(CFLAGS) $(CFLAGS_FLTO) -c src/afl-sharedmem.c -o src/afl-sharedmem.o
|
||||
$(CC) $(CFLAGS) $(CFLAGS_FLTO) $(SPECIAL_PERFORMANCE) -c src/afl-sharedmem.c -o src/afl-sharedmem.o
|
||||
|
||||
afl-fuzz: $(COMM_HDR) include/afl-fuzz.h $(AFL_FUZZ_FILES) src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o src/afl-performance.o | test_x86
|
||||
$(CC) $(CFLAGS) $(COMPILE_STATIC) $(CFLAGS_FLTO) $(AFL_FUZZ_FILES) src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o src/afl-performance.o -o $@ $(PYFLAGS) $(LDFLAGS) -lm
|
||||
$(CC) $(CFLAGS) $(COMPILE_STATIC) $(CFLAGS_FLTO) $(SPECIAL_PERFORMANCE) $(AFL_FUZZ_FILES) src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o src/afl-performance.o -o $@ $(PYFLAGS) $(LDFLAGS) -lm
|
||||
|
||||
afl-showmap: src/afl-showmap.c src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o src/afl-performance.o $(COMM_HDR) | test_x86
|
||||
$(CC) $(CFLAGS) $(COMPILE_STATIC) $(CFLAGS_FLTO) src/$@.c src/afl-fuzz-mutators.c src/afl-fuzz-python.c src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o src/afl-performance.o -o $@ $(PYFLAGS) $(LDFLAGS)
|
||||
$(CC) $(CFLAGS) $(COMPILE_STATIC) $(CFLAGS_FLTO) $(SPECIAL_PERFORMANCE) src/$@.c src/afl-fuzz-mutators.c src/afl-fuzz-python.c src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o src/afl-performance.o -o $@ $(PYFLAGS) $(LDFLAGS)
|
||||
|
||||
afl-tmin: src/afl-tmin.c src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o src/afl-performance.o $(COMM_HDR) | test_x86
|
||||
$(CC) $(CFLAGS) $(COMPILE_STATIC) $(CFLAGS_FLTO) src/$@.c src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o src/afl-performance.o -o $@ $(LDFLAGS)
|
||||
$(CC) $(CFLAGS) $(COMPILE_STATIC) $(CFLAGS_FLTO) $(SPECIAL_PERFORMANCE) src/$@.c src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o src/afl-performance.o -o $@ $(LDFLAGS)
|
||||
|
||||
afl-analyze: src/afl-analyze.c src/afl-common.o src/afl-sharedmem.o src/afl-performance.o src/afl-forkserver.o $(COMM_HDR) | test_x86
|
||||
$(CC) $(CFLAGS) $(COMPILE_STATIC) $(CFLAGS_FLTO) src/$@.c src/afl-common.o src/afl-sharedmem.o src/afl-performance.o src/afl-forkserver.o -o $@ $(LDFLAGS)
|
||||
$(CC) $(CFLAGS) $(COMPILE_STATIC) $(CFLAGS_FLTO) $(SPECIAL_PERFORMANCE) src/$@.c src/afl-common.o src/afl-sharedmem.o src/afl-performance.o src/afl-forkserver.o -o $@ $(LDFLAGS)
|
||||
|
||||
afl-gotcpu: src/afl-gotcpu.c src/afl-common.o $(COMM_HDR) | test_x86
|
||||
$(CC) $(CFLAGS) $(COMPILE_STATIC) $(CFLAGS_FLTO) src/$@.c src/afl-common.o -o $@ $(LDFLAGS)
|
||||
$(CC) $(CFLAGS) $(COMPILE_STATIC) $(CFLAGS_FLTO) $(SPECIAL_PERFORMANCE) src/$@.c src/afl-common.o -o $@ $(LDFLAGS)
|
||||
|
||||
.PHONY: document
|
||||
document: afl-fuzz-document
|
||||
@ -490,17 +508,17 @@ unit_maybe_alloc: test/unittests/unit_maybe_alloc.o
|
||||
./test/unittests/unit_maybe_alloc
|
||||
|
||||
test/unittests/unit_hash.o : $(COMM_HDR) include/alloc-inl.h test/unittests/unit_hash.c $(AFL_FUZZ_FILES) src/afl-performance.o
|
||||
@$(CC) $(CFLAGS) $(ASAN_CFLAGS) -c test/unittests/unit_hash.c -o test/unittests/unit_hash.o
|
||||
@$(CC) $(CFLAGS) $(ASAN_CFLAGS) $(SPECIAL_PERFORMANCE) -c test/unittests/unit_hash.c -o test/unittests/unit_hash.o
|
||||
|
||||
unit_hash: test/unittests/unit_hash.o src/afl-performance.o
|
||||
@$(CC) $(CFLAGS) -Wl,--wrap=exit -Wl,--wrap=printf $^ -o test/unittests/unit_hash $(LDFLAGS) $(ASAN_LDFLAGS) -lcmocka
|
||||
@$(CC) $(CFLAGS) $(SPECIAL_PERFORMANCE) -Wl,--wrap=exit -Wl,--wrap=printf $^ -o test/unittests/unit_hash $(LDFLAGS) $(ASAN_LDFLAGS) -lcmocka
|
||||
./test/unittests/unit_hash
|
||||
|
||||
test/unittests/unit_rand.o : $(COMM_HDR) include/alloc-inl.h test/unittests/unit_rand.c $(AFL_FUZZ_FILES) src/afl-performance.o
|
||||
@$(CC) $(CFLAGS) $(ASAN_CFLAGS) -c test/unittests/unit_rand.c -o test/unittests/unit_rand.o
|
||||
@$(CC) $(CFLAGS) $(ASAN_CFLAGS) $(SPECIAL_PERFORMANCE) -c test/unittests/unit_rand.c -o test/unittests/unit_rand.o
|
||||
|
||||
unit_rand: test/unittests/unit_rand.o src/afl-common.o src/afl-performance.o
|
||||
@$(CC) $(CFLAGS) $(ASAN_CFLAGS) -Wl,--wrap=exit -Wl,--wrap=printf $^ -o test/unittests/unit_rand $(LDFLAGS) $(ASAN_LDFLAGS) -lcmocka
|
||||
@$(CC) $(CFLAGS) $(ASAN_CFLAGS) $(SPECIAL_PERFORMANCE) -Wl,--wrap=exit -Wl,--wrap=printf $^ -o test/unittests/unit_rand $(LDFLAGS) $(ASAN_LDFLAGS) -lcmocka
|
||||
./test/unittests/unit_rand
|
||||
|
||||
test/unittests/unit_list.o : $(COMM_HDR) include/list.h test/unittests/unit_list.c $(AFL_FUZZ_FILES)
|
||||
@ -555,27 +573,27 @@ code-format:
|
||||
|
||||
.PHONY: test_build
|
||||
ifndef AFL_NO_X86
|
||||
test_build: afl-cc afl-gcc afl-as afl-showmap
|
||||
test_build: afl-cc afl-showmap
|
||||
@echo "[*] Testing the CC wrapper afl-cc and its instrumentation output..."
|
||||
@unset AFL_MAP_SIZE AFL_USE_UBSAN AFL_USE_CFISAN AFL_USE_LSAN AFL_USE_ASAN AFL_USE_MSAN; ASAN_OPTIONS=detect_leaks=0 AFL_INST_RATIO=100 AFL_PATH=. ./afl-cc test-instr.c $(LDFLAGS) -o test-instr 2>&1 || (echo "Oops, afl-cc failed"; exit 1 )
|
||||
@unset AFL_MAP_SIZE AFL_USE_UBSAN AFL_USE_CFISAN AFL_USE_LSAN AFL_USE_ASAN AFL_USE_MSAN AFL_LLVM_ALLOWLIST AFL_LLVM_DENYLIST; ASAN_OPTIONS=detect_leaks=0 AFL_INST_RATIO=100 AFL_PATH=. ./afl-cc test-instr.c $(LDFLAGS) -o test-instr 2>&1 || (echo "Oops, afl-cc failed"; exit 1 )
|
||||
-ASAN_OPTIONS=detect_leaks=0 ./afl-showmap -q -m none -o .test-instr0 ./test-instr < /dev/null
|
||||
-echo 1 | ASAN_OPTIONS=detect_leaks=0 ./afl-showmap -m none -q -o .test-instr1 ./test-instr
|
||||
@rm -f test-instr
|
||||
@cmp -s .test-instr0 .test-instr1; DR="$$?"; rm -f .test-instr0 .test-instr1; if [ "$$DR" = "0" ]; then echo; echo "Oops, the instrumentation of afl-cc does not seem to be behaving correctly!"; echo; echo "Please post to https://github.com/AFLplusplus/AFLplusplus/issues to troubleshoot the issue."; echo; exit 1; fi
|
||||
@echo
|
||||
@echo "[+] All right, the instrumentation of afl-cc seems to be working!"
|
||||
# @echo "[*] Testing the CC wrapper afl-gcc and its instrumentation output..."
|
||||
# @unset AFL_MAP_SIZE AFL_USE_UBSAN AFL_USE_CFISAN AFL_USE_LSAN AFL_USE_ASAN AFL_USE_MSAN; AFL_CC=$(CC) ASAN_OPTIONS=detect_leaks=0 AFL_INST_RATIO=100 AFL_PATH=. ./afl-gcc test-instr.c -o test-instr 2>&1 || (echo "Oops, afl-gcc failed"; exit 1 )
|
||||
# @echo "[*] Testing the CC wrapper and its instrumentation output..."
|
||||
# @unset AFL_MAP_SIZE AFL_USE_UBSAN AFL_USE_CFISAN AFL_USE_LSAN AFL_USE_ASAN AFL_USE_MSAN; AFL_CC=$(CC) ASAN_OPTIONS=detect_leaks=0 AFL_INST_RATIO=100 AFL_PATH=. ./afl-clang-fast test-instr.c -o test-instr 2>&1 || (echo "Oops, afl-clang-fast failed"; exit 1 )
|
||||
# ASAN_OPTIONS=detect_leaks=0 ./afl-showmap -m none -q -o .test-instr0 ./test-instr < /dev/null
|
||||
# echo 1 | ASAN_OPTIONS=detect_leaks=0 ./afl-showmap -m none -q -o .test-instr1 ./test-instr
|
||||
# @rm -f test-instr
|
||||
# @cmp -s .test-instr0 .test-instr1; DR="$$?"; rm -f .test-instr0 .test-instr1; if [ "$$DR" = "0" ]; then echo; echo "Oops, the instrumentation of afl-gcc does not seem to be behaving correctly!"; \
|
||||
# @cmp -s .test-instr0 .test-instr1; DR="$$?"; rm -f .test-instr0 .test-instr1; if [ "$$DR" = "0" ]; then echo; echo "Oops, the instrumentation of afl-clang-fast does not seem to be behaving correctly!"; \
|
||||
# gcc -v 2>&1 | grep -q -- --with-as= && ( echo; echo "Gcc is configured not to use an external assembler with the -B option." ) || \
|
||||
# ( echo; echo "Please post to https://github.com/AFLplusplus/AFLplusplus/issues to troubleshoot the issue." ); echo; exit 0; fi
|
||||
# @echo
|
||||
# @echo "[+] All right, the instrumentation of afl-gcc seems to be working!"
|
||||
# @echo "[+] All right, the instrumentation of afl-clang-fast seems to be working!"
|
||||
else
|
||||
test_build: afl-cc afl-as afl-showmap
|
||||
test_build: afl-cc afl-showmap
|
||||
@echo "[!] Note: skipping build tests (you may need to use LLVM or QEMU mode)."
|
||||
endif
|
||||
|
||||
@ -585,7 +603,8 @@ all_done: test_build
|
||||
@test -e cmplog-instructions-pass.so && echo "[+] LLVM mode for 'afl-cc' successfully built!" || echo "[-] LLVM mode for 'afl-cc' failed to build, likely you either don't have llvm installed, or you need to set LLVM_CONFIG, to point to e.g. llvm-config-11. See instrumentation/README.llvm.md how to do this. Highly recommended!"
|
||||
@test -e SanitizerCoverageLTO.so && echo "[+] LLVM LTO mode for 'afl-cc' successfully built!" || echo "[-] LLVM LTO mode for 'afl-cc' failed to build, this would need LLVM 11+, see instrumentation/README.lto.md how to build it"
|
||||
@test -e afl-gcc-pass.so && echo "[+] gcc_plugin for 'afl-cc' successfully built!" || echo "[-] gcc_plugin for 'afl-cc' failed to build, unless you really need it that is fine - or read instrumentation/README.gcc_plugin.md how to build it"
|
||||
@echo "[+] All done! Be sure to review the README.md - it's pretty short and useful."
|
||||
@test -e afl-cc && echo "[+] All done! Be sure to review the README.md - it's pretty short and useful."
|
||||
@test -e afl-cc || echo "[-] ERROR - neither afl-clang-fast or afl-gcc-fast could be compiled - YOU ARE MISSING PACKAGES! Read docs/INSTALL.md!"
|
||||
@if [ "$(SYS)" = "Darwin" ]; then printf "\nWARNING: Fuzzing on MacOS X is slow because of the unusually high overhead of\nfork() on this OS. Consider using Linux or *BSD for fuzzing software not\nspecifically for MacOS.\n\n"; fi
|
||||
@! tty <&1 >/dev/null || printf "\033[0;30mNOTE: If you can read this, your terminal probably uses white background.\nThis will make the UI hard to read. See docs/status_screen.md for advice.\033[0m\n" 2>/dev/null
|
||||
|
||||
@ -593,7 +612,7 @@ all_done: test_build
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
rm -rf $(PROGS) afl-fuzz-document afl-as as afl-g++ afl-clang afl-clang++ *.o src/*.o *~ a.out core core.[1-9][0-9]* *.stackdump .test .test1 .test2 test-instr .test-instr0 .test-instr1 afl-cs-proxy afl-qemu-trace afl-gcc-fast afl-g++-fast ld *.so *.8 test/unittests/*.o test/unittests/unit_maybe_alloc test/unittests/preallocable .afl-* afl-gcc afl-g++ afl-clang afl-clang++ test/unittests/unit_hash test/unittests/unit_rand *.dSYM lib*.a
|
||||
rm -rf $(PROGS) afl-fuzz-document as afl-as afl-g++ afl-clang afl-clang++ *.o src/*.o *~ a.out core core.[1-9][0-9]* *.stackdump .test .test1 .test2 test-instr .test-instr0 .test-instr1 afl-cs-proxy afl-qemu-trace afl-gcc-fast afl-g++-fast ld *.so *.8 test/unittests/*.o test/unittests/unit_maybe_alloc test/unittests/preallocable .afl-* afl-gcc afl-g++ afl-clang afl-clang++ test/unittests/unit_hash test/unittests/unit_rand *.dSYM lib*.a
|
||||
-$(MAKE) -f GNUmakefile.llvm clean
|
||||
-$(MAKE) -f GNUmakefile.gcc_plugin clean
|
||||
-$(MAKE) -C utils/libdislocator clean
|
||||
@ -649,16 +668,16 @@ endif
|
||||
# -$(MAKE) -C utils/plot_ui
|
||||
-$(MAKE) -C frida_mode
|
||||
ifneq "$(SYS)" "Darwin"
|
||||
ifeq "$(ARCH)" "aarch64"
|
||||
ifndef NO_CORESIGHT
|
||||
ifeq "$(ARCH)" "aarch64"
|
||||
ifndef NO_CORESIGHT
|
||||
-$(MAKE) -C coresight_mode
|
||||
endif
|
||||
endif
|
||||
ifeq "$(SYS)" "Linux"
|
||||
ifndef NO_NYX
|
||||
endif
|
||||
ifeq "$(SYS)" "Linux"
|
||||
ifndef NO_NYX
|
||||
-cd nyx_mode && ./build_nyx_support.sh
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
-cd qemu_mode && sh ./build_qemu_support.sh
|
||||
ifeq "$(ARCH)" "aarch64"
|
||||
ifndef NO_UNICORN_ARM64
|
||||
@ -748,7 +767,7 @@ endif
|
||||
@test -e SanitizerCoveragePCGUARD.so && echo "[+] LLVM mode successfully built" || echo "[-] LLVM mode could not be built, please install at least llvm-13 and clang-13 or newer, see docs/INSTALL.md"
|
||||
@test -e SanitizerCoverageLTO.so && echo "[+] LLVM LTO mode successfully built" || echo "[-] LLVM LTO mode could not be built, it is optional, if you want it, please install LLVM 11-14. More information at instrumentation/README.lto.md on how to build it"
|
||||
ifneq "$(SYS)" "Darwin"
|
||||
test -e afl-gcc-pass.so && echo "[+] gcc_mode successfully built" || echo "[-] gcc_mode could not be built, it is optional, install gcc-VERSION-plugin-dev to enable this"
|
||||
@test -e afl-gcc-pass.so && echo "[+] gcc_mode successfully built" || echo "[-] gcc_mode could not be built, it is optional, install gcc-VERSION-plugin-dev to enable this"
|
||||
endif
|
||||
ifeq "$(SYS)" "Linux"
|
||||
ifndef NO_NYX
|
||||
@ -782,7 +801,7 @@ install: all $(MANPAGES)
|
||||
@rm -f $${DESTDIR}$(BIN_PATH)/afl-plot.sh
|
||||
@rm -f $${DESTDIR}$(BIN_PATH)/afl-as
|
||||
@rm -f $${DESTDIR}$(HELPER_PATH)/afl-llvm-rt.o $${DESTDIR}$(HELPER_PATH)/afl-llvm-rt-32.o $${DESTDIR}$(HELPER_PATH)/afl-llvm-rt-64.o $${DESTDIR}$(HELPER_PATH)/afl-gcc-rt.o
|
||||
@for i in afl-llvm-dict2file.so afl-llvm-lto-instrumentlist.so afl-llvm-pass.so cmplog-instructions-pass.so cmplog-routines-pass.so cmplog-switches-pass.so compare-transform-pass.so libcompcov.so libdislocator.so libnyx.so libqasan.so libtokencap.so SanitizerCoverageLTO.so SanitizerCoveragePCGUARD.so split-compares-pass.so split-switches-pass.so; do echo rm -fv $${DESTDIR}$(HELPER_PATH)/$${i}; done
|
||||
@for i in afl-llvm-dict2file.so afl-llvm-lto-instrumentlist.so afl-llvm-pass.so cmplog-instructions-pass.so cmplog-routines-pass.so cmplog-switches-pass.so compare-transform-pass.so libcompcov.so libdislocator.so libnyx.so libqasan.so libtokencap.so SanitizerCoverageLTO.so SanitizerCoveragePCGUARD.so split-compares-pass.so split-switches-pass.so injection-pass.so; do echo rm -fv $${DESTDIR}$(HELPER_PATH)/$${i}; done
|
||||
install -m 755 $(PROGS) $(SH_PROGS) $${DESTDIR}$(BIN_PATH)
|
||||
@if [ -f afl-qemu-trace ]; then install -m 755 afl-qemu-trace $${DESTDIR}$(BIN_PATH); fi
|
||||
@if [ -f utils/plot_ui/afl-plot-ui ]; then install -m 755 utils/plot_ui/afl-plot-ui $${DESTDIR}$(BIN_PATH); fi
|
||||
@ -806,22 +825,25 @@ endif
|
||||
ln -sf afl-cc $${DESTDIR}$(BIN_PATH)/afl-g++
|
||||
ln -sf afl-cc $${DESTDIR}$(BIN_PATH)/afl-clang
|
||||
ln -sf afl-cc $${DESTDIR}$(BIN_PATH)/afl-clang++
|
||||
@mkdir -m 755 -p $${DESTDIR}$(INCLUDE_PATH)
|
||||
install -m 644 $(HEADERS) $${DESTDIR}$(INCLUDE_PATH)
|
||||
@mkdir -m 0755 -p ${DESTDIR}$(MAN_PATH)
|
||||
install -m0644 *.8 ${DESTDIR}$(MAN_PATH)
|
||||
install -m 755 afl-as $${DESTDIR}$(HELPER_PATH)
|
||||
ln -sf afl-as $${DESTDIR}$(HELPER_PATH)/as
|
||||
install -m 644 docs/*.md $${DESTDIR}$(DOC_PATH)
|
||||
cp -r testcases/ $${DESTDIR}$(MISC_PATH)
|
||||
cp -r dictionaries/ $${DESTDIR}$(MISC_PATH)
|
||||
cp injections.dic $${DESTDIR}$(MISC_PATH)
|
||||
|
||||
.PHONY: uninstall
|
||||
uninstall:
|
||||
-cd $${DESTDIR}$(BIN_PATH) && rm -f $(PROGS) $(SH_PROGS) afl-cs-proxy afl-qemu-trace afl-plot-ui afl-fuzz-document afl-network-server afl-g* afl-plot.sh afl-as afl-ld-lto afl-c* afl-lto*
|
||||
-cd $${DESTDIR}$(HELPER_PATH) && rm -f afl-g*.*o afl-llvm-*.*o afl-compiler-*.*o libdislocator.so libtokencap.so libcompcov.so libqasan.so afl-frida-trace.so libnyx.so socketfuzz*.so argvfuzz*.so libAFLDriver.a libAFLQemuDriver.a as afl-as SanitizerCoverage*.so compare-transform-pass.so cmplog-*-pass.so split-*-pass.so dynamic_list.txt
|
||||
-cd $${DESTDIR}$(BIN_PATH) && rm -f $(PROGS) $(SH_PROGS) afl-cs-proxy afl-qemu-trace afl-plot-ui afl-fuzz-document afl-network-client afl-network-server afl-g* afl-plot.sh afl-ld-lto afl-c* afl-lto*
|
||||
-cd $${DESTDIR}$(INCLUDE_PATH) && rm -f $(HEADERS:include/%=%)
|
||||
-cd $${DESTDIR}$(HELPER_PATH) && rm -f afl-g*.*o afl-llvm-*.*o afl-compiler-*.*o libdislocator.so libtokencap.so libcompcov.so libqasan.so afl-frida-trace.so libnyx.so socketfuzz*.so argvfuzz*.so libAFLDriver.a libAFLQemuDriver.a as afl-as SanitizerCoverage*.so compare-transform-pass.so cmplog-*-pass.so split-*-pass.so dynamic_list.txt injections.dic
|
||||
-rm -rf $${DESTDIR}$(MISC_PATH)/testcases $${DESTDIR}$(MISC_PATH)/dictionaries
|
||||
-sh -c "ls docs/*.md | sed 's|^docs/|$${DESTDIR}$(DOC_PATH)/|' | xargs rm -f"
|
||||
-cd $${DESTDIR}$(MAN_PATH) && rm -f $(MANPAGES)
|
||||
-rmdir $${DESTDIR}$(BIN_PATH) 2>/dev/null
|
||||
-rmdir $${DESTDIR}$(INCLUDE_PATH) 2>/dev/null
|
||||
-rmdir $${DESTDIR}$(HELPER_PATH) 2>/dev/null
|
||||
-rmdir $${DESTDIR}$(MISC_PATH) 2>/dev/null
|
||||
-rmdir $${DESTDIR}$(DOC_PATH) 2>/dev/null
|
||||
|
@ -11,7 +11,7 @@
|
||||
# from Laszlo Szekeres.
|
||||
#
|
||||
# Copyright 2015 Google Inc. All rights reserved.
|
||||
# Copyright 2019-2023 AFLplusplus Project. All rights reserved.
|
||||
# Copyright 2019-2024 AFLplusplus Project. All rights reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
@ -163,7 +163,7 @@ $(PASSES): instrumentation/afl-gcc-common.h
|
||||
.PHONY: test_build
|
||||
test_build: $(PROGS)
|
||||
@echo "[*] Testing the CC wrapper and instrumentation output..."
|
||||
unset AFL_USE_ASAN AFL_USE_MSAN; ASAN_OPTIONS=detect_leaks=0 AFL_QUIET=1 AFL_INST_RATIO=100 AFL_PATH=. AFL_CC=$(CC) ./afl-gcc-fast $(CFLAGS) $(CPPFLAGS) ./test-instr.c -o test-instr $(LDFLAGS)
|
||||
unset AFL_USE_ASAN AFL_USE_MSAN AFL_LLVM_ALLOWLIST AFL_LLVM_DENYLIST; ASAN_OPTIONS=detect_leaks=0 AFL_QUIET=1 AFL_INST_RATIO=100 AFL_PATH=. AFL_CC=$(CC) ./afl-gcc-fast $(CFLAGS) $(CPPFLAGS) ./test-instr.c -o test-instr $(LDFLAGS)
|
||||
ASAN_OPTIONS=detect_leaks=0 ./afl-showmap -m none -q -o .test-instr0 ./test-instr </dev/null
|
||||
echo 1 | ASAN_OPTIONS=detect_leaks=0 ./afl-showmap -m none -q -o .test-instr1 ./test-instr
|
||||
@rm -f test-instr
|
||||
|
@ -32,6 +32,9 @@ VERSION = $(shell grep '^$(HASH)define VERSION ' ./config.h | cut -d '"' -f2
|
||||
|
||||
SYS = $(shell uname -s)
|
||||
|
||||
override LLVM_TOO_NEW_DEFAULT := 18
|
||||
override LLVM_TOO_OLD_DEFAULT := 13
|
||||
|
||||
ifeq "$(SYS)" "OpenBSD"
|
||||
LLVM_CONFIG ?= $(BIN_PATH)/llvm-config
|
||||
HAS_OPT = $(shell test -x $(BIN_PATH)/opt && echo 0 || echo 1)
|
||||
@ -39,24 +42,36 @@ ifeq "$(SYS)" "OpenBSD"
|
||||
$(warning llvm_mode needs a complete llvm installation (versions 6.0 up to 13) -> e.g. "pkg_add llvm-7.0.1p9")
|
||||
endif
|
||||
else
|
||||
LLVM_CONFIG ?= llvm-config
|
||||
# Small function to use Bash to detect the latest available clang and clang++ binaries, if using them by that name fails
|
||||
override _CLANG_VERSIONS_TO_TEST := $(patsubst %,-%,$(shell seq $(LLVM_TOO_NEW_DEFAULT) -1 $(LLVM_TOO_OLD_DEFAULT)))
|
||||
detect_newest=$(shell for v in "" $(_CLANG_VERSIONS_TO_TEST); do test -n "$$(command -v -- $1$$v)" && { echo "$1$$v"; break; }; done)
|
||||
LLVM_CONFIG ?= $(call detect_newest,llvm-config)
|
||||
endif
|
||||
|
||||
LLVMVER = $(shell $(LLVM_CONFIG) --version 2>/dev/null | sed 's/git//' | sed 's/svn//' )
|
||||
LLVM_MAJOR = $(shell $(LLVM_CONFIG) --version 2>/dev/null | sed 's/\..*//' )
|
||||
LLVM_MINOR = $(shell $(LLVM_CONFIG) --version 2>/dev/null | sed 's/.*\.//' | sed 's/git//' | sed 's/svn//' | sed 's/ .*//' )
|
||||
LLVM_UNSUPPORTED = $(shell $(LLVM_CONFIG) --version 2>/dev/null | grep -E -q '^[0-2]\.|^3.[0-7]\.' && echo 1 || echo 0 )
|
||||
LLVM_TOO_NEW = $(shell $(LLVM_CONFIG) --version 2>/dev/null | grep -E -q '^1[8-9]|^2[0-9]' && echo 1 || echo 0 )
|
||||
LLVM_TOO_OLD = $(shell $(LLVM_CONFIG) --version 2>/dev/null | grep -E -q '^[1-9]\.|^1[012]\.' && echo 1 || echo 0 )
|
||||
LLVM_NEW_API = $(shell $(LLVM_CONFIG) --version 2>/dev/null | grep -E -q '^1[0-9]' && echo 1 || echo 0 )
|
||||
LLVM_NEWER_API = $(shell $(LLVM_CONFIG) --version 2>/dev/null | grep -E -q '^1[6-9]' && echo 1 || echo 0 )
|
||||
LLVM_13_OK = $(shell $(LLVM_CONFIG) --version 2>/dev/null | grep -E -q '^1[3-9]' && echo 1 || echo 0 )
|
||||
LLVM_HAVE_LTO = $(shell $(LLVM_CONFIG) --version 2>/dev/null | grep -E -q '^1[1-9]' && echo 1 || echo 0 )
|
||||
LLVM_BINDIR = $(shell $(LLVM_CONFIG) --bindir 2>/dev/null)
|
||||
LLVM_LIBDIR = $(shell $(LLVM_CONFIG) --libdir 2>/dev/null)
|
||||
LLVM_STDCXX = gnu++11
|
||||
LLVM_APPLE_XCODE = $(shell $(CC) -v 2>&1 | grep -q Apple && echo 1 || echo 0)
|
||||
LLVM_LTO = 0
|
||||
ifneq "$(LLVM_CONFIG)" ""
|
||||
override LLVM_RAW_VER := $(shell $(LLVM_CONFIG) --version 2>/dev/null)
|
||||
LLVMVER := $(subst svn,,$(subst git,,$(LLVM_RAW_VER)))
|
||||
|
||||
LLVM_BINDIR := $(shell $(LLVM_CONFIG) --bindir 2>/dev/null)
|
||||
LLVM_LIBDIR := $(shell $(LLVM_CONFIG) --libdir 2>/dev/null)
|
||||
endif
|
||||
|
||||
ifneq "$(LLVMVER)" ""
|
||||
LLVM_MAJOR := $(firstword $(subst ., ,$(LLVMVER)))
|
||||
LLVM_MINOR := $(firstword $(subst ., ,$(subst $(LLVM_MAJOR).,,$(LLVMVER))))
|
||||
LLVM_TOO_NEW := $(shell test $(LLVM_MAJOR) -gt $(LLVM_TOO_NEW_DEFAULT) && echo 1 || echo 0)
|
||||
LLVM_TOO_OLD := $(shell test $(LLVM_MAJOR) -lt $(LLVM_TOO_OLD_DEFAULT) && echo 1 || echo 0)
|
||||
LLVM_NEW_API := $(shell test $(LLVM_MAJOR) -ge 10 && echo 1 || echo 0)
|
||||
LLVM_NEWER_API := $(shell test $(LLVM_MAJOR) -ge 16 && echo 1 || echo 0)
|
||||
LLVM_13_OK := $(shell test $(LLVM_MAJOR) -ge 13 && echo 1 || echo 0)
|
||||
LLVM_HAVE_LTO := $(shell test $(LLVM_MAJOR) -ge 12 && echo 1 || echo 0)
|
||||
endif
|
||||
|
||||
LLVM_STDCXX := gnu++11
|
||||
LLVM_LTO := 0
|
||||
LLVM_UNSUPPORTED := $(shell echo "$(LLVMVER)" | grep -E -q '^[0-2]\.|^3\.[0-7]\.' && echo 1 || echo 0)
|
||||
# Uncomment to see the values assigned above
|
||||
# $(foreach var,LLVM_CONFIG LLVMVER LLVM_MAJOR LLVM_MINOR LLVM_TOO_NEW LLVM_TOO_OLD LLVM_TOO_NEW_DEFAULT LLVM_TOO_OLD_DEFAULT LLVM_NEW_API LLVM_NEWER_API LLVM_13_OK LLVM_HAVE_LTO LLVM_BINDIR LLVM_LIBDIR LLVM_STDCXX LLVM_APPLE_XCODE LLVM_LTO LLVM_UNSUPPORTED,$(warning $(var) = $($(var))))
|
||||
|
||||
ifeq "$(LLVMVER)" ""
|
||||
$(warning [!] llvm_mode needs llvm-config, which was not found. Set LLVM_CONFIG to its path and retry.)
|
||||
@ -95,16 +110,12 @@ ifeq "$(LLVM_NEWER_API)" "1"
|
||||
endif
|
||||
|
||||
ifeq "$(LLVM_HAVE_LTO)" "1"
|
||||
$(info [+] llvm_mode detected llvm 11+, enabling afl-lto LTO implementation)
|
||||
$(info [+] llvm_mode detected llvm 12+, enabling afl-lto LTO implementation)
|
||||
LLVM_LTO = 1
|
||||
endif
|
||||
|
||||
ifeq "$(LLVM_LTO)" "0"
|
||||
$(info [+] llvm_mode detected llvm < 11, afl-lto LTO will not be build.)
|
||||
endif
|
||||
|
||||
ifeq "$(LLVM_APPLE_XCODE)" "1"
|
||||
$(warning llvm_mode will not compile with Xcode clang...)
|
||||
$(info [+] llvm_mode detected llvm < 12, afl-lto LTO will not be build.)
|
||||
endif
|
||||
|
||||
# We were using llvm-config --bindir to get the location of clang, but
|
||||
@ -114,6 +125,11 @@ endif
|
||||
CC = $(LLVM_BINDIR)/clang
|
||||
CXX = $(LLVM_BINDIR)/clang++
|
||||
|
||||
LLVM_APPLE_XCODE := $(shell $(CC) -v 2>&1 | grep -q Apple && echo 1 || echo 0)
|
||||
ifeq "$(LLVM_APPLE_XCODE)" "1"
|
||||
$(warning llvm_mode will not compile with Xcode clang...)
|
||||
endif
|
||||
|
||||
# llvm-config --bindir may not providing a valid path, so ...
|
||||
ifeq "$(shell test -e $(CC) || echo 1 )" "1"
|
||||
# however we must ensure that this is not a "CC=gcc make"
|
||||
@ -147,7 +163,7 @@ endif
|
||||
|
||||
# sanity check.
|
||||
# Are versions of clang --version and llvm-config --version equal?
|
||||
CLANGVER = $(shell $(CC) --version | sed -E -ne '/^.*version\ (1?[0-9]\.[0-9]\.[0-9]).*/s//\1/p')
|
||||
CLANGVER = $(shell $(CC) --version | sed -E -ne '/^.*version\ ([12]?[0-9]\.[0-9]\.[0-9]).*/s//\1/p')
|
||||
|
||||
# I disable this because it does not make sense with what we did before (marc)
|
||||
# We did exactly set these 26 lines above with these values, and it would break
|
||||
@ -245,7 +261,7 @@ endif
|
||||
|
||||
AFL_CLANG_FUSELD=
|
||||
ifeq "$(LLVM_LTO)" "1"
|
||||
ifeq "$(shell echo 'int main() {return 0; }' | $(CLANG_BIN) -x c - -fuse-ld=`command -v ld` -o .test 2>/dev/null && echo 1 || echo 0 ; rm -f .test )" "1"
|
||||
ifeq "$(shell echo 'int main() {return 0; }' | $(CLANG_BIN) -x c - -fuse-ld=$$(command -v ld) -o .test 2>/dev/null && echo 1 || echo 0 ; rm -f .test )" "1"
|
||||
AFL_CLANG_FUSELD=1
|
||||
ifeq "$(shell echo 'int main() {return 0; }' | $(CLANG_BIN) -x c - -fuse-ld=ld.lld --ld-path=$(AFL_REAL_LD) -o .test 2>/dev/null && echo 1 || echo 0 ; rm -f .test )" "1"
|
||||
AFL_CLANG_LDPATH=1
|
||||
@ -300,8 +316,8 @@ endif
|
||||
ifneq "$(LLVM_CONFIG)" ""
|
||||
CLANG_CFL += -I$(shell dirname $(LLVM_CONFIG))/../include
|
||||
endif
|
||||
CLANG_CPPFL = `$(LLVM_CONFIG) --cxxflags` -fno-rtti -fno-exceptions -fPIC $(CXXFLAGS) $(CPPFLAGS) -Wno-deprecated-declarations
|
||||
CLANG_LFL = `$(LLVM_CONFIG) --ldflags` $(LDFLAGS)
|
||||
CLANG_CPPFL = $$($(LLVM_CONFIG) --cxxflags) -fno-rtti -fno-exceptions -fPIC $(CXXFLAGS) $(CPPFLAGS) -Wno-deprecated-declarations
|
||||
CLANG_LFL = $$($(LLVM_CONFIG) --ldflags) $(LDFLAGS)
|
||||
|
||||
# wasm fuzzing: disable thread-local storage and unset LLVM debug flag
|
||||
ifdef WAFL_MODE
|
||||
@ -311,7 +327,7 @@ endif
|
||||
|
||||
# User teor2345 reports that this is required to make things work on MacOS X.
|
||||
ifeq "$(SYS)" "Darwin"
|
||||
CLANG_LFL += -Wl,-flat_namespace -Wl,-undefined,suppress
|
||||
CLANG_LFL += -Wl,-undefined,dynamic_lookup
|
||||
override LLVM_HAVE_LTO := 0
|
||||
override LLVM_LTO := 0
|
||||
else
|
||||
@ -319,7 +335,7 @@ else
|
||||
endif
|
||||
|
||||
ifeq "$(SYS)" "OpenBSD"
|
||||
CLANG_LFL += `$(LLVM_CONFIG) --libdir`/libLLVM.so
|
||||
CLANG_LFL += $$($(LLVM_CONFIG) --libdir)/libLLVM.so
|
||||
CLANG_CPPFL += -mno-retpoline
|
||||
CFLAGS += -mno-retpoline
|
||||
# Needed for unwind symbols
|
||||
@ -341,7 +357,7 @@ ifeq "$(TEST_MMAP)" "1"
|
||||
endif
|
||||
|
||||
PROGS_ALWAYS = ./afl-cc ./afl-compiler-rt.o ./afl-compiler-rt-32.o ./afl-compiler-rt-64.o
|
||||
PROGS = $(PROGS_ALWAYS) ./afl-llvm-pass.so ./SanitizerCoveragePCGUARD.so ./split-compares-pass.so ./split-switches-pass.so ./cmplog-routines-pass.so ./cmplog-instructions-pass.so ./cmplog-switches-pass.so ./afl-llvm-dict2file.so ./compare-transform-pass.so ./afl-ld-lto ./afl-llvm-lto-instrumentlist.so ./SanitizerCoverageLTO.so
|
||||
PROGS = $(PROGS_ALWAYS) ./afl-llvm-pass.so ./SanitizerCoveragePCGUARD.so ./split-compares-pass.so ./split-switches-pass.so ./cmplog-routines-pass.so ./cmplog-instructions-pass.so ./cmplog-switches-pass.so ./afl-llvm-dict2file.so ./compare-transform-pass.so ./afl-ld-lto ./afl-llvm-lto-instrumentlist.so ./SanitizerCoverageLTO.so ./injection-pass.so
|
||||
|
||||
# If prerequisites are not given, warn, do not build anything, and exit with code 0
|
||||
ifeq "$(LLVMVER)" ""
|
||||
@ -417,7 +433,7 @@ endif
|
||||
endif
|
||||
|
||||
instrumentation/afl-llvm-common.o: instrumentation/afl-llvm-common.cc instrumentation/afl-llvm-common.h
|
||||
$(CXX) $(CFLAGS) $(CPPFLAGS) `$(LLVM_CONFIG) --cxxflags` -fno-rtti -fPIC -std=$(LLVM_STDCXX) -c $< -o $@
|
||||
$(CXX) $(CFLAGS) $(CPPFLAGS) $$($(LLVM_CONFIG) --cxxflags) -fno-rtti -fPIC -std=$(LLVM_STDCXX) -c $< -o $@
|
||||
|
||||
./afl-llvm-pass.so: instrumentation/afl-llvm-pass.so.cc instrumentation/afl-llvm-common.o | test_deps
|
||||
ifeq "$(LLVM_MIN_4_0_1)" "0"
|
||||
@ -469,6 +485,9 @@ endif
|
||||
afl-llvm-dict2file.so: instrumentation/afl-llvm-dict2file.so.cc instrumentation/afl-llvm-common.o | test_deps
|
||||
$(CXX) $(CLANG_CPPFL) -shared $< -o $@ $(CLANG_LFL) instrumentation/afl-llvm-common.o
|
||||
|
||||
./injection-pass.so: instrumentation/injection-pass.cc instrumentation/afl-llvm-common.o | test_deps
|
||||
$(CXX) $(CLANG_CPPFL) -shared $< -o $@ $(CLANG_LFL) instrumentation/afl-llvm-common.o
|
||||
|
||||
.PHONY: document
|
||||
document:
|
||||
$(CLANG_BIN) -D_AFL_DOCUMENT_MUTATIONS $(CFLAGS_SAFE) $(CPPFLAGS) $(CLANG_CFL) -O3 -Wno-unused-result -fPIC -c instrumentation/afl-compiler-rt.o.c -o ./afl-compiler-rt.o
|
||||
@ -489,7 +508,7 @@ document:
|
||||
.PHONY: test_build
|
||||
test_build: $(PROGS)
|
||||
@echo "[*] Testing the CC wrapper and instrumentation output..."
|
||||
unset AFL_USE_ASAN AFL_USE_MSAN AFL_INST_RATIO; ASAN_OPTIONS=detect_leaks=0 AFL_QUIET=1 AFL_PATH=. AFL_LLVM_LAF_ALL=1 ./afl-cc $(CFLAGS) $(CPPFLAGS) ./test-instr.c -o test-instr $(LDFLAGS)
|
||||
unset AFL_USE_ASAN AFL_USE_MSAN AFL_INST_RATIO AFL_LLVM_ALLOWLIST AFL_LLVM_DENYLIST; ASAN_OPTIONS=detect_leaks=0 AFL_QUIET=1 AFL_PATH=. AFL_LLVM_LAF_ALL=1 ./afl-cc $(CFLAGS) $(CPPFLAGS) ./test-instr.c -o test-instr $(LDFLAGS)
|
||||
ASAN_OPTIONS=detect_leaks=0 ./afl-showmap -m none -q -o .test-instr0 ./test-instr < /dev/null
|
||||
echo 1 | ASAN_OPTIONS=detect_leaks=0 ./afl-showmap -m none -q -o .test-instr1 ./test-instr
|
||||
@rm -f test-instr
|
||||
|
@ -1,10 +1,10 @@
|
||||
# American Fuzzy Lop plus plus (AFL++)
|
||||
|
||||
<img align="right" src="https://raw.githubusercontent.com/AFLplusplus/Website/main/static/aflpp_bg.svg" alt="AFL++ logo" width="250" heigh="250">
|
||||
<img align="right" src="https://raw.githubusercontent.com/AFLplusplus/Website/main/static/aflpp_bg.svg" alt="AFL++ logo" width="250" height="250">
|
||||
|
||||
Release version: [4.09c](https://github.com/AFLplusplus/AFLplusplus/releases)
|
||||
Release version: [4.30c](https://github.com/AFLplusplus/AFLplusplus/releases)
|
||||
|
||||
GitHub version: 4.09c
|
||||
GitHub version: 4.31a
|
||||
|
||||
Repository:
|
||||
[https://github.com/AFLplusplus/AFLplusplus](https://github.com/AFLplusplus/AFLplusplus)
|
||||
|
21
TODO.md
21
TODO.md
@ -2,26 +2,23 @@
|
||||
|
||||
## Must
|
||||
|
||||
- ijon support?
|
||||
- check for null ptr for xml/curl/g_ string transform functions
|
||||
- hardened_usercopy=0 page_alloc.shuffle=0
|
||||
- add value_profile but only enable after 15 minutes without finds
|
||||
- cmplog max items env?
|
||||
- adapt MOpt to new mutation engine
|
||||
- Update afl->pending_not_fuzzed for MOpt
|
||||
- cmplog rtn sanity check on fixed length? + no length 1
|
||||
- Update afl->pending_not_fuzzed for MOpt
|
||||
- cmplog rtn sanity check on fixed length? currently we ignore the length
|
||||
- afl-showmap -f support
|
||||
- afl-fuzz multicore wrapper script
|
||||
- when trimming then perform crash detection
|
||||
- either -L0 and/or -p mmopt results in zero new coverage
|
||||
|
||||
|
||||
## Should
|
||||
|
||||
<<<<<<< Updated upstream
|
||||
- add value_profile but only enable after 15 minutes without finds?
|
||||
=======
|
||||
- afl-showmap -f support
|
||||
- afl-fuzz multicore wrapper script
|
||||
- UI revamp
|
||||
- hardened_usercopy=0 page_alloc.shuffle=0
|
||||
- add value_profile but only enable after 15 minutes without finds
|
||||
>>>>>>> Stashed changes
|
||||
- afl-crash-analysis
|
||||
- cmplog: add loop count resolving (byte -> loop cnt change, calc special values)
|
||||
- support persistent and deferred fork server in afl-showmap?
|
||||
- better autodetection of shifting runtime timeout values
|
||||
- afl-plot to support multiple plot_data
|
||||
|
14
afl-cmin
14
afl-cmin
@ -1,15 +1,19 @@
|
||||
#!/usr/bin/env sh
|
||||
SYS=$(uname -s)
|
||||
test "$SYS" = "Darwin" && {
|
||||
echo Error: afl-cmin does not work on Apple currently. please use afl-cmin.bash instead.
|
||||
exit 1
|
||||
}
|
||||
export AFL_QUIET=1
|
||||
export ASAN_OPTIONS=detect_leaks=0
|
||||
THISPATH=`dirname ${0}`
|
||||
export PATH="${THISPATH}:$PATH"
|
||||
awk -f - -- ${@+"$@"} <<'EOF'
|
||||
#!/usr/bin/awk -f
|
||||
|
||||
# awk script to minimize a test corpus of input files
|
||||
#
|
||||
# based on afl-cmin bash script written by Michal Zalewski
|
||||
# rewritten by Heiko Eißfeldt (hexcoder-)
|
||||
# rewritten by Heiko Eissfeldt (hexcoder-)
|
||||
# tested with:
|
||||
# gnu awk (x86 Linux)
|
||||
# bsd awk (x86 *BSD)
|
||||
@ -104,7 +108,7 @@ function usage() {
|
||||
"\n" \
|
||||
"Execution control settings:\n" \
|
||||
" -T tasks - how many parallel tasks to run (default: 1, all=nproc)\n" \
|
||||
" -f file - location read by the fuzzed program (stdin)\n" \
|
||||
" -f file - location read by the fuzzed program (default: stdin)\n" \
|
||||
" -m megs - memory limit for child process ("mem_limit" MB)\n" \
|
||||
" -t msec - run time limit for child process (default: 5000)\n" \
|
||||
" -O - use binary-only instrumentation (FRIDA mode)\n" \
|
||||
@ -599,8 +603,8 @@ BEGIN {
|
||||
# create path for the trace file from afl-showmap
|
||||
tracefile_path = trace_dir"/"fn
|
||||
# ensure the file size is not zero
|
||||
cmd = "du -b "tracefile_path
|
||||
"ls -l "tracefile_path
|
||||
cmd = "du -b \""tracefile_path"\""
|
||||
# "ls -l \""tracefile_path"\""
|
||||
cmd | getline output
|
||||
close(cmd)
|
||||
split(output, result, "\t")
|
||||
|
@ -7,7 +7,7 @@
|
||||
#
|
||||
# Copyright 2014, 2015 Google Inc. All rights reserved.
|
||||
#
|
||||
# Copyright 2019-2023 AFLplusplus
|
||||
# Copyright 2019-2024 AFLplusplus
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
@ -152,6 +152,7 @@ Minimization settings:
|
||||
-e - solve for edge coverage only, ignore hit counts
|
||||
|
||||
For additional tips, please consult README.md.
|
||||
This script cannot read filenames that end with a space ' '.
|
||||
|
||||
Environment variables used:
|
||||
AFL_KEEP_TRACES: leave the temporary <out_dir>\.traces directory
|
||||
|
@ -38,6 +38,7 @@ fi
|
||||
|
||||
echo
|
||||
PLATFORM=`uname -s`
|
||||
ARCH=`uname -m`
|
||||
|
||||
# check that we're on Mac
|
||||
if [[ "$PLATFORM" = "Darwin" ]] ; then
|
||||
@ -87,6 +88,13 @@ if [[ "$PLATFORM" = "Darwin" ]] ; then
|
||||
</plist>
|
||||
EOF
|
||||
|
||||
if [[ "$ARCH" = "x86_64" ]]; then
|
||||
echo "Disabling ASLR system wide"
|
||||
nvram boot-args="no_aslr=1"
|
||||
else
|
||||
echo NOTICE: on ARM64 we do not know currently how to disable system wide ASLR, please report if you know how.
|
||||
fi
|
||||
|
||||
echo
|
||||
echo "Reboot and enjoy your fuzzing"
|
||||
exit 0
|
||||
@ -116,17 +124,26 @@ kernel.sched_latency_ns=250000000
|
||||
EOF
|
||||
}
|
||||
|
||||
grep -E -q '^GRUB_CMDLINE_LINUX_DEFAULT=' /etc/default/grub 2>/dev/null || echo Error: /etc/default/grub with GRUB_CMDLINE_LINUX_DEFAULT is not present, cannot set boot options
|
||||
grep -E -q '^GRUB_CMDLINE_LINUX_DEFAULT=' /etc/default/grub 2>/dev/null && {
|
||||
grep -E '^GRUB_CMDLINE_LINUX_DEFAULT=' /etc/default/grub | grep -E -q 'noibrs pcid nopti' || {
|
||||
grub_try_disable_mitigation () {
|
||||
KEY="$1"
|
||||
if ! grep -E "^$KEY=" /etc/default/grub | grep -E -q 'noibrs pcid nopti'; then
|
||||
echo "Configuring performance boot options"
|
||||
LINE=`grep -E '^GRUB_CMDLINE_LINUX_DEFAULT=' /etc/default/grub | sed 's/^GRUB_CMDLINE_LINUX_DEFAULT=//' | tr -d '"'`
|
||||
OPTIONS="$LINE ibpb=off ibrs=off kpti=off l1tf=off mds=off mitigations=off no_stf_barrier noibpb noibrs pcid nopti nospec_store_bypass_disable nospectre_v1 nospectre_v2 pcid=on pti=off spec_store_bypass_disable=off spectre_v2=off stf_barrier=off srbds=off noexec=off noexec32=off tsx=on tsx=on tsx_async_abort=off mitigations=off audit=0 hardened_usercopy=off ssbd=force-off"
|
||||
echo Setting boot options in /etc/default/grub to GRUB_CMDLINE_LINUX_DEFAULT=\"$OPTIONS\"
|
||||
sed -i "s|^GRUB_CMDLINE_LINUX_DEFAULT=.*|GRUB_CMDLINE_LINUX_DEFAULT=\"$OPTIONS\"|" /etc/default/grub
|
||||
}
|
||||
LINE=`grep -E "^$KEY=" /etc/default/grub | sed "s/^$KEY=//" | tr -d '"'`
|
||||
OPTIONS="$LINE ibpb=off ibrs=off kpti=off l1tf=off spec_rstack_overflow=off mds=off no_stf_barrier noibpb noibrs pcid nopti nospec_store_bypass_disable nospectre_v1 nospectre_v2 pcid=on pti=off spec_store_bypass_disable=off spectre_v2=off stf_barrier=off srbds=off noexec=off noexec32=off tsx=on tsx=on tsx_async_abort=off mitigations=off audit=0 hardened_usercopy=off ssbd=force-off"
|
||||
echo Setting boot options in /etc/default/grub to $KEY=\"$OPTIONS\"
|
||||
sed -i "s|^$KEY=.*|$KEY=\"$OPTIONS\"|" /etc/default/grub
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
if grep -E -q '^GRUB_CMDLINE_LINUX=' /etc/default/grub || grep -E -q '^GRUB_CMDLINE_LINUX_DEFAULT=' /etc/default/grub; then
|
||||
grub_try_disable_mitigation "GRUB_CMDLINE_LINUX_DEFAULT"
|
||||
# We also overwrite GRUB_CMDLINE_LINUX because some distributions already overwrite GRUB_CMDLINE_LINUX_DEFAULT
|
||||
grub_try_disable_mitigation "GRUB_CMDLINE_LINUX"
|
||||
else
|
||||
echo "Error: /etc/default/grub with GRUB_CMDLINE_LINUX is not present, cannot set boot options"
|
||||
fi
|
||||
|
||||
echo
|
||||
echo "Reboot and enjoy your fuzzing"
|
||||
exit 0
|
||||
|
@ -25,6 +25,7 @@ echo "WARNING: this reduces the security of the system!"
|
||||
echo
|
||||
if [ '!' "$EUID" = 0 ] && [ '!' `id -u` = 0 ] ; then
|
||||
echo "Warning: you need to be root to run this!"
|
||||
sleep 1
|
||||
# we do not exit as other mechanisms exist that allows to do this than
|
||||
# being root. let the errors speak for themselves.
|
||||
fi
|
||||
|
52
afl-whatsup
52
afl-whatsup
@ -6,7 +6,7 @@
|
||||
# Originally written by Michal Zalewski
|
||||
#
|
||||
# Copyright 2015 Google Inc. All rights reserved.
|
||||
# Copyright 2019-2023 AFLplusplus Project. All rights reserved.
|
||||
# Copyright 2019-2024 AFLplusplus Project. All rights reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
@ -111,9 +111,16 @@ if [ -z "$NO_COLOR" ]; then
|
||||
RESET="$NC"
|
||||
fi
|
||||
|
||||
CUR_TIME=`date +%s`
|
||||
PLATFORM=`uname -s`
|
||||
#if [ "$PLATFORM" = "Linux" ] ; then
|
||||
# CUR_TIME=`cat /proc/uptime | awk '{printf "%.0f\n", $1}'`
|
||||
#else
|
||||
# This will lead to inacurate results but will prevent the script from breaking on platforms other than Linux
|
||||
CUR_TIME=`date +%s`
|
||||
#fi
|
||||
|
||||
TMP=`mktemp -t .afl-whatsup-XXXXXXXX` || TMP=`mktemp -p /data/local/tmp .afl-whatsup-XXXXXXXX` || TMP=`mktemp -p /data/local/tmp .afl-whatsup-XXXXXXXX` || exit 1
|
||||
trap "rm -f $TMP" 1 2 3 13 15
|
||||
|
||||
ALIVE_CNT=0
|
||||
DEAD_CNT=0
|
||||
@ -122,6 +129,7 @@ START_CNT=0
|
||||
TOTAL_TIME=0
|
||||
TOTAL_EXECS=0
|
||||
TOTAL_EPS=0
|
||||
TOTAL_EPLM=0
|
||||
TOTAL_CRASHES=0
|
||||
TOTAL_HANGS=0
|
||||
TOTAL_PFAV=0
|
||||
@ -181,6 +189,8 @@ for j in `find . -maxdepth 2 -iname fuzzer_setup | sort`; do
|
||||
|
||||
if [ -f "$i" ]; then
|
||||
|
||||
IS_STARTING=
|
||||
IS_DEAD=
|
||||
sed 's/^command_line.*$/_skip:1/;s/[ ]*:[ ]*/="/;s/$/"/' "$i" >"$TMP"
|
||||
. "$TMP"
|
||||
DIRECTORY=$DIR
|
||||
@ -211,9 +221,6 @@ for j in `find . -maxdepth 2 -iname fuzzer_setup | sort`; do
|
||||
|
||||
if ! kill -0 "$fuzzer_pid" 2>/dev/null; then
|
||||
|
||||
IS_STARTING=
|
||||
IS_DEAD=
|
||||
|
||||
if [ -e "$i" ] && [ -e "$j" ] && [ -n "$FUSER" ]; then
|
||||
|
||||
if [ "$i" -ot "$j" ]; then
|
||||
@ -272,11 +279,15 @@ for j in `find . -maxdepth 2 -iname fuzzer_setup | sort`; do
|
||||
ALIVE_CNT=$((ALIVE_CNT + 1))
|
||||
|
||||
EXEC_SEC=0
|
||||
EXEC_MIN=0
|
||||
test -z "$RUN_UNIX" -o "$RUN_UNIX" = 0 || EXEC_SEC=$((execs_done / RUN_UNIX))
|
||||
PATH_PERC=$((cur_item * 100 / corpus_count))
|
||||
|
||||
test "$IS_DEAD" = 1 || EXEC_MIN=$(echo $execs_ps_last_min|sed 's/\..*//')
|
||||
|
||||
TOTAL_TIME=$((TOTAL_TIME + RUN_UNIX))
|
||||
TOTAL_EPS=$((TOTAL_EPS + EXEC_SEC))
|
||||
TOTAL_EPLM=$((TOTAL_EPLM + EXEC_MIN))
|
||||
TOTAL_EXECS=$((TOTAL_EXECS + execs_done))
|
||||
TOTAL_CRASHES=$((TOTAL_CRASHES + saved_crashes))
|
||||
TOTAL_HANGS=$((TOTAL_HANGS + saved_hangs))
|
||||
@ -398,41 +409,44 @@ if [ -z "$SUMMARY_ONLY" -o -z "$MINIMAL_ONLY" ]; then
|
||||
echo
|
||||
fi
|
||||
|
||||
echo " Fuzzers alive : $ALIVE_CNT"
|
||||
echo " Fuzzers alive : $ALIVE_CNT"
|
||||
|
||||
if [ ! "$START_CNT" = "0" ]; then
|
||||
echo " Starting up : $START_CNT ($TXT)"
|
||||
echo " Starting up : $START_CNT ($TXT)"
|
||||
fi
|
||||
|
||||
if [ ! "$DEAD_CNT" = "0" ]; then
|
||||
echo " Dead or remote : $DEAD_CNT ($TXT)"
|
||||
echo " Dead or remote : $DEAD_CNT ($TXT)"
|
||||
fi
|
||||
|
||||
echo " Total run time : $FMT_TIME"
|
||||
echo " Total run time : $FMT_TIME"
|
||||
if [ -z "$MINIMAL_ONLY" ]; then
|
||||
echo " Total execs : $FMT_EXECS"
|
||||
echo " Cumulative speed : $TOTAL_EPS execs/sec"
|
||||
echo " Total execs : $FMT_EXECS"
|
||||
echo " Cumulative speed : $TOTAL_EPS execs/sec"
|
||||
if [ "$ALIVE_CNT" -gt "0" ]; then
|
||||
echo " Total average speed : $((TOTAL_EPS / ALIVE_CNT)) execs/sec"
|
||||
fi
|
||||
fi
|
||||
if [ "$ALIVE_CNT" -gt "0" ]; then
|
||||
echo " Average speed : $((TOTAL_EPS / ALIVE_CNT)) execs/sec"
|
||||
echo "Current average speed : $TOTAL_EPLM execs/sec"
|
||||
fi
|
||||
if [ -z "$MINIMAL_ONLY" ]; then
|
||||
echo " Pending items : $TOTAL_PFAV faves, $TOTAL_PENDING total"
|
||||
echo " Pending items : $TOTAL_PFAV faves, $TOTAL_PENDING total"
|
||||
fi
|
||||
|
||||
if [ "$ALIVE_CNT" -gt "1" -o -n "$MINIMAL_ONLY" ]; then
|
||||
if [ "$ALIVE_CNT" -gt "0" ]; then
|
||||
echo " Pending per fuzzer : $((TOTAL_PFAV/ALIVE_CNT)) faves, $((TOTAL_PENDING/ALIVE_CNT)) total (on average)"
|
||||
echo " Pending per fuzzer : $((TOTAL_PFAV/ALIVE_CNT)) faves, $((TOTAL_PENDING/ALIVE_CNT)) total (on average)"
|
||||
fi
|
||||
fi
|
||||
|
||||
echo " Coverage reached : ${TOTAL_COVERAGE}%"
|
||||
echo " Crashes saved : $TOTAL_CRASHES"
|
||||
echo " Coverage reached : ${TOTAL_COVERAGE}%"
|
||||
echo " Crashes saved : $TOTAL_CRASHES"
|
||||
if [ -z "$MINIMAL_ONLY" ]; then
|
||||
echo " Hangs saved : $TOTAL_HANGS"
|
||||
echo "Cycles without finds : $TOTAL_WCOP"
|
||||
echo " Hangs saved : $TOTAL_HANGS"
|
||||
echo " Cycles without finds : $TOTAL_WCOP"
|
||||
fi
|
||||
echo " Time without finds : $TOTAL_LAST_FIND"
|
||||
echo " Time without finds : $TOTAL_LAST_FIND"
|
||||
echo
|
||||
|
||||
exit 0
|
||||
|
@ -1,9 +1,14 @@
|
||||
CPU | MHz | threads | singlecore | multicore | afl-*-config |
|
||||
====================================================|=======|=========|============|===========|==============|
|
||||
Raspberry Pi 5 | 2400 | 4 | 25786 | 101114 | both |
|
||||
AMD EPYC 7282 16-Core Processor | 3194 | 32 | 87199 | 769001 | both |
|
||||
AMD Ryzen 5 PRO 4650G with Radeon Graphics | 3700 | 12 | 95356 | 704840 | both |
|
||||
Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz | 4995 | 16 | 120064 | 1168943 | both |
|
||||
12th Gen Intel(R) Core(TM) i7-1270P | 4761 | 16 | 149778 | 641219 | both |
|
||||
AMD Ryzen 9 5950X 16-Core Processor | 4792 | 32 | 161690 | 2339763 | both |
|
||||
Apple Mac Studio M2 Ultra 2023, Linux VM guest | 3500 | 16 | 163570 | 1157465 | both |
|
||||
|CPU | MHz | threads | singlecore | multicore | afl-*-config |
|
||||
|----------------------------------------------------|-------|---------|------------|-----------|--------------|
|
||||
|Raspberry Pi 5 | 2400 | 4 | 25786 | 101114 | both |
|
||||
|AMD EPYC 7282 16-Core Processor | 3194 | 32 | 87199 | 769001 | both |
|
||||
|AMD Ryzen 5 PRO 4650G with Radeon Graphics | 3700 | 12 | 95356 | 704840 | both |
|
||||
|Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz | 4995 | 16 | 120064 | 1168943 | both |
|
||||
|12th Gen Intel(R) Core(TM) i7-1270P | 4761 | 16 | 149778 | 641219 | both |
|
||||
|AMD Ryzen 9 5950X 16-Core Processor | 4792 | 32 | 161690 | 2339763 | both |
|
||||
|Apple Mac Studio M2 Ultra 2023, Linux VM guest | 3500 | 16 | 163570 | 1157465 | both |
|
||||
|AMD Ryzen 9 6900HS with Radeon Graphics | 4676 | 16 | 62860 | 614404 | system |
|
||||
|AMD Ryzen 9 6900HS with Radeon Graphics | 4745 | 16 | 135501 | 991133 | both |
|
||||
|AMD Ryzen 9 7950X3D 16-Core Processor | 5400 | 32 | 71566 | 1566279 | system |
|
||||
|AMD Ryzen 9 7950X3D 16-Core Processor | 5478 | 32 | 161960 | 2173959 | both |
|
||||
|Ampere Altra Q80-30 | 0 | 80 | 54477 | 1604482 | system |
|
||||
|
@ -418,3 +418,7 @@
|
||||
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.08a", "comment": "", "compiler": "Ubuntu clang version 14.0.0-1ubuntu1.1", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3700.0, "cpu_model": "AMD Ryzen 5 PRO 4650G with Radeon Graphics", "cpu_threads": 12}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 704840.16, "execs_total": 21163992, "fuzzers_used": 12}, "singlecore": {"execs_per_sec": 95356.14, "execs_total": 2862114, "fuzzers_used": 1}}}}
|
||||
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "", "compiler": "Debian clang version 14.0.6", "target_arch": "aarch64-unknown-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 2400.0, "cpu_model": "Raspberry Pi 5", "cpu_threads": 4}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 101114.23, "execs_total": 3036637, "fuzzers_used": 4}, "singlecore": {"execs_per_sec": 25786.11, "execs_total": 774460, "fuzzers_used": 1}}}}
|
||||
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.07a", "comment": "", "compiler": "Debian clang version 17.0.0 (++20230417071830+ae77aceba5ad-1~exp1~20230417071935.630)", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4792.073, "cpu_model": "AMD Ryzen 9 5950X 16-Core Processor", "cpu_threads": 32}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 2339762.91, "execs_total": 70253164, "fuzzers_used": 32}, "singlecore": {"execs_per_sec": 161690.07, "execs_total": 4851838, "fuzzers_used": 1}}}}
|
||||
{"config": {"afl_persistent_config": false, "afl_system_config": true, "afl_version": "++4.10c", "comment": "", "compiler": "clang version 17.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4675.949, "cpu_model": "AMD Ryzen 9 6900HS with Radeon Graphics", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 614403.91, "execs_total": 18435083, "fuzzers_used": 16}, "singlecore": {"execs_per_sec": 62859.9, "execs_total": 1886111, "fuzzers_used": 1}}}}
|
||||
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.10c", "comment": "", "compiler": "clang version 17.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4744.522, "cpu_model": "AMD Ryzen 9 6900HS with Radeon Graphics", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 991132.96, "execs_total": 29737588, "fuzzers_used": 16}, "singlecore": {"execs_per_sec": 135501.07, "execs_total": 4066116, "fuzzers_used": 1}}}}
|
||||
{"config": {"afl_persistent_config": false, "afl_system_config": true, "afl_version": "++4.10c", "comment": "", "compiler": "Ubuntu clang version 14.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 5399.822, "cpu_model": "AMD Ryzen 9 7950X3D 16-Core Processor", "cpu_threads": 32}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 1566279.42, "execs_total": 46994452, "fuzzers_used": 32}, "singlecore": {"execs_per_sec": 71565.56, "execs_total": 2147396, "fuzzers_used": 1}}}}
|
||||
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.10c", "comment": "", "compiler": "clang version 17.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 5478.258, "cpu_model": "AMD Ryzen 9 7950X3D 16-Core Processor", "cpu_threads": 32}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 2173959.15, "execs_total": 65229513, "fuzzers_used": 32}, "singlecore": {"execs_per_sec": 161960.29, "execs_total": 4859457, "fuzzers_used": 1}}}}
|
||||
|
@ -205,7 +205,7 @@ async def save_benchmark_results() -> None:
|
||||
single = str(round(results.targets["test-instr-persist-shmem"]["singlecore"].execs_per_sec)).ljust(10)
|
||||
multi = str(round(results.targets["test-instr-persist-shmem"]["multicore"].execs_per_sec)).ljust(9)
|
||||
cores = str(args.fuzzers).ljust(7)
|
||||
comparisonfile.write(f"{cpu_model} | {cpu_mhz} | {cores} | {single} | {multi} | {aflconfig} |\n")
|
||||
comparisonfile.write(f"|{cpu_model} | {cpu_mhz} | {cores} | {single} | {multi} | {aflconfig} |\n")
|
||||
print(blue(f" [*] Results have been written to the COMPARISON.md file."))
|
||||
with open("COMPARISON.md", "r") as comparisonfile:
|
||||
print(comparisonfile.read())
|
||||
|
@ -1,3 +1,4 @@
|
||||
#include "afl-fuzz.h"
|
||||
#include "afl-mutations.h"
|
||||
|
||||
typedef struct my_mutator {
|
||||
@ -47,7 +48,7 @@ size_t afl_custom_fuzz(my_mutator_t *data, uint8_t *buf, size_t buf_size,
|
||||
|
||||
u8 *ptr = realloc(data->buf, max_size);
|
||||
|
||||
if (ptr) {
|
||||
if (!ptr) {
|
||||
|
||||
return 0;
|
||||
|
||||
|
@ -4,7 +4,7 @@ CFLAGS = -O3 -funroll-loops -fPIC
|
||||
all: aflpp-standalone
|
||||
|
||||
aflpp-standalone: aflpp-standalone.c
|
||||
$(CC) $(CFLAGS) -I../../../include -I. -o aflpp-standalone aflpp-standalone.c ../../../src/afl-performance.c
|
||||
$(CC) $(CFLAGS) -DBIN_PATH=\"foo\" -I../../../include -I. -o aflpp-standalone aflpp-standalone.c ../../../src/afl-performance.c ../../../src/afl-fuzz-extras.c ../../../src/afl-common.c
|
||||
|
||||
clean:
|
||||
rm -f *.o *~ aflpp-standalone core
|
||||
|
@ -5,6 +5,6 @@ this is the AFL++ havoc mutator as a standalone mutator
|
||||
just type `make` to build.
|
||||
|
||||
```
|
||||
aflpp-standalone inputfile outputfile [splicefile]
|
||||
aflpp-standalone -h # to see all parameteres
|
||||
cat file | aflpp-standalone -m 4 -x foo.dict - outputfile splicefile # example
|
||||
```
|
||||
|
||||
|
@ -1,8 +1,11 @@
|
||||
#include "afl-fuzz.h"
|
||||
#include "afl-mutations.h"
|
||||
|
||||
s8 interesting_8[] = {INTERESTING_8};
|
||||
s16 interesting_16[] = {INTERESTING_8, INTERESTING_16};
|
||||
s32 interesting_32[] = {INTERESTING_8, INTERESTING_16, INTERESTING_32};
|
||||
#include <unistd.h>
|
||||
#include <getopt.h>
|
||||
|
||||
static int max_havoc = 16, verbose;
|
||||
static unsigned char *dict;
|
||||
|
||||
typedef struct my_mutator {
|
||||
|
||||
@ -24,14 +27,14 @@ my_mutator_t *afl_custom_init(afl_state_t *afl, unsigned int seed) {
|
||||
|
||||
}
|
||||
|
||||
if ((data->buf = malloc(1024*1024)) == NULL) {
|
||||
if ((data->buf = malloc(1024 * 1024)) == NULL) {
|
||||
|
||||
perror("afl_custom_init alloc");
|
||||
return NULL;
|
||||
|
||||
} else {
|
||||
|
||||
data->buf_size = 1024*1024;
|
||||
data->buf_size = 1024 * 1024;
|
||||
|
||||
}
|
||||
|
||||
@ -39,9 +42,23 @@ my_mutator_t *afl_custom_init(afl_state_t *afl, unsigned int seed) {
|
||||
data->afl = calloc(1, sizeof(afl_state_t));
|
||||
data->afl->queue_cycle = 1;
|
||||
data->afl->fsrv.dev_urandom_fd = open("/dev/urandom", O_RDONLY);
|
||||
if (data->afl->fsrv.dev_urandom_fd < 0) { PFATAL("Unable to open /dev/urandom"); }
|
||||
if (data->afl->fsrv.dev_urandom_fd < 0) {
|
||||
|
||||
PFATAL("Unable to open /dev/urandom");
|
||||
|
||||
}
|
||||
|
||||
rand_set_seed(data->afl, getpid());
|
||||
|
||||
if (dict) {
|
||||
|
||||
load_extras(data->afl, dict);
|
||||
if (verbose)
|
||||
fprintf(stderr, "Loaded dictionary: %s (%u entries)\n", dict,
|
||||
data->afl->extras_cnt);
|
||||
|
||||
}
|
||||
|
||||
return data;
|
||||
|
||||
}
|
||||
@ -56,7 +73,7 @@ size_t afl_custom_fuzz(my_mutator_t *data, uint8_t *buf, size_t buf_size,
|
||||
|
||||
u8 *ptr = realloc(data->buf, max_size);
|
||||
|
||||
if (ptr) {
|
||||
if (!ptr) {
|
||||
|
||||
return 0;
|
||||
|
||||
@ -69,14 +86,20 @@ size_t afl_custom_fuzz(my_mutator_t *data, uint8_t *buf, size_t buf_size,
|
||||
|
||||
}
|
||||
|
||||
u32 havoc_steps = 1 + rand_below(data->afl, 16);
|
||||
u32 havoc_steps = 1 + rand_below(data->afl, max_havoc);
|
||||
if (verbose) fprintf(stderr, "Havoc steps: %u\n", havoc_steps);
|
||||
|
||||
/* set everything up, costly ... :( */
|
||||
memcpy(data->buf, buf, buf_size);
|
||||
|
||||
/* the mutation */
|
||||
u32 out_buf_len = afl_mutate(data->afl, data->buf, buf_size, havoc_steps,
|
||||
false, true, add_buf, add_buf_size, max_size);
|
||||
u32 out_buf_len;
|
||||
do {
|
||||
|
||||
out_buf_len = afl_mutate(data->afl, data->buf, buf_size, havoc_steps, false,
|
||||
true, add_buf, add_buf_size, max_size);
|
||||
|
||||
} while (out_buf_len == buf_size && memcmp(buf, data->buf, buf_size) == 0);
|
||||
|
||||
/* return size of mutated data */
|
||||
*out_buf = data->buf;
|
||||
@ -87,80 +110,143 @@ size_t afl_custom_fuzz(my_mutator_t *data, uint8_t *buf, size_t buf_size,
|
||||
int main(int argc, char *argv[]) {
|
||||
|
||||
if (argc > 1 && strncmp(argv[1], "-h", 2) == 0) {
|
||||
printf("Syntax: %s [-v] [inputfile [outputfile [splicefile]]]\n\n", argv[0]);
|
||||
printf("Reads a testcase from stdin when no input file (or '-') is specified,\n");
|
||||
printf("mutates according to AFL++'s mutation engine, and write to stdout when '-' or\n");
|
||||
printf("no output filename is given. As an optional third parameter you can give a file\n");
|
||||
|
||||
printf(
|
||||
"Syntax: %s [-v] [-m maxmutations] [-x dict] [inputfile [outputfile "
|
||||
"[splicefile]]]\n\n",
|
||||
argv[0]);
|
||||
printf(
|
||||
"Reads a testcase from stdin when no input file (or '-') is "
|
||||
"specified,\n");
|
||||
printf(
|
||||
"mutates according to AFL++'s mutation engine, and write to stdout "
|
||||
"when '-' or\n");
|
||||
printf(
|
||||
"no output filename is given. As an optional third parameter you can "
|
||||
"give a file\n");
|
||||
printf("for splicing. Maximum input and output length is 1MB.\n");
|
||||
printf("The -v verbose option prints debug output to stderr.\n");
|
||||
printf("Options:\n");
|
||||
printf(" -v verbose debug output to stderr.\n");
|
||||
printf(" -m val max mutations (1-val, val default is 16)\n");
|
||||
printf(" -x file dictionary file (AFL++ format)\n");
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
FILE *in = stdin, *out = stdout, *splice = NULL;
|
||||
unsigned char *inbuf = malloc(1024 * 1024), *outbuf, *splicebuf = NULL;
|
||||
int verbose = 0, splicelen = 0;
|
||||
FILE *in = stdin, *out = stdout, *splice = NULL;
|
||||
unsigned char *inbuf = malloc(1024 * 1024), *outbuf = NULL, *splicebuf = NULL;
|
||||
int splicelen = 0, opt;
|
||||
|
||||
while ((opt = getopt(argc, argv, "vm:x:")) > 0) {
|
||||
|
||||
switch (opt) {
|
||||
|
||||
case 'm':
|
||||
max_havoc = atoi(optarg);
|
||||
break;
|
||||
case 'v':
|
||||
verbose = 1;
|
||||
break;
|
||||
case 'x':
|
||||
dict = optarg;
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Error: unknown parameter -%c\n", opt);
|
||||
exit(-1);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (max_havoc < 1) {
|
||||
|
||||
fprintf(stderr, "Error: illegal -m value\n");
|
||||
exit(-1);
|
||||
|
||||
if (argc > 1 && strcmp(argv[1], "-v") == 0) {
|
||||
verbose = 1;
|
||||
argc--;
|
||||
argv++;
|
||||
fprintf(stderr, "Verbose active\n");
|
||||
}
|
||||
|
||||
my_mutator_t *data = afl_custom_init(NULL, 0);
|
||||
|
||||
if (argc > 1 && strcmp(argv[1], "-") != 0) {
|
||||
if ((in = fopen(argv[1], "r")) == NULL) {
|
||||
if (argc > optind && strcmp(argv[optind], "-") != 0) {
|
||||
|
||||
if ((in = fopen(argv[optind], "r")) == NULL) {
|
||||
|
||||
perror(argv[1]);
|
||||
return -1;
|
||||
|
||||
}
|
||||
if (verbose) fprintf(stderr, "Input: %s\n", argv[1]);
|
||||
|
||||
if (verbose) fprintf(stderr, "Input: %s\n", argv[optind]);
|
||||
|
||||
}
|
||||
|
||||
size_t inlen = fread(inbuf, 1, 1024*1024, in);
|
||||
|
||||
size_t inlen = fread(inbuf, 1, 1024 * 1024, in);
|
||||
|
||||
if (!inlen) {
|
||||
fprintf(stderr, "Error: empty file %s\n", argv[1] ? argv[1] : "stdin");
|
||||
|
||||
fprintf(stderr, "Error: empty file %s\n",
|
||||
argv[optind] ? argv[optind] : "stdin");
|
||||
return -1;
|
||||
|
||||
}
|
||||
|
||||
if (argc > 2 && strcmp(argv[2], "-") != 0) {
|
||||
if ((out = fopen(argv[2], "w")) == NULL) {
|
||||
perror(argv[2]);
|
||||
if (argc > optind + 1 && strcmp(argv[optind + 1], "-") != 0) {
|
||||
|
||||
if ((out = fopen(argv[optind + 1], "w")) == NULL) {
|
||||
|
||||
perror(argv[optind + 1]);
|
||||
return -1;
|
||||
|
||||
}
|
||||
if (verbose) fprintf(stderr, "Output: %s\n", argv[2]);
|
||||
|
||||
if (verbose) fprintf(stderr, "Output: %s\n", argv[optind + 1]);
|
||||
|
||||
}
|
||||
|
||||
if (argc > 3) {
|
||||
if ((splice = fopen(argv[3], "r")) == NULL) {
|
||||
perror(argv[3]);
|
||||
if (argc > optind + 2) {
|
||||
|
||||
if ((splice = fopen(argv[optind + 2], "r")) == NULL) {
|
||||
|
||||
perror(argv[optind + 2]);
|
||||
return -1;
|
||||
|
||||
}
|
||||
if (verbose) fprintf(stderr, "Splice: %s\n", argv[3]);
|
||||
splicebuf = malloc(1024*1024);
|
||||
size_t splicelen = fread(splicebuf, 1, 1024*1024, splice);
|
||||
|
||||
if (verbose) fprintf(stderr, "Splice: %s\n", argv[optind + 2]);
|
||||
splicebuf = malloc(1024 * 1024);
|
||||
size_t splicelen = fread(splicebuf, 1, 1024 * 1024, splice);
|
||||
if (!splicelen) {
|
||||
fprintf(stderr, "Error: empty file %s\n", argv[3]);
|
||||
|
||||
fprintf(stderr, "Error: empty file %s\n", argv[optind + 2]);
|
||||
return -1;
|
||||
|
||||
}
|
||||
|
||||
if (verbose) fprintf(stderr, "Mutation splice length: %zu\n", splicelen);
|
||||
|
||||
}
|
||||
|
||||
if (verbose) fprintf(stderr, "Mutation input length: %zu\n", inlen);
|
||||
unsigned int outlen = afl_custom_fuzz(data, inbuf, inlen, &outbuf, splicebuf, splicelen, 1024*1024);
|
||||
unsigned int outlen = afl_custom_fuzz(data, inbuf, inlen, &outbuf, splicebuf,
|
||||
splicelen, 1024 * 1024);
|
||||
|
||||
if (outlen == 0 || !outbuf) {
|
||||
|
||||
fprintf(stderr, "Error: no mutation data returned.\n");
|
||||
return -1;
|
||||
|
||||
}
|
||||
|
||||
if (verbose) fprintf(stderr, "Mutation output length: %zu\n", outlen);
|
||||
if (verbose) fprintf(stderr, "Mutation output length: %u\n", outlen);
|
||||
|
||||
if (fwrite(outbuf, 1, outlen, out) != outlen) {
|
||||
|
||||
fprintf(stderr, "Warning: incomplete write.\n");
|
||||
return -1;
|
||||
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
|
@ -13,7 +13,7 @@ Just type `make` to build `atnwalk.so`.
|
||||
**NOTE:** The commands below just demonstrate an example how running ATNwalk looks like and require a working [testbed](https://github.com/atnwalk/testbed)
|
||||
|
||||
```bash
|
||||
# create the required a random seed first
|
||||
# create the required random seed first
|
||||
mkdir -p ~/campaign/example/seeds
|
||||
cd ~/campaign/example/seeds
|
||||
head -c1 /dev/urandom | ~/atnwalk/build/javascript/bin/decode -wb > seed.decoded 2> seed.encoded
|
||||
|
@ -180,7 +180,8 @@ size_t fail_fatal(int fd_socket, uint8_t **out_buf) {
|
||||
|
||||
if (fd_socket != -1) { close(fd_socket); }
|
||||
*out_buf = NULL;
|
||||
return 0;
|
||||
fprintf(stderr, "atnwalk.socket not found in current directory!\n");
|
||||
exit(-1);
|
||||
|
||||
}
|
||||
|
||||
|
@ -39,6 +39,7 @@ extern "C" {
|
||||
#ifndef AFL_TXT_MAX_LEN
|
||||
#define AFL_TXT_MAX_LEN 65535
|
||||
#endif
|
||||
#define AUTOTOKENS_TXT_MIN_LEN 1
|
||||
|
||||
#if AUTOTOKENS_SPLICE_MIN >= AUTOTOKENS_SIZE_MIN
|
||||
#error SPLICE_MIN must be lower than SIZE_MIN
|
||||
@ -57,8 +58,9 @@ typedef struct my_mutator {
|
||||
if (unlikely(debug)) fprintf
|
||||
#define IFDEBUG if (unlikely(debug))
|
||||
|
||||
int module_disabled = 0;
|
||||
|
||||
static afl_state *afl_ptr;
|
||||
static int module_disabled = 0;
|
||||
static int auto_disable = AUTOTOKENS_AUTO_DISABLE;
|
||||
static int debug = AUTOTOKENS_DEBUG;
|
||||
static int only_fav = AUTOTOKENS_ONLY_FAV;
|
||||
@ -104,9 +106,9 @@ static void first_run(void *data) {
|
||||
if (afl_ptr->custom_only || !auto_disable) { return; }
|
||||
|
||||
if (unlikely(afl_ptr->active_items == 1 &&
|
||||
afl_ptr->queue_cur->len < AFL_TXT_MIN_LEN)) {
|
||||
afl_ptr->queue_cur->len < AUTOTOKENS_TXT_MIN_LEN)) {
|
||||
|
||||
if (afl_ptr->extras_cnt > 8) {
|
||||
if (afl_ptr->extras_cnt) {
|
||||
|
||||
u32 valid = 0;
|
||||
|
||||
@ -237,7 +239,7 @@ extern "C" u32 afl_custom_fuzz_count(void *data, const u8 *buf,
|
||||
|
||||
}
|
||||
|
||||
extern "C" size_t afl_custom_fuzz(my_mutator_t *data, u8 *buf, size_t buf_size,
|
||||
extern "C" size_t afl_custom_fuzz(void *data, u8 *buf, size_t buf_size,
|
||||
u8 **out_buf, u8 *add_buf,
|
||||
size_t add_buf_size, size_t max_size) {
|
||||
|
||||
@ -655,6 +657,7 @@ extern "C" unsigned char afl_custom_queue_get(void *data,
|
||||
if (current_id > whitespace_ids + 6 && afl_ptr->active_items == 1 &&
|
||||
afl_ptr->queue_cur->len < AFL_TXT_MIN_LEN) {
|
||||
|
||||
retry_thin_air:
|
||||
DEBUGF(stderr, "Creating an entry from thin air...\n");
|
||||
structure = new vector<u32>();
|
||||
u32 item, prev, cnt = current_id >> 1;
|
||||
@ -684,8 +687,6 @@ extern "C" unsigned char afl_custom_queue_get(void *data,
|
||||
|
||||
}
|
||||
|
||||
create_from_thin_air = 0;
|
||||
|
||||
}
|
||||
|
||||
if (entry == file_mapping.end()) {
|
||||
@ -693,7 +694,7 @@ extern "C" unsigned char afl_custom_queue_get(void *data,
|
||||
// this input file was not analyzed for tokens yet, so let's do it!
|
||||
size_t len = afl_ptr->queue_cur->len;
|
||||
|
||||
if (len < AFL_TXT_MIN_LEN) {
|
||||
if (len < AUTOTOKENS_TXT_MIN_LEN) {
|
||||
|
||||
file_mapping[fn] = structure; // NULL ptr so we don't read the file again
|
||||
s = NULL;
|
||||
@ -895,6 +896,7 @@ extern "C" unsigned char afl_custom_queue_get(void *data,
|
||||
|
||||
if (tokens.size() < AUTOTOKENS_SIZE_MIN) {
|
||||
|
||||
if (create_from_thin_air) { goto retry_thin_air; }
|
||||
file_mapping[fn] = NULL;
|
||||
s = NULL;
|
||||
DEBUGF(stderr, "too few tokens\n");
|
||||
@ -955,7 +957,7 @@ extern "C" unsigned char afl_custom_queue_get(void *data,
|
||||
|
||||
}
|
||||
|
||||
extern "C" my_mutator_t *afl_custom_init(afl_state *afl, unsigned int seed) {
|
||||
extern "C" void *afl_custom_init(afl_state_t *afl, unsigned int seed) {
|
||||
|
||||
(void)(seed);
|
||||
my_mutator_t *data = (my_mutator_t *)calloc(1, sizeof(my_mutator_t));
|
||||
@ -1070,7 +1072,7 @@ extern "C" my_mutator_t *afl_custom_init(afl_state *afl, unsigned int seed) {
|
||||
id_to_token[current_id] = "'";
|
||||
++current_id;
|
||||
|
||||
return data;
|
||||
return (void *)data;
|
||||
|
||||
}
|
||||
|
||||
|
19
custom_mutators/autotokens/standalone/Makefile
Normal file
19
custom_mutators/autotokens/standalone/Makefile
Normal file
@ -0,0 +1,19 @@
|
||||
|
||||
CFLAGS = -g -O3 -funroll-loops -fPIC -D_STANDALONE_MODULE=1 -Wno-implicit-function-declaration
|
||||
CXXFLAGS= -g -O3 -funroll-loops -fPIC -D_STANDALONE_MODULE=1
|
||||
|
||||
all: autotokens-standalone
|
||||
|
||||
autotokens.o: ../autotokens.cpp
|
||||
$(CXX) $(CXXFLAGS) -I../../../include -I. -I../.. -c ../autotokens.cpp
|
||||
|
||||
autotokens-standalone: autotokens-standalone.c autotokens.o
|
||||
$(CC) $(CFLAGS) -DBIN_PATH=\"foo\" -I../../../include -I. -c autotokens-standalone.c
|
||||
$(CC) $(CFLAGS) -DBIN_PATH=\"foo\" -I../../../include -I. -c ../../../src/afl-performance.c
|
||||
$(CC) $(CFLAGS) -DBIN_PATH=\"foo\" -I../../../include -I. -c ../../../src/afl-fuzz-extras.c
|
||||
$(CC) $(CFLAGS) -DBIN_PATH=\"foo\" -I../../../include -I. -c ../../../src/afl-fuzz-queue.c
|
||||
$(CC) $(CFLAGS) -DBIN_PATH=\"foo\" -I../../../include -I. -c ../../../src/afl-common.c
|
||||
$(CXX) $(CFLAGS) -DBIN_PATH=\"foo\" -I../../../include -I. -o autotokens-standalone *.o
|
||||
|
||||
clean:
|
||||
rm -f *.o *~ autotokens-standalone core
|
12
custom_mutators/autotokens/standalone/README.md
Normal file
12
custom_mutators/autotokens/standalone/README.md
Normal file
@ -0,0 +1,12 @@
|
||||
# Autotokens standalone mutator
|
||||
|
||||
this is a standalone version of the AFL++ autotokens custom mutator.
|
||||
|
||||
just type `make` to build.
|
||||
|
||||
You *MUST* use a dictionary file to have an effective grammarless grammar fuzzer!
|
||||
|
||||
```
|
||||
autotokens-standalone -h # to see all parameteres
|
||||
autotokens-standalone -x foo.dict inputfile outputfile # example
|
||||
```
|
192
custom_mutators/autotokens/standalone/autotokens-standalone.c
Normal file
192
custom_mutators/autotokens/standalone/autotokens-standalone.c
Normal file
@ -0,0 +1,192 @@
|
||||
#include "afl-fuzz.h"
|
||||
#include "afl-mutations.h"
|
||||
|
||||
#include <unistd.h>
|
||||
#include <getopt.h>
|
||||
|
||||
static int max_havoc = 16, verbose;
|
||||
static unsigned char *dict, *mh = "16";
|
||||
|
||||
extern int module_disabled;
|
||||
|
||||
void *afl_custom_init(afl_state_t *, unsigned int);
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
|
||||
if (argc > 1 && strncmp(argv[1], "-h", 2) == 0) {
|
||||
|
||||
printf(
|
||||
"Syntax: %s [-v] [-m maxmutations] [-x dict] [inputfile [outputfile "
|
||||
"[splicefile]]]\n\n",
|
||||
argv[0]);
|
||||
printf("Reads a testcase from a file (not stdin!),\n");
|
||||
printf("writes to stdout when '-' or\n");
|
||||
printf(
|
||||
"no output filename is given. As an optional third parameter you can "
|
||||
"give a file\n");
|
||||
printf("for splicing. Maximum input and output length is 1MB.\n");
|
||||
printf("Options:\n");
|
||||
printf(" -v verbose debug output to stderr.\n");
|
||||
printf(" -m val max mutations (1-val, val default is 16)\n");
|
||||
printf(" -x file dictionary file (AFL++ format)\n");
|
||||
printf("You can set the following environment variable parameters:\n");
|
||||
printf("AUTOTOKENS_COMMENT` - what character or string starts a comment which will be\n");
|
||||
printf(" removed. Default: \"/* ... */\"\n");
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
FILE *in = stdin, *out = stdout, *splice = NULL;
|
||||
unsigned char *inbuf = malloc(1024 * 1024), *outbuf = NULL, *splicebuf = NULL;
|
||||
int splicelen = 0, opt;
|
||||
|
||||
while ((opt = getopt(argc, argv, "vm:x:")) > 0) {
|
||||
|
||||
switch (opt) {
|
||||
|
||||
case 'm':
|
||||
max_havoc = atoi(optarg);
|
||||
mh = optarg;
|
||||
break;
|
||||
case 'v':
|
||||
verbose = 1;
|
||||
break;
|
||||
case 'x':
|
||||
dict = optarg;
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Error: unknown parameter -%c\n", opt);
|
||||
exit(-1);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (max_havoc < 1) {
|
||||
|
||||
fprintf(stderr, "Error: illegal -m value\n");
|
||||
exit(-1);
|
||||
|
||||
}
|
||||
|
||||
if (argc > optind && strcmp(argv[optind], "-") != 0) {
|
||||
|
||||
if ((in = fopen(argv[optind], "r")) == NULL) {
|
||||
|
||||
perror(argv[1]);
|
||||
return -1;
|
||||
|
||||
}
|
||||
|
||||
if (verbose) fprintf(stderr, "Input: %s\n", argv[optind]);
|
||||
|
||||
}
|
||||
|
||||
size_t inlen = fread(inbuf, 1, 1024 * 1024, in);
|
||||
|
||||
if (!inlen) {
|
||||
|
||||
fprintf(stderr, "Error: empty file %s\n",
|
||||
argv[optind] ? argv[optind] : "stdin");
|
||||
return -1;
|
||||
|
||||
}
|
||||
|
||||
if (argc > optind + 1 && strcmp(argv[optind + 1], "-") != 0) {
|
||||
|
||||
if ((out = fopen(argv[optind + 1], "w")) == NULL) {
|
||||
|
||||
perror(argv[optind + 1]);
|
||||
return -1;
|
||||
|
||||
}
|
||||
|
||||
if (verbose) fprintf(stderr, "Output: %s\n", argv[optind + 1]);
|
||||
|
||||
}
|
||||
|
||||
if (argc > optind + 2) {
|
||||
|
||||
if ((splice = fopen(argv[optind + 2], "r")) == NULL) {
|
||||
|
||||
perror(argv[optind + 2]);
|
||||
return -1;
|
||||
|
||||
}
|
||||
|
||||
if (verbose) fprintf(stderr, "Splice: %s\n", argv[optind + 2]);
|
||||
splicebuf = malloc(1024 * 1024);
|
||||
size_t splicelen = fread(splicebuf, 1, 1024 * 1024, splice);
|
||||
if (!splicelen) {
|
||||
|
||||
fprintf(stderr, "Error: empty file %s\n", argv[optind + 2]);
|
||||
return -1;
|
||||
|
||||
}
|
||||
|
||||
if (verbose) fprintf(stderr, "Mutation splice length: %zu\n", splicelen);
|
||||
|
||||
}
|
||||
|
||||
/* configure autotokens */
|
||||
setenv("AUTOTOKENS_LEARN_DICT", "1", 0);
|
||||
setenv("AUTOTOKENS_CREATE_FROM_THIN_AIR", "1", 0);
|
||||
setenv("AUTOTOKENS_CHANGE_MAX", mh, 0);
|
||||
|
||||
/* fake AFL++ state */
|
||||
afl_state_t *afl = (afl_state_t *)calloc(1, sizeof(afl_state_t));
|
||||
afl->queue_cycle = afl->havoc_div = afl->active_items = afl->queued_items = 1;
|
||||
afl->shm.cmplog_mode = 0;
|
||||
afl->fsrv.dev_urandom_fd = open("/dev/urandom", O_RDONLY);
|
||||
if (afl->fsrv.dev_urandom_fd < 0) { PFATAL("Unable to open /dev/urandom"); }
|
||||
|
||||
rand_set_seed(afl, getpid());
|
||||
|
||||
if (dict) {
|
||||
|
||||
load_extras(afl, dict);
|
||||
if (verbose)
|
||||
fprintf(stderr, "Loaded dictionary: %s (%u entries)\n", dict,
|
||||
afl->extras_cnt);
|
||||
|
||||
}
|
||||
|
||||
// setup a fake queue entry
|
||||
afl->queue_buf = malloc(64);
|
||||
afl->queue_buf[0] = afl->queue_cur =
|
||||
(struct queue_entry *)malloc(sizeof(struct queue_entry));
|
||||
afl->queue_cur->testcase_buf = inbuf;
|
||||
afl->queue_cur->fname = (u8 *)argv[optind];
|
||||
afl->queue_cur->len = inlen;
|
||||
afl->queue_cur->perf_score = 100;
|
||||
afl->queue_cur->favored = afl->queue_cur->is_ascii = 1;
|
||||
// afl->custom_only = 1;
|
||||
|
||||
void *data = (void *)afl_custom_init(afl, (u32)0);
|
||||
|
||||
u8 res = afl_custom_queue_get(inbuf, (u8 *)argv[optind]);
|
||||
|
||||
if (verbose) fprintf(stderr, "Mutation input length: %zu\n", inlen);
|
||||
unsigned int outlen = afl_custom_fuzz(data, inbuf, inlen, &outbuf, splicebuf,
|
||||
splicelen, 1024 * 1024);
|
||||
|
||||
if (outlen == 0 || !outbuf) {
|
||||
|
||||
fprintf(stderr, "Error: no mutation data returned.\n");
|
||||
return -1;
|
||||
|
||||
}
|
||||
|
||||
if (verbose) fprintf(stderr, "Mutation output length: %u\n", outlen);
|
||||
|
||||
if (fwrite(outbuf, 1, outlen, out) != outlen) {
|
||||
|
||||
fprintf(stderr, "Warning: incomplete write.\n");
|
||||
return -1;
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
7
custom_mutators/custom_send_tcp/Makefile
Normal file
7
custom_mutators/custom_send_tcp/Makefile
Normal file
@ -0,0 +1,7 @@
|
||||
all: custom_send_tcp.so
|
||||
|
||||
custom_send_tcp.so:
|
||||
$(CC) -Wno-unused-result -g -O3 -shared -fPIC -o custom_send_tcp.so -I../../include custom_send_tcp.c
|
||||
|
||||
clean:
|
||||
rm -f custom_send_tcp.so *.o *~ core
|
13
custom_mutators/custom_send_tcp/README.md
Normal file
13
custom_mutators/custom_send_tcp/README.md
Normal file
@ -0,0 +1,13 @@
|
||||
# Send testcases via TCP custom mutator
|
||||
|
||||
This custom mutator sends the fuzzing testcases via TCP.
|
||||
|
||||
`AFL_CUSTOM_MUTATOR_LATE_SEND` - MUST be set!
|
||||
`CUSTOM_SEND_IP` - the IP address to send to (basically only 127.0.0.1 makes sense)
|
||||
`CUSTOM_SEND_PORT` - the TCP port to send to
|
||||
`CUSTOM_SEND_READ` - if the custom mutator should wait for a reply from the target
|
||||
|
||||
Example:
|
||||
```
|
||||
CUSTOM_SEND_IP=127.0.0.1 CUSTOM_SEND_PORT=8000 CUSTOM_SEND_READ=1 AFL_CUSTOM_MUTATOR_LATE_SEND=1 AFL_CUSTOM_MUTATOR_LIBRARY=custom_send_tcp.so ./afl-fuzz ...
|
||||
```
|
113
custom_mutators/custom_send_tcp/custom_send_tcp.c
Normal file
113
custom_mutators/custom_send_tcp/custom_send_tcp.c
Normal file
@ -0,0 +1,113 @@
|
||||
#include <time.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/select.h>
|
||||
|
||||
#include "afl-fuzz.h"
|
||||
|
||||
static int my_debug = 0;
|
||||
static int my_read = 0;
|
||||
|
||||
#define DEBUG(...) if (my_debug) printf(__VA_ARGS__)
|
||||
|
||||
typedef struct tcp_send_mutator {
|
||||
afl_state_t* afl;
|
||||
struct sockaddr_in server_addr;
|
||||
} tcp_send_mutator_t;
|
||||
|
||||
void *afl_custom_init(afl_state_t* afl, uint32_t seed) {
|
||||
const char* ip = getenv("CUSTOM_SEND_IP");
|
||||
const char* port = getenv("CUSTOM_SEND_PORT");
|
||||
|
||||
if (getenv("AFL_DEBUG")) my_debug = 1;
|
||||
if (getenv("CUSTOM_SEND_READ")) my_read = 1;
|
||||
|
||||
if (!ip || !port) {
|
||||
fprintf(stderr, "You forgot to set CUSTOM_SEND_IP and/or CUSTOM_SEND_PORT\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
tcp_send_mutator_t* mutator = calloc(1, sizeof(tcp_send_mutator_t));
|
||||
if (!mutator) {
|
||||
fprintf(stderr, "Failed to allocate mutator struct\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
mutator->afl = afl;
|
||||
|
||||
bzero(&mutator->server_addr, sizeof(mutator->server_addr));
|
||||
mutator->server_addr.sin_family = AF_INET;
|
||||
if (inet_pton(AF_INET, ip, &mutator->server_addr.sin_addr) <= 0) {
|
||||
fprintf(stderr, "Could not convert target ip address!\n");
|
||||
exit(1);
|
||||
}
|
||||
mutator->server_addr.sin_port = htons(atoi(port));
|
||||
|
||||
printf("[+] Custom tcp send mutator setup ready to go!\n");
|
||||
|
||||
return mutator;
|
||||
}
|
||||
|
||||
int try_connect(tcp_send_mutator_t *mutator, int sock, int max_attempts) {
|
||||
while (max_attempts > 0) {
|
||||
if (connect(sock, (struct sockaddr*)&mutator->server_addr, sizeof(mutator->server_addr)) == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Even with AFL_CUSTOM_LATE_SEND=1, there is a race between the
|
||||
// application under test having started to listen for connections and
|
||||
// afl_custom_fuzz_send being called. To address this race, we attempt
|
||||
// to connect N times and sleep a short period of time in between
|
||||
// connection attempts.
|
||||
struct timespec t;
|
||||
t.tv_sec = 0;
|
||||
t.tv_nsec = 100;
|
||||
nanosleep(&t, NULL);
|
||||
--max_attempts;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
void afl_custom_fuzz_send(tcp_send_mutator_t *mutator, uint8_t *buf, size_t buf_size) {
|
||||
int sock = socket(AF_INET, SOCK_STREAM, 0);
|
||||
|
||||
int written = 0;
|
||||
if (sock >= 0 && try_connect(mutator, sock, 10000) == 0) {
|
||||
DEBUG("connected, write()\n");
|
||||
written = write(sock, buf, buf_size);
|
||||
} else {
|
||||
DEBUG("socket() or connect() error: %d\n", errno);
|
||||
}
|
||||
|
||||
if (written < 0) {
|
||||
DEBUG("write() error: %d\n", errno);
|
||||
} else if (my_read) {
|
||||
struct timeval timeout;
|
||||
timeout.tv_sec = 1;
|
||||
timeout.tv_usec = 0;
|
||||
|
||||
fd_set set;
|
||||
FD_ZERO(&set);
|
||||
FD_SET(sock, &set);
|
||||
|
||||
int select_res = select(sock + 1, &set, NULL, NULL, &timeout);
|
||||
if (select_res == -1) {
|
||||
DEBUG("select() error: %d\n", errno);
|
||||
} else if (select_res == 0) {
|
||||
DEBUG("read() timeout!\n");
|
||||
} else {
|
||||
uint8_t buf[64];
|
||||
(void)read(sock, buf, sizeof(buf));
|
||||
}
|
||||
}
|
||||
|
||||
close(sock);
|
||||
}
|
||||
|
||||
void afl_custom_deinit(tcp_send_mutator_t* mutator) {
|
||||
free(mutator);
|
||||
}
|
Submodule custom_mutators/gramatron/json-c updated: 11546bfd07...af8dd4a307
@ -1 +1 @@
|
||||
ff4e5a2
|
||||
05d8f53
|
||||
|
Submodule custom_mutators/grammar_mutator/grammar_mutator updated: ff4e5a265d...05d8f537f8
@ -3707,7 +3707,7 @@ typedef intptr_t wdiff;
|
||||
1024 * 1024 * 8 /* static malloc'd heap size if used as a library */
|
||||
#define FBITS 24 /* bits in fixnum, on the way to 24 and beyond */
|
||||
#define FMAX \
|
||||
((1 << FBITS) - 1) /* maximum fixnum (and most negative fixnum) \
|
||||
((1U << FBITS) - 1) /* maximum fixnum (and most negative fixnum) \
|
||||
*/
|
||||
#define MAXOBJ 0xffff /* max words in tuple including header */
|
||||
#define MAXPAYL \
|
||||
|
@ -5,4 +5,5 @@ members = [
|
||||
"example",
|
||||
# Lain needs a nightly toolchain
|
||||
# "example_lain",
|
||||
]
|
||||
# "example_lain_post_process",
|
||||
]
|
||||
|
@ -5,7 +5,15 @@ Bindings to create custom mutators in Rust.
|
||||
These bindings are documented with rustdoc. To view the documentation run
|
||||
```cargo doc -p custom_mutator --open```.
|
||||
|
||||
A minimal example can be found in `example`. Build it using `cargo build --example example_mutator`.
|
||||
A minimal example can be found in `example`. Build it using `cargo build --example example_mutator`.
|
||||
|
||||
An example using [lain](https://github.com/microsoft/lain) for structured fuzzing can be found in `example_lain`.
|
||||
Since lain requires a nightly rust toolchain, you need to set one up before you can play with it.
|
||||
|
||||
An example for the use of the post_process function, using [lain](https://github.com/microsoft/lain) with [serde](https://github.com/serde-rs/serde) and [bincode](https://github.com/bincode-org/bincode) can be found in `example_lain_post_process`.
|
||||
In order for it to work you need to:
|
||||
|
||||
- disable input trimming with `AFL_DISABLE_TRIM=1`
|
||||
- provide an initial instance serialized with `bincode` or use the `AFL_NO_STARTUP_CALIBRATION=1` environment variable.
|
||||
|
||||
Note that `bincode` can also be used to serialize/deserialize the lain-generated structure and mutate it rather than generating a new one at each iteration, but it requires some structure serialized with `bincode` as input seed.
|
||||
|
@ -73,6 +73,8 @@ pub trait RawCustomMutator {
|
||||
None
|
||||
}
|
||||
|
||||
fn post_process<'b, 's: 'b>(&'s mut self, buffer: &'b mut [u8]) -> Option<&'b [u8]>;
|
||||
|
||||
/*fn post_process(&self, buffer: &[u8], unsigned char **out_buf)-> usize;
|
||||
int afl_custom_init_trim(&self, buffer: &[u8]);
|
||||
size_t afl_custom_trim(&self, unsigned char **out_buf);
|
||||
@ -353,6 +355,33 @@ pub mod wrappers {
|
||||
Err(err) => panic_handler("afl_custom_queue_get", &err),
|
||||
}
|
||||
}
|
||||
|
||||
/// Internal function used in the macro
|
||||
pub unsafe fn afl_custom_post_process<M: RawCustomMutator>(
|
||||
data: *mut c_void,
|
||||
buf: *mut u8,
|
||||
buf_size: usize,
|
||||
out_buf: *mut *const u8,
|
||||
) -> usize {
|
||||
match catch_unwind(|| {
|
||||
let mut context = FFIContext::<M>::from(data);
|
||||
|
||||
assert!(!buf.is_null(), "null buf passed to afl_custom_post_process");
|
||||
assert!(
|
||||
!out_buf.is_null(),
|
||||
"null out_buf passed to afl_custom_post_process"
|
||||
);
|
||||
let buff_slice = slice::from_raw_parts_mut(buf, buf_size);
|
||||
if let Some(buffer) = context.mutator.post_process(buff_slice) {
|
||||
*out_buf = buffer.as_ptr();
|
||||
return buffer.len();
|
||||
}
|
||||
0
|
||||
}) {
|
||||
Ok(ret) => ret,
|
||||
Err(err) => panic_handler("afl_custom_post_process", &err),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// An exported macro to defined afl_custom_init meant for insternal usage
|
||||
@ -480,6 +509,16 @@ macro_rules! export_mutator {
|
||||
pub unsafe extern "C" fn afl_custom_deinit(data: *mut ::std::os::raw::c_void) {
|
||||
$crate::wrappers::afl_custom_deinit_::<$mutator_type>(data)
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn afl_custom_post_process(
|
||||
data: *mut ::std::os::raw::c_void,
|
||||
buf: *mut u8,
|
||||
buf_size: usize,
|
||||
out_buf: *mut *const u8,
|
||||
) -> usize {
|
||||
$crate::wrappers::afl_custom_post_process::<$mutator_type>(data, buf, buf_size, out_buf)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@ -512,6 +551,10 @@ mod sanity_test {
|
||||
) -> Option<&'b [u8]> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn post_process<'b, 's: 'b>(&'s mut self, buffer: &'b mut [u8]) -> Option<&'b [u8]> {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
||||
export_mutator!(ExampleMutator);
|
||||
@ -579,6 +622,13 @@ pub trait CustomMutator {
|
||||
fn introspection(&mut self) -> Result<Option<&str>, Self::Error> {
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
fn post_process<'b, 's: 'b>(
|
||||
&'s mut self,
|
||||
buffer: &'b mut [u8],
|
||||
) -> Result<Option<&'b [u8]>, Self::Error> {
|
||||
Ok(Some(buffer))
|
||||
}
|
||||
}
|
||||
|
||||
impl<M> RawCustomMutator for M
|
||||
@ -682,6 +732,16 @@ where
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn post_process<'b, 's: 'b>(&'s mut self, buffer: &'b mut [u8]) -> Option<&'b [u8]> {
|
||||
match self.post_process(buffer) {
|
||||
Ok(r) => r,
|
||||
Err(e) => {
|
||||
Self::handle_error(e);
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// the default value to return from [`CustomMutator::describe`].
|
||||
|
@ -8,9 +8,9 @@ edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
custom_mutator = { path = "../custom_mutator" }
|
||||
lain="0.5"
|
||||
lain = { git = "https://github.com/AFLplusplus/lain.git" }
|
||||
|
||||
[[example]]
|
||||
name = "example_lain"
|
||||
path = "./src/lain_mutator.rs"
|
||||
crate-type = ["cdylib"]
|
||||
crate-type = ["cdylib"]
|
||||
|
21
custom_mutators/rust/example_lain_post_process/Cargo.toml
Normal file
21
custom_mutators/rust/example_lain_post_process/Cargo.toml
Normal file
@ -0,0 +1,21 @@
|
||||
[package]
|
||||
name = "example_lain_post_process"
|
||||
version = "0.1.0"
|
||||
authors = [
|
||||
"Julius Hohnerlein <julihoh@users.noreply.github.com>",
|
||||
"jma <94166787+jma-qb@users.noreply.github.com>",
|
||||
]
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
custom_mutator = { path = "../custom_mutator" }
|
||||
lain = { git = "https://github.com/AFLplusplus/lain.git" }
|
||||
bincode = "1.3.3"
|
||||
serde = { version = "1.0.214", features = ["derive"] }
|
||||
|
||||
[[example]]
|
||||
name = "example_lain_post_process"
|
||||
path = "./src/lain_mutator.rs"
|
||||
crate-type = ["cdylib"]
|
@ -0,0 +1 @@
|
||||
nightly
|
@ -0,0 +1,70 @@
|
||||
#![cfg(unix)]
|
||||
|
||||
use custom_mutator::{export_mutator, CustomMutator};
|
||||
use lain::{
|
||||
mutator::Mutator,
|
||||
prelude::*,
|
||||
rand::{rngs::StdRng, SeedableRng},
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize, Mutatable, NewFuzzed, BinarySerialize)]
|
||||
struct MyStruct {
|
||||
tag: u8,
|
||||
#[lain(ignore)]
|
||||
length: u32,
|
||||
#[lain(min = 0, max = 10)]
|
||||
data: Vec<u8>,
|
||||
}
|
||||
|
||||
struct LainMutator {
|
||||
mutator: Mutator<StdRng>,
|
||||
buffer: Vec<u8>,
|
||||
post_buffer: Vec<u8>,
|
||||
}
|
||||
|
||||
impl CustomMutator for LainMutator {
|
||||
type Error = ();
|
||||
|
||||
fn init(seed: u32) -> Result<Self, ()> {
|
||||
Ok(Self {
|
||||
mutator: Mutator::new(StdRng::seed_from_u64(seed as u64)),
|
||||
buffer: Vec::new(),
|
||||
post_buffer: Vec::new(),
|
||||
})
|
||||
}
|
||||
|
||||
fn fuzz<'b, 's: 'b>(
|
||||
&'s mut self,
|
||||
_buffer: &'b mut [u8],
|
||||
_add_buff: Option<&[u8]>,
|
||||
max_size: usize,
|
||||
) -> Result<Option<&'b [u8]>, ()> {
|
||||
// we just sample an instance of MyStruct, ignoring the current input
|
||||
let instance = MyStruct::new_fuzzed(&mut self.mutator, None);
|
||||
let serialized = bincode::serialize(&instance).unwrap();
|
||||
let size = serialized.len();
|
||||
if size > max_size {
|
||||
return Err(());
|
||||
}
|
||||
self.buffer.clear();
|
||||
self.buffer.reserve(size);
|
||||
self.buffer.extend_from_slice(&serialized);
|
||||
Ok(Some(self.buffer.as_slice()))
|
||||
}
|
||||
|
||||
fn post_process<'b, 's: 'b>(
|
||||
&'s mut self,
|
||||
buffer: &'b mut [u8],
|
||||
) -> Result<Option<&'b [u8]>, Self::Error> {
|
||||
let mut instance = bincode::deserialize::<MyStruct>(&buffer).unwrap();
|
||||
instance.length = instance.data.len() as u32;
|
||||
let size = instance.serialized_size();
|
||||
self.post_buffer.clear();
|
||||
self.post_buffer.reserve(size);
|
||||
instance.binary_serialize::<_, BigEndian>(&mut self.post_buffer);
|
||||
Ok(Some(&self.post_buffer))
|
||||
}
|
||||
}
|
||||
|
||||
export_mutator!(LainMutator);
|
@ -22,10 +22,10 @@ afl_state_t *afl_struct;
|
||||
typedef struct my_mutator {
|
||||
|
||||
afl_state_t *afl;
|
||||
u8 * mutator_buf;
|
||||
u8 * out_dir;
|
||||
u8 * tmp_dir;
|
||||
u8 * target;
|
||||
u8 *mutator_buf;
|
||||
u8 *out_dir;
|
||||
u8 *tmp_dir;
|
||||
u8 *target;
|
||||
uint32_t seed;
|
||||
|
||||
} my_mutator_t;
|
||||
@ -101,7 +101,7 @@ my_mutator_t *afl_custom_init(afl_state_t *afl, unsigned int seed) {
|
||||
|
||||
/* When a new queue entry is added we run this input with the symcc
|
||||
instrumented binary */
|
||||
uint8_t afl_custom_queue_new_entry(my_mutator_t * data,
|
||||
uint8_t afl_custom_queue_new_entry(my_mutator_t *data,
|
||||
const uint8_t *filename_new_queue,
|
||||
const uint8_t *filename_orig_queue) {
|
||||
|
||||
@ -176,7 +176,7 @@ uint8_t afl_custom_queue_new_entry(my_mutator_t * data,
|
||||
|
||||
struct dirent **nl;
|
||||
int32_t items = scandir(data->tmp_dir, &nl, NULL, NULL);
|
||||
u8 * origin_name = basename(filename_new_queue);
|
||||
u8 *origin_name = basename(filename_new_queue);
|
||||
int32_t i;
|
||||
if (items > 0) {
|
||||
|
||||
@ -187,8 +187,8 @@ uint8_t afl_custom_queue_new_entry(my_mutator_t * data,
|
||||
DBG("test=%s\n", fn);
|
||||
if (stat(source_name, &st) == 0 && S_ISREG(st.st_mode) && st.st_size) {
|
||||
|
||||
u8 *destination_name =
|
||||
alloc_printf("%s/%s.%s", data->out_dir, origin_name, nl[i]->d_name);
|
||||
u8 *destination_name = alloc_printf("%s/%s.%s", data->out_dir,
|
||||
origin_name, nl[i]->d_name);
|
||||
rename(source_name, destination_name);
|
||||
ck_free(destination_name);
|
||||
DBG("found=%s\n", source_name);
|
||||
@ -248,7 +248,7 @@ uint32_t afl_custom_fuzz_count(my_mutator_t *data, const u8 *buf,
|
||||
for (i = 0; i < (u32)items; ++i) {
|
||||
|
||||
struct stat st;
|
||||
u8 * fn = alloc_printf("%s/%s", data->out_dir, nl[i]->d_name);
|
||||
u8 *fn = alloc_printf("%s/%s", data->out_dir, nl[i]->d_name);
|
||||
DBG("test=%s\n", fn);
|
||||
if (stat(fn, &st) == 0 && S_ISREG(st.st_mode) && st.st_size) {
|
||||
|
||||
@ -282,12 +282,12 @@ size_t afl_custom_fuzz(my_mutator_t *data, uint8_t *buf, size_t buf_size,
|
||||
|
||||
if (items <= 0) return 0;
|
||||
|
||||
for (i = 0; i < (u32)items; ++i) {
|
||||
for (i = 0; i < (s32)items; ++i) {
|
||||
|
||||
struct stat st;
|
||||
u8 * fn = alloc_printf("%s/%s", data->out_dir, nl[i]->d_name);
|
||||
if (!done) {
|
||||
|
||||
if (done == 0) {
|
||||
struct stat st;
|
||||
u8 *fn = alloc_printf("%s/%s", data->out_dir, nl[i]->d_name);
|
||||
|
||||
if (stat(fn, &st) == 0 && S_ISREG(st.st_mode) && st.st_size) {
|
||||
|
||||
@ -306,10 +306,10 @@ size_t afl_custom_fuzz(my_mutator_t *data, uint8_t *buf, size_t buf_size,
|
||||
}
|
||||
|
||||
unlink(fn);
|
||||
ck_free(fn);
|
||||
|
||||
}
|
||||
|
||||
ck_free(fn);
|
||||
free(nl[i]);
|
||||
|
||||
}
|
||||
|
120
dictionaries/jsonschema.dict
Normal file
120
dictionaries/jsonschema.dict
Normal file
@ -0,0 +1,120 @@
|
||||
#
|
||||
# AFL dictionary for JSON Schema
|
||||
# https://json-schema.org/
|
||||
# -----------------------
|
||||
#
|
||||
|
||||
"\"$schema\""
|
||||
"\"$id\""
|
||||
"\"$ref\""
|
||||
"\"$defs\""
|
||||
"\"definitions\""
|
||||
"\"enum\""
|
||||
"\"const\""
|
||||
"\"type\""
|
||||
|
||||
# Annotations
|
||||
|
||||
"\"title\""
|
||||
"\"description\""
|
||||
"\"default\""
|
||||
"\"examples\""
|
||||
"\"$comment\""
|
||||
"\"readOnly\""
|
||||
"\"writeOnly\""
|
||||
"\"deprecated\""
|
||||
|
||||
# Types
|
||||
|
||||
"\"string\""
|
||||
"\"integer\""
|
||||
"\"number\""
|
||||
"\"object\""
|
||||
"\"array\""
|
||||
"\"null\""
|
||||
"\"boolean\""
|
||||
|
||||
# String
|
||||
|
||||
"\"minLength\""
|
||||
"\"maxLength\""
|
||||
"\"pattern\""
|
||||
"\"format\""
|
||||
"\"contentMediaType\""
|
||||
"\"contentEncoding\""
|
||||
"\"contentSchema\""
|
||||
|
||||
# Formats
|
||||
|
||||
"\"date-time\""
|
||||
"\"time\""
|
||||
"\"date\""
|
||||
"\"duration\""
|
||||
"\"email\""
|
||||
"\"idn-email\""
|
||||
"\"hostname\""
|
||||
"\"idn-hostname\""
|
||||
"\"ipv4\""
|
||||
"\"ipv6\""
|
||||
"\"uuid\""
|
||||
"\"uri\""
|
||||
"\"uri-reference\""
|
||||
"\"iri\""
|
||||
"\"iri-reference\""
|
||||
"\"uri-template\""
|
||||
"\"json-pointer\""
|
||||
"\"relative-json-pointer\""
|
||||
"\"regex\""
|
||||
|
||||
# Numeric
|
||||
|
||||
"\"multipleOf\""
|
||||
"\"minimum\""
|
||||
"\"exclusiveMinimum\""
|
||||
"\"maximum\""
|
||||
"\"exclusiveMaximum\""
|
||||
|
||||
# Object
|
||||
|
||||
"\"properties\""
|
||||
"\"patternProperties\""
|
||||
"\"additionalProperties\""
|
||||
"\"unevaluatedProperties\""
|
||||
"\"required\""
|
||||
"\"propertyNames\""
|
||||
"\"minProperties\""
|
||||
"\"maxProperties\""
|
||||
"\"dependencies\""
|
||||
|
||||
# Array
|
||||
|
||||
"\"items\""
|
||||
"\"prefixItems\""
|
||||
"\"additionalItems\""
|
||||
"\"unevaluatedItems\""
|
||||
"\"contains\""
|
||||
"\"minContains\""
|
||||
"\"maxContains\""
|
||||
"\"minItems\""
|
||||
"\"maxItems\""
|
||||
"\"uniqueItems\""
|
||||
|
||||
# Booleans
|
||||
|
||||
"true"
|
||||
"false"
|
||||
|
||||
# Composition
|
||||
|
||||
"\"allOf\""
|
||||
"\"anyOf\""
|
||||
"\"oneOf\""
|
||||
"\"not\""
|
||||
|
||||
# Conditions
|
||||
|
||||
"\"dependentRequired\""
|
||||
"\"dependentSchemas\""
|
||||
"\"if\""
|
||||
"\"then\""
|
||||
"\"else\""
|
5713
dictionaries/ruby.dict
Normal file
5713
dictionaries/ruby.dict
Normal file
File diff suppressed because it is too large
Load Diff
@ -3,6 +3,161 @@
|
||||
This is the list of all noteworthy changes made in every public
|
||||
release of the tool. See README.md for the general instruction manual.
|
||||
|
||||
### Version ++4.30c (release)
|
||||
! afl-gcc and afl-clang funcionality is now removed !
|
||||
- afl-fuzz:
|
||||
- fastresume feature added. if you abort fuzzing and resume fuzzing
|
||||
with `-i -` or `AFL_AUTORESUME=1` and the target binary has not changed
|
||||
then a dump will be loaded and the calibration phase skipped.
|
||||
to disable this feature set `AFL_NO_FASTRESUME=1`
|
||||
zlib compression is used if zlib is found at compile time
|
||||
- improved seed selection algorithm
|
||||
- added `AFL_CUSTOM_MUTATOR_LATE_SEND=1` to call the custom send()
|
||||
function after the target has been restarted.
|
||||
- because of bad math and undefined behaviour fixes we have to change
|
||||
the CMPLOG map. **YOU NEED TO RECOMPILE CMPLOG TARGETS**
|
||||
- fixed custom_post_process for calibration
|
||||
- fixes for AFL_EXIT_ON_TIME and AFL_EXIT_WHEN_DONE, changed behaviour of
|
||||
AFL_EXIT_WHEN_DONE to finish when really done :-)
|
||||
- frida_mode:
|
||||
- AFL_FRIDA_PERSISTENT_ADDR can now be be any reachable address not just
|
||||
a function entry
|
||||
- AFL_DEBUG is now the same as AFL_FRIDA_VERBOSE
|
||||
- AFL_FRIDA_DEBUG_MAPS now works as expected
|
||||
- qemu_mode:
|
||||
- new hooks supported (optional), see qemu_mode/hooking_bridge - thanks to
|
||||
@CowBoy4mH3LL
|
||||
- unicorn_mode:
|
||||
- fix install and forkserver (thanks aarnav!)
|
||||
- pin unicorn version
|
||||
- nyx_mode:
|
||||
- bugfixes
|
||||
- custom mutators:
|
||||
- custom_send_tcp custom mutator added, thanks to @dergoegge
|
||||
- afl-cc
|
||||
- fix to support pointless changes in LLVM 20
|
||||
- new runtime (!) variable: `AFL_OLD_FORKSERVER` to use the old vanilla
|
||||
AFL type forkserver. Useful for symcc/symqemu/nautilus/etc. with
|
||||
AFL_LLVM_INSTRUMENT=CLASSIC
|
||||
- new compile time variable: `AFL_OPT_LEVEL` to set a specific optimization
|
||||
level, default is `3`
|
||||
- correctly explain how to get the correct map size for large targets
|
||||
- small fix for weird LLVM defines in redhat
|
||||
- code formatting updated to llvm 18
|
||||
- improved custom_mutators/aflpp/standalone/aflpp-standalone
|
||||
- added custom_mutators/autotokens/standalone/autotokens-standalone
|
||||
- AFL++ headers are now installed to $PREFIX/include/afl
|
||||
|
||||
### Version ++4.21c (release)
|
||||
* afl-fuzz
|
||||
- fixed a regression in afl-fuzz that resulted in a 5-10% performace loss
|
||||
do a switch from gettimeofday() to clock_gettime() which should be rather
|
||||
three times faster. The reason for this is unknown.
|
||||
- new queue selection algorithm based on 2 core years of queue data
|
||||
analysis. gives a noticable improvement on coverage although the results
|
||||
seem counterintuitive :-)
|
||||
- added AFL_DISABLE_REDUNDANT for huge queues
|
||||
- added `AFL_NO_SYNC` environment variable that does what you think it does
|
||||
- fix AFL_PERSISTENT_RECORD
|
||||
- run custom_post_process after standard trimming
|
||||
- prevent filenames in the queue that have spaces
|
||||
- minor fix for FAST schedules
|
||||
- more frequent stats update when syncing (todo: check performance impact)
|
||||
- now timing of calibration, trimming and syncing is measured seperately,
|
||||
thanks to @eqv!
|
||||
- -V timing is now accurately the fuzz time (without syncing), before
|
||||
long calibration times and syncing could result in now fuzzing being
|
||||
made when the time was already run out until then, thanks to @eqv!
|
||||
- fix -n uninstrumented mode when ending fuzzing
|
||||
- enhanced the ASAN configuration
|
||||
- make afl-fuzz use less memory with cmplog and fix a memleak
|
||||
* afl-cc:
|
||||
- re-enable i386 support that was accidently disabled
|
||||
- fixes for LTO and outdated afl-gcc mode for i386
|
||||
- fix COMPCOV split compare for old LLVMs
|
||||
- disable xml/curl/g_ string transform functions because we do not check
|
||||
for null pointers ... TODO
|
||||
- ensure shared memory variables are visible in weird build setups
|
||||
- compatability to new LLVM 19 changes
|
||||
* afl-cmin
|
||||
- work with input files that have a space
|
||||
* afl-showmap
|
||||
- fix memory leak on shmem testcase usage (thanks to @ndrewh)
|
||||
- minor fix to collect coverage -C (thanks to @bet4it)
|
||||
* Fixed a shmem mmap bug (that rarely came up on MacOS)
|
||||
* libtokencap: script generate_libtoken_dict.sh added by @a-shvedov
|
||||
|
||||
### Version ++4.20c (release)
|
||||
! A new forkserver communication model is now introduced. afl-fuzz is
|
||||
backward compatible to old compiled targets if they are not built
|
||||
for CMPLOG/Redqueen, but new compiled targets will not work with
|
||||
old afl-fuzz versions!
|
||||
! Recompile all targets that are instrumented for CMPLOG/Redqueen!
|
||||
- AFL++ now supports up to 4 billion coverage edges, up from 6 million.
|
||||
- New compile option: `make PERFORMANCE=1` - this will enable special
|
||||
CPU dependent optimizations that make everything more performant - but
|
||||
the binaries will likely won't work on different platforms. Also
|
||||
enables a faster hasher if the CPU requirements are met.
|
||||
- The persistent record feature (see config.h) was expanded to also
|
||||
support replay, thanks to @quarta-qti !
|
||||
- afl-fuzz:
|
||||
- the new deterministic fuzzing feature is now activated by default,
|
||||
deactivate with -z. Parameters -d and -D are ignored.
|
||||
- small improvements to CMPLOG/redqueen
|
||||
- workround for a bug with MOpt -L when used with -M - in the future
|
||||
we will either remove or rewrite MOpt.
|
||||
- fix for `-t xxx+` feature
|
||||
- -e extension option now saves the queue items, crashes, etc. with the
|
||||
extension too
|
||||
- fixes for trimmming, correct -V time and reading stats on resume by eqv
|
||||
thanks a lot!
|
||||
- afl-cc:
|
||||
- added collision free caller instrumentation to LTO mode. activate with
|
||||
`AFL_LLVM_LTO_CALLER=1`. You can set a max depth to go through single
|
||||
block functions with `AFL_LLVM_LTO_CALLER_DEPTH` (default 0)
|
||||
- fixes for COMPCOV/LAF and most other modules
|
||||
- fix for GCC_PLUGIN cmplog that broke on std::strings
|
||||
- afl-whatsup:
|
||||
- now also displays current average speed
|
||||
- small bugfixes
|
||||
- custom mutators:
|
||||
- fixes for aflpp custom mutator and standalone tool
|
||||
- important fix to the symcc custom mutator
|
||||
- Minor edits to afl-persistent-config
|
||||
- Prevent temporary files being left behind on aborted afl-whatsup
|
||||
- More CPU benchmarks added to benchmark/
|
||||
|
||||
### Version ++4.10c (release)
|
||||
- afl-fuzz:
|
||||
- default power schedule is now EXPLORE, due a fix in fast schedules
|
||||
explore is slightly better now.
|
||||
- fixed minor issues in the mutation engine, thanks to @futhewo for
|
||||
reporting!
|
||||
- better deterministic fuzzing is now available, benchmarks have shown
|
||||
to improve fuzzing. Enable with -D. Thanks to @kdsjZh for the PR!
|
||||
- afl-cc:
|
||||
- large rewrite by @SonicStark which fixes a few corner cases, thanks!
|
||||
- LTO mode now requires llvm 12+
|
||||
- workaround for ASAN with gcc_plugin mode
|
||||
- instrumentation:
|
||||
- LLVM 18 support, thanks to @devnexen!
|
||||
- Injection (SQL, LDAP, XSS) fuzzing feature now available, see
|
||||
`instrumentation/README.injections.md` how to activate/use/expand.
|
||||
- compcov/LAF-intel:
|
||||
- floating point splitting bug fix by @hexcoder
|
||||
- due a bug in LLVM 17 integer splitting is disabled there!
|
||||
- when splitting floats was selected, integers were always split as well,
|
||||
fixed to require AFL_LLVM_LAF_SPLIT_COMPARES or _ALL as it should
|
||||
- dynamic instrumentation filtering for LLVM NATIVE, thanks @Mozilla!
|
||||
see utils/dynamic_covfilter/README.md
|
||||
- qemu_mode:
|
||||
- plugins are now activated by default and a new module is included that
|
||||
produces drcov compatible traces for lighthouse/lightkeeper/...
|
||||
thanks to @JRomainG to submitting!
|
||||
- updated Nyx checkout (fixes a bug) and some QOL
|
||||
- updated the custom grammar mutator
|
||||
- document afl-cmin does not work on macOS (but afl-cmin.bash does)
|
||||
|
||||
### Version ++4.09c (release)
|
||||
- afl-fuzz:
|
||||
- fixed the new mutation implementation for two bugs
|
||||
@ -34,7 +189,6 @@
|
||||
- added benchmark/benchmark.py if you want to see how good your fuzzing
|
||||
speed is in comparison to other setups.
|
||||
|
||||
|
||||
### Version ++4.08c (release)
|
||||
- afl-fuzz:
|
||||
- new mutation engine: mutations that favor discovery more paths are
|
||||
|
129
docs/INSTALL.md
129
docs/INSTALL.md
@ -21,7 +21,7 @@ If you want to build AFL++ yourself, you have many options. The easiest choice
|
||||
is to build and install everything:
|
||||
|
||||
NOTE: depending on your Debian/Ubuntu/Kali/... release, replace `-14` with
|
||||
whatever llvm version is available. We recommend llvm 13, 14, 15 or 16.
|
||||
whatever llvm version is available. We recommend llvm 13 or newer.
|
||||
|
||||
```shell
|
||||
sudo apt-get update
|
||||
@ -30,6 +30,9 @@ sudo apt-get install -y build-essential python3-dev automake cmake git flex biso
|
||||
sudo apt-get install -y lld-14 llvm-14 llvm-14-dev clang-14 || sudo apt-get install -y lld llvm llvm-dev clang
|
||||
sudo apt-get install -y gcc-$(gcc --version|head -n1|sed 's/\..*//'|sed 's/.* //')-plugin-dev libstdc++-$(gcc --version|head -n1|sed 's/\..*//'|sed 's/.* //')-dev
|
||||
sudo apt-get install -y ninja-build # for QEMU mode
|
||||
sudo apt-get install -y cpio libcapstone-dev # for Nyx mode
|
||||
sudo apt-get install -y wget curl # for Frida mode
|
||||
sudo apt-get install -y python3-pip # for Unicorn mode
|
||||
git clone https://github.com/AFLplusplus/AFLplusplus
|
||||
cd AFLplusplus
|
||||
make distrib
|
||||
@ -67,19 +70,20 @@ These build targets exist:
|
||||
* unit: perform unit tests (based on cmocka)
|
||||
* help: shows these build options
|
||||
|
||||
[Unless you are on Mac OS X](https://developer.apple.com/library/archive/qa/qa1118/_index.html),
|
||||
[Unless you are on macOS](https://developer.apple.com/library/archive/qa/qa1118/_index.html),
|
||||
you can also build statically linked versions of the AFL++ binaries by passing
|
||||
the `STATIC=1` argument to make:
|
||||
the `PERFORMANCE=1` argument to make:
|
||||
|
||||
```shell
|
||||
make STATIC=1
|
||||
make PERFORMANCE=1
|
||||
```
|
||||
|
||||
These build options exist:
|
||||
|
||||
* STATIC - compile AFL++ static
|
||||
* CODE_COVERAGE - compile the target for code coverage (see docs/instrumentation/README.llvm.md)
|
||||
* ASAN_BUILD - compiles AFL++ with memory sanitizer for debug purposes
|
||||
* PERFORMANCE - compile with performance options that make the binary not transferable to other systems. Recommended (except on macOS)!
|
||||
* STATIC - compile AFL++ static (does not work on macOS)
|
||||
* CODE_COVERAGE - compile the target for code coverage (see [README.llvm.md](../instrumentation/README.llvm.md))
|
||||
* ASAN_BUILD - compiles AFL++ with address sanitizer for debug purposes
|
||||
* UBSAN_BUILD - compiles AFL++ tools with undefined behaviour sanitizer for debug purposes
|
||||
* DEBUG - no optimization, -ggdb3, all warnings and -Werror
|
||||
* LLVM_DEBUG - shows llvm deprecation warnings
|
||||
@ -91,101 +95,78 @@ These build options exist:
|
||||
* NO_NYX - disable building nyx mode dependencies
|
||||
* NO_CORESIGHT - disable building coresight (arm64 only)
|
||||
* NO_UNICORN_ARM64 - disable building unicorn on arm64
|
||||
* AFL_NO_X86 - if compiling on non-intel/amd platforms
|
||||
* AFL_NO_X86 - if compiling on non-Intel/AMD platforms
|
||||
* LLVM_CONFIG - if your distro doesn't use the standard name for llvm-config (e.g., Debian)
|
||||
|
||||
e.g.: `make LLVM_CONFIG=llvm-config-14`
|
||||
|
||||
## MacOS X on x86 and arm64 (M1)
|
||||
## macOS on x86_64 and arm64
|
||||
|
||||
MacOS has some gotchas due to the idiosyncrasies of the platform.
|
||||
macOS has some gotchas due to the idiosyncrasies of the platform.
|
||||
|
||||
To build AFL, install llvm (and perhaps gcc) from brew and follow the general
|
||||
instructions for Linux. If possible, avoid Xcode at all cost.
|
||||
macOS supports SYSV shared memory used by AFL++'s instrumentation, but the
|
||||
default settings aren't sufficient. Before even building, increase
|
||||
them by running the provided script:
|
||||
|
||||
```shell
|
||||
sudo afl-system-config
|
||||
```
|
||||
|
||||
See
|
||||
[https://www.spy-hill.com/help/apple/SharedMemory.html](https://www.spy-hill.com/help/apple/SharedMemory.html)
|
||||
for documentation for the shared memory settings and how to make them permanent.
|
||||
|
||||
Next, to build AFL++, install the following packages from brew:
|
||||
|
||||
```shell
|
||||
brew install wget git make cmake llvm gdb coreutils
|
||||
```
|
||||
|
||||
Be sure to setup `PATH` to point to the correct clang binaries and use the
|
||||
freshly installed clang, clang++, llvm-config, gmake and coreutils, e.g.:
|
||||
Depending on your macOS system + brew version, brew may be installed in different places.
|
||||
You can check with `brew info llvm` to know where, then create a variable for it:
|
||||
|
||||
```shell
|
||||
# Depending on your MacOS system + brew version it is either
|
||||
export PATH="/opt/homebrew/opt/llvm/bin:$PATH"
|
||||
# or
|
||||
export PATH="/usr/local/opt/llvm/bin:$PATH"
|
||||
# you can check with "brew info llvm"
|
||||
export HOMEBREW_BASE="/opt/homebrew/opt"
|
||||
```
|
||||
|
||||
export PATH="/usr/local/opt/coreutils/libexec/gnubin:/usr/local/bin:$PATH"
|
||||
or
|
||||
|
||||
```shell
|
||||
export HOMEBREW_BASE="/usr/local/opt"
|
||||
```
|
||||
|
||||
Set `PATH` to point to the brew clang, clang++, llvm-config, gmake and coreutils.
|
||||
Also use the brew clang compiler; the Xcode clang compiler must not be used.
|
||||
|
||||
```shell
|
||||
export PATH="$HOMEBREW_BASE/coreutils/libexec/gnubin:/usr/local/bin:$HOMEBREW_BASE/llvm/bin:$PATH"
|
||||
export CC=clang
|
||||
export CXX=clang++
|
||||
gmake
|
||||
cd frida_mode
|
||||
gmake
|
||||
cd ..
|
||||
sudo gmake install
|
||||
```
|
||||
|
||||
`afl-gcc` will fail unless you have GCC installed, but that is using outdated
|
||||
instrumentation anyway. `afl-clang` might fail too depending on your PATH setup.
|
||||
But you don't want neither, you want `afl-clang-fast` anyway :) Note that
|
||||
`afl-clang-lto`, `afl-gcc-fast` and `qemu_mode` are not working on MacOS.
|
||||
Then build following the general Linux instructions.
|
||||
|
||||
The crash reporting daemon that comes by default with MacOS X will cause
|
||||
problems with fuzzing. You need to turn it off:
|
||||
If everything worked, you should then have `afl-clang-fast` installed, which you can check with:
|
||||
|
||||
```
|
||||
launchctl unload -w /System/Library/LaunchAgents/com.apple.ReportCrash.plist
|
||||
sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.ReportCrash.Root.plist
|
||||
```shell
|
||||
which afl-clang-fast
|
||||
```
|
||||
|
||||
The `fork()` semantics on OS X are a bit unusual compared to other unix systems
|
||||
Note that `afl-clang-lto`, `afl-gcc-fast` and `qemu_mode` are not working on macOS.
|
||||
|
||||
The crash reporting daemon that comes by default with macOS will cause
|
||||
problems with fuzzing. You need to turn it off, which you can do with `afl-system-config`.
|
||||
|
||||
The `fork()` semantics on macOS are a bit unusual compared to other unix systems
|
||||
and definitely don't look POSIX-compliant. This means two things:
|
||||
|
||||
- Fuzzing will be probably slower than on Linux. In fact, some folks report
|
||||
considerable performance gains by running the jobs inside a Linux VM on
|
||||
MacOS X.
|
||||
macOS.
|
||||
- Some non-portable, platform-specific code may be incompatible with the AFL++
|
||||
forkserver. If you run into any problems, set `AFL_NO_FORKSRV=1` in the
|
||||
environment before starting afl-fuzz.
|
||||
|
||||
User emulation mode of QEMU does not appear to be supported on MacOS X, so
|
||||
User emulation mode of QEMU does not appear to be supported on macOS, so
|
||||
black-box instrumentation mode (`-Q`) will not work. However, FRIDA mode (`-O`)
|
||||
works on both x86 and arm64 MacOS boxes.
|
||||
|
||||
MacOS X supports SYSV shared memory used by AFL's instrumentation, but the
|
||||
default settings aren't usable with AFL++. The default settings on 10.14 seem to
|
||||
be:
|
||||
|
||||
```bash
|
||||
$ ipcs -M
|
||||
IPC status from <running system> as of XXX
|
||||
shminfo:
|
||||
shmmax: 4194304 (max shared memory segment size)
|
||||
shmmin: 1 (min shared memory segment size)
|
||||
shmmni: 32 (max number of shared memory identifiers)
|
||||
shmseg: 8 (max shared memory segments per process)
|
||||
shmall: 1024 (max amount of shared memory in pages)
|
||||
```
|
||||
|
||||
To temporarily change your settings to something minimally usable with AFL++,
|
||||
run these commands as root:
|
||||
|
||||
```bash
|
||||
sysctl kern.sysv.shmmax=8388608
|
||||
sysctl kern.sysv.shmall=4096
|
||||
```
|
||||
|
||||
If you're running more than one instance of AFL, you likely want to make
|
||||
`shmall` bigger and increase `shmseg` as well:
|
||||
|
||||
```bash
|
||||
sysctl kern.sysv.shmmax=8388608
|
||||
sysctl kern.sysv.shmseg=48
|
||||
sysctl kern.sysv.shmall=98304
|
||||
```
|
||||
|
||||
See
|
||||
[http://www.spy-hill.com/help/apple/SharedMemory.html](http://www.spy-hill.com/help/apple/SharedMemory.html)
|
||||
for documentation for these settings and how to make them permanent.
|
||||
works on both x86 and arm64 macOS boxes.
|
||||
|
@ -38,9 +38,8 @@ For PCGUARD instrumentation `abort()` is called if this is detected, for LTO
|
||||
there will either be no coverage for the instrumented dlopen()'ed libraries or
|
||||
you will see lots of crashes in the UI.
|
||||
|
||||
Note that this is not an issue if you use the inferiour `afl-gcc-fast`,
|
||||
`afl-gcc` or`AFL_LLVM_INSTRUMENT=CLASSIC/NGRAM/CTX afl-clang-fast`
|
||||
instrumentation.
|
||||
Note that this is not an issue if you use the inferiour `afl-gcc-fast`, or
|
||||
`AFL_LLVM_INSTRUMENT=CLASSIC/NGRAM/CTX afl-clang-fast` instrumentation.
|
||||
|
||||
### Fuzzing a binary-only target
|
||||
|
||||
|
@ -73,7 +73,7 @@ def init(seed):
|
||||
def fuzz_count(buf):
|
||||
return cnt
|
||||
|
||||
def splice_optout()
|
||||
def splice_optout():
|
||||
pass
|
||||
|
||||
def fuzz(buf, add_buf, max_size):
|
||||
@ -198,7 +198,12 @@ def deinit(): # optional for Python
|
||||
This method can be used if you want to send data to the target yourself,
|
||||
e.g. via IPC. This replaces some usage of utils/afl_proxy but requires
|
||||
that you start the target with afl-fuzz.
|
||||
Example: [custom_mutators/examples/custom_send.c](custom_mutators/examples/custom_send.c)
|
||||
|
||||
Setting `AFL_CUSTOM_MUTATOR_LATE_SEND` will call the afl_custom_fuzz_send()
|
||||
function after the target has been restarted. (This is needed for e.g. TCP
|
||||
services.)
|
||||
|
||||
Example: [custom_mutators/examples/custom_send.c](../custom_mutators/examples/custom_send.c)
|
||||
|
||||
- `queue_new_entry` (optional):
|
||||
|
||||
@ -266,6 +271,11 @@ trimmed input. Here's a quick API description:
|
||||
Omitting any of three trimming methods will cause the trimming to be disabled
|
||||
and trigger a fallback to the built-in default trimming routine.
|
||||
|
||||
**IMPORTANT** If you have a custom post process mutator that needs to be run
|
||||
after trimming, you must call it yourself at the end of your successful
|
||||
trimming!
|
||||
|
||||
|
||||
### Environment Variables
|
||||
|
||||
Optionally, the following environment variables are supported:
|
||||
@ -377,4 +387,4 @@ See [example.c](../custom_mutators/examples/example.c) and
|
||||
- [bruce30262/libprotobuf-mutator_fuzzing_learning](https://github.com/bruce30262/libprotobuf-mutator_fuzzing_learning/tree/master/4_libprotobuf_aflpp_custom_mutator)
|
||||
- [thebabush/afl-libprotobuf-mutator](https://github.com/thebabush/afl-libprotobuf-mutator)
|
||||
- [XML Fuzzing@NullCon 2017](https://www.agarri.fr/docs/XML_Fuzzing-NullCon2017-PUBLIC.pdf)
|
||||
- [A bug detected by AFL + XML-aware mutators](https://bugs.chromium.org/p/chromium/issues/detail?id=930663)
|
||||
- [A bug detected by AFL + XML-aware mutators](https://bugs.chromium.org/p/chromium/issues/detail?id=930663)
|
||||
|
@ -24,7 +24,6 @@ To select the different instrumentation modes, use one of the following options:
|
||||
- Use the `AFL_CC_COMPILER` environment variable with `MODE`. To select
|
||||
`MODE`, use one of the following values:
|
||||
|
||||
- `GCC` (afl-gcc/afl-g++)
|
||||
- `GCC_PLUGIN` (afl-g*-fast)
|
||||
- `LLVM` (afl-clang-fast*)
|
||||
- `LTO` (afl-clang-lto*).
|
||||
@ -45,14 +44,10 @@ fairly broad use of environment variables instead:
|
||||
make
|
||||
```
|
||||
|
||||
- Setting `AFL_AS`, `AFL_CC`, and `AFL_CXX` lets you use alternate downstream
|
||||
compilation tools, rather than the default 'as', 'clang', or 'gcc' binaries
|
||||
- Setting `AFL_CC`, and `AFL_CXX` lets you use alternate downstream
|
||||
compilation tools, rather than the default 'clang', or 'gcc' binaries
|
||||
in your `$PATH`.
|
||||
|
||||
- If you are a weird person that wants to compile and instrument asm text
|
||||
files, then use the `AFL_AS_FORCE_INSTRUMENT` variable:
|
||||
`AFL_AS_FORCE_INSTRUMENT=1 afl-gcc foo.s -o foo`
|
||||
|
||||
- Most AFL tools do not print any output if stdout/stderr are redirected. If
|
||||
you want to get the output into a file, then set the `AFL_DEBUG` environment
|
||||
variable. This is sadly necessary for various build processes which fail
|
||||
@ -64,6 +59,9 @@ fairly broad use of environment variables instead:
|
||||
optimizations, set `AFL_DONT_OPTIMIZE`. However, if `-O...` and/or
|
||||
`-fno-unroll-loops` are set, these are not overridden.
|
||||
|
||||
- The optimization level can also be set with `AFL_OPT_LEVEL`, e.g.
|
||||
`AFL_OPT_LEVEL=z` for `-Oz`, default is `3`
|
||||
|
||||
- Setting `AFL_HARDEN` automatically adds code hardening options when invoking
|
||||
the downstream compiler. This currently includes `-D_FORTIFY_SOURCE=2` and
|
||||
`-fstack-protector-all`. The setting is useful for catching non-crashing
|
||||
@ -80,17 +78,13 @@ fairly broad use of environment variables instead:
|
||||
Setting `AFL_INST_RATIO` to 0 is a valid choice. This will instrument only
|
||||
the transitions between function entry points, but not individual branches.
|
||||
|
||||
Note that this is an outdated variable. A few instances (e.g., afl-gcc)
|
||||
still support these, but state-of-the-art (e.g., LLVM LTO and LLVM PCGUARD)
|
||||
do not need this.
|
||||
Note that this is an outdated variable. Only LLVM CLASSIC pass can use this.
|
||||
|
||||
- `AFL_NO_BUILTIN` causes the compiler to generate code suitable for use with
|
||||
libtokencap.so (but perhaps running a bit slower than without the flag).
|
||||
|
||||
- `AFL_PATH` can be used to point afl-gcc to an alternate location of afl-as.
|
||||
One possible use of this is utils/clang_asm_normalize/, which lets you
|
||||
instrument hand-written assembly when compiling clang code by plugging a
|
||||
normalizer into the chain. (There is no equivalent feature for GCC.)
|
||||
- `AFL_PATH` can be used to point a directory that contains LLVM/GCC plugins
|
||||
for AFL++, AFL++'s runtime objects and QEMU/Frida support files.
|
||||
|
||||
- Setting `AFL_QUIET` will prevent afl-as and afl-cc banners from being
|
||||
displayed during compilation, in case you find them distracting.
|
||||
@ -101,6 +95,7 @@ fairly broad use of environment variables instead:
|
||||
detection)
|
||||
- `AFL_USE_CFISAN=1` - activates the Control Flow Integrity sanitizer (e.g.
|
||||
type confusion vulnerabilities)
|
||||
- `AFL_CFISAN_VERBOSE=1` - outputs detailed information when control flow integrity violations occur, instead of simply terminating with "Illegal Instruction"
|
||||
- `AFL_USE_LSAN` - activates the leak sanitizer. To perform a leak check
|
||||
within your program at a certain point (such as at the end of an
|
||||
`__AFL_LOOP()`), you can run the macro `__AFL_LEAK_CHECK();` which will
|
||||
@ -111,6 +106,9 @@ fairly broad use of environment variables instead:
|
||||
- `AFL_USE_TSAN=1` - activates the thread sanitizer to find thread race
|
||||
conditions
|
||||
- `AFL_USE_UBSAN=1` - activates the undefined behavior sanitizer
|
||||
- `AFL_UBSAN_VERBOSE=1` - outputs detailed diagnostic information when undefined behavior is detected, instead of simply terminating with "Illegal Instruction"
|
||||
|
||||
- Note: both `AFL_CFISAN_VERBOSE=1` and `AFL_UBSAN_VERBOSE=1` are disabled by default as verbose output can significantly slow down fuzzing performance. Use these options only during debugging or when additional crash diagnostics are required
|
||||
|
||||
- `TMPDIR` is used by afl-as for temporary files; if this variable is not set,
|
||||
the tool defaults to /tmp.
|
||||
@ -196,6 +194,19 @@ in the specified file.
|
||||
For more information, see
|
||||
[instrumentation/README.instrument_list.md](../instrumentation/README.instrument_list.md).
|
||||
|
||||
#### INJECTIONS
|
||||
|
||||
This feature is able to find simple injection vulnerabilities in insecure
|
||||
calls to mysql/mariadb/nosql/postgresql/ldap and XSS in libxml2.
|
||||
|
||||
- Setting `AFL_LLVM_INJECTIONS_ALL` will enable all injection hooking
|
||||
|
||||
- Setting `AFL_LLVM_INJECTIONS_SQL` will enable SQL injection hooking
|
||||
|
||||
- Setting `AFL_LLVM_INJECTIONS_LDAP` will enable LDAP injection hooking
|
||||
|
||||
- Setting `AFL_LLVM_INJECTIONS_XSS` will enable XSS injection hooking
|
||||
|
||||
#### LAF-INTEL
|
||||
|
||||
This great feature will split compares into series of single byte comparisons to
|
||||
@ -235,6 +246,9 @@ use (which only ever the author of this LTO implementation will use). These are
|
||||
used if several separated instrumentations are performed which are then later
|
||||
combined.
|
||||
|
||||
- `AFL_LLVM_LTO_CALLER` activates collision free CALLER instrumentation
|
||||
- `AFL_LLVM_LTO_CALLER` sets the maximum mumber of single block functions
|
||||
to dig deeper into a real function. Default 0.
|
||||
- `AFL_LLVM_DOCUMENT_IDS=file` will document to a file which edge ID was given
|
||||
to which function. This helps to identify functions with variable bytes or
|
||||
which functions were touched by an input.
|
||||
@ -307,6 +321,11 @@ mode.
|
||||
[instrumentation/README.instrument_list.md](../instrumentation/README.instrument_list.md)
|
||||
for more information.
|
||||
|
||||
Setting `AFL_GCC_DISABLE_VERSION_CHECK=1` will disable the GCC plugin
|
||||
version check if the target GCC plugin differs from the system-installed
|
||||
version, resolving issues caused by version mismatches between GCC and
|
||||
the plugin.
|
||||
|
||||
Setting `AFL_GCC_OUT_OF_LINE=1` will instruct afl-gcc-fast to instrument the
|
||||
code with calls to an injected subroutine instead of the much more efficient
|
||||
inline instrumentation.
|
||||
@ -315,7 +334,26 @@ mode.
|
||||
the target performs only a few loops, then this will give a small
|
||||
performance boost.
|
||||
|
||||
## 4) Settings for afl-fuzz
|
||||
## 4) Runtime settings
|
||||
|
||||
The following environment variables are for a compiled AFL++ target.
|
||||
|
||||
- Setting `AFL_DUMP_MAP_SIZE` when executing the target directly will
|
||||
dump the map size of the target and exit.
|
||||
|
||||
- Setting `AFL_OLD_FORKSERVER` will use the old AFL vanilla forkserver.
|
||||
This makes only sense when you
|
||||
a) compile in a classic colliding coverage mode (e.g.
|
||||
AFL_LLVM_INSTRUMENT=CLASSIC) or if the map size of the target is
|
||||
below MAP_SIZE (65536 by default), AND
|
||||
b) you want to use this compiled AFL++ target with a different tool
|
||||
that expects vanilla AFL behaviour, e.g. symcc, symqemu, nautilus, etc.
|
||||
You would use this option together with the target fuzzing application.
|
||||
|
||||
- Setting `AFL_DISABLE_LLVM_INSTRUMENTATION` will disable collecting
|
||||
instrumentation. (More of an internal option.)
|
||||
|
||||
## 5) Settings for afl-fuzz
|
||||
|
||||
The main fuzzer binary accepts several options that disable a couple of sanity
|
||||
checks or alter some of the more exotic semantics of the tool:
|
||||
@ -352,6 +390,10 @@ checks or alter some of the more exotic semantics of the tool:
|
||||
XML or other highly flexible structured input. For details, see
|
||||
[custom_mutators.md](custom_mutators.md).
|
||||
|
||||
- Setting `AFL_CUSTOM_MUTATOR_LATE_SEND` will call the afl_custom_fuzz_send()
|
||||
function after the target has been restarted. (This is needed for e.g. TCP
|
||||
services.)
|
||||
|
||||
- Setting `AFL_CYCLE_SCHEDULES` will switch to a different schedule every time
|
||||
a cycle is finished.
|
||||
|
||||
@ -365,6 +407,9 @@ checks or alter some of the more exotic semantics of the tool:
|
||||
- Setting `AFL_DISABLE_TRIM` tells afl-fuzz not to trim test cases. This is
|
||||
usually a bad idea!
|
||||
|
||||
- Setting `AFL_DISABLE_REDUNDANT` disables any queue items that are redundant.
|
||||
This can be useful with huge queues.
|
||||
|
||||
- Setting `AFL_KEEP_TIMEOUTS` will keep longer running inputs if they reach
|
||||
new coverage
|
||||
|
||||
@ -382,9 +427,8 @@ checks or alter some of the more exotic semantics of the tool:
|
||||
types of automated jobs.
|
||||
|
||||
- `AFL_EXIT_WHEN_DONE` causes afl-fuzz to terminate when all existing paths
|
||||
have been fuzzed and there were no new finds for a while. This would be
|
||||
normally indicated by the cycle counter in the UI turning green. May be
|
||||
convenient for some types of automated jobs.
|
||||
have been fuzzed and there were no new finds for a while. This is basically
|
||||
when the fuzzing state says `state: finished`
|
||||
|
||||
- Setting `AFL_EXPAND_HAVOC_NOW` will start in the extended havoc mode that
|
||||
includes costly mutations. afl-fuzz automatically enables this mode when
|
||||
@ -495,6 +539,8 @@ checks or alter some of the more exotic semantics of the tool:
|
||||
- `AFL_NO_SNAPSHOT` will advise afl-fuzz not to use the snapshot feature if
|
||||
the snapshot lkm is loaded.
|
||||
|
||||
- `AFL_NO_FASTRESUME` will not try to read or write a fast resume file.
|
||||
|
||||
- Setting `AFL_NO_UI` inhibits the UI altogether and just periodically prints
|
||||
some basic stats. This behavior is also automatically triggered when the
|
||||
output from afl-fuzz is redirected to a file or to a pipe.
|
||||
@ -531,6 +577,9 @@ checks or alter some of the more exotic semantics of the tool:
|
||||
use a custom afl-qemu-trace or if you need to modify the afl-qemu-trace
|
||||
arguments.
|
||||
|
||||
- `AFL_SHA1_FILENAMES` causes AFL++ to generate files named by the SHA1 hash
|
||||
of their contents, rather than use the standard `id:000000,...` names.
|
||||
|
||||
- `AFL_SHUFFLE_QUEUE` randomly reorders the input queue on startup. Requested
|
||||
by some users for unorthodox parallelized fuzzing setups, but not advisable
|
||||
otherwise.
|
||||
@ -563,9 +612,12 @@ checks or alter some of the more exotic semantics of the tool:
|
||||
see [rpc_statsd.md](rpc_statsd.md).
|
||||
|
||||
- `AFL_SYNC_TIME` allows you to specify a different minimal time (in minutes)
|
||||
between fuzzing instances synchronization. Default sync time is 30 minutes,
|
||||
between fuzzing instances synchronization. Default sync time is 20 minutes,
|
||||
note that time is halved for -M main nodes.
|
||||
|
||||
- `AFL_NO_SYNC` disables any syncing whatsoever and takes priority on all
|
||||
other syncing parameters.
|
||||
|
||||
- Setting `AFL_TARGET_ENV` causes AFL++ to set extra environment variables for
|
||||
the target binary. Example: `AFL_TARGET_ENV="VAR1=1 VAR2='a b c'" afl-fuzz
|
||||
... `. This exists mostly for things like `LD_LIBRARY_PATH` but it would
|
||||
@ -611,7 +663,7 @@ checks or alter some of the more exotic semantics of the tool:
|
||||
Note that will not be exact and with slow targets it can take seconds
|
||||
until there is a slice for the time test.
|
||||
|
||||
## 5) Settings for afl-qemu-trace
|
||||
## 6) Settings for afl-qemu-trace
|
||||
|
||||
The QEMU wrapper used to instrument binary-only code supports several settings:
|
||||
|
||||
@ -683,7 +735,7 @@ The QEMU wrapper used to instrument binary-only code supports several settings:
|
||||
crash is found. Setting `AFL_NO_CRASH_README` will prevent this. Useful when
|
||||
counting crashes based on a file count in that directory.
|
||||
|
||||
## 7) Settings for afl-frida-trace
|
||||
## 8) Settings for afl-frida-trace
|
||||
|
||||
The FRIDA wrapper used to instrument binary-only code supports many of the same
|
||||
options as `afl-qemu-trace`, but also has a number of additional advanced
|
||||
@ -773,7 +825,7 @@ support.
|
||||
dump you must set a sufficient timeout (using `-t`) to avoid `afl-fuzz`
|
||||
killing the process whilst it is being dumped.
|
||||
|
||||
## 8) Settings for afl-cmin
|
||||
## 9) Settings for afl-cmin
|
||||
|
||||
The corpus minimization script offers very little customization:
|
||||
|
||||
@ -791,7 +843,7 @@ The corpus minimization script offers very little customization:
|
||||
- `AFL_PRINT_FILENAMES` prints each filename to stdout, as it gets processed.
|
||||
This can help when embedding `afl-cmin` or `afl-showmap` in other scripts.
|
||||
|
||||
## 9) Settings for afl-tmin
|
||||
## 10) Settings for afl-tmin
|
||||
|
||||
Virtually nothing to play with. Well, in QEMU mode (`-Q`), `AFL_PATH` will be
|
||||
searched for afl-qemu-trace. In addition to this, `TMPDIR` may be used if a
|
||||
@ -802,12 +854,12 @@ to match when minimizing crashes. This will make minimization less useful, but
|
||||
may prevent the tool from "jumping" from one crashing condition to another in
|
||||
very buggy software. You probably want to combine it with the `-e` flag.
|
||||
|
||||
## 10) Settings for afl-analyze
|
||||
## 11) Settings for afl-analyze
|
||||
|
||||
You can set `AFL_ANALYZE_HEX` to get file offsets printed as hexadecimal instead
|
||||
of decimal.
|
||||
|
||||
## 11) Settings for libdislocator
|
||||
## 12) Settings for libdislocator
|
||||
|
||||
The library honors these environment variables:
|
||||
|
||||
@ -829,12 +881,12 @@ The library honors these environment variables:
|
||||
- `AFL_LD_VERBOSE` causes the library to output some diagnostic messages that
|
||||
may be useful for pinpointing the cause of any observed issues.
|
||||
|
||||
## 11) Settings for libtokencap
|
||||
## 13) Settings for libtokencap
|
||||
|
||||
This library accepts `AFL_TOKEN_FILE` to indicate the location to which the
|
||||
discovered tokens should be written.
|
||||
|
||||
## 12) Third-party variables set by afl-fuzz & other tools
|
||||
## 14) Third-party variables set by afl-fuzz & other tools
|
||||
|
||||
Several variables are not directly interpreted by afl-fuzz, but are set to
|
||||
optimal values if not already present in the environment:
|
||||
|
@ -6,20 +6,22 @@ QEMU 5.1 with laf-intel and Redqueen, FRIDA mode, unicorn mode, gcc plugin, full
|
||||
|
||||
## Features and instrumentation
|
||||
|
||||
| Feature/Instrumentation | afl-gcc | llvm | gcc_plugin | FRIDA mode(9) | QEMU mode(10) | unicorn_mode(10) | nyx_mode(12) | coresight_mode(11) |
|
||||
| ------------------------------|:--------:|:---------:|:----------:|:--------------:|:----------------:|:----------------:|:------------:|:------------------:|
|
||||
| Threadsafe counters [A] | | x(3) | | | | | x | |
|
||||
| NeverZero [B] | x86[_64] | x(1) | x | x | x | x | | |
|
||||
| Persistent Mode [C] | | x | x | x86[_64]/arm64 | x86[_64]/arm[64] | x | | |
|
||||
| LAF-Intel / CompCov [D] | | x | | | x86[_64]/arm[64] | x86[_64]/arm[64] | x86[_64] | |
|
||||
| CmpLog [E] | | x | x | x86[_64]/arm64 | x86[_64]/arm[64] | | | |
|
||||
| Selective Instrumentation [F] | | x | x | x | x | | | |
|
||||
| Non-Colliding Coverage [G] | | x(4) | | | (x)(5) | | | |
|
||||
| Ngram prev_loc Coverage [H] | | x(6) | | | | | | |
|
||||
| Context Coverage [I] | | x(6) | | | | | | |
|
||||
| Auto Dictionary [J] | | x(7) | | | | | | |
|
||||
| Snapshot Support [K] | | (x)(8) | (x)(8) | | (x)(5) | | x | |
|
||||
| Shared Memory Test cases [L] | | x | x | x86[_64]/arm64 | x | x | x | |
|
||||
Note that afl-gcc and afl-clang have been removed because their instrumentation is absolutely outdated.
|
||||
|
||||
| Feature/Instrumentation | llvm | gcc_plugin | FRIDA mode(9) | QEMU mode(10) | unicorn_mode(10) | nyx_mode(12) | coresight_mode(11) |
|
||||
| ------------------------------|:---------:|:----------:|:--------------:|:----------------:|:----------------:|:------------:|:------------------:|
|
||||
| Threadsafe counters [A] | x(3) | | | | | x | |
|
||||
| NeverZero [B] | x(1) | x | x | x | x | | |
|
||||
| Persistent Mode [C] | x | x | x86[_64]/arm64 | x86[_64]/arm[64] | x | | |
|
||||
| LAF-Intel / CompCov [D] | x | | | x86[_64]/arm[64] | x86[_64]/arm[64] | x86[_64] | |
|
||||
| CmpLog [E] | x | x | x86[_64]/arm64 | x86[_64]/arm[64] | | | |
|
||||
| Selective Instrumentation [F] | x | x | x | x | | | |
|
||||
| Non-Colliding Coverage [G] | x(4) | | | (x)(5) | | | |
|
||||
| Ngram prev_loc Coverage [H] | x(6) | | | | | | |
|
||||
| Context Coverage [I] | x(6) | | | | | | |
|
||||
| Auto Dictionary [J] | x(7) | | | | | | |
|
||||
| Snapshot Support [K] | (x)(8) | (x)(8) | | (x)(5) | | x | |
|
||||
| Shared Memory Test cases [L] | x | x | x86[_64]/arm64 | x | x | x | |
|
||||
|
||||
## More information about features
|
||||
|
||||
@ -94,7 +96,7 @@ L. Faster fuzzing and less kernel syscall overhead by in-memory fuzz testcase
|
||||
|
||||
Among others, the following features and patches have been integrated:
|
||||
|
||||
* NeverZero patch for afl-gcc, instrumentation, QEMU mode and unicorn_mode which
|
||||
* NeverZero for llvm/gcc instrumentation, QEMU mode and unicorn_mode which
|
||||
prevents a wrapping map value to zero, increases coverage
|
||||
* Persistent mode, deferred forkserver and in-memory fuzzing for QEMU mode
|
||||
* Unicorn mode which allows fuzzing of binaries from completely different
|
||||
|
@ -46,10 +46,9 @@ The following setup to use QEMU mode is recommended:
|
||||
`AFL_COMPCOV_LEVEL=2`), alternatively you can use FRIDA mode, just switch `-Q`
|
||||
with `-O` and remove the LAF instance
|
||||
|
||||
Then run as many instances as you have cores left with either -Q mode or - even
|
||||
better - use a binary rewriter like Dyninst, RetroWrite, ZAFL, etc.
|
||||
The binary rewriters all have their own advantages and caveats.
|
||||
ZAFL is the best but cannot be used in a business/commercial context.
|
||||
Then run as many instances as you have cores left with either `-Q` mode or use
|
||||
a static binary rewriter like Dyninst, RetroWrite, ZAFL, etc.
|
||||
The binary rewriters all have their own advantages and caveats, but ZAFL is a good choice.
|
||||
|
||||
If a binary rewriter works for your target then you can use afl-fuzz normally
|
||||
and it will have twice the speed compared to QEMU mode (but slower than QEMU
|
||||
@ -94,8 +93,7 @@ For more information, see
|
||||
|
||||
In FRIDA mode, you can fuzz binary-only targets as easily as with QEMU mode.
|
||||
FRIDA mode is most of the times slightly faster than QEMU mode. It is also
|
||||
newer, lacks COMPCOV, and has the advantage that it works on MacOS (both intel
|
||||
and M1).
|
||||
newer, and has the advantage that it works on MacOS (both intel and M1).
|
||||
|
||||
To build FRIDA mode:
|
||||
|
||||
@ -113,10 +111,6 @@ The mode is approximately 2-5x slower than compile-time instrumentation, and is
|
||||
less conducive to parallelization. But for binary-only fuzzing, it gives a huge
|
||||
speed improvement if it is possible to use.
|
||||
|
||||
If you want to fuzz a binary-only library, then you can fuzz it with frida-gum
|
||||
via frida_mode/. You will have to write a harness to call the target function in
|
||||
the library, use afl-frida.c as a template.
|
||||
|
||||
You can also perform remote fuzzing with frida, e.g., if you want to fuzz on
|
||||
iPhone or Android devices, for this you can use
|
||||
[https://github.com/ttdennis/fpicker/](https://github.com/ttdennis/fpicker/) as
|
||||
@ -205,6 +199,7 @@ have an x86_64 or arm64 binary that does not contain C++ exceptions and - if
|
||||
x86_64 - still has it's symbols and compiled with position independent code
|
||||
(PIC/PIE), then the RetroWrite solution might be for you.
|
||||
It decompiles to ASM files which can then be instrumented with afl-gcc.
|
||||
Note that afl-gcc is only present until AFL++ v4.21c and was subsequently removed as it is obsolete.
|
||||
|
||||
Binaries that are statically instrumented for fuzzing using RetroWrite are close
|
||||
in performance to compiler-instrumented binaries and outperform the QEMU-based
|
||||
@ -302,7 +297,6 @@ some are very hard to set up...
|
||||
* S2E: [https://github.com/S2E](https://github.com/S2E)
|
||||
* TinyInst:
|
||||
[https://github.com/googleprojectzero/TinyInst](https://github.com/googleprojectzero/TinyInst)
|
||||
(Mac/Windows only)
|
||||
* ... please send me any missing that are good
|
||||
|
||||
## Closing words
|
||||
|
@ -61,6 +61,8 @@ evaluation flow will help you to select the best possible.
|
||||
It is highly recommended to have the newest llvm version possible installed,
|
||||
anything below 9 is not recommended.
|
||||
|
||||
IMPORTANT NOTICE: afl-gcc/afl-clang have been removed from AFL++ as they are obsolete.
|
||||
|
||||
```
|
||||
+--------------------------------+
|
||||
| clang/clang++ 11+ is available | --> use LTO mode (afl-clang-lto/afl-clang-lto++)
|
||||
@ -84,7 +86,7 @@ anything below 9 is not recommended.
|
||||
| if not, or if you do not have a gcc with plugin support
|
||||
|
|
||||
v
|
||||
use GCC mode (afl-gcc/afl-g++) (or afl-clang/afl-clang++ for clang)
|
||||
GAME OVER! Install gcc-VERSION-plugin-dev or llvm-VERSION-dev
|
||||
```
|
||||
|
||||
Clickable README links for the chosen compiler:
|
||||
@ -92,14 +94,12 @@ Clickable README links for the chosen compiler:
|
||||
* [LTO mode - afl-clang-lto](../instrumentation/README.lto.md)
|
||||
* [LLVM mode - afl-clang-fast](../instrumentation/README.llvm.md)
|
||||
* [GCC_PLUGIN mode - afl-gcc-fast](../instrumentation/README.gcc_plugin.md)
|
||||
* GCC/CLANG modes (afl-gcc/afl-clang) have no README as they have no own
|
||||
features
|
||||
|
||||
You can select the mode for the afl-cc compiler by one of the following methods:
|
||||
|
||||
* Using a symlink to afl-cc: afl-gcc, afl-g++, afl-clang, afl-clang++,
|
||||
* Using a symlink to afl-cc:
|
||||
afl-clang-fast, afl-clang-fast++, afl-clang-lto, afl-clang-lto++,
|
||||
afl-gcc-fast, afl-g++-fast (recommended!).
|
||||
afl-gcc-fast, afl-g++-fast.
|
||||
* Using the environment variable `AFL_CC_COMPILER` with `MODE`.
|
||||
* Passing --afl-`MODE` command line options to the compiler via
|
||||
`CFLAGS`/`CXXFLAGS`/`CPPFLAGS`.
|
||||
@ -108,8 +108,7 @@ You can select the mode for the afl-cc compiler by one of the following methods:
|
||||
|
||||
* LTO (afl-clang-lto*)
|
||||
* LLVM (afl-clang-fast*)
|
||||
* GCC_PLUGIN (afl-g*-fast) or GCC (afl-gcc/afl-g++)
|
||||
* CLANG(afl-clang/afl-clang++)
|
||||
* GCC_PLUGIN (afl-g*-fast)
|
||||
|
||||
Because no AFL++ specific command-line options are accepted (beside the
|
||||
--afl-MODE command), the compile-time tools make fairly broad use of environment
|
||||
@ -201,6 +200,9 @@ type. This is enough because e.g. a use-after-free bug will be picked up by ASAN
|
||||
(address sanitizer) anyway after syncing test cases from other fuzzing
|
||||
instances, so running more than one address sanitized target would be a waste.
|
||||
|
||||
*IF* you are running a saturated corpus, then you can run up to half of the
|
||||
instances with sanitizers.
|
||||
|
||||
The following sanitizers have built-in support in AFL++:
|
||||
|
||||
* ASAN = Address SANitizer, finds memory corruption vulnerabilities like
|
||||
@ -632,7 +634,7 @@ crash or timeout during startup.
|
||||
|
||||
Also, it is recommended to set `export AFL_IMPORT_FIRST=1` to load test cases
|
||||
from other fuzzers in the campaign first. But note that can slow down the start
|
||||
of the first fuzz by quite a lot of you have many fuzzers and/or many seeds.
|
||||
of the first fuzz by quite a lot if you have many fuzzers and/or many seeds.
|
||||
|
||||
If you have a large corpus, a corpus from a previous run or are fuzzing in a CI,
|
||||
then also set `export AFL_CMPLOG_ONLY_NEW=1` and `export AFL_FAST_CAL=1`.
|
||||
@ -958,7 +960,7 @@ too long for your overall available fuzz run time.
|
||||
campaign but not good for short CI runs.
|
||||
|
||||
How this can look like can, e.g., be seen at AFL++'s setup in Google's
|
||||
[oss-fuzz](https://github.com/google/oss-fuzz/blob/master/infra/base-images/base-builder/compile_afl)
|
||||
[previous oss-fuzz version](https://github.com/google/oss-fuzz/blob/3e2c5312417d1a6f9564472f3df1fd27759b289d/infra/base-images/base-builder/compile_afl)
|
||||
and
|
||||
[clusterfuzz](https://github.com/google/clusterfuzz/blob/master/src/clusterfuzz/_internal/bot/fuzzers/afl/launcher.py).
|
||||
|
||||
|
File diff suppressed because one or more lines are too long
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
@ -5,6 +5,10 @@
|
||||
* [afl-rs](https://github.com/rust-fuzz/afl.rs) - AFL++ for RUST
|
||||
* [WASM](https://github.com/fgsect/WAFL) - AFL++ for WASM
|
||||
|
||||
## Starting multiple AFL++ instances in parallel with recommended settings:
|
||||
* [https://github.com/0xricksanchez/AFL_Runner](https://github.com/0xricksanchez/AFL_Runner)
|
||||
* [https://github.com/MegaManSec/AFLplusplus-Parallel-Gen](https://github.com/MegaManSec/AFLplusplus-Parallel-Gen)
|
||||
|
||||
## Speeding up fuzzing
|
||||
|
||||
* [libfiowrapper](https://github.com/marekzmyslowski/libfiowrapper) - if the
|
||||
|
@ -21,6 +21,9 @@ training, then we can highly recommend the following:
|
||||
|
||||
* [https://github.com/antonio-morales/Fuzzing101](https://github.com/antonio-morales/Fuzzing101)
|
||||
|
||||
A good workflow overview (like our [fuzzing_in_depth.md](fuzzing_in_depth.md)):
|
||||
* [https://appsec.guide/docs/fuzzing/c-cpp/aflpp/](https://appsec.guide/docs/fuzzing/c-cpp/aflpp/)
|
||||
|
||||
Here is a good workflow description (and tutorial) for qemu_mode:
|
||||
|
||||
* [https://airbus-seclab.github.io/AFLplusplus-blogpost/](https://airbus-seclab.github.io/AFLplusplus-blogpost/)
|
||||
|
@ -214,6 +214,9 @@ all: $(FRIDA_TRACE) $(FRIDA_TRACE_LIB) $(AFLPP_FRIDA_DRIVER_HOOK_OBJ) $(AFLPP_QE
|
||||
arm:
|
||||
CFLAGS="-marm" LDFLAGS="-marm" ARCH="armhf" TARGET_CC=arm-linux-gnueabihf-gcc TARGET_CXX=arm-linux-gnueabihf-g++ make all
|
||||
|
||||
arm64:
|
||||
ARCH="arm64" TARGET_CC=aarch64-linux-gnu-gcc TARGET_CXX=aarch64-linux-gnu-g++ make all
|
||||
|
||||
$(BUILD_DIR):
|
||||
mkdir -p $(BUILD_DIR)
|
||||
|
||||
|
@ -390,7 +390,7 @@ Consider the [following](test/js/test2.c) test code...
|
||||
--------------------------------------------------------
|
||||
Originally written by Michal Zalewski
|
||||
Copyright 2014 Google Inc. All rights reserved.
|
||||
Copyright 2019-2023 AFLplusplus Project. All rights reserved.
|
||||
Copyright 2019-2024 AFLplusplus Project. All rights reserved.
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at:
|
||||
|
@ -6,34 +6,39 @@
|
||||
|
||||
#define UNUSED_PARAMETER(x) (void)(x)
|
||||
|
||||
int phdr_callback(struct dl_phdr_info *info, size_t size, void *data)
|
||||
{
|
||||
UNUSED_PARAMETER (size);
|
||||
int phdr_callback(struct dl_phdr_info *info, size_t size, void *data) {
|
||||
|
||||
ElfW(Addr) * base = data;
|
||||
UNUSED_PARAMETER(size);
|
||||
|
||||
ElfW(Addr) *base = data;
|
||||
|
||||
if (info->dlpi_name[0] == 0) { *base = info->dlpi_addr; }
|
||||
return 0;
|
||||
|
||||
if (info->dlpi_name[0] == 0) { *base = info->dlpi_addr; }
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main (int argc, char** argv, char** envp) {
|
||||
UNUSED_PARAMETER (argc);
|
||||
int main(int argc, char **argv, char **envp) {
|
||||
|
||||
ElfW(Addr) base = 0;
|
||||
UNUSED_PARAMETER(argc);
|
||||
|
||||
int persona = personality(ADDR_NO_RANDOMIZE);
|
||||
if (persona == -1) {
|
||||
ElfW(Addr) base = 0;
|
||||
|
||||
printf("Failed to set ADDR_NO_RANDOMIZE: %d", errno);
|
||||
return 1;
|
||||
}
|
||||
int persona = personality(ADDR_NO_RANDOMIZE);
|
||||
if (persona == -1) {
|
||||
|
||||
if ((persona & ADDR_NO_RANDOMIZE) == 0) { execvpe(argv[0], argv, envp); }
|
||||
printf("Failed to set ADDR_NO_RANDOMIZE: %d", errno);
|
||||
return 1;
|
||||
|
||||
dl_iterate_phdr(phdr_callback, &base);
|
||||
}
|
||||
|
||||
printf("%p\n", (void *)base);
|
||||
if (base == 0) { return 1; }
|
||||
if ((persona & ADDR_NO_RANDOMIZE) == 0) { execvpe(argv[0], argv, envp); }
|
||||
|
||||
dl_iterate_phdr(phdr_callback, &base);
|
||||
|
||||
printf("%p\n", (void *)base);
|
||||
if (base == 0) { return 1; }
|
||||
|
||||
return 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -45,6 +45,7 @@
|
||||
js_api_set_stdout;
|
||||
js_api_set_traceable;
|
||||
js_api_set_verbose;
|
||||
js_api_ijon_set;
|
||||
|
||||
local:
|
||||
*;
|
||||
|
@ -31,8 +31,8 @@ __attribute__((visibility("default"))) void afl_persistent_hook(
|
||||
// do a length check matching the target!
|
||||
|
||||
void **esp = (void **)regs->esp;
|
||||
void *arg1 = esp[0];
|
||||
void **arg2 = &esp[1];
|
||||
void *arg1 = esp[1];
|
||||
void **arg2 = &esp[2];
|
||||
memcpy(arg1, input_buf, input_buf_len);
|
||||
*arg2 = (void *)input_buf_len;
|
||||
|
||||
|
@ -36,7 +36,7 @@ struct x86_64_regs {
|
||||
void afl_persistent_hook(struct x86_64_regs *regs, uint64_t guest_base,
|
||||
uint8_t *input_buf, uint32_t input_buf_len) {
|
||||
|
||||
(void)guest_base; /* unused */
|
||||
(void)guest_base; /* unused */
|
||||
memcpy((void *)regs->rdi, input_buf, input_buf_len);
|
||||
regs->rsi = input_buf_len;
|
||||
|
||||
@ -76,14 +76,15 @@ struct x86_regs {
|
||||
void afl_persistent_hook(struct x86_regs *regs, uint64_t guest_base,
|
||||
uint8_t *input_buf, uint32_t input_buf_len) {
|
||||
|
||||
(void)guest_base; /* unused */
|
||||
(void)guest_base; /* unused */
|
||||
void **esp = (void **)regs->esp;
|
||||
void * arg1 = esp[1];
|
||||
void *arg1 = esp[1];
|
||||
void **arg2 = &esp[2];
|
||||
memcpy(arg1, input_buf, input_buf_len);
|
||||
*arg2 = (void *)input_buf_len;
|
||||
|
||||
}
|
||||
|
||||
#elif defined(__aarch64__)
|
||||
|
||||
struct arm64_regs {
|
||||
@ -177,9 +178,10 @@ struct arm64_regs {
|
||||
void afl_persistent_hook(struct arm64_regs *regs, uint64_t guest_base,
|
||||
uint8_t *input_buf, uint32_t input_buf_len) {
|
||||
|
||||
(void)guest_base; /* unused */
|
||||
(void)guest_base; /* unused */
|
||||
memcpy((void *)regs->x0, input_buf, input_buf_len);
|
||||
regs->x1 = input_buf_len;
|
||||
|
||||
}
|
||||
|
||||
#else
|
||||
@ -193,3 +195,4 @@ int afl_persistent_hook_init(void) {
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
|
@ -22,6 +22,7 @@ extern guint64 instrument_fixed_seed;
|
||||
|
||||
extern uint8_t *__afl_area_ptr;
|
||||
extern uint32_t __afl_map_size;
|
||||
extern void __afl_coverage_interesting(uint8_t, uint32_t);
|
||||
|
||||
extern __thread guint64 *instrument_previous_pc_addr;
|
||||
|
||||
@ -72,5 +73,7 @@ void instrument_cache(const cs_insn *instr, GumStalkerOutput *output);
|
||||
void instrument_write_regs(GumCpuContext *cpu_context, gpointer user_data);
|
||||
void instrument_regs_format(int fd, char *format, ...);
|
||||
|
||||
void ijon_set(uint32_t edge);
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -39,18 +39,18 @@ static void asan_callout(GumCpuContext *ctx, gpointer user_data) {
|
||||
|
||||
address = base + index + mem->disp;
|
||||
|
||||
if ((operand->access & CS_AC_READ) == CS_AC_READ) {
|
||||
|
||||
asan_loadN(address, asan_ctx->size);
|
||||
|
||||
}
|
||||
|
||||
if ((operand->access & CS_AC_WRITE) == CS_AC_WRITE) {
|
||||
|
||||
asan_storeN(address, asan_ctx->size);
|
||||
|
||||
}
|
||||
|
||||
if ((operand->access & CS_AC_READ) == CS_AC_READ) {
|
||||
|
||||
asan_loadN(address, asan_ctx->size);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void asan_instrument(const cs_insn *instr, GumStalkerIterator *iterator) {
|
||||
|
@ -449,3 +449,9 @@ void instrument_regs_format(int fd, char *format, ...) {
|
||||
|
||||
}
|
||||
|
||||
void ijon_set(uint32_t edge) {
|
||||
|
||||
__afl_coverage_interesting(1, edge);
|
||||
|
||||
}
|
||||
|
||||
|
@ -818,6 +818,9 @@ void instrument_coverage_unstable_find_output(void) {
|
||||
|
||||
GDir *dir = g_dir_open(fds_name, 0, NULL);
|
||||
|
||||
gchar *path_tmp = getenv("AFL_CUSTOM_INFO_OUT");
|
||||
gchar *instance_name = g_path_get_basename(path_tmp);
|
||||
|
||||
FVERBOSE("Coverage Unstable - fds: %s", fds_name);
|
||||
|
||||
for (const gchar *filename = g_dir_read_name(dir); filename != NULL;
|
||||
@ -829,7 +832,7 @@ void instrument_coverage_unstable_find_output(void) {
|
||||
if (link == NULL) { FFATAL("Failed to read link: %s", fullname); }
|
||||
|
||||
gchar *basename = g_path_get_basename(link);
|
||||
if (g_strcmp0(basename, "default") != 0) {
|
||||
if (g_strcmp0(basename, instance_name) != 0) {
|
||||
|
||||
g_free(basename);
|
||||
g_free(link);
|
||||
@ -874,6 +877,7 @@ void instrument_coverage_unstable_find_output(void) {
|
||||
}
|
||||
|
||||
g_dir_close(dir);
|
||||
g_free(instance_name);
|
||||
g_free(fds_name);
|
||||
|
||||
if (unstable_coverage_fuzzer_stats == NULL) {
|
||||
|
@ -49,14 +49,23 @@ void instrument_cache_init(void) {
|
||||
|
||||
if (setrlimit(RLIMIT_AS, &data_limit) != 0) {
|
||||
|
||||
FFATAL("Failed to setrlimit: %d", errno);
|
||||
FWARNF("Failed to setrlimit: %d, you may need root or CAP_SYS_RESOURCE",
|
||||
errno);
|
||||
|
||||
}
|
||||
|
||||
map_base =
|
||||
gum_memory_allocate(NULL, instrument_cache_size, instrument_cache_size,
|
||||
GUM_PAGE_READ | GUM_PAGE_WRITE);
|
||||
if (map_base == MAP_FAILED) { FFATAL("Failed to map segment: %d", errno); }
|
||||
if (map_base == MAP_FAILED) {
|
||||
|
||||
FFATAL(
|
||||
"Failed to map segment: %d. This can be caused by failure to setrlimit."
|
||||
"Disabling or reducing the size of the allocation using "
|
||||
"AFL_FRIDA_INST_NO_CACHE or AFL_FRIDA_INST_CACHE_SIZE may help",
|
||||
errno);
|
||||
|
||||
}
|
||||
|
||||
FOKF(cBLU "Instrumentation" cRST " - " cGRN "cache addr:" cYEL " [0x%016lX]",
|
||||
GUM_ADDRESS(map_base));
|
||||
|
@ -326,6 +326,12 @@ class Afl {
|
||||
static jsApiGetSymbol(name) {
|
||||
return Afl.module.getExportByName(name);
|
||||
}
|
||||
|
||||
static IJON = class {
|
||||
static set(addr, val) {
|
||||
Afl.jsApiIjonSet((addr ^ val) & 0xffffffff);
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Field containing the `Module` object for `afl-frida-trace.so` (the FRIDA mode
|
||||
@ -377,3 +383,4 @@ Afl.jsApiSetVerbose = Afl.jsApiGetFunction("js_api_set_verbose", "void", []);
|
||||
Afl.jsApiWrite = new NativeFunction(
|
||||
/* tslint:disable-next-line:no-null-keyword */
|
||||
Module.getExportByName(null, "write"), "int", ["int", "pointer", "int"]);
|
||||
Afl.jsApiIjonSet = Afl.jsApiGetFunction("js_api_ijon_set", "void", ["uint32"]);
|
||||
|
@ -316,3 +316,9 @@ __attribute__((visibility("default"))) void js_api_set_verbose(void) {
|
||||
|
||||
}
|
||||
|
||||
__attribute__((visibility("default"))) void js_api_ijon_set(uint32_t edge) {
|
||||
|
||||
ijon_set(edge);
|
||||
|
||||
}
|
||||
|
||||
|
@ -166,7 +166,7 @@ static void afl_print_env(void) {
|
||||
|
||||
if (fd < 0) {
|
||||
|
||||
FWARNF("Failed to open /proc/self/cmdline, errno: (%d)", errno);
|
||||
FWARNF("Failed to open /proc/self/environ, errno: (%d)", errno);
|
||||
return;
|
||||
|
||||
}
|
||||
@ -174,7 +174,7 @@ static void afl_print_env(void) {
|
||||
ssize_t bytes_read = read(fd, buffer, PROC_MAX - 1);
|
||||
if (bytes_read < 0) {
|
||||
|
||||
FFATAL("Failed to read /proc/self/cmdline, errno: (%d)", errno);
|
||||
FFATAL("Failed to read /proc/self/environ, errno: (%d)", errno);
|
||||
|
||||
}
|
||||
|
||||
|
@ -33,7 +33,7 @@
|
||||
// r15 - pc
|
||||
|
||||
static GumCpuContext saved_regs = {0};
|
||||
static gpointer saved_lr = NULL;
|
||||
static gpointer persistent_loop = NULL;
|
||||
|
||||
gboolean persistent_is_supported(void) {
|
||||
|
||||
@ -141,17 +141,10 @@ static void instrument_persitent_restore_regs(GumArmWriter *cw,
|
||||
|
||||
}
|
||||
|
||||
static void instrument_exit(GumArmWriter *cw) {
|
||||
static void instrument_afl_persistent_loop_func(void) {
|
||||
|
||||
gum_arm_writer_put_sub_reg_reg_reg(cw, ARM_REG_R0, ARM_REG_R0, ARM_REG_R0);
|
||||
gum_arm_writer_put_call_address_with_arguments(cw, GUM_ADDRESS(_exit), 1,
|
||||
GUM_ARG_REGISTER, ARM_REG_R0);
|
||||
if (__afl_persistent_loop(persistent_count) == 0) { _exit(0); }
|
||||
|
||||
}
|
||||
|
||||
static int instrument_afl_persistent_loop_func(void) {
|
||||
|
||||
int ret = __afl_persistent_loop(persistent_count);
|
||||
if (instrument_previous_pc_addr == NULL) {
|
||||
|
||||
FATAL("instrument_previous_pc_addr uninitialized");
|
||||
@ -159,7 +152,6 @@ static int instrument_afl_persistent_loop_func(void) {
|
||||
}
|
||||
|
||||
*instrument_previous_pc_addr = instrument_hash_zero;
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
@ -203,7 +195,8 @@ static void instrument_persitent_save_lr(GumArmWriter *cw) {
|
||||
gum_arm_writer_put_str_reg_reg_offset(cw, ARM_REG_R0, ARM_REG_SP,
|
||||
GUM_RED_ZONE_SIZE);
|
||||
|
||||
gum_arm_writer_put_ldr_reg_address(cw, ARM_REG_R0, GUM_ADDRESS(&saved_lr));
|
||||
gum_arm_writer_put_ldr_reg_address(cw, ARM_REG_R0,
|
||||
GUM_ADDRESS(&persistent_ret));
|
||||
gum_arm_writer_put_str_reg_reg_offset(cw, ARM_REG_LR, ARM_REG_R0, 0);
|
||||
|
||||
gum_arm_writer_put_ldr_reg_reg_offset(cw, ARM_REG_R0, ARM_REG_SP,
|
||||
@ -214,65 +207,35 @@ static void instrument_persitent_save_lr(GumArmWriter *cw) {
|
||||
void persistent_prologue_arch(GumStalkerOutput *output) {
|
||||
|
||||
/*
|
||||
* SAVE RET (Used to write the epilogue if persistent_ret is not set)
|
||||
* SAVE REGS
|
||||
* SAVE RET
|
||||
* POP RET
|
||||
* loop:
|
||||
* loop: (Save address of where the eiplogue should jump back to)
|
||||
* CALL instrument_afl_persistent_loop
|
||||
* TEST EAX, EAX
|
||||
* JZ end:
|
||||
* call hook (optionally)
|
||||
* CALL hook (optionally)
|
||||
* RESTORE REGS
|
||||
* call original
|
||||
* jmp loop:
|
||||
*
|
||||
* end:
|
||||
* JMP SAVED RET
|
||||
*
|
||||
* original:
|
||||
* INSTRUMENTED PERSISTENT FUNC
|
||||
*/
|
||||
|
||||
GumArmWriter *cw = output->writer.arm;
|
||||
|
||||
gconstpointer loop = cw->code + 1;
|
||||
|
||||
FVERBOSE("Persistent loop reached");
|
||||
|
||||
if (persistent_ret == 0) { instrument_persitent_save_lr(cw); }
|
||||
|
||||
/* Save the current context */
|
||||
instrument_persitent_save_regs(cw, &saved_regs);
|
||||
|
||||
/* loop: */
|
||||
gum_arm_writer_put_label(cw, loop);
|
||||
/* Store a pointer to where we should return for our next iteration */
|
||||
persistent_loop = gum_arm_writer_cur(cw);
|
||||
|
||||
/* call instrument_prologue_func */
|
||||
/* call __afl_persistent_loop and _exit if zero. Also reset our previous_pc */
|
||||
instrument_afl_persistent_loop(cw);
|
||||
|
||||
/* jz done */
|
||||
gconstpointer done = cw->code + 1;
|
||||
gum_arm_writer_put_cmp_reg_imm(cw, ARM_REG_R0, 0);
|
||||
gum_arm_writer_put_b_cond_label(cw, ARM_CC_EQ, done);
|
||||
|
||||
/* Optionally call the persistent hook */
|
||||
persistent_prologue_hook(cw, &saved_regs);
|
||||
|
||||
/* Restore our CPU context before we continue execution */
|
||||
instrument_persitent_restore_regs(cw, &saved_regs);
|
||||
gconstpointer original = cw->code + 1;
|
||||
/* call original */
|
||||
|
||||
gum_arm_writer_put_bl_label(cw, original);
|
||||
|
||||
/* jmp loop */
|
||||
gum_arm_writer_put_b_label(cw, loop);
|
||||
|
||||
/* done: */
|
||||
gum_arm_writer_put_label(cw, done);
|
||||
|
||||
instrument_exit(cw);
|
||||
|
||||
/* original: */
|
||||
gum_arm_writer_put_label(cw, original);
|
||||
|
||||
instrument_persitent_save_lr(cw);
|
||||
|
||||
if (persistent_debug) { gum_arm_writer_put_breakpoint(cw); }
|
||||
|
||||
@ -284,7 +247,8 @@ void persistent_epilogue_arch(GumStalkerOutput *output) {
|
||||
|
||||
if (persistent_debug) { gum_arm_writer_put_breakpoint(cw); }
|
||||
|
||||
gum_arm_writer_put_ldr_reg_address(cw, ARM_REG_R0, GUM_ADDRESS(&saved_lr));
|
||||
gum_arm_writer_put_ldr_reg_address(cw, ARM_REG_R0,
|
||||
GUM_ADDRESS(&persistent_loop));
|
||||
|
||||
gum_arm_writer_put_ldr_reg_reg_offset(cw, ARM_REG_R0, ARM_REG_R0, 0);
|
||||
|
||||
|
@ -16,7 +16,7 @@ typedef struct {
|
||||
} persistent_ctx_t;
|
||||
|
||||
static persistent_ctx_t saved_regs = {0};
|
||||
static gpointer saved_lr = NULL;
|
||||
static gpointer persistent_loop = NULL;
|
||||
|
||||
gboolean persistent_is_supported(void) {
|
||||
|
||||
@ -216,17 +216,10 @@ static void instrument_persitent_restore_regs(GumArm64Writer *cw,
|
||||
|
||||
}
|
||||
|
||||
static void instrument_exit(GumArm64Writer *cw) {
|
||||
static void instrument_afl_persistent_loop_func(void) {
|
||||
|
||||
gum_arm64_writer_put_mov_reg_reg(cw, ARM64_REG_X0, ARM64_REG_XZR);
|
||||
gum_arm64_writer_put_call_address_with_arguments(
|
||||
cw, GUM_ADDRESS(_exit), 1, GUM_ARG_REGISTER, ARM64_REG_X0);
|
||||
if (__afl_persistent_loop(persistent_count) == 0) { _exit(0); }
|
||||
|
||||
}
|
||||
|
||||
static int instrument_afl_persistent_loop_func(void) {
|
||||
|
||||
int ret = __afl_persistent_loop(persistent_count);
|
||||
if (instrument_previous_pc_addr == NULL) {
|
||||
|
||||
FATAL("instrument_previous_pc_addr uninitialized");
|
||||
@ -234,7 +227,6 @@ static int instrument_afl_persistent_loop_func(void) {
|
||||
}
|
||||
|
||||
*instrument_previous_pc_addr = instrument_hash_zero;
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
@ -284,7 +276,7 @@ static void instrument_persitent_save_lr(GumArm64Writer *cw) {
|
||||
GUM_INDEX_PRE_ADJUST);
|
||||
|
||||
gum_arm64_writer_put_ldr_reg_address(cw, ARM64_REG_X0,
|
||||
GUM_ADDRESS(&saved_lr));
|
||||
GUM_ADDRESS(&persistent_ret));
|
||||
|
||||
gum_arm64_writer_put_str_reg_reg_offset(cw, ARM64_REG_LR, ARM64_REG_X0, 0);
|
||||
|
||||
@ -297,65 +289,35 @@ static void instrument_persitent_save_lr(GumArm64Writer *cw) {
|
||||
void persistent_prologue_arch(GumStalkerOutput *output) {
|
||||
|
||||
/*
|
||||
* SAVE RET (Used to write the epilogue if persistent_ret is not set)
|
||||
* SAVE REGS
|
||||
* SAVE RET
|
||||
* POP RET
|
||||
* loop:
|
||||
* loop: (Save address of where the eiplogue should jump back to)
|
||||
* CALL instrument_afl_persistent_loop
|
||||
* TEST EAX, EAX
|
||||
* JZ end:
|
||||
* call hook (optionally)
|
||||
* CALL hook (optionally)
|
||||
* RESTORE REGS
|
||||
* call original
|
||||
* jmp loop:
|
||||
*
|
||||
* end:
|
||||
* JMP SAVED RET
|
||||
*
|
||||
* original:
|
||||
* INSTRUMENTED PERSISTENT FUNC
|
||||
*/
|
||||
|
||||
GumArm64Writer *cw = output->writer.arm64;
|
||||
|
||||
gconstpointer loop = cw->code + 1;
|
||||
|
||||
FVERBOSE("Persistent loop reached");
|
||||
|
||||
if (persistent_ret == 0) { instrument_persitent_save_lr(cw); }
|
||||
|
||||
/* Save the current context */
|
||||
instrument_persitent_save_regs(cw, &saved_regs);
|
||||
|
||||
/* loop: */
|
||||
gum_arm64_writer_put_label(cw, loop);
|
||||
/* Store a pointer to where we should return for our next iteration */
|
||||
persistent_loop = gum_arm64_writer_cur(cw);
|
||||
|
||||
/* call instrument_prologue_func */
|
||||
/* call __afl_persistent_loop and _exit if zero. Also reset our previous_pc */
|
||||
instrument_afl_persistent_loop(cw);
|
||||
|
||||
/* jz done */
|
||||
gconstpointer done = cw->code + 1;
|
||||
gum_arm64_writer_put_cmp_reg_reg(cw, ARM64_REG_X0, ARM64_REG_XZR);
|
||||
gum_arm64_writer_put_b_cond_label(cw, ARM64_CC_EQ, done);
|
||||
|
||||
/* Optionally call the persistent hook */
|
||||
persistent_prologue_hook(cw, &saved_regs);
|
||||
|
||||
/* Restore our CPU context before we continue execution */
|
||||
instrument_persitent_restore_regs(cw, &saved_regs);
|
||||
gconstpointer original = cw->code + 1;
|
||||
/* call original */
|
||||
|
||||
gum_arm64_writer_put_bl_label(cw, original);
|
||||
|
||||
/* jmp loop */
|
||||
gum_arm64_writer_put_b_label(cw, loop);
|
||||
|
||||
/* done: */
|
||||
gum_arm64_writer_put_label(cw, done);
|
||||
|
||||
instrument_exit(cw);
|
||||
|
||||
/* original: */
|
||||
gum_arm64_writer_put_label(cw, original);
|
||||
|
||||
instrument_persitent_save_lr(cw);
|
||||
|
||||
if (persistent_debug) { gum_arm64_writer_put_brk_imm(cw, 0); }
|
||||
|
||||
@ -368,7 +330,7 @@ void persistent_epilogue_arch(GumStalkerOutput *output) {
|
||||
if (persistent_debug) { gum_arm64_writer_put_brk_imm(cw, 0); }
|
||||
|
||||
gum_arm64_writer_put_ldr_reg_address(cw, ARM64_REG_X0,
|
||||
GUM_ADDRESS(&saved_lr));
|
||||
GUM_ADDRESS(&persistent_loop));
|
||||
|
||||
gum_arm64_writer_put_ldr_reg_reg_offset(cw, ARM64_REG_X0, ARM64_REG_X0, 0);
|
||||
|
||||
|
@ -17,7 +17,7 @@ typedef struct {
|
||||
} persistent_ctx_t;
|
||||
|
||||
static persistent_ctx_t saved_regs = {0};
|
||||
static gpointer saved_ret = NULL;
|
||||
static gpointer persistent_loop = NULL;
|
||||
|
||||
gboolean persistent_is_supported(void) {
|
||||
|
||||
@ -162,17 +162,10 @@ static void instrument_persitent_restore_regs(GumX86Writer *cw,
|
||||
|
||||
}
|
||||
|
||||
static void instrument_exit(GumX86Writer *cw) {
|
||||
static void instrument_afl_persistent_loop_func(void) {
|
||||
|
||||
gum_x86_writer_put_mov_reg_address(cw, GUM_X86_RAX, GUM_ADDRESS(_exit));
|
||||
gum_x86_writer_put_mov_reg_u32(cw, GUM_X86_RDI, 0);
|
||||
gum_x86_writer_put_call_reg(cw, GUM_X86_RAX);
|
||||
if (__afl_persistent_loop(persistent_count) == 0) { _exit(0); }
|
||||
|
||||
}
|
||||
|
||||
static int instrument_afl_persistent_loop_func(void) {
|
||||
|
||||
int ret = __afl_persistent_loop(persistent_count);
|
||||
if (instrument_previous_pc_addr == NULL) {
|
||||
|
||||
FATAL("instrument_previous_pc_addr uninitialized");
|
||||
@ -180,7 +173,6 @@ static int instrument_afl_persistent_loop_func(void) {
|
||||
}
|
||||
|
||||
*instrument_previous_pc_addr = instrument_hash_zero;
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
@ -190,7 +182,6 @@ static void instrument_afl_persistent_loop(GumX86Writer *cw) {
|
||||
-(GUM_RED_ZONE_SIZE));
|
||||
gum_x86_writer_put_call_address_with_arguments(
|
||||
cw, GUM_CALL_CAPI, GUM_ADDRESS(instrument_afl_persistent_loop_func), 0);
|
||||
gum_x86_writer_put_test_reg_reg(cw, GUM_X86_RAX, GUM_X86_RAX);
|
||||
|
||||
gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_X86_RSP, GUM_X86_RSP,
|
||||
(GUM_RED_ZONE_SIZE));
|
||||
@ -235,7 +226,8 @@ static void instrument_persitent_save_ret(GumX86Writer *cw) {
|
||||
gum_x86_writer_put_push_reg(cw, GUM_X86_RAX);
|
||||
gum_x86_writer_put_push_reg(cw, GUM_X86_RBX);
|
||||
|
||||
gum_x86_writer_put_mov_reg_address(cw, GUM_X86_RAX, GUM_ADDRESS(&saved_ret));
|
||||
gum_x86_writer_put_mov_reg_address(cw, GUM_X86_RAX,
|
||||
GUM_ADDRESS(&persistent_ret));
|
||||
gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_X86_RBX, GUM_X86_RSP,
|
||||
offset);
|
||||
gum_x86_writer_put_mov_reg_ptr_reg(cw, GUM_X86_RAX, GUM_X86_RBX);
|
||||
@ -252,70 +244,44 @@ static void instrument_persitent_save_ret(GumX86Writer *cw) {
|
||||
void persistent_prologue_arch(GumStalkerOutput *output) {
|
||||
|
||||
/*
|
||||
* SAVE RET (Used to write the epilogue if persistent_ret is not set)
|
||||
* SAVE REGS
|
||||
* SAVE RET
|
||||
* POP RET
|
||||
* loop:
|
||||
* loop: (Save address of where the eiplogue should jump back to)
|
||||
* CALL instrument_afl_persistent_loop
|
||||
* TEST EAX, EAX
|
||||
* JZ end:
|
||||
* call hook (optionally)
|
||||
* CALL hook (optionally)
|
||||
* RESTORE REGS
|
||||
* call original
|
||||
* jmp loop:
|
||||
*
|
||||
* end:
|
||||
* JMP SAVED RET
|
||||
*
|
||||
* original:
|
||||
* INSTRUMENTED PERSISTENT FUNC
|
||||
*/
|
||||
|
||||
GumX86Writer *cw = output->writer.x86;
|
||||
|
||||
gconstpointer loop = cw->code + 1;
|
||||
|
||||
FVERBOSE("Persistent loop reached");
|
||||
|
||||
/* Pop the return value */
|
||||
gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_X86_RSP, GUM_X86_RSP, 8);
|
||||
/*
|
||||
* If we haven't set persistent_ret, then assume that we are dealing with a
|
||||
* function and we should loop when that function returns.
|
||||
*/
|
||||
if (persistent_ret == 0) { instrument_persitent_save_ret(cw); }
|
||||
|
||||
/* Save the current context */
|
||||
instrument_persitent_save_regs(cw, &saved_regs);
|
||||
|
||||
/* loop: */
|
||||
gum_x86_writer_put_label(cw, loop);
|
||||
/* Store a pointer to where we should return for our next iteration */
|
||||
persistent_loop = gum_x86_writer_cur(cw);
|
||||
|
||||
/* call instrument_prologue_func */
|
||||
/* call __afl_persistent_loop and _exit if zero. Also reset our previous_pc */
|
||||
instrument_afl_persistent_loop(cw);
|
||||
|
||||
/* jz done */
|
||||
gconstpointer done = cw->code + 1;
|
||||
gum_x86_writer_put_jcc_near_label(cw, X86_INS_JE, done, GUM_UNLIKELY);
|
||||
|
||||
/* Optionally call the persistent hook */
|
||||
persistent_prologue_hook(cw, &saved_regs);
|
||||
|
||||
/* Restore our CPU context before we continue execution */
|
||||
instrument_persitent_restore_regs(cw, &saved_regs);
|
||||
gconstpointer original = cw->code + 1;
|
||||
/* call original */
|
||||
|
||||
gum_x86_writer_put_call_near_label(cw, original);
|
||||
|
||||
/* jmp loop */
|
||||
gum_x86_writer_put_jmp_near_label(cw, loop);
|
||||
|
||||
/* done: */
|
||||
gum_x86_writer_put_label(cw, done);
|
||||
|
||||
instrument_exit(cw);
|
||||
|
||||
/* original: */
|
||||
gum_x86_writer_put_label(cw, original);
|
||||
|
||||
instrument_persitent_save_ret(cw);
|
||||
|
||||
if (persistent_debug) { gum_x86_writer_put_breakpoint(cw); }
|
||||
|
||||
/* The original instrumented code is emitted here. */
|
||||
|
||||
}
|
||||
|
||||
void persistent_epilogue_arch(GumStalkerOutput *output) {
|
||||
@ -331,7 +297,8 @@ void persistent_epilogue_arch(GumStalkerOutput *output) {
|
||||
gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_X86_RSP, GUM_X86_RSP, -8);
|
||||
gum_x86_writer_put_label(cw, zero);
|
||||
|
||||
gum_x86_writer_put_mov_reg_address(cw, GUM_X86_RAX, GUM_ADDRESS(&saved_ret));
|
||||
gum_x86_writer_put_mov_reg_address(cw, GUM_X86_RAX,
|
||||
GUM_ADDRESS(&persistent_loop));
|
||||
gum_x86_writer_put_jmp_reg_ptr(cw, GUM_X86_RAX);
|
||||
|
||||
}
|
||||
|
@ -16,8 +16,7 @@ typedef struct {
|
||||
} persistent_ctx_t;
|
||||
|
||||
static persistent_ctx_t saved_regs = {0};
|
||||
|
||||
static gpointer saved_ret = NULL;
|
||||
static gpointer persistent_loop = NULL;
|
||||
|
||||
gboolean persistent_is_supported(void) {
|
||||
|
||||
@ -118,18 +117,10 @@ static void instrument_persitent_restore_regs(GumX86Writer *cw,
|
||||
|
||||
}
|
||||
|
||||
static void instrument_exit(GumX86Writer *cw) {
|
||||
static void instrument_afl_persistent_loop_func(void) {
|
||||
|
||||
gum_x86_writer_put_mov_reg_address(cw, GUM_X86_EAX, GUM_ADDRESS(_exit));
|
||||
gum_x86_writer_put_mov_reg_u32(cw, GUM_X86_EDI, 0);
|
||||
gum_x86_writer_put_push_reg(cw, GUM_X86_EDI);
|
||||
gum_x86_writer_put_call_reg(cw, GUM_X86_EAX);
|
||||
if (__afl_persistent_loop(persistent_count) == 0) { _exit(0); };
|
||||
|
||||
}
|
||||
|
||||
static int instrument_afl_persistent_loop_func(void) {
|
||||
|
||||
int ret = __afl_persistent_loop(persistent_count);
|
||||
if (instrument_previous_pc_addr == NULL) {
|
||||
|
||||
FATAL("instrument_previous_pc_addr uninitialized");
|
||||
@ -137,7 +128,6 @@ static int instrument_afl_persistent_loop_func(void) {
|
||||
}
|
||||
|
||||
*instrument_previous_pc_addr = instrument_hash_zero;
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
@ -145,7 +135,6 @@ static void instrument_afl_persistent_loop(GumX86Writer *cw) {
|
||||
|
||||
gum_x86_writer_put_call_address_with_arguments(
|
||||
cw, GUM_CALL_CAPI, GUM_ADDRESS(instrument_afl_persistent_loop_func), 0);
|
||||
gum_x86_writer_put_test_reg_reg(cw, GUM_X86_EAX, GUM_X86_EAX);
|
||||
|
||||
}
|
||||
|
||||
@ -179,7 +168,8 @@ static void instrument_persitent_save_ret(GumX86Writer *cw) {
|
||||
gum_x86_writer_put_push_reg(cw, GUM_X86_EAX);
|
||||
gum_x86_writer_put_push_reg(cw, GUM_X86_EBX);
|
||||
|
||||
gum_x86_writer_put_mov_reg_address(cw, GUM_X86_EAX, GUM_ADDRESS(&saved_ret));
|
||||
gum_x86_writer_put_mov_reg_address(cw, GUM_X86_EAX,
|
||||
GUM_ADDRESS(&persistent_ret));
|
||||
gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_X86_EBX, GUM_X86_ESP,
|
||||
offset);
|
||||
gum_x86_writer_put_mov_reg_ptr_reg(cw, GUM_X86_EAX, GUM_X86_EBX);
|
||||
@ -193,68 +183,44 @@ static void instrument_persitent_save_ret(GumX86Writer *cw) {
|
||||
void persistent_prologue_arch(GumStalkerOutput *output) {
|
||||
|
||||
/*
|
||||
* SAVE RET (Used to write the epilogue if persistent_ret is not set)
|
||||
* SAVE REGS
|
||||
* SAVE RET
|
||||
* POP RET
|
||||
* loop:
|
||||
* loop: (Save address of where the eiplogue should jump back to)
|
||||
* CALL instrument_afl_persistent_loop
|
||||
* TEST EAX, EAX
|
||||
* JZ end:
|
||||
* call hook (optionally)
|
||||
* CALL hook (optionally)
|
||||
* RESTORE REGS
|
||||
* call original
|
||||
* jmp loop:
|
||||
*
|
||||
* end:
|
||||
* JMP SAVED RET
|
||||
*
|
||||
* original:
|
||||
* INSTRUMENTED PERSISTENT FUNC
|
||||
*/
|
||||
|
||||
GumX86Writer *cw = output->writer.x86;
|
||||
|
||||
gconstpointer loop = cw->code + 1;
|
||||
|
||||
FVERBOSE("Persistent loop reached");
|
||||
|
||||
/* Pop the return value */
|
||||
gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_X86_ESP, GUM_X86_ESP, 4);
|
||||
/*
|
||||
* If we haven't set persistent_ret, then assume that we are dealing with a
|
||||
* function and we should loop when that function returns.
|
||||
*/
|
||||
if (persistent_ret == 0) { instrument_persitent_save_ret(cw); }
|
||||
|
||||
/* Save the current context */
|
||||
instrument_persitent_save_regs(cw, &saved_regs);
|
||||
|
||||
/* loop: */
|
||||
gum_x86_writer_put_label(cw, loop);
|
||||
/* Store a pointer to where we should return for our next iteration */
|
||||
persistent_loop = gum_x86_writer_cur(cw);
|
||||
|
||||
/* call instrument_prologue_func */
|
||||
/* call __afl_persistent_loop and _exit if zero. Also reset our previous_pc */
|
||||
instrument_afl_persistent_loop(cw);
|
||||
|
||||
/* jz done */
|
||||
gconstpointer done = cw->code + 1;
|
||||
gum_x86_writer_put_jcc_near_label(cw, X86_INS_JE, done, GUM_UNLIKELY);
|
||||
|
||||
/* Optionally call the persistent hook */
|
||||
persistent_prologue_hook(cw, &saved_regs);
|
||||
|
||||
/* Restore our CPU context before we continue execution */
|
||||
instrument_persitent_restore_regs(cw, &saved_regs);
|
||||
gconstpointer original = cw->code + 1;
|
||||
/* call original */
|
||||
gum_x86_writer_put_call_near_label(cw, original);
|
||||
/* jmp loop */
|
||||
gum_x86_writer_put_jmp_near_label(cw, loop);
|
||||
|
||||
/* done: */
|
||||
gum_x86_writer_put_label(cw, done);
|
||||
|
||||
instrument_exit(cw);
|
||||
|
||||
/* original: */
|
||||
gum_x86_writer_put_label(cw, original);
|
||||
|
||||
instrument_persitent_save_ret(cw);
|
||||
|
||||
if (persistent_debug) { gum_x86_writer_put_breakpoint(cw); }
|
||||
|
||||
/* The original instrumented code is emitted here. */
|
||||
|
||||
}
|
||||
|
||||
void persistent_epilogue_arch(GumStalkerOutput *output) {
|
||||
@ -263,7 +229,12 @@ void persistent_epilogue_arch(GumStalkerOutput *output) {
|
||||
|
||||
if (persistent_debug) { gum_x86_writer_put_breakpoint(cw); }
|
||||
|
||||
gum_x86_writer_put_mov_reg_address(cw, GUM_X86_EAX, GUM_ADDRESS(&saved_ret));
|
||||
/* The stack should be aligned when we re-enter our loop */
|
||||
gum_x86_writer_put_and_reg_u32(cw, GUM_X86_ESP, 0xfffffff0);
|
||||
gum_x86_writer_put_sub_reg_imm(cw, GUM_X86_ESP, 0x4);
|
||||
|
||||
gum_x86_writer_put_mov_reg_address(cw, GUM_X86_EAX,
|
||||
GUM_ADDRESS(&persistent_loop));
|
||||
gum_x86_writer_put_jmp_reg_ptr(cw, GUM_X86_EAX);
|
||||
|
||||
}
|
||||
|
@ -194,24 +194,23 @@ static gboolean print_ranges_callback(const GumRangeDetails *details,
|
||||
|
||||
if (details->file == NULL) {
|
||||
|
||||
FVERBOSE("\t0x%016" G_GINT64_MODIFIER "x-0x%016" G_GINT64_MODIFIER
|
||||
"X %c%c%c",
|
||||
details->range->base_address,
|
||||
details->range->base_address + details->range->size,
|
||||
details->protection & GUM_PAGE_READ ? 'R' : '-',
|
||||
details->protection & GUM_PAGE_WRITE ? 'W' : '-',
|
||||
details->protection & GUM_PAGE_EXECUTE ? 'X' : '-');
|
||||
OKF("\t0x%016" G_GINT64_MODIFIER "x-0x%016" G_GINT64_MODIFIER "X %c%c%c",
|
||||
details->range->base_address,
|
||||
details->range->base_address + details->range->size,
|
||||
details->protection & GUM_PAGE_READ ? 'R' : '-',
|
||||
details->protection & GUM_PAGE_WRITE ? 'W' : '-',
|
||||
details->protection & GUM_PAGE_EXECUTE ? 'X' : '-');
|
||||
|
||||
} else {
|
||||
|
||||
FVERBOSE("\t0x%016" G_GINT64_MODIFIER "x-0x%016" G_GINT64_MODIFIER
|
||||
"X %c%c%c %s(0x%016" G_GINT64_MODIFIER "x)",
|
||||
details->range->base_address,
|
||||
details->range->base_address + details->range->size,
|
||||
details->protection & GUM_PAGE_READ ? 'R' : '-',
|
||||
details->protection & GUM_PAGE_WRITE ? 'W' : '-',
|
||||
details->protection & GUM_PAGE_EXECUTE ? 'X' : '-',
|
||||
details->file->path, details->file->offset);
|
||||
OKF("\t0x%016" G_GINT64_MODIFIER "x-0x%016" G_GINT64_MODIFIER
|
||||
"X %c%c%c %s(0x%016" G_GINT64_MODIFIER "x)",
|
||||
details->range->base_address,
|
||||
details->range->base_address + details->range->size,
|
||||
details->protection & GUM_PAGE_READ ? 'R' : '-',
|
||||
details->protection & GUM_PAGE_WRITE ? 'W' : '-',
|
||||
details->protection & GUM_PAGE_EXECUTE ? 'X' : '-', details->file->path,
|
||||
details->file->offset);
|
||||
|
||||
}
|
||||
|
||||
@ -581,7 +580,7 @@ static GArray *merge_ranges(GArray *a) {
|
||||
|
||||
void ranges_print_debug_maps(void) {
|
||||
|
||||
FVERBOSE("Maps");
|
||||
OKF("Maps");
|
||||
gum_process_enumerate_ranges(GUM_PAGE_NO_ACCESS, print_ranges_callback, NULL);
|
||||
|
||||
}
|
||||
@ -653,7 +652,7 @@ void ranges_init(void) {
|
||||
/*
|
||||
* After step 4 we have the total ranges to be instrumented, we now subtract
|
||||
* that either from the original ranges of the modules or from the whole
|
||||
* memory if AFL_INST_NO_DYNAMIC_LOAD to configure the stalker.
|
||||
* memory if AFL_FRIDA_INST_NO_DYNAMIC_LOAD to configure the stalker.
|
||||
*/
|
||||
if (ranges_inst_dynamic_load) {
|
||||
|
||||
|
@ -110,7 +110,11 @@ gboolean util_verbose_enabled(void) {
|
||||
if (!initialized) {
|
||||
|
||||
initialized = TRUE;
|
||||
if (getenv("AFL_FRIDA_VERBOSE") != NULL) { util_verbose = TRUE; }
|
||||
if (getenv("AFL_FRIDA_VERBOSE") || getenv("AFL_DEBUG")) {
|
||||
|
||||
util_verbose = TRUE;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
69
frida_mode/test/cache/cache.c
vendored
69
frida_mode/test/cache/cache.c
vendored
@ -6,46 +6,45 @@
|
||||
|
||||
void LLVMFuzzerTestOneInput(char *buf, int len);
|
||||
|
||||
__asm__ (
|
||||
"LLVMFuzzerTestOneInput:\n"
|
||||
".func LLVMFuzzerTestOneInput\n"
|
||||
".global LLVMFuzzerTestOneInput\n"
|
||||
" jmpq *jmp_offset(%rip)\n"
|
||||
" nop\n"
|
||||
" nop\n"
|
||||
"call_target:\n"
|
||||
" ret\n"
|
||||
" nop\n"
|
||||
" nop\n"
|
||||
"jmp_target:\n"
|
||||
" callq *call_offset(%rip)\n"
|
||||
" nop\n"
|
||||
" nop\n"
|
||||
" leaq rax_offset(%rip), %rax\n"
|
||||
" jmp (%rax)\n"
|
||||
" nop\n"
|
||||
" ud2\n"
|
||||
" nop\n"
|
||||
"rax_target:\n"
|
||||
" ret\n"
|
||||
"\n"
|
||||
"\n"
|
||||
".global jmp_offset\n"
|
||||
".p2align 3\n"
|
||||
"jmp_offset:\n"
|
||||
" .quad jmp_target\n"
|
||||
"call_offset:\n"
|
||||
" .quad call_target\n"
|
||||
"rax_offset:\n"
|
||||
" .quad rax_target\n"
|
||||
);
|
||||
__asm__(
|
||||
"LLVMFuzzerTestOneInput:\n"
|
||||
".func LLVMFuzzerTestOneInput\n"
|
||||
".global LLVMFuzzerTestOneInput\n"
|
||||
" jmpq *jmp_offset(%rip)\n"
|
||||
" nop\n"
|
||||
" nop\n"
|
||||
"call_target:\n"
|
||||
" ret\n"
|
||||
" nop\n"
|
||||
" nop\n"
|
||||
"jmp_target:\n"
|
||||
" callq *call_offset(%rip)\n"
|
||||
" nop\n"
|
||||
" nop\n"
|
||||
" leaq rax_offset(%rip), %rax\n"
|
||||
" jmp (%rax)\n"
|
||||
" nop\n"
|
||||
" ud2\n"
|
||||
" nop\n"
|
||||
"rax_target:\n"
|
||||
" ret\n"
|
||||
"\n"
|
||||
"\n"
|
||||
".global jmp_offset\n"
|
||||
".p2align 3\n"
|
||||
"jmp_offset:\n"
|
||||
" .quad jmp_target\n"
|
||||
"call_offset:\n"
|
||||
" .quad call_target\n"
|
||||
"rax_offset:\n"
|
||||
" .quad rax_target\n");
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
|
||||
char * file;
|
||||
char *file;
|
||||
int fd = -1;
|
||||
off_t len;
|
||||
char * buf = NULL;
|
||||
char *buf = NULL;
|
||||
size_t n_read;
|
||||
int result = -1;
|
||||
|
||||
|
@ -6,8 +6,8 @@
|
||||
|
||||
static bool cmov_test(char *x, char *y, size_t len) {
|
||||
|
||||
register char * __rdi __asm__("rdi") = x;
|
||||
register char * __rsi __asm__("rsi") = y;
|
||||
register char *__rdi __asm__("rdi") = x;
|
||||
register char *__rsi __asm__("rsi") = y;
|
||||
register size_t __rcx __asm__("rcx") = len;
|
||||
|
||||
register long __rax __asm__("rax");
|
||||
@ -49,10 +49,10 @@ void LLVMFuzzerTestOneInput(char *buf, int len) {
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
|
||||
char * file;
|
||||
char *file;
|
||||
int fd = -1;
|
||||
off_t len;
|
||||
char * buf = NULL;
|
||||
char *buf = NULL;
|
||||
size_t n_read;
|
||||
int result = -1;
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
//
|
||||
// Author: Mateusz Jurczyk (mjurczyk@google.com)
|
||||
//
|
||||
// Copyright 2019-2023 Google LLC
|
||||
// Copyright 2019-2024 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
@ -3,7 +3,7 @@
|
||||
--------------------------------------------------------
|
||||
Originally written by Michal Zalewski
|
||||
Copyright 2014 Google Inc. All rights reserved.
|
||||
Copyright 2019-2023 AFLplusplus Project. All rights reserved.
|
||||
Copyright 2019-2024 AFLplusplus Project. All rights reserved.
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at:
|
||||
@ -41,7 +41,7 @@ int run(char *file) {
|
||||
|
||||
int fd = -1;
|
||||
off_t len;
|
||||
char * buf = NULL;
|
||||
char *buf = NULL;
|
||||
size_t n_read;
|
||||
int result = -1;
|
||||
|
||||
@ -51,6 +51,7 @@ int run(char *file) {
|
||||
|
||||
fd = open(file, O_RDONLY);
|
||||
if (fd < 0) {
|
||||
|
||||
perror("open");
|
||||
break;
|
||||
|
||||
@ -110,8 +111,10 @@ void slow() {
|
||||
|
||||
}
|
||||
|
||||
TESTINSTR_SECTION int do_run(char * file) {
|
||||
TESTINSTR_SECTION int do_run(char *file) {
|
||||
|
||||
return run(file);
|
||||
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
|
@ -3,7 +3,7 @@
|
||||
--------------------------------------------------------
|
||||
Originally written by Michal Zalewski
|
||||
Copyright 2014 Google Inc. All rights reserved.
|
||||
Copyright 2019-2023 AFLplusplus Project. All rights reserved.
|
||||
Copyright 2019-2024 AFLplusplus Project. All rights reserved.
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at:
|
||||
@ -19,32 +19,40 @@
|
||||
typedef void (*fntestinstrlib)(char *buf, int len);
|
||||
|
||||
void testinstr(char *buf, int len) {
|
||||
|
||||
void *lib = dlopen("testinstrlib.so", RTLD_NOW);
|
||||
if (lib == NULL) {
|
||||
|
||||
puts("Library not found");
|
||||
abort();
|
||||
|
||||
}
|
||||
|
||||
fntestinstrlib fn = (fntestinstrlib)(dlsym(lib, "testinstrlib"));
|
||||
if (fn == NULL) {
|
||||
|
||||
puts("Function not found");
|
||||
abort();
|
||||
|
||||
}
|
||||
|
||||
fn(buf, len);
|
||||
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
char * file;
|
||||
|
||||
char *file;
|
||||
int fd = -1;
|
||||
off_t len;
|
||||
char * buf = NULL;
|
||||
char *buf = NULL;
|
||||
size_t n_read;
|
||||
int result = -1;
|
||||
|
||||
if (argc != 2) { return 1; }
|
||||
|
||||
do {
|
||||
|
||||
file = argv[1];
|
||||
printf("file: %s\n", file);
|
||||
|
||||
@ -52,33 +60,43 @@ int main(int argc, char **argv) {
|
||||
|
||||
fd = open(file, O_RDONLY);
|
||||
if (fd < 0) {
|
||||
|
||||
perror("open");
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
len = lseek(fd, 0, SEEK_END);
|
||||
if (len < 0) {
|
||||
|
||||
perror("lseek (SEEK_END)");
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
if (lseek(fd, 0, SEEK_SET) != 0) {
|
||||
|
||||
perror("lseek (SEEK_SET)");
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
printf("len: %ld\n", len);
|
||||
|
||||
buf = malloc(len);
|
||||
if (buf == NULL) {
|
||||
|
||||
perror("malloc");
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
n_read = read(fd, buf, len);
|
||||
if (n_read != len) {
|
||||
|
||||
perror("read");
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
dprintf(STDERR_FILENO, "Running: %s: (%zd bytes)\n", file, n_read);
|
||||
@ -95,4 +113,6 @@ int main(int argc, char **argv) {
|
||||
if (fd != -1) { close(fd); }
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
#include <stdio.h>
|
||||
|
||||
void testinstrlib(char *buf, int len) {
|
||||
|
||||
if (len < 1) return;
|
||||
buf[len] = 0;
|
||||
|
||||
@ -11,4 +12,6 @@ void testinstrlib(char *buf, int len) {
|
||||
printf("Pretty sure that is a one!\n");
|
||||
else
|
||||
printf("Neither one or zero? How quaint!\n");
|
||||
|
||||
}
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
--------------------------------------------------------
|
||||
Originally written by Michal Zalewski
|
||||
Copyright 2014 Google Inc. All rights reserved.
|
||||
Copyright 2019-2023 AFLplusplus Project. All rights reserved.
|
||||
Copyright 2019-2024 AFLplusplus Project. All rights reserved.
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at:
|
||||
@ -41,7 +41,7 @@ int run(char *file) {
|
||||
|
||||
int fd = -1;
|
||||
off_t len;
|
||||
char * buf = NULL;
|
||||
char *buf = NULL;
|
||||
size_t n_read;
|
||||
int result = -1;
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
--------------------------------------------------------
|
||||
Originally written by Michal Zalewski
|
||||
Copyright 2014 Google Inc. All rights reserved.
|
||||
Copyright 2019-2023 AFLplusplus Project. All rights reserved.
|
||||
Copyright 2019-2024 AFLplusplus Project. All rights reserved.
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at:
|
||||
@ -39,10 +39,10 @@ void testinstr(char *buf, int len) {
|
||||
|
||||
TESTINSTR_SECTION int main(int argc, char **argv) {
|
||||
|
||||
char * file;
|
||||
char *file;
|
||||
int fd = -1;
|
||||
off_t len;
|
||||
char * buf = NULL;
|
||||
char *buf = NULL;
|
||||
size_t n_read;
|
||||
int result = -1;
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
--------------------------------------------------------
|
||||
Originally written by Michal Zalewski
|
||||
Copyright 2014 Google Inc. All rights reserved.
|
||||
Copyright 2019-2023 AFLplusplus Project. All rights reserved.
|
||||
Copyright 2019-2024 AFLplusplus Project. All rights reserved.
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at:
|
||||
@ -35,7 +35,7 @@ int run(char *file) {
|
||||
|
||||
int fd = -1;
|
||||
off_t len;
|
||||
char * buf = NULL;
|
||||
char *buf = NULL;
|
||||
size_t n_read;
|
||||
int result = -1;
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
--------------------------------------------------------
|
||||
Originally written by Michal Zalewski
|
||||
Copyright 2014 Google Inc. All rights reserved.
|
||||
Copyright 2019-2023 AFLplusplus Project. All rights reserved.
|
||||
Copyright 2019-2024 AFLplusplus Project. All rights reserved.
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at:
|
||||
@ -22,60 +22,60 @@
|
||||
#define IGNORED_RETURN(x) (void)!(x)
|
||||
|
||||
const uint32_t crc32_tab[] = {
|
||||
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
|
||||
0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
|
||||
0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
|
||||
0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
|
||||
0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
|
||||
0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
|
||||
0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
|
||||
0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
|
||||
0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
|
||||
0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
|
||||
0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
|
||||
0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
|
||||
0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
|
||||
0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
|
||||
0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
|
||||
0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
|
||||
0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
|
||||
0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
|
||||
0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
|
||||
0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
|
||||
0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
|
||||
0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
|
||||
0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
|
||||
0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
|
||||
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
|
||||
0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
|
||||
0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
|
||||
0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
|
||||
0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
|
||||
0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
|
||||
0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
|
||||
0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
|
||||
0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
|
||||
0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
|
||||
0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
|
||||
0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
|
||||
0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
|
||||
0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
|
||||
0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
|
||||
0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
|
||||
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
|
||||
0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
|
||||
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
|
||||
};
|
||||
|
||||
uint32_t
|
||||
crc32(const void *buf, size_t size)
|
||||
{
|
||||
const uint8_t *p = buf;
|
||||
uint32_t crc;
|
||||
crc = ~0U;
|
||||
while (size--)
|
||||
crc = crc32_tab[(crc ^ *p++) & 0xFF] ^ (crc >> 8);
|
||||
return crc ^ ~0U;
|
||||
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
|
||||
0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
|
||||
0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
|
||||
0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
|
||||
0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
|
||||
0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
|
||||
0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
|
||||
0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
|
||||
0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
|
||||
0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
|
||||
0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
|
||||
0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
|
||||
0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
|
||||
0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
|
||||
0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
|
||||
0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
|
||||
0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
|
||||
0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
|
||||
0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
|
||||
0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
|
||||
0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
|
||||
0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
|
||||
0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
|
||||
0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
|
||||
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
|
||||
0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
|
||||
0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
|
||||
0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
|
||||
0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
|
||||
0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
|
||||
0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
|
||||
0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
|
||||
0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
|
||||
0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
|
||||
0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
|
||||
0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
|
||||
0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
|
||||
0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
|
||||
0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
|
||||
0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
|
||||
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
|
||||
0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
|
||||
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d};
|
||||
|
||||
uint32_t crc32(const void *buf, size_t size) {
|
||||
|
||||
const uint8_t *p = buf;
|
||||
uint32_t crc;
|
||||
crc = ~0U;
|
||||
while (size--)
|
||||
crc = crc32_tab[(crc ^ *p++) & 0xFF] ^ (crc >> 8);
|
||||
return crc ^ ~0U;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
@ -83,11 +83,13 @@ crc32(const void *buf, size_t size)
|
||||
* FRIDA to patch this function out and always return success. Otherwise, we
|
||||
* could change it to actually correct the checksum.
|
||||
*/
|
||||
int crc32_check (char * buf, int len) {
|
||||
int crc32_check(char *buf, int len) {
|
||||
|
||||
if (len < sizeof(uint32_t)) { return 0; }
|
||||
uint32_t expected = *(uint32_t *)&buf[len - sizeof(uint32_t)];
|
||||
uint32_t calculated = crc32(buf, len - sizeof(uint32_t));
|
||||
return expected == calculated;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
@ -97,27 +99,31 @@ int crc32_check (char * buf, int len) {
|
||||
* cloud your output unnecessarily. Again, we can use FRIDA to patch it out.
|
||||
*/
|
||||
void some_boring_bug(char c) {
|
||||
|
||||
switch (c) {
|
||||
case 'A'...'Z':
|
||||
case 'a'...'z':
|
||||
|
||||
case 'A' ... 'Z':
|
||||
case 'a' ... 'z':
|
||||
__builtin_trap();
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extern void some_boring_bug2(char c);
|
||||
|
||||
__asm__ (
|
||||
".text \n"
|
||||
"some_boring_bug2: \n"
|
||||
".global some_boring_bug2 \n"
|
||||
".type some_boring_bug2, @function \n"
|
||||
"mov %edi, %eax \n"
|
||||
"cmp $0xb4, %al \n"
|
||||
"jne ok \n"
|
||||
"ud2 \n"
|
||||
"ok: \n"
|
||||
"ret \n");
|
||||
__asm__(
|
||||
".text \n"
|
||||
"some_boring_bug2: \n"
|
||||
".global some_boring_bug2 \n"
|
||||
".type some_boring_bug2, @function \n"
|
||||
"mov %edi, %eax \n"
|
||||
"cmp $0xb4, %al \n"
|
||||
"jne ok \n"
|
||||
"ud2 \n"
|
||||
"ok: \n"
|
||||
"ret \n");
|
||||
|
||||
void LLVMFuzzerTestOneInput(char *buf, int len) {
|
||||
|
||||
@ -127,16 +133,20 @@ void LLVMFuzzerTestOneInput(char *buf, int len) {
|
||||
some_boring_bug2(buf[0]);
|
||||
|
||||
if (buf[0] == '0') {
|
||||
|
||||
printf("Looks like a zero to me!\n");
|
||||
}
|
||||
else if (buf[0] == '1') {
|
||||
|
||||
} else if (buf[0] == '1') {
|
||||
|
||||
printf("Pretty sure that is a one!\n");
|
||||
}
|
||||
else if (buf[0] == '2') {
|
||||
|
||||
} else if (buf[0] == '2') {
|
||||
|
||||
printf("Oh we, weren't expecting that!");
|
||||
__builtin_trap();
|
||||
}
|
||||
else
|
||||
|
||||
} else
|
||||
|
||||
printf("Neither one or zero? How quaint!\n");
|
||||
|
||||
}
|
||||
@ -145,7 +155,7 @@ int main(int argc, char **argv) {
|
||||
|
||||
int fd = -1;
|
||||
off_t len;
|
||||
char * buf = NULL;
|
||||
char *buf = NULL;
|
||||
size_t n_read;
|
||||
int result = -1;
|
||||
|
||||
@ -173,5 +183,6 @@ int main(int argc, char **argv) {
|
||||
printf("Done: %s: (%zd bytes)\n", argv[1], n_read);
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
|
@ -4,66 +4,68 @@
|
||||
#include <stdlib.h>
|
||||
#include <dlfcn.h>
|
||||
|
||||
|
||||
//typedef for our exported target function.
|
||||
// typedef for our exported target function.
|
||||
typedef void (*CRASHME)(const uint8_t *Data, size_t Size);
|
||||
|
||||
//globals
|
||||
// globals
|
||||
CRASHME fpn_crashme = NULL;
|
||||
|
||||
int LLVMFuzzerTestOneInput(const unsigned char *data, size_t size) {
|
||||
|
||||
fpn_crashme(data, size);
|
||||
return 0;
|
||||
|
||||
int LLVMFuzzerTestOneInput(const unsigned char* data, size_t size){
|
||||
fpn_crashme(data, size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, const char * argv[])
|
||||
{
|
||||
int main(int argc, const char *argv[]) {
|
||||
|
||||
for (int i = 1; i < argc; i++) {
|
||||
fprintf(stderr, "Running: %s\n", argv[i]);
|
||||
FILE *f = fopen(argv[i], "r");
|
||||
assert(f);
|
||||
fseek(f, 0, SEEK_END);
|
||||
size_t len = ftell(f);
|
||||
fseek(f, 0, SEEK_SET);
|
||||
unsigned char *buf = (unsigned char*)malloc(len);
|
||||
size_t n_read = fread(buf, 1, len, f);
|
||||
fclose(f);
|
||||
assert(n_read == len);
|
||||
LLVMFuzzerTestOneInput(buf, len);
|
||||
free(buf);
|
||||
fprintf(stderr, "Done: %s: (%zd bytes)\n", argv[i], n_read);
|
||||
}
|
||||
for (int i = 1; i < argc; i++) {
|
||||
|
||||
fprintf(stderr, "Running: %s\n", argv[i]);
|
||||
FILE *f = fopen(argv[i], "r");
|
||||
assert(f);
|
||||
fseek(f, 0, SEEK_END);
|
||||
size_t len = ftell(f);
|
||||
fseek(f, 0, SEEK_SET);
|
||||
unsigned char *buf = (unsigned char *)malloc(len);
|
||||
size_t n_read = fread(buf, 1, len, f);
|
||||
fclose(f);
|
||||
assert(n_read == len);
|
||||
LLVMFuzzerTestOneInput(buf, len);
|
||||
free(buf);
|
||||
fprintf(stderr, "Done: %s: (%zd bytes)\n", argv[i], n_read);
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
__attribute__((constructor()))
|
||||
void constructor(void) {
|
||||
// handles to required libs
|
||||
void *dylib = NULL;
|
||||
__attribute__((constructor())) void constructor(void) {
|
||||
|
||||
dylib = dlopen("./libcrashme.dylib", RTLD_NOW);
|
||||
if (dylib == NULL)
|
||||
{
|
||||
// handles to required libs
|
||||
void *dylib = NULL;
|
||||
|
||||
printf("[-] Failed to load lib\n");
|
||||
printf("[-] Dlerror: %s\n", dlerror());
|
||||
exit(1);
|
||||
dylib = dlopen("./libcrashme.dylib", RTLD_NOW);
|
||||
if (dylib == NULL) {
|
||||
|
||||
}
|
||||
printf("[-] Failed to load lib\n");
|
||||
printf("[-] Dlerror: %s\n", dlerror());
|
||||
exit(1);
|
||||
|
||||
printf("[+] Resolve function\n");
|
||||
}
|
||||
|
||||
fpn_crashme = (CRASHME)dlsym(dylib, "crashme");
|
||||
if (!fpn_crashme)
|
||||
{
|
||||
printf("[+] Resolve function\n");
|
||||
|
||||
printf("[-] Failed to find function\n");
|
||||
exit(1);
|
||||
fpn_crashme = (CRASHME)dlsym(dylib, "crashme");
|
||||
if (!fpn_crashme) {
|
||||
|
||||
}
|
||||
printf("[-] Failed to find function\n");
|
||||
exit(1);
|
||||
|
||||
}
|
||||
|
||||
printf("[+] Found function.\n");
|
||||
|
||||
printf("[+] Found function.\n");
|
||||
}
|
||||
|
||||
|
@ -4,66 +4,68 @@
|
||||
#include <stdlib.h>
|
||||
#include <dlfcn.h>
|
||||
|
||||
|
||||
//typedef for our exported target function.
|
||||
// typedef for our exported target function.
|
||||
typedef void (*CRASHME)(const uint8_t *Data, size_t Size);
|
||||
|
||||
//globals
|
||||
// globals
|
||||
CRASHME fpn_crashme = NULL;
|
||||
|
||||
int LLVMFuzzerTestOneInput(const unsigned char *data, size_t size) {
|
||||
|
||||
fpn_crashme(data, size);
|
||||
return 0;
|
||||
|
||||
int LLVMFuzzerTestOneInput(const unsigned char* data, size_t size){
|
||||
fpn_crashme(data, size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, const char * argv[])
|
||||
{
|
||||
int main(int argc, const char *argv[]) {
|
||||
|
||||
for (int i = 1; i < argc; i++) {
|
||||
fprintf(stderr, "Running: %s\n", argv[i]);
|
||||
FILE *f = fopen(argv[i], "r");
|
||||
assert(f);
|
||||
fseek(f, 0, SEEK_END);
|
||||
size_t len = ftell(f);
|
||||
fseek(f, 0, SEEK_SET);
|
||||
unsigned char *buf = (unsigned char*)malloc(len);
|
||||
size_t n_read = fread(buf, 1, len, f);
|
||||
fclose(f);
|
||||
assert(n_read == len);
|
||||
LLVMFuzzerTestOneInput(buf, len);
|
||||
free(buf);
|
||||
fprintf(stderr, "Done: %s: (%zd bytes)\n", argv[i], n_read);
|
||||
}
|
||||
for (int i = 1; i < argc; i++) {
|
||||
|
||||
fprintf(stderr, "Running: %s\n", argv[i]);
|
||||
FILE *f = fopen(argv[i], "r");
|
||||
assert(f);
|
||||
fseek(f, 0, SEEK_END);
|
||||
size_t len = ftell(f);
|
||||
fseek(f, 0, SEEK_SET);
|
||||
unsigned char *buf = (unsigned char *)malloc(len);
|
||||
size_t n_read = fread(buf, 1, len, f);
|
||||
fclose(f);
|
||||
assert(n_read == len);
|
||||
LLVMFuzzerTestOneInput(buf, len);
|
||||
free(buf);
|
||||
fprintf(stderr, "Done: %s: (%zd bytes)\n", argv[i], n_read);
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
__attribute__((constructor()))
|
||||
void constructor(void) {
|
||||
// handles to required libs
|
||||
void *dylib = NULL;
|
||||
__attribute__((constructor())) void constructor(void) {
|
||||
|
||||
dylib = dlopen("./libcrashme2.dylib", RTLD_NOW);
|
||||
if (dylib == NULL)
|
||||
{
|
||||
// handles to required libs
|
||||
void *dylib = NULL;
|
||||
|
||||
printf("[-] Failed to load lib\n");
|
||||
printf("[-] Dlerror: %s\n", dlerror());
|
||||
exit(1);
|
||||
dylib = dlopen("./libcrashme2.dylib", RTLD_NOW);
|
||||
if (dylib == NULL) {
|
||||
|
||||
}
|
||||
printf("[-] Failed to load lib\n");
|
||||
printf("[-] Dlerror: %s\n", dlerror());
|
||||
exit(1);
|
||||
|
||||
printf("[+] Resolve function\n");
|
||||
}
|
||||
|
||||
fpn_crashme = (CRASHME)dlsym(dylib, "crashme");
|
||||
if (!fpn_crashme)
|
||||
{
|
||||
printf("[+] Resolve function\n");
|
||||
|
||||
printf("[-] Failed to find function\n");
|
||||
exit(1);
|
||||
fpn_crashme = (CRASHME)dlsym(dylib, "crashme");
|
||||
if (!fpn_crashme) {
|
||||
|
||||
}
|
||||
printf("[-] Failed to find function\n");
|
||||
exit(1);
|
||||
|
||||
}
|
||||
|
||||
printf("[+] Found function.\n");
|
||||
|
||||
printf("[+] Found function.\n");
|
||||
}
|
||||
|
||||
|
@ -4,37 +4,42 @@
|
||||
#include <stdlib.h>
|
||||
#include <dlfcn.h>
|
||||
|
||||
|
||||
extern void crashme(const uint8_t *Data, size_t Size);
|
||||
|
||||
int LLVMFuzzerTestOneInput(const unsigned char* data, size_t size){
|
||||
crashme(data, size);
|
||||
return 0;
|
||||
int LLVMFuzzerTestOneInput(const unsigned char *data, size_t size) {
|
||||
|
||||
crashme(data, size);
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
void run (int argc, const char * argv[])
|
||||
{
|
||||
for (int i = 1; i < argc; i++) {
|
||||
fprintf(stderr, "Running: %s\n", argv[i]);
|
||||
FILE *f = fopen(argv[i], "r");
|
||||
assert(f);
|
||||
fseek(f, 0, SEEK_END);
|
||||
size_t len = ftell(f);
|
||||
fseek(f, 0, SEEK_SET);
|
||||
unsigned char *buf = (unsigned char*)malloc(len);
|
||||
size_t n_read = fread(buf, 1, len, f);
|
||||
fclose(f);
|
||||
assert(n_read == len);
|
||||
LLVMFuzzerTestOneInput(buf, len);
|
||||
free(buf);
|
||||
fprintf(stderr, "Done: %s: (%zd bytes)\n", argv[i], n_read);
|
||||
}
|
||||
void run(int argc, const char *argv[]) {
|
||||
|
||||
for (int i = 1; i < argc; i++) {
|
||||
|
||||
fprintf(stderr, "Running: %s\n", argv[i]);
|
||||
FILE *f = fopen(argv[i], "r");
|
||||
assert(f);
|
||||
fseek(f, 0, SEEK_END);
|
||||
size_t len = ftell(f);
|
||||
fseek(f, 0, SEEK_SET);
|
||||
unsigned char *buf = (unsigned char *)malloc(len);
|
||||
size_t n_read = fread(buf, 1, len, f);
|
||||
fclose(f);
|
||||
assert(n_read == len);
|
||||
LLVMFuzzerTestOneInput(buf, len);
|
||||
free(buf);
|
||||
fprintf(stderr, "Done: %s: (%zd bytes)\n", argv[i], n_read);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int main(int argc, const char * argv[])
|
||||
{
|
||||
int main(int argc, const char *argv[]) {
|
||||
|
||||
run(argc, argv);
|
||||
run(argc, argv);
|
||||
|
||||
return 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,6 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
void __attribute__((noinline)) crashme(const uint8_t *Data, size_t Size) {
|
||||
|
||||
if (Size < 5) return;
|
||||
@ -13,5 +12,5 @@ void __attribute__((noinline)) crashme(const uint8_t *Data, size_t Size) {
|
||||
if (Data[3] == '$')
|
||||
if (Data[4] == '$') abort();
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
@ -3,7 +3,6 @@
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
void __attribute__((noinline)) crashme(const uint8_t *Data, size_t Size) {
|
||||
|
||||
if (Size < 1) return;
|
||||
@ -56,6 +55,5 @@ void __attribute__((noinline)) crashme(const uint8_t *Data, size_t Size) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
--------------------------------------------------------
|
||||
Originally written by Michal Zalewski
|
||||
Copyright 2014 Google Inc. All rights reserved.
|
||||
Copyright 2019-2023 AFLplusplus Project. All rights reserved.
|
||||
Copyright 2019-2024 AFLplusplus Project. All rights reserved.
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at:
|
||||
@ -39,10 +39,10 @@ void testinstr(char *buf, int len) {
|
||||
|
||||
TESTINSTR_SECTION int main(int argc, char **argv) {
|
||||
|
||||
char * file;
|
||||
char *file;
|
||||
int fd = -1;
|
||||
off_t len;
|
||||
char * buf = NULL;
|
||||
char *buf = NULL;
|
||||
size_t n_read;
|
||||
int result = -1;
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
--------------------------------------------------------
|
||||
Originally written by Michal Zalewski
|
||||
Copyright 2014 Google Inc. All rights reserved.
|
||||
Copyright 2019-2023 AFLplusplus Project. All rights reserved.
|
||||
Copyright 2019-2024 AFLplusplus Project. All rights reserved.
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at:
|
||||
@ -20,22 +20,32 @@ void LLVMFuzzerTestOneInput(char *buf, int len) {
|
||||
|
||||
int ret = 0;
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
switch(buf[i]) {
|
||||
case 'A': ret += 2; break;
|
||||
case '1': ret += 3; break;
|
||||
default: ret++;
|
||||
|
||||
switch (buf[i]) {
|
||||
|
||||
case 'A':
|
||||
ret += 2;
|
||||
break;
|
||||
case '1':
|
||||
ret += 3;
|
||||
break;
|
||||
default:
|
||||
ret++;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
printf("ret: %d\n", ret);
|
||||
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
|
||||
char * file;
|
||||
char *file;
|
||||
int fd = -1;
|
||||
off_t len;
|
||||
char * buf = NULL;
|
||||
char *buf = NULL;
|
||||
size_t n_read;
|
||||
int result = -1;
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
--------------------------------------------------------
|
||||
Originally written by Michal Zalewski
|
||||
Copyright 2014 Google Inc. All rights reserved.
|
||||
Copyright 2019-2023 AFLplusplus Project. All rights reserved.
|
||||
Copyright 2019-2024 AFLplusplus Project. All rights reserved.
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at:
|
||||
@ -18,7 +18,7 @@
|
||||
|
||||
void LLVMFuzzerTestOneInput(char *buf, int len) {
|
||||
|
||||
printf (">>> LLVMFuzzerTestOneInput >>>\n");
|
||||
printf(">>> LLVMFuzzerTestOneInput >>>\n");
|
||||
if (len < 1) return;
|
||||
buf[len] = 0;
|
||||
|
||||
@ -40,10 +40,10 @@ void slow() {
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
|
||||
char * file;
|
||||
char *file;
|
||||
int fd = -1;
|
||||
off_t len;
|
||||
char * buf = NULL;
|
||||
char *buf = NULL;
|
||||
size_t n_read;
|
||||
int result = -1;
|
||||
|
||||
|
@ -48,7 +48,7 @@ all: $(TEST_BIN)
|
||||
CFLAGS="-m32" LDFLAGS="-m32" make $(TEST_BIN)
|
||||
|
||||
arm:
|
||||
CFLAGS="-marm" LDFLAGS="-marm" CC="arm-linux-gnueabihf-gcc" CXX="arm-linux-gnueabihf-g++" make $(TEST_BIN)
|
||||
CFLAGS="-marm" LDFLAGS="-marm" CC="arm-linux-gnueabihf-gcc" CXX="arm-linux-gnueabihf-g++" PNG_ARCH="arm" make $(TEST_BIN)
|
||||
|
||||
$(BUILD_DIR):
|
||||
mkdir -p $@
|
||||
@ -93,8 +93,7 @@ $(LIBZ_PC): | $(LIBZ_DIR)
|
||||
cd $(LIBZ_DIR) && \
|
||||
CFLAGS="$(CFLAGS) -fPIC" \
|
||||
./configure \
|
||||
--static \
|
||||
--archs="$(ARCH)"
|
||||
--static
|
||||
|
||||
$(LIBZ_LIB): | $(LIBZ_PC)
|
||||
CFLAGS="$(CFLAGS) -fPIC" \
|
||||
@ -120,7 +119,7 @@ $(LIBPNG_MAKEFILE): $(LIBZ_LIB) | $(LIBPNG_DIR)
|
||||
CFLAGS="$(CFLAGS) -I$(LIBZ_DIR)" \
|
||||
LDFLAGS="-L$(LIBZ_DIR)" \
|
||||
./configure \
|
||||
--host="$(ARCH)"
|
||||
--host="$(PNG_ARCH)"
|
||||
|
||||
$(LIBPNG_LIB): $(LIBPNG_MAKEFILE)
|
||||
CFLAGS="$(CFLAGS) -I$(LIBZ_DIR)" \
|
||||
|
@ -3,7 +3,7 @@
|
||||
--------------------------------------------------------
|
||||
Originally written by Michal Zalewski
|
||||
Copyright 2014 Google Inc. All rights reserved.
|
||||
Copyright 2019-2023 AFLplusplus Project. All rights reserved.
|
||||
Copyright 2019-2024 AFLplusplus Project. All rights reserved.
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at:
|
||||
@ -39,10 +39,10 @@ void testinstr(char *buf, int len) {
|
||||
|
||||
TESTINSTR_SECTION int main(int argc, char **argv) {
|
||||
|
||||
char * file;
|
||||
char *file;
|
||||
int fd = -1;
|
||||
off_t len;
|
||||
char * buf = NULL;
|
||||
char *buf = NULL;
|
||||
size_t n_read;
|
||||
int result = -1;
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
--------------------------------------------------------
|
||||
Originally written by Michal Zalewski
|
||||
Copyright 2014 Google Inc. All rights reserved.
|
||||
Copyright 2019-2023 AFLplusplus Project. All rights reserved.
|
||||
Copyright 2019-2024 AFLplusplus Project. All rights reserved.
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at:
|
||||
@ -22,7 +22,7 @@
|
||||
#define TESTINSTR_SECTION __attribute__((section(".testinstr")))
|
||||
#endif
|
||||
|
||||
void LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
|
||||
void LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
|
||||
|
||||
if (size < 1) return;
|
||||
|
||||
@ -30,9 +30,13 @@ void LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
|
||||
if (gettimeofday(&tv, NULL) < 0) return;
|
||||
|
||||
if ((tv.tv_usec % 2) == 0) {
|
||||
printf ("Hooray all even\n");
|
||||
|
||||
printf("Hooray all even\n");
|
||||
|
||||
} else {
|
||||
printf ("Hmm that's odd\n");
|
||||
|
||||
printf("Hmm that's odd\n");
|
||||
|
||||
}
|
||||
|
||||
// we support three input cases
|
||||
@ -45,26 +49,33 @@ void LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
|
||||
|
||||
}
|
||||
|
||||
void run_test(char * file) {
|
||||
void run_test(char *file) {
|
||||
|
||||
fprintf(stderr, "Running: %s\n", file);
|
||||
FILE *f = fopen(file, "r");
|
||||
assert(f);
|
||||
fseek(f, 0, SEEK_END);
|
||||
size_t len = ftell(f);
|
||||
fseek(f, 0, SEEK_SET);
|
||||
unsigned char *buf = (unsigned char*)malloc(len);
|
||||
size_t n_read = fread(buf, 1, len, f);
|
||||
unsigned char *buf = (unsigned char *)malloc(len);
|
||||
size_t n_read = fread(buf, 1, len, f);
|
||||
fclose(f);
|
||||
assert(n_read == len);
|
||||
LLVMFuzzerTestOneInput(buf, len);
|
||||
free(buf);
|
||||
fprintf(stderr, "Done: %s: (%zd bytes)\n", file, n_read);
|
||||
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
|
||||
srand(1);
|
||||
fprintf(stderr, "StandaloneFuzzTargetMain: running %d inputs\n", argc - 1);
|
||||
for (int i = 1; i < argc; i++) {
|
||||
|
||||
run_test(argv[i]);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
test -n "$1" && { echo This script has no options. It updates the referenced Frida version in GNUmakefile to the most current one. ; exit 1 ; }
|
||||
|
||||
OLD=$(grep -E '^GUM_DEVKIT_VERSION=' GNUmakefile 2>/dev/null|awk -F= '{print$2}')
|
||||
NEW=$(curl https://github.com/frida/frida/releases/ 2>/dev/null|grep -E 'frida-gum-devkit-[0-9.]*-linux-x86_64'|head -n 1|sed 's/.*frida-gum-devkit-//'|sed 's/-linux.*//')
|
||||
NEW=$(curl https://github.com/frida/frida/releases/ 2>/dev/null|grep 'Frida\ [0-9.]*'|head -n 1|sed 's/.*Frida\ //'| sed 's/<\/h2>//')
|
||||
|
||||
echo Current set version: $OLD
|
||||
echo Newest available version: $NEW
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user