Compare commits

...

258 Commits
win ... 4.00c

Author SHA1 Message Date
143c9d175e Merge pull request #1301 from AFLplusplus/dev
v4.00c release
2022-01-26 11:00:55 +01:00
b0758ac8db 4.00c readiness 2022-01-26 09:55:12 +01:00
77c06408c3 resized logo 2022-01-26 09:26:03 +01:00
6bf52c1434 svg logo 2022-01-26 09:24:37 +01:00
eebc2f4f1e adapt test harness to unicornafl for uc2 2022-01-26 01:33:58 +01:00
016bdc36bb code-format 2022-01-25 19:54:46 +01:00
ed72b9ec1d Merge pull request #1308 from schumilo/dev
add autodict capability to Nyx mode
2022-01-25 19:51:05 +01:00
615a8ff986 close autodict file even if fstat fails (Nyx mode) 2022-01-25 19:33:47 +01:00
026096ccf3 add AFL autodict capability to Nyx mode 2022-01-25 19:13:26 +01:00
87f2789e98 fix unicorn python test path 2022-01-25 18:05:35 +01:00
d9ed784298 ensure all fuzz targets are killed on exit 2022-01-25 14:51:02 +01:00
0fd6315dfb nit 2022-01-25 13:32:45 +01:00
28a1765781 fix atexit for rt 2022-01-25 12:41:22 +01:00
0b5ad8ee84 nits 2022-01-25 09:44:12 +01:00
3a78db2ade update sub gits 2022-01-25 09:11:06 +01:00
605b0e6465 fix libqasan repeated line 2022-01-24 18:35:16 +01:00
7270cbe756 try fix 2022-01-24 10:32:07 +01:00
a790bf6cc2 fix citation 2022-01-23 19:32:38 +01:00
86983f4060 fix citation 2022-01-23 19:31:33 +01:00
319c7457ff fix citation 2022-01-23 19:31:04 +01:00
e9be58b69c add citation 2022-01-23 19:28:48 +01:00
61d79f85c5 code format 2022-01-23 19:20:32 +01:00
9baa402344 update refs 2022-01-23 18:39:55 +01:00
04e3b5a6d3 update commit ids 2022-01-23 18:38:04 +01:00
227b42b1d0 unicorn fixes 2022-01-22 19:44:07 +01:00
ac169c3087 fix makefiles for uc2 c examples 2022-01-22 17:22:00 +01:00
3609912f41 new logo 2022-01-22 10:31:50 +01:00
6d2b8e3ed2 Merge pull request #1303 from schumilo/dev
update Nyx mode submodules
2022-01-22 00:35:07 +01:00
06ee6b1986 update Nyx custom harness:
use a coverage bitmap that is smaller than 64k
2022-01-21 21:07:28 +01:00
0090b3a3f0 update Nyx submodules 2022-01-21 21:03:07 +01:00
452a4cf5be Merge pull request #1302 from llzmb/docs_quality_assurance_4
Docs content - quality assurance - Unicorn mode
2022-01-21 16:33:02 +01:00
f63d2b0f55 Fix typo, add link 2022-01-21 16:27:17 +01:00
29235a7935 Fix punctuation, formatting, and line length 2022-01-21 16:18:25 +01:00
ac0e855907 Merge pull request #1259 from dmell/unicorn_docs
Adjustments to unicorn docs and speedtest sample
2022-01-21 14:09:23 +01:00
f7a5ea667b update changelog 2022-01-21 13:23:11 +01:00
fce512db40 update grammar mutator 2022-01-21 13:20:16 +01:00
b427a53a6b Merge pull request #1299 from llzmb/docs_quality_assurance_3
Docs content - quality assurance - 3rd run
2022-01-21 13:08:20 +01:00
2bb86863e6 Merge branch 'dev' into docs_quality_assurance_3 2022-01-21 13:06:15 +01:00
26a3d1b53b add nyx_mode to make clean target 2022-01-21 10:36:41 +01:00
2a0f082723 code-format 2022-01-21 10:14:20 +01:00
22da04f077 fix 2022-01-21 10:13:37 +01:00
5933e787f9 Merge pull request #1300 from schumilo/dev
add Nyx LTO support (and some other improvements)
2022-01-21 08:51:29 +01:00
6ce736aa91 use MAX_FILE as maximum size in Nyx mode 2022-01-21 08:13:33 +01:00
830dcacc07 update nyx custom_harness example 2022-01-21 08:06:31 +01:00
74d9da7203 update nyx_mode README 2022-01-21 08:05:30 +01:00
9d3e6a869e add LTO support in nyx_mode 2022-01-21 07:33:42 +01:00
1a15e98fff fix typo (QEMU_NXY_VERSION -> QEMU_NYX_VERSION) 2022-01-21 07:33:42 +01:00
a594182314 update nyx_mode build script 2022-01-21 07:33:42 +01:00
9d87f408dd update nyx_mode git submodules 2022-01-21 07:33:13 +01:00
b4c2fc9416 Fix formatting and line length 2022-01-20 21:40:28 +01:00
ecf8db0014 Fix punctuation 2022-01-20 21:26:13 +01:00
ec7b14a3d6 Fix line length 2022-01-20 21:25:06 +01:00
c74686e20d Fix structure 2022-01-20 21:23:28 +01:00
4902bb91d2 Fix links and spelling of Redqueen 2022-01-20 20:59:36 +01:00
237a475d9b Fix structure and formatting 2022-01-20 20:54:38 +01:00
686a595df3 Fix typo 2022-01-20 20:48:09 +01:00
1529bd070e Fix punctuation, formatting, and line length 2022-01-20 20:41:49 +01:00
29f8040f09 Fix formatting and line length 2022-01-20 20:35:19 +01:00
029bfc386f Fix formatting 2022-01-20 20:33:23 +01:00
88905c65af Add missing tags, fix punctuation 2022-01-20 20:27:02 +01:00
492418ebd6 Fix punctuation and line length 2022-01-20 20:22:00 +01:00
a9d549ca07 Raw read syscall in aflpp_driver.c to bypass ASan checks 2022-01-20 17:41:38 +01:00
4721d869ad Poison with ASan the remaining unused input buffer in aflpp_driver.c 2022-01-20 17:33:17 +01:00
7aced239e8 Merge pull request #1294 from AFLplusplus/dev
Push to stable
2022-01-20 16:17:08 +01:00
d1de12d617 updated uc ref 2022-01-20 16:14:58 +01:00
5deae7924f insert android.bp outdated statement 2022-01-20 12:06:15 +01:00
1d9d5936d9 Merge remote-tracking branch 'origin/dev' into dev 2022-01-19 23:03:19 +01:00
7afad147d1 update uc2 ref 2022-01-19 22:59:36 +01:00
550ba4d772 nits and code format 2022-01-19 22:26:52 +01:00
25c8336c0c tidy up unicornafl, changelog 2022-01-19 22:23:25 +01:00
4bcb177f62 Revert "fix classify counts"
This reverts commit 4217a6606c.
2022-01-19 22:17:36 +01:00
409a6517c1 update changelog 2022-01-19 22:12:14 +01:00
d9fefafae7 move to unicorn2 2022-01-19 22:10:29 +01:00
16bd6aad7c Merge pull request #1298 from WorksButNotTested/mapsize
Changes to support variations in the mapsize
2022-01-19 21:55:30 +01:00
5b06078a41 Changes to support variations in the mapsize 2022-01-19 18:22:27 +00:00
a3cf7c1224 change video order 2022-01-19 15:22:03 +01:00
6de9b37b2a Merge pull request #1296 from hardik05/patch-1
Update tutorials.md
2022-01-19 15:20:10 +01:00
1e5699ccaa Update tutorials.md 2022-01-19 19:36:29 +05:30
bdec40ae5d Merge pull request #1295 from devnexen/afl_untracer_disable_aslr_fbsd
afl-untracer, disable ASLR on FreeBSD.
2022-01-18 21:16:25 +01:00
56ce081ac7 afl-untracer, disable ASLR on FreeBSD. 2022-01-18 18:53:18 +00:00
861bd5e04b update macos path info 2022-01-17 20:31:08 +01:00
c5117b42ca fix iselect instrumentation 2022-01-17 20:15:27 +01:00
0e2c832499 fix laf transform for strcmp like functions 2022-01-17 19:35:49 +01:00
34caf7d781 Cleaned unicorn speedtest sample README 2022-01-17 17:38:46 +01:00
c8061e5b35 fix nyx -M 2022-01-17 17:16:58 +01:00
a45cdb240c fixup! Fixed Rust harness name to be consistent with the others 2022-01-17 14:32:06 +01:00
2b82492457 Merge pull request #1260 from 0xsan-z/Welcome2022
more welcome 2022
2022-01-16 16:43:40 +01:00
d51ec57d91 more welcome 2022 2022-01-15 15:19:29 -05:00
751e09f47b Fixed Rust harness name to be consistent with the others 2022-01-15 20:02:57 +01:00
c1415b816a Adjustments to unicorn docs and speedtest sample 2022-01-15 19:28:18 +01:00
4217a6606c fix classify counts 2022-01-15 13:58:17 +01:00
20177151e6 add email 2022-01-14 15:56:51 +01:00
9a4552d6c4 Merge pull request #1258 from llzmb/docs_edit_images_2
Edit images
2022-01-14 15:54:41 +01:00
8c58bdb504 Add margin to images 2022-01-14 15:17:25 +01:00
f42c0047c8 nits 2022-01-14 15:01:14 +01:00
1ca3317425 Add link to image 2022-01-14 11:22:16 +01:00
630ba07054 Merge pull request #1251 from pwnforce/patch-2
Update fuzzing_binary-only_targets.md
2022-01-13 16:40:22 +01:00
27ab84fbf1 fix skipping unfavored fuzzed entries 2022-01-13 16:38:18 +01:00
4c07e37eae Update fuzzing_binary-only_targets.md 2022-01-13 14:48:05 +01:00
8f7e584b82 more faq 2022-01-13 12:29:49 +01:00
f6c08c3a1c Merge pull request #1256 from dmell/lpm_patches
Lpm patches
2022-01-13 10:34:24 +01:00
9e38c43686 update changelog 2022-01-13 10:32:47 +01:00
c8e6a59e7d Removed unused byte in allocation 2022-01-13 10:12:23 +01:00
bedd812e7b Fixed wrong delete operator and added mutator's destructor 2022-01-13 10:11:43 +01:00
110cc27632 fix laf-intel split switches 2022-01-13 10:09:35 +01:00
21ebfec79c better ignore problem handling 2022-01-12 21:59:38 +01:00
8701cdcc2c Merge pull request #1255 from llzmb/docs_edit_images
Edit SVG files
2022-01-12 21:32:35 +01:00
e7ddd15fa5 Incorporate feedback 2022-01-12 20:46:37 +01:00
5e47829462 Add white background to SVG files 2022-01-12 20:27:09 +01:00
e663897a8a fix 2022-01-12 11:27:19 +01:00
b7ddde636b svg test 2022-01-12 10:42:40 +01:00
8764375357 test svg background 2022-01-12 10:36:22 +01:00
657c1e9b9b Merge pull request #1252 from tokatoka/dev
Add missing backticks (`)
2022-01-11 21:46:04 +01:00
0ed1cb4d31 change 2022-01-12 04:42:47 +09:00
741dcabd5d Merge pull request #1248 from intrigus-lgtm/patch-2
Fix two typos.
2022-01-11 19:35:04 +01:00
2342c85db4 Update fuzzing_binary-only_targets.md 2022-01-11 18:08:52 +01:00
091fa09e5e Update fuzzing_binary-only_targets.md
Fixing some parts in the description of Retrowrite.
2022-01-11 17:42:38 +01:00
d8920e31f8 Add a comma to make sentence easier to understand. 2022-01-11 17:13:25 +01:00
6a7f184c4e Fix broken code formatting 2022-01-11 17:00:26 +01:00
30666cb81e Highlight what a basic block is.
Highlight the different parts that characterize what
a basic block is. This makes it slightly easier to
read/understand IMHO.
2022-01-11 16:59:37 +01:00
9242e0db8a Merge pull request #1249 from AFLplusplus/dev
update nyx in stable
2022-01-11 16:36:42 +01:00
add85f34d1 Format some terms as code. 2022-01-11 15:26:30 +01:00
c7dbeb8568 update nyx 2022-01-11 15:21:07 +01:00
179b118bc9 Fix some typos and wrong words. 2022-01-11 15:13:04 +01:00
7884e0f449 Fix two typos. 2022-01-11 15:06:14 +01:00
10dae419d6 Merge pull request #1236 from AFLplusplus/dev
push to stable
2022-01-11 12:20:35 +01:00
d2715336a5 link docs/README.md 2022-01-11 12:03:21 +01:00
41b07983f1 add feature list 2022-01-11 11:59:12 +01:00
ef77d552e9 add new tutorial 2022-01-10 11:12:19 +01:00
85f3ebc714 Merge pull request #1243 from yuawn/dev
more welcome 2022
2022-01-07 10:38:00 +01:00
b7d741b18e more welcome 2022 2022-01-07 09:18:51 +00:00
da5ff0df0a Merge pull request #1242 from yuawn/dev
rename
2022-01-07 10:03:03 +01:00
7ae90a66c4 rename 2022-01-07 08:49:56 +00:00
ee295801a6 Merge pull request #1240 from adrianherrera/bugfix/optimin-showmap
optimin: -A -> -H
2022-01-04 12:21:12 +01:00
03ba344e6d optimin: -A -> -H
Inline with afl-showmap change
2022-01-04 15:18:31 +11:00
cc94e37ae1 doc nits 2022-01-03 23:26:23 +01:00
8c1015ac39 Proofreading 2022-01-03 22:50:08 +01:00
dc7b607080 doc nits 2022-01-03 20:47:52 +01:00
511ffc06d2 typo fixed 2022-01-03 20:42:34 +01:00
3b96c8ae13 doc nits 2022-01-03 17:02:38 +01:00
226450600c Merge pull request #1239 from MegaManSec/dev
Fix typo.
2022-01-03 17:02:08 +01:00
845c32b5fb Fix typo. 2022-01-03 16:47:33 +01:00
ee57053be1 add missing gcc env vars 2022-01-03 11:18:10 +01:00
a010d356de wording 2022-01-03 10:02:27 +01:00
3b3ba08daa did some proofreading 2022-01-03 09:37:33 +01:00
72cebac42e fix wrong replacements 2022-01-03 09:14:43 +01:00
e1082f2548 welcome 2022 2022-01-01 00:49:17 +01:00
128413690e nyx references 2022-01-01 00:38:54 +01:00
b6b81a687d update qemuafl 2021-12-31 17:06:16 +01:00
b8e61da8ab Merge pull request #1238 from AFLplusplus/more_havoc
more havoc
2021-12-31 17:04:01 +01:00
cda84594cc Merge pull request #1237 from MegaManSec/dev
Fix LeakSanitizer Usage.
2021-12-30 10:38:10 +01:00
fd9f61a8c5 fix map size for nyx 2021-12-30 10:37:16 +01:00
8b75680c7a Fix type. 2021-12-30 03:09:04 +01:00
09c4d9ed75 Fix LeakSanitizer Usage.
Previously, __lsan_do_leak_check() was run when using __AFL_LEAK_CHECK,
however this was the incorrect function to use. According to the
documentation: "Subsequent calls to this function will have no effect
and end-of-process leak check will not run".
This meant that if the memory did not leak on the first usage of
__AFL_LEAK_CHECK, subsquent calls to this macro would never do anything.

Likewise, it is not possible to use an LSAN suppression list with
symbolize=0, so instead __lsan_disable and __lsan_enable are used to
'ignore' certain memory allocations where needed.
2021-12-30 02:54:40 +01:00
02082bcd2e afl-cc lto fix 2021-12-29 18:24:47 +01:00
fa6a0aba61 typo 2021-12-29 12:54:24 +01:00
dbc62dbe56 sprinkle nyx links in the docs 2021-12-29 11:55:16 +01:00
1a25ccb618 readme for nyx 2021-12-29 11:43:21 +01:00
0792cab566 add power schedule info 2021-12-29 10:57:37 +01:00
b5cb99f6fe fix nyx lib loading 2021-12-28 20:30:52 +01:00
0a18bf8db5 add readme (needs more though) 2021-12-28 18:01:52 +01:00
48ad95f0e5 nit 2021-12-28 17:42:45 +01:00
fd99ddb1d6 nyx build and install 2021-12-28 17:40:23 +01:00
7e8a491500 exec perm 2021-12-28 17:27:37 +01:00
8b8aaa93bd nyx code format 2021-12-28 17:26:54 +01:00
f511ebd125 nyx nits 2021-12-28 17:25:46 +01:00
83bf876255 Merge pull request #1233 from nyx-fuzz/dev
add Nyx mode
2021-12-28 17:19:34 +01:00
41291d8c72 add Nyx mode 2021-12-28 15:51:43 +01:00
f9d4dcdd85 Merge pull request #1232 from WorksButNotTested/frida
Removed redundant instruction
2021-12-28 12:07:16 +01:00
jon
8a681bc163 Removed redundant instruction 2021-12-28 10:10:42 +00:00
53fa703755 more havoc 2021-12-27 19:06:06 +01:00
51d6f863f5 fix imports to build on Mac (#1231)
Co-authored-by: Jesse Hertz <>
2021-12-27 18:12:02 +01:00
be00dbc2ac Merge pull request #1230 from WorksButNotTested/frida
Further optimization of AARCH64 code
2021-12-27 15:26:10 +01:00
jon
65ffa4b472 Further optimization of AARCH64 code 2021-12-27 13:07:31 +00:00
7bd2899f2e fix cpu selection 2021-12-27 12:52:16 +01:00
43b162c222 Merge pull request #1228 from WorksButNotTested/frida
Frida
2021-12-27 11:23:24 +01:00
5d9134d6ad Added test for libxslt 2021-12-27 03:46:28 +00:00
jon
6c8a47f7dc Changes to not build addr for OSX 2021-12-27 02:38:38 +00:00
jon
89c4fa3051 Fix broken op-codes for AARCH64 2021-12-27 02:28:52 +00:00
jon
81aae9b54c Changes to explicitly place the previous_pc 2021-12-27 02:28:34 +00:00
54eca027a5 doc review 2021-12-26 03:54:29 +01:00
8fe6282164 force frida test in ci for macos 2021-12-26 03:04:48 +01:00
8588becf47 force frida test in ci for macos 2021-12-26 02:34:34 +01:00
a91d445b5f make tests working on macos 2021-12-26 01:55:52 +01:00
2d9e0f56b0 debug ci 2021-12-26 01:54:19 +01:00
146eb32c31 make tests working on macos 2021-12-26 01:49:31 +01:00
550dc989b3 debug ci 2021-12-26 01:35:10 +01:00
251264fde5 debug ci 2021-12-26 01:29:58 +01:00
649076600d debug ci 2021-12-26 01:24:03 +01:00
8521eb8413 debug ci 2021-12-26 01:15:53 +01:00
699c16c7e0 macos ci 2021-12-26 01:08:45 +01:00
6b50a001b0 macos ci 2021-12-26 01:07:29 +01:00
24dd35ef96 macos ci 2021-12-26 01:05:07 +01:00
8217b5ff81 macos ci 2021-12-26 00:00:49 +01:00
7b3b707ae6 macos ci 2021-12-25 23:59:17 +01:00
60b0c38022 macos ci 2021-12-25 23:53:29 +01:00
17d4ae9a16 macos ci 2021-12-25 23:51:12 +01:00
71621bbc52 macos ci 2021-12-25 23:49:47 +01:00
ddc90e1176 macos ci 2021-12-25 23:47:38 +01:00
47488dcd02 nits 2021-12-25 14:21:59 +01:00
185d7f2ede Merge pull request #1227 from WorksButNotTested/frida
Frida
2021-12-24 12:43:42 +01:00
376d1736a8 Optimize AARCH64 inline assembly 2021-12-23 23:55:07 +00:00
edeaf72ea8 Fix compiler warnings 2021-12-23 22:39:43 +00:00
c76dc73c7a better macos install docs 2021-12-22 01:25:32 +01:00
964819d3fc fix qbdi 2021-12-21 15:06:14 +01:00
68436b277b update grammar mutator 2021-12-21 11:05:05 +01:00
6106efa301 Merge pull request #1223 from WorksButNotTested/frida
Improvements to debug output
2021-12-20 21:30:55 +01:00
d59a76261d Improvements to debug output 2021-12-20 18:14:57 +00:00
db19116ce6 Merge pull request #1221 from WorksButNotTested/frida
Frida
2021-12-17 21:14:34 +01:00
a3421f8099 Added addr for finding default base address 2021-12-17 18:23:49 +00:00
fd1d162149 Fix broken test configuration 2021-12-17 18:23:49 +00:00
5a28157ffd Fix instrumentation debugging (inadvertant CS_MODE_THUMB) 2021-12-17 18:23:49 +00:00
e3106e6f52 Changes to build frida-source without devkit 2021-12-17 18:23:49 +00:00
b3a0ecfd48 allow ignore dlopen issues 2021-12-17 09:42:05 +01:00
641a943d95 more -z defs filtering 2021-12-16 21:31:37 +01:00
74a8f145e0 Merge pull request #1219 from AFLplusplus/dev
push to stable
2021-12-16 12:40:35 +01:00
3cb7319ccd fix for older llvm 2021-12-16 10:41:33 +01:00
5f70bc5404 disable cmplog vector FP cmp hooking 2021-12-16 10:08:31 +01:00
ee10461f48 fix llvm 14 changes for ctx and ngram 2021-12-16 01:44:50 +01:00
9f911bf0bd cleanup of TIMES macro 2021-12-15 20:43:18 +01:00
88814be474 Merge pull request #1218 from CityOfLight77/dev
Add AFLtriage in crash processing tool
2021-12-15 17:14:07 +01:00
a2314fc37f Add AFLtriage in crash processing tool 2021-12-15 20:38:52 +07:00
176ede3fc8 afl-cc -v without errors 2021-12-15 09:50:45 +01:00
d89fa8c7ad Merge pull request #1217 from CityOfLight77/dev
Fix typo
2021-12-15 09:32:08 +01:00
63087d9bd9 Fix env var typo
`AFL_MAX_EXRAS` -> `AFL_MAX_EXTRAS`
2021-12-15 09:24:28 +07:00
fad8a3feb8 Fix CodeQL command typo
fix command to create CodeQL database and use all cores to compile CodeQL database
2021-12-15 09:22:17 +07:00
02fba1cc7e Merge pull request #1215 from AFLplusplus/dev
Push to stable
2021-12-14 22:10:19 +01:00
2564eb6f8c Merge pull request #1214 from yuawn/dev
Fix and update afl-whatup
2021-12-14 17:28:21 +01:00
495348261d update output 2021-12-14 14:08:58 +00:00
7a939a6c59 remove "locally unique" 2021-12-14 14:08:36 +00:00
425cbb9025 update variables name 2021-12-14 14:03:58 +00:00
ab699bbeea update comments 2021-12-14 14:00:09 +00:00
bf8e07d168 update output 2021-12-14 13:58:54 +00:00
ae958acc83 rename unique_crashes 2021-12-14 13:38:36 +00:00
088aae7c25 rename path 2021-12-14 13:37:56 +00:00
75ac9c013c better instrumentlist filename detection 2021-12-14 10:15:09 +01:00
22e2362f0f Merge pull request #1213 from AFLplusplus/dev
push to stable
2021-12-13 22:58:19 +01:00
c6bad07d75 Merge pull request #1208 from llzmb/docs_add_overview
Add docs content overview
2021-12-13 22:17:02 +01:00
83487415b1 Fix images 2021-12-13 21:22:33 +01:00
9de3de6cdf Update images 2021-12-13 21:14:20 +01:00
aceb1af908 Merge branch 'dev' into docs_add_overview 2021-12-13 18:23:28 +01:00
3a60f6a251 Add image references, update image 2021-12-13 18:03:02 +01:00
52dd5d479d update qemu 2021-12-13 17:13:31 +01:00
ece717c424 fix 2021-12-13 16:43:16 +01:00
57bc3c0701 fix qemu/unicorn oob 2021-12-13 15:45:52 +01:00
630272bac5 Merge pull request #1211 from llzmb/docs_add_images
Add images
2021-12-13 12:59:33 +01:00
5590d1836a Merge pull request #1210 from llzmb/docs_quality_assurance_2
Docs content - quality assurance - 2nd run
2021-12-13 12:59:26 +01:00
e41ac9564b Merge pull request #1212 from devnexen/libradmsa_fbsd_upd
radamsa mutator adding freebsd specific fcntl flags.
2021-12-13 12:58:57 +01:00
2c144e88fb Delete fuzzing_process_overview.drawio.svg 2021-12-12 22:42:15 +01:00
5c7e84c5c8 Add images 2021-12-12 22:41:19 +01:00
52cae6d132 Fix formatting and spelling 2021-12-12 22:35:11 +01:00
6eb752a65c radamsa mutator adding freebsd specific fcntl flags. 2021-12-12 20:32:18 +00:00
ed3eb61610 Add image with fuzzing process overview 2021-12-12 20:05:26 +01:00
0993bcdc4e Delete image 2021-12-12 20:04:42 +01:00
d28bb47a38 Fix formatting and spelling 2021-12-12 20:01:44 +01:00
9d7dd5a69f Fix formatting and references 2021-12-12 17:59:14 +01:00
77ce31c8ba Add docs content overview 2021-12-11 19:13:22 +01:00
08ca4d54a5 Merge pull request #1101 from AFLplusplus/dev
Dev
2021-12-09 11:55:36 +01:00
247 changed files with 3781 additions and 1774 deletions

View File

@ -6,7 +6,7 @@
# Written and maintaned by Andrea Fioraldi <andreafioraldi@gmail.com>
#
# Copyright 2015, 2016, 2017 Google Inc. All rights reserved.
# Copyright 2019-2020 AFLplusplus Project. All rights reserved.
# Copyright 2019-2022 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.

View File

@ -7,24 +7,47 @@ on:
branches: [ stable, dev ]
jobs:
build:
linux:
runs-on: '${{ matrix.os }}'
strategy:
matrix:
os: [ubuntu-20.04, ubuntu-18.04]
env:
AFL_SKIP_CPUFREQ: 1
AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES: 1
steps:
- uses: actions/checkout@v2
- name: debug
run: apt-cache search plugin-dev | grep gcc- ; echo ; apt-cache search clang-format- | grep clang-format-
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
- name: compiler installed
run: gcc -v ; echo ; clang -v
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
- name: run tests
run: sudo -E ./afl-system-config ; export AFL_SKIP_CPUFREQ=1 ; make 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@v2
- name: install
run: brew install make gcc
- 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

9
.gitmodules vendored
View File

@ -19,3 +19,12 @@
[submodule "coresight_mode/coresight-trace"]
path = coresight_mode/coresight-trace
url = https://github.com/RICSecLab/coresight-trace.git
[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

View File

@ -1,3 +1,11 @@
//
// NOTE: This file is outdated. None of the AFL++ team uses Android hence
// we need users to keep this updated.
// In the current state it will likely fail, please send fixes!
// Also, this should build frida_mode.
//
cc_defaults {
name: "afl-defaults",
@ -175,7 +183,7 @@ cc_binary_host {
}
cc_library_static {
name: "afl-llvm-rt",
name: "afl-compiler-rt",
compile_multilib: "64",
vendor_available: true,
host_supported: true,
@ -225,6 +233,7 @@ cc_library_headers {
],
}
/*
cc_prebuilt_library_static {
name: "libfrida-gum",
compile_multilib: "64",
@ -272,7 +281,7 @@ cc_binary {
],
static_libs: [
"afl-llvm-rt",
"afl-compiler-rt",
"libfrida-gum",
],
@ -290,6 +299,7 @@ cc_binary {
"utils/afl_frida/android",
],
}
*/
cc_binary {
name: "afl-fuzz-32",
@ -346,7 +356,7 @@ cc_binary_host {
}
cc_library_static {
name: "afl-llvm-rt-32",
name: "afl-compiler-rt-32",
compile_multilib: "32",
vendor_available: true,
host_supported: true,
@ -385,6 +395,7 @@ cc_library_static {
],
}
/*
cc_prebuilt_library_static {
name: "libfrida-gum-32",
compile_multilib: "32",
@ -400,6 +411,7 @@ cc_prebuilt_library_static {
"utils/afl_frida/android/arm",
],
}
*/
subdirs = [
"custom_mutators",

31
CITATION.cff Normal file
View File

@ -0,0 +1,31 @@
cff-version: 1.2.0
message: "If you use this software, please cite it as below."
authors:
- given-names: Marc
family-names: Heuse
email: mh@mh-sec.de
- given-names: Heiko
family-names: Eißfeldt
email: heiko.eissfeldt@hexco.de
- given-names: Andrea
family-names: Fioraldi
email: andreafioraldi@gmail.com
- given-names: Dominik
family-names: Meier
email: mail@dmnk.co
title: "AFL++"
version: 3.14
type: software
date-released: 2021-07-19
url: "https://github.com/AFLplusplus/AFLplusplus"
keywords:
- fuzzing
- fuzzer
- fuzz-testing
- instrumentation
- afl-fuzz
- qemu
- llvm
- unicorn-emulator
- securiy
license: AGPL-3.0-or-later

View File

@ -345,9 +345,9 @@ performance-test: source-only
help:
@echo "HELP --- the following make targets exist:"
@echo "=========================================="
@echo "all: just the main afl++ binaries"
@echo "binary-only: everything for binary-only fuzzing: qemu_mode, frida_mode, unicorn_mode, coresight_mode, libdislocator, libtokencap"
@echo "source-only: everything for source code fuzzing: gcc_plugin, libdislocator, libtokencap"
@echo "all: the main afl++ binaries and llvm/gcc instrumentation"
@echo "binary-only: everything for binary-only fuzzing: frida_mode, nyx_mode, qemu_mode, frida_mode, unicorn_mode, coresight_mode, libdislocator, libtokencap"
@echo "source-only: everything for source code fuzzing: nyx_mode, libdislocator, libtokencap"
@echo "distrib: everything (for both binary-only and source code fuzzing)"
@echo "man: creates simple man pages from the help option of the programs"
@echo "install: installs everything you have compiled with the build option above"
@ -564,24 +564,26 @@ all_done: test_build
.PHONY: clean
clean:
rm -rf $(PROGS) libradamsa.so 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-gcc-pass.so 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
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
-$(MAKE) -f GNUmakefile.llvm clean
-$(MAKE) -f GNUmakefile.gcc_plugin clean
$(MAKE) -C utils/libdislocator clean
$(MAKE) -C utils/libtokencap clean
-$(MAKE) -C utils/libdislocator clean
-$(MAKE) -C utils/libtokencap clean
$(MAKE) -C utils/aflpp_driver clean
$(MAKE) -C utils/afl_network_proxy clean
$(MAKE) -C utils/socket_fuzzing clean
$(MAKE) -C utils/argv_fuzzing clean
-$(MAKE) -C utils/afl_network_proxy clean
-$(MAKE) -C utils/socket_fuzzing clean
-$(MAKE) -C utils/argv_fuzzing clean
-$(MAKE) -C utils/plot_ui clean
$(MAKE) -C qemu_mode/unsigaction clean
$(MAKE) -C qemu_mode/libcompcov clean
$(MAKE) -C qemu_mode/libqasan clean
-$(MAKE) -C qemu_mode/unsigaction clean
-$(MAKE) -C qemu_mode/libcompcov clean
-$(MAKE) -C qemu_mode/libqasan clean
-$(MAKE) -C frida_mode clean
rm -rf nyx_mode/packer/linux_initramfs/init.cpio.gz nyx_mode/libnyx/libnyx/target/release/* nyx_mode/QEMU-Nyx/x86_64-softmmu/qemu-system-x86_64
ifeq "$(IN_REPO)" "1"
-test -e coresight_mode/coresight-trace/Makefile && $(MAKE) -C coresight_mode/coresight-trace clean || true
-test -e qemu_mode/qemuafl/Makefile && $(MAKE) -C qemu_mode/qemuafl clean || true
test -e unicorn_mode/unicornafl/Makefile && $(MAKE) -C unicorn_mode/unicornafl clean || true
-test -e unicorn_mode/unicornafl/Makefile && $(MAKE) -C unicorn_mode/unicornafl clean || true
-test -e nyx_mode/QEMU-Nyx/Makefile && $(MAKE) -C nyx_mode/QEMU-Nyx clean || true
else
rm -rf coresight_mode/coresight_trace
rm -rf qemu_mode/qemuafl
@ -593,11 +595,14 @@ deepclean: clean
rm -rf coresight_mode/coresight-trace
rm -rf unicorn_mode/unicornafl
rm -rf qemu_mode/qemuafl
rm -rf nyx_mode/libnyx nyx_mode/packer nyx_mode/QEMU-Nyx
ifeq "$(IN_REPO)" "1"
# NEVER EVER ACTIVATE THAT!!!!! git reset --hard >/dev/null 2>&1 || true
git checkout coresight_mode/coresight-trace
git checkout unicorn_mode/unicornafl
git checkout qemu_mode/qemuafl
git checkout nyx_mode/libnyx
git checkout nyx_mode/packer
git checkout nyx_mode/QEMU-Nyx
endif
.PHONY: distrib
@ -606,16 +611,19 @@ distrib: all
ifneq "$(SYS)" "Darwin"
-$(MAKE) -f GNUmakefile.gcc_plugin
endif
$(MAKE) -C utils/libdislocator
$(MAKE) -C utils/libtokencap
$(MAKE) -C utils/afl_network_proxy
$(MAKE) -C utils/socket_fuzzing
$(MAKE) -C utils/argv_fuzzing
-$(MAKE) -C utils/libdislocator
-$(MAKE) -C utils/libtokencap
-$(MAKE) -C utils/afl_network_proxy
-$(MAKE) -C utils/socket_fuzzing
-$(MAKE) -C utils/argv_fuzzing
# -$(MAKE) -C utils/plot_ui
-$(MAKE) -C frida_mode
ifneq "$(SYS)" "Darwin"
ifeq "$(ARCH)" "aarch64"
-$(MAKE) -C coresight_mode
endif
ifeq "$(SYS)" "Linux"
-cd nyx_mode && ./build_nyx_support.sh
endif
-cd qemu_mode && sh ./build_qemu_support.sh
-cd unicorn_mode && unset CFLAGS && sh ./build_unicorn_support.sh
@ -623,16 +631,19 @@ endif
.PHONY: binary-only
binary-only: test_shm test_python ready $(PROGS)
$(MAKE) -C utils/libdislocator
$(MAKE) -C utils/libtokencap
$(MAKE) -C utils/afl_network_proxy
$(MAKE) -C utils/socket_fuzzing
$(MAKE) -C utils/argv_fuzzing
-$(MAKE) -C utils/libdislocator
-$(MAKE) -C utils/libtokencap
-$(MAKE) -C utils/afl_network_proxy
-$(MAKE) -C utils/socket_fuzzing
-$(MAKE) -C utils/argv_fuzzing
# -$(MAKE) -C utils/plot_ui
-$(MAKE) -C frida_mode
ifneq "$(SYS)" "Darwin"
ifeq "$(ARCH)" "aarch64"
-$(MAKE) -C coresight_mode
endif
ifeq "$(SYS)" "Linux"
-cd nyx_mode && ./build_nyx_support.sh
endif
-cd qemu_mode && sh ./build_qemu_support.sh
-cd unicorn_mode && unset CFLAGS && sh ./build_unicorn_support.sh
@ -644,9 +655,12 @@ source-only: all
ifneq "$(SYS)" "Darwin"
-$(MAKE) -f GNUmakefile.gcc_plugin
endif
$(MAKE) -C utils/libdislocator
$(MAKE) -C utils/libtokencap
-$(MAKE) -C utils/libdislocator
-$(MAKE) -C utils/libtokencap
# -$(MAKE) -C utils/plot_ui
ifeq "$(SYS)" "Linux"
-cd nyx_mode && ./build_nyx_support.sh
endif
%.8: %
@echo .TH $* 8 $(BUILD_DATE) "afl++" > $@
@ -684,6 +698,7 @@ install: all $(MANPAGES)
@if [ -f socketfuzz32.so -o -f socketfuzz64.so ]; then $(MAKE) -C utils/socket_fuzzing install; fi
@if [ -f argvfuzz32.so -o -f argvfuzz64.so ]; then $(MAKE) -C utils/argv_fuzzing install; fi
@if [ -f afl-frida-trace.so ]; then install -m 755 afl-frida-trace.so $${DESTDIR}$(HELPER_PATH); fi
@if [ -f libnyx.so ]; then install -m 755 libnyx.so $${DESTDIR}$(HELPER_PATH); fi
@if [ -f utils/afl_network_proxy/afl-network-server ]; then $(MAKE) -C utils/afl_network_proxy install; fi
@if [ -f utils/aflpp_driver/libAFLDriver.a ]; then set -e; install -m 644 utils/aflpp_driver/libAFLDriver.a $${DESTDIR}$(HELPER_PATH); fi
@if [ -f utils/aflpp_driver/libAFLQemuDriver.a ]; then set -e; install -m 644 utils/aflpp_driver/libAFLQemuDriver.a $${DESTDIR}$(HELPER_PATH); fi
@ -706,7 +721,7 @@ endif
.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 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}$(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
-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)

View File

@ -11,7 +11,7 @@
# from Laszlo Szekeres.
#
# Copyright 2015 Google Inc. All rights reserved.
# Copyright 2019-2020 AFLplusplus Project. All rights reserved.
# Copyright 2019-2022 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.

View File

@ -1,20 +1,21 @@
# American Fuzzy Lop plus plus (AFL++)
<img align="right" src="https://raw.githubusercontent.com/andreafioraldi/AFLplusplus-website/master/static/logo_256x256.png" alt="AFL++ logo">
<img align="right" src="https://raw.githubusercontent.com/AFLplusplus/Website/master/static/aflpp_bg.svg" alt="AFL++ logo" width="250" heigh="250">
Release version: [3.14c](https://github.com/AFLplusplus/AFLplusplus/releases)
Release version: [4.00c](https://github.com/AFLplusplus/AFLplusplus/releases)
GitHub version: 3.15a
GitHub version: 4.00c
Repository:
[https://github.com/AFLplusplus/AFLplusplus](https://github.com/AFLplusplus/AFLplusplus)
AFL++ is maintained by:
* Marc "van Hauser" Heuse <mh@mh-sec.de>,
* Heiko "hexcoder-" Eißfeldt <heiko.eissfeldt@hexco.de>,
* Andrea Fioraldi <andreafioraldi@gmail.com> and
* Dominik Maier <mail@dmnk.co>.
* Marc "van Hauser" Heuse <mh@mh-sec.de>
* Heiko "hexcoder-" Eißfeldt <heiko.eissfeldt@hexco.de>
* Andrea Fioraldi <andreafioraldi@gmail.com>
* Dominik Maier <mail@dmnk.co>
* Documentation: Jana Aydinbas <jana.aydinbas@gmail.com>
Originally developed by Michał "lcamtuf" Zalewski.
@ -28,9 +29,14 @@ terms of the Apache-2.0 License. See the [LICENSE](LICENSE) for details.
Here is some information to get you started:
* For an overview of the AFL++ documentation and a very helpful graphical guide,
please visit [docs/README.md](docs/README.md).
* To get you started with tutorials, go to
[docs/tutorials.md](docs/tutorials.md).
* For releases, see the
[Releases tab](https://github.com/AFLplusplus/AFLplusplus/releases) and
[branches](#branches). Also take a look at the list of
[branches](#branches). The best branches to use are, however, `stable` or
`dev` - depending on your risk appetite. Also take a look at the list of
[important changes in AFL++](docs/important_changes.md) and the list of
[features](docs/features.md).
* If you want to use AFL++ for your academic work, check the
@ -40,8 +46,6 @@ Here is some information to get you started:
`afl-clang-fast` with `AFL_LLVM_CMPLOG=1`. You can find the `aflplusplus`
default configuration on Google's
[fuzzbench](https://github.com/google/fuzzbench/tree/master/fuzzers/aflplusplus).
* To get you started with tutorials, go to
[docs/tutorials.md](docs/tutorials.md).
## Building and installing AFL++
@ -57,7 +61,8 @@ This image is automatically generated when a push to the stable repo happens
(see [branches](#branches)). You will find your target source code in `/src` in
the container.
To build AFL++ yourself, continue at [docs/INSTALL.md](docs/INSTALL.md).
To build AFL++ yourself - which we recommend - continue at
[docs/INSTALL.md](docs/INSTALL.md).
## Quick start: Fuzzing with AFL++
@ -115,20 +120,24 @@ Step-by-step quick start:
You can generate cores or use gdb directly to follow up the crashes.
6. We cannot stress this enough - if you want to fuzz effectively, read the
[docs/fuzzing_in_depth.md](docs/fuzzing_in_depth.md) document!
## Contact
Questions? Concerns? Bug reports?
* The contributors can be reached via
* The contributors can be reached via (e.g., by creating an issue):
[https://github.com/AFLplusplus/AFLplusplus](https://github.com/AFLplusplus/AFLplusplus).
* Take a look at our [FAQ](docs/FAQ.md). If you find an interesting or important
question missing, submit it via
[https://github.com/AFLplusplus/AFLplusplus/discussions](https://github.com/AFLplusplus/AFLplusplus/discussions).
* There is a mailing list for the AFL/AFL++ project
* Best: join the [Awesome Fuzzing](https://discord.gg/gCraWct) Discord server.
* There is a (not really used) mailing list for the AFL/AFL++ project
([browse archive](https://groups.google.com/group/afl-users)). To compare
notes with other users or to get notified about major new features, send an
email to <afl-users+subscribe@googlegroups.com>.
* Or join the [Awesome Fuzzing](https://discord.gg/gCraWct) Discord server.
email to <afl-users+subscribe@googlegroups.com>, but note that this is not
managed by us.
## Branches
@ -141,7 +150,7 @@ The following branches exist:
stability
* [dev](https://github.com/AFLplusplus/AFLplusplus/tree/dev): development state
of AFL++ - bleeding edge and you might catch a checkout which does not compile
or has a bug. *We only accept PRs in dev!!*
or has a bug. **We only accept PRs (pull requests) for the 'dev' branch!**
* (any other): experimental branches to work on specific features or testing new
functionality or changes.
@ -155,7 +164,7 @@ This can be your way to support and contribute to AFL++ - extend it to do
something cool.
For everyone who wants to contribute (and send pull requests), please read our
[contributing guidelines](CONTRIBUTING.md) before your submit.
[contributing guidelines](CONTRIBUTING.md) before you submit.
## Special thanks
@ -215,7 +224,7 @@ Thank you! (For people sending pull requests - please add yourself to this list
Josephine Calliotte Konrad Welc
Thomas Rooijakkers David Carlier
Ruben ten Hove Joey Jiao
fuzzah
fuzzah @intrigus-lgtm
```
</details>
@ -243,4 +252,4 @@ presented at WOOT'20:
}
```
</details>
</details>

View File

@ -6,7 +6,7 @@
# Originally written by Michal Zalewski
#
# Copyright 2015 Google Inc. All rights reserved.
# Copyright 2019-2020 AFLplusplus Project. All rights reserved.
# Copyright 2019-2022 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.
@ -91,9 +91,9 @@ TOTAL_CRASHES=0
TOTAL_PFAV=0
TOTAL_PENDING=0
# Time since last path / crash / hang, formatted as string
# Time since last find / crash / hang, formatted as string
FMT_TIME="0 days 0 hours"
FMT_PATH="${RED}none seen yet${NC}"
FMT_FIND="${RED}none seen yet${NC}"
FMT_CRASH="none seen yet"
FMT_HANG="none seen yet"
@ -135,7 +135,7 @@ fmt_duration()
FIRST=true
TOTAL_WCOP=
TOTAL_LAST_PATH=0
TOTAL_LAST_FIND=0
for i in `find . -maxdepth 2 -iname fuzzer_stats | sort`; do
@ -169,7 +169,7 @@ for i in `find . -maxdepth 2 -iname fuzzer_stats | sort`; do
fi
DEAD_CNT=$((DEAD_CNT + 1))
last_path=0
last_find=0
if [ "$PROCESS_DEAD" = "" ]; then
@ -183,17 +183,17 @@ for i in `find . -maxdepth 2 -iname fuzzer_stats | sort`; do
EXEC_SEC=0
test -z "$RUN_UNIX" -o "$RUN_UNIX" = 0 || EXEC_SEC=$((execs_done / RUN_UNIX))
PATH_PERC=$((cur_path * 100 / paths_total))
PATH_PERC=$((cur_item * 100 / corpus_count))
TOTAL_TIME=$((TOTAL_TIME + RUN_UNIX))
TOTAL_EPS=$((TOTAL_EPS + EXEC_SEC))
TOTAL_EXECS=$((TOTAL_EXECS + execs_done))
TOTAL_CRASHES=$((TOTAL_CRASHES + unique_crashes))
TOTAL_CRASHES=$((TOTAL_CRASHES + saved_crashes))
TOTAL_PENDING=$((TOTAL_PENDING + pending_total))
TOTAL_PFAV=$((TOTAL_PFAV + pending_favs))
if [ "$last_path" -gt "$TOTAL_LAST_PATH" ]; then
TOTAL_LAST_PATH=$last_path
if [ "$last_find" -gt "$TOTAL_LAST_FIND" ]; then
TOTAL_LAST_FIND=$last_find
fi
if [ "$SUMMARY_ONLY" = "" ]; then
@ -210,7 +210,7 @@ for i in `find . -maxdepth 2 -iname fuzzer_stats | sort`; do
echo " ${RED}slow execution, $EXEC_SEC execs/sec${NC}"
fi
fmt_duration $last_path && FMT_PATH=$DUR_STRING
fmt_duration $last_find && FMT_FIND=$DUR_STRING
fmt_duration $last_crash && FMT_CRASH=$DUR_STRING
fmt_duration $last_hang && FMT_HANG=$DUR_STRING
FMT_CWOP="not available"
@ -220,7 +220,7 @@ for i in `find . -maxdepth 2 -iname fuzzer_stats | sort`; do
test "$cycles_wo_finds" -gt 50 && FMT_CWOP="${RED}$cycles_wo_finds${NC}"
}
echo " last_path : $FMT_PATH"
echo " last_find : $FMT_FIND"
echo " last_crash : $FMT_CRASH"
echo " last_hang : $FMT_HANG"
echo " cycles_wo_finds : $FMT_CWOP"
@ -229,12 +229,12 @@ for i in `find . -maxdepth 2 -iname fuzzer_stats | sort`; do
MEM_USAGE=$(ps aux | grep $fuzzer_pid | grep -v grep | awk '{print $4}')
echo " cpu usage $CPU_USAGE%, memory usage $MEM_USAGE%"
echo " cycle $((cycles_done + 1)), lifetime speed $EXEC_SEC execs/sec, path $cur_path/$paths_total (${PATH_PERC}%)"
echo " cycles $((cycles_done + 1)), lifetime speed $EXEC_SEC execs/sec, items $cur_item/$corpus_count (${PATH_PERC}%)"
if [ "$unique_crashes" = "0" ]; then
if [ "$saved_crashes" = "0" ]; then
echo " pending $pending_favs/$pending_total, coverage $bitmap_cvg, no crashes yet"
else
echo " pending $pending_favs/$pending_total, coverage $bitmap_cvg, crash count $unique_crashes (!)"
echo " pending $pending_favs/$pending_total, coverage $bitmap_cvg, crashes saved $saved_crashes (!)"
fi
echo
@ -243,7 +243,7 @@ for i in `find . -maxdepth 2 -iname fuzzer_stats | sort`; do
done
# Formatting for total time, time since last path, crash, and hang
# Formatting for total time, time since last find, crash, and hang
fmt_duration $((CUR_TIME - TOTAL_TIME)) && FMT_TIME=$DUR_STRING
# Formatting for total execution
FMT_EXECS="0 millions"
@ -263,7 +263,7 @@ TOTAL_DAYS=$((TOTAL_TIME / 60 / 60 / 24))
TOTAL_HRS=$(((TOTAL_TIME / 60 / 60) % 24))
test -z "$TOTAL_WCOP" && TOTAL_WCOP="not available"
fmt_duration $TOTAL_LAST_PATH && TOTAL_LAST_PATH=$DUR_STRING
fmt_duration $TOTAL_LAST_FIND && TOTAL_LAST_FIND=$DUR_STRING
test "$TOTAL_TIME" = "0" && TOTAL_TIME=1
@ -293,15 +293,15 @@ echo " Cumulative speed : $TOTAL_EPS execs/sec"
if [ "$ALIVE_CNT" -gt "0" ]; then
echo " Average speed : $((TOTAL_EPS / ALIVE_CNT)) execs/sec"
fi
echo " Pending paths : $TOTAL_PFAV faves, $TOTAL_PENDING total"
echo " Pending items : $TOTAL_PFAV faves, $TOTAL_PENDING total"
if [ "$ALIVE_CNT" -gt "1" ]; then
echo " Pending per fuzzer : $((TOTAL_PFAV/ALIVE_CNT)) faves, $((TOTAL_PENDING/ALIVE_CNT)) total (on average)"
fi
echo " Crashes found : $TOTAL_CRASHES locally unique"
echo " Crashes saved : $TOTAL_CRASHES"
echo "Cycles without finds : $TOTAL_WCOP"
echo " Time without finds : $TOTAL_LAST_PATH"
echo " Time without finds : $TOTAL_LAST_FIND"
echo
exit 0

View File

@ -11,7 +11,7 @@
# Adapted for AFLplusplus by Dominik Maier <mail@dmnk.co>
#
# Copyright 2017 Battelle Memorial Institute. All rights reserved.
# Copyright 2019-2020 AFLplusplus Project. All rights reserved.
# Copyright 2019-2022 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.

View File

@ -1 +1 @@
eedf07d
cbe5e32

View File

@ -14,7 +14,7 @@
# <andreafioraldi@gmail.com>
#
# Copyright 2017 Battelle Memorial Institute. All rights reserved.
# Copyright 2019-2020 AFLplusplus Project. All rights reserved.
# Copyright 2019-2022 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.

View File

@ -100,8 +100,8 @@ extern "C" size_t afl_custom_fuzz(MyMutator *mutator, // return value from afl_c
// Copy to a new buffer ( mutated_out )
size_t mutated_size = s.size() <= max_size ? s.size() : max_size; // check if raw data's size is larger than max_size
delete mutator->mutated_out;
mutator->mutated_out = new uint8_t[mutated_size+1];
delete[] mutator->mutated_out;
mutator->mutated_out = new uint8_t[mutated_size];
memcpy(mutator->mutated_out, s.c_str(), mutated_size); // copy the mutated data
// Assign the mutated data and return mutated_size
*out_buf = mutator->mutated_out;

View File

@ -4,4 +4,7 @@
class MyMutator : public protobuf_mutator::Mutator {
public:
uint8_t *mutated_out = nullptr;
~MyMutator() {
delete[] mutated_out;
}
};

View File

@ -4473,6 +4473,10 @@ static word prim_sys(word op, word a, word b, word c) {
FD_CLOEXEC,
F_DUPFD,
F_DUPFD_CLOEXEC,
#if defined(F_DUP2FD)
F_DUP2FD,
F_DUP2FD_CLOEXEC,
#endif
F_GETFD,
F_SETFD,
F_GETFL,

View File

@ -1,6 +1,6 @@
# AFL++ dictionaries
(See [../README.md](../README.md) for the general instruction manual.)
For the general instruction manual, see [docs/README.md](../docs/README.md).
This subdirectory contains a set of dictionaries that can be used in conjunction
with the -x option to allow the fuzzer to effortlessly explore the grammar of

View File

@ -1,24 +1,31 @@
# Changelog
This is the list of all noteworthy changes made in every public release of
the tool. See README.md for the general instruction manual.
This is the list of all noteworthy changes made in every public
release of the tool. See README.md for the general instruction manual.
## Staying informed
Want to stay in the loop on major new features? Join our mailing list by
sending a mail to <afl-users+subscribe@googlegroups.com>.
### Version ++3.15a (dev)
- documentation restructuring, made possible by Google Season of Docs
### Version ++4.00c (release)
- complete documentation restructuring, made possible by Google Season
of Docs :) thank you Jana!
- we renamed several UI and fuzzer_stat entries to be more precise,
e.g. "unique crashes" -> "saved crashes", "total paths" ->
"corpus count", "current path" -> "current item".
This might need changing custom scripting!
- Nyx mode (full system emulation with snapshot capability) has been
added - thanks to @schumilo and @eqv!
- unicorn_mode:
- Moved to unicorn2! by Ziqiao Kong (@lazymio)
- Faster, more accurate emulation (newer QEMU base), risc-v support
- removed indirections in rust callbacks
- new binary-only fuzzing mode: coresight_mode for aarch64 CPUs :)
thanks to RICSecLab submitting!
- if instrumented libaries are dlopen()'ed after the forkserver you
will now see crashes. before you would have colliding coverage.
we changed this to force fixing a broken setup rather then allowing
will now see a crash. Before you would have colliding coverage.
We changed this to force fixing a broken setup rather then allowing
ineffective fuzzing.
See docs/best_practices.md how to fix such setups.
- afl-fuzz:
@ -26,14 +33,17 @@ sending a mail to <afl-users+subscribe@googlegroups.com>.
(it is better!)
- fix a regression introduced in 3.10 that resulted in less
coverage being detected. thanks to Collin May for reporting!
- ensure all spawned targets are killed on exit
- added AFL_IGNORE_PROBLEMS, plus checks to identify and abort on
incorrect LTO usage setups and enhanced the READMEs for better
information on how to deal with instrumenting libraries
- fix -n dumb mode (nobody should use this)
- fix -n dumb mode (nobody should use this mode though)
- fix stability issue with LTO and cmplog
- better banner
- more effective cmplog mode
- more often update the UI when in input2stage mode
- qemu_mode/unicorn_mode: fixed OOB write when using libcompcov,
thanks to kotee4ko for reporting!
- frida_mode:
- better performance, bug fixes
- David Carlier added Android support :)
@ -43,16 +53,22 @@ sending a mail to <afl-users+subscribe@googlegroups.com>.
- fix bug where targets are not killed on timeouts
- moved hidden afl-showmap -A option to -H to be used for
coresight_mode
- Prevent accidently killing non-afl/fuzz services when aborting
- Prevent accidentaly killing non-afl/fuzz services when aborting
afl-showmap and other tools.
- afl-cc:
- detect overflow reads on initial input buffer for asan
- new cmplog mode (incompatible with older afl++ versions)
- support llvm IR select instrumentation for default PCGUARD and LTO
- fix for shared linking on MacOS
- better selective instrumentation AFL_LLVM_{ALLOW|DENY}LIST
on filename matching (requires llvm 11 or newer)
- fixed a potential crash in targets for LAF string handling
- fixed a bad assert in LAF split switches
- added AFL_USE_TSAN thread sanitizer support
- llvm and LTO mode modified to work with new llvm 14-dev (again. again.)
- llvm and LTO mode modified to work with new llvm 14-dev (again.)
- fix for AFL_REAL_LD
- more -z defs filtering
- make -v without options work
- added the very good grammar mutator "GramaTron" to the
custom_mutators
- added optimin, a faster and better corpus minimizer by
@ -60,11 +76,10 @@ sending a mail to <afl-users+subscribe@googlegroups.com>.
- added afl-persistent-config script to set perform permanent system
configuration settings for fuzzing, for Linux and Macos.
thanks to jhertz!
- added xml, curl and exotic string functions to llvm dictionary features
- added xml, curl & exotic string functions to llvm dictionary feature
- fix AFL_PRELOAD issues on MacOS
- removed utils/afl_frida because frida_mode/ is now so much better
- added uninstall target to makefile (todo: update new readme!)
- removed indirections in rust callbacks for unicornafl
### Version ++3.14c (release)
- afl-fuzz:
@ -84,7 +99,7 @@ sending a mail to <afl-users+subscribe@googlegroups.com>.
- Fix to instrument global namespace functions in c++
- Fix for llvm 13
- support partial linking
- do honor AFL_LLVM_{ALLOW/DENY}LIST for LTO autodictionary and DICT2FILE
- do honor AFL_LLVM_{ALLOW/DENY}LIST for LTO autodictionary andDICT2FILE
- We do support llvm versions from 3.8 to 5.0 again
- frida_mode:
- several fixes for cmplog

View File

@ -58,10 +58,10 @@ If you find an interesting or important question missing, submit it via
A program contains `functions`, `functions` contain the compiled machine code.
The compiled machine code in a `function` can be in a single or many `basic
blocks`. A `basic block` is the largest possible number of subsequent machine
code instructions that has exactly one entry point (which can be be entered by
multiple other basic blocks) and runs linearly without branching or jumping to
other addresses (except at the end).
blocks`. A `basic block` is the **largest possible number of subsequent machine
code instructions** that has **exactly one entry point** (which can be be entered by
multiple other basic blocks) and runs linearly **without branching or jumping to
other addresses** (except at the end).
```
function() {
@ -180,8 +180,58 @@ If you find an interesting or important question missing, submit it via
[best_practices.md#improving-stability](best_practices.md#improving-stability).
</p></details>
<details>
<summary id="what-are-power-schedules">What are power schedules?</summary><p>
Not every item in our queue/corpus is the same, some are more interesting,
others provide little value.
A power schedule measures how "interesting" a value is, and depending on
the calculated value spends more or less time mutating it.
AFL++ comes with several power schedules, initially ported from
[AFLFast](https://github.com/mboehme/aflfast), however, modified to be more
effective and several more modes added.
The most effective modes are `-p fast` (default) and `-p explore`.
If you fuzz with several parallel afl-fuzz instances, then it is beneficial
to assign a different schedule to each instance, however the majority should
be `fast` and `explore`.
It does not make sense to explain the details of the calculation and
reasoning behind all of the schedules. If you are interested, read the source
code and the AFLFast paper.
</p></details>
## Troubleshooting
<details>
<summary id="fatal-forkserver-is-already-up-but-an-instrumented-dlopen-library-loaded-afterwards">FATAL: forkserver is already up but an instrumented dlopen library loaded afterwards</summary><p>
It can happen that you see this error on startup when fuzzing a target:
```
[-] FATAL: forkserver is already up, but an instrumented dlopen() library
loaded afterwards. You must AFL_PRELOAD such libraries to be able
to fuzz them or LD_PRELOAD to run outside of afl-fuzz.
To ignore this set AFL_IGNORE_PROBLEMS=1.
```
As the error describes, a dlopen() call is happening in the target that is
loading an instrumented library after the forkserver is already in place. This
is a problem for afl-fuzz because when the forkserver is started, we must know
the map size already and it can't be changed later.
The best solution is to simply set `AFL_PRELOAD=foo.so` to the libraries that
are dlopen'ed (e.g., use `strace` to see which), or to set a manual forkserver
after the final dlopen().
If this is not a viable option, you can set `AFL_IGNORE_PROBLEMS=1` but then
the existing map will be used also for the newly loaded libraries, which
allows it to work, however, the efficiency of the fuzzing will be partially
degraded.
</p></details>
<details>
<summary id="i-got-a-weird-compile-error-from-clang">I got a weird compile error from clang.</summary><p>
@ -204,4 +254,4 @@ If you find an interesting or important question missing, submit it via
package and because of that the AFL++ llvm plugins do not match anymore.
Solution: `git pull ; make clean install` of AFL++.
</p></details>
</p></details>

View File

@ -12,7 +12,7 @@ docker run -ti -v /location/of/your/target:/src aflplusplus/aflplusplus
```
This image is automatically generated when a push to the stable repo happens.
You will find your target source code in /src in the container.
You will find your target source code in `/src` in the container.
If you want to build AFL++ yourself, you have many options. The easiest choice
is to build and install everything:
@ -33,10 +33,10 @@ sudo make install
It is recommended to install the newest available gcc, clang and llvm-dev
possible in your distribution!
Note that "make distrib" also builds instrumentation, QEMU mode, unicorn_mode
and more. If you just want plain AFL++, then do "make all". However, compiling
and using at least instrumentation is highly recommended for much better results
- hence in this case choose:
Note that `make distrib` also builds FRIDA mode, QEMU mode, unicorn_mode, and
more. If you just want plain AFL++, then do `make all`. If you want some
assisting tooling compiled but are not interested in binary-only targets, then
instead choose:
```shell
make source-only
@ -44,11 +44,12 @@ make source-only
These build targets exist:
* all: just the main AFL++ binaries
* binary-only: everything for binary-only fuzzing: qemu_mode, unicorn_mode,
libdislocator, libtokencap
* source-only: everything for source code fuzzing: instrumentation,
libdislocator, libtokencap
* all: the main afl++ binaries and llvm/gcc instrumentation
* binary-only: everything for binary-only fuzzing: frida_mode, nyx_mode,
qemu_mode, frida_mode, unicorn_mode, coresight_mode, libdislocator,
libtokencap
* source-only: everything for source code fuzzing: nyx_mode, libdislocator,
libtokencap
* distrib: everything (for both binary-only and source code fuzzing)
* man: creates simple man pages from the help option of the programs
* install: installs everything you have compiled with the build options above
@ -86,32 +87,39 @@ e.g.: `make ASAN_BUILD=1`
## MacOS X on x86 and arm64 (M1)
MacOS X should work, but there are some gotchas due to the idiosyncrasies of the
platform. On top of this, we have limited release testing capabilities and
depend mostly on user feedback.
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.
`brew install wget git make cmake llvm gdb`
```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++ and gmake, e.g.:
freshly installed clang, clang++, llvm-config, gmake and coreutils, e.g.:
```
export PATH="/usr/local/Cellar/llvm/12.0.1/bin/:$PATH"
```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 PATH="/usr/local/opt/coreutils/libexec/gnubin:/usr/local/bin:$PATH"
export CC=clang
export CXX=clang++
gmake
cd frida_mode
gmake
cd ..
gmake install
sudo gmake install
```
`afl-gcc` will fail unless you have GCC installed, but that is using outdated
instrumentation anyway. You don't want that. Note that `afl-clang-lto`,
`afl-gcc-fast` and `qemu_mode` are not working on MacOS.
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.
The crash reporting daemon that comes by default with MacOS X will cause
problems with fuzzing. You need to turn it off:
@ -133,7 +141,7 @@ and definitely don't look POSIX-compliant. This means two things:
User emulation mode of QEMU does not appear to be supported on MacOS X, so
black-box instrumentation mode (`-Q`) will not work. However, Frida mode (`-O`)
should work on x86 and arm64 MacOS boxes.
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
@ -169,4 +177,4 @@ 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.
for documentation for these settings and how to make them permanent.

65
docs/README.md Normal file
View File

@ -0,0 +1,65 @@
# AFL++ documentation
This is the overview of the AFL++ docs content.
For general information on AFL++, see the
[README.md of the repository](../README.md).
Also take a look at our [FAQ.md](FAQ.md) and
[best_practices.md](best_practices.md).
## Fuzzing targets with the source code available
You can find a quickstart for fuzzing targets with the source code available in
the [README.md of the repository](../README.md#quick-start-fuzzing-with-afl).
For in-depth information on the steps of the fuzzing process, see
[fuzzing_in_depth.md](fuzzing_in_depth.md) or click on the following
image and select a step.
![Fuzzing process overview](https://raw.githubusercontent.com/AFLplusplus/AFLplusplus/dev/docs/resources/0_fuzzing_process_overview.drawio.svg "Fuzzing process overview")
For further information on instrumentation, see the
[READMEs in the instrumentation/ folder](../instrumentation/).
### Instrumenting the target
For more information, click on the following image and select a step.
![Instrumenting the target](https://raw.githubusercontent.com/AFLplusplus/AFLplusplus/dev/docs/resources/1_instrument_target.drawio.svg "Instrumenting the target")
### Preparing the fuzzing campaign
For more information, click on the following image and select a step.
![Preparing the fuzzing campaign](https://raw.githubusercontent.com/AFLplusplus/AFLplusplus/dev/docs/resources/2_prepare_campaign.drawio.svg "Preparing the fuzzing campaign")
### Fuzzing the target
For more information, click on the following image and select a step.
![Fuzzing the target](https://raw.githubusercontent.com/AFLplusplus/AFLplusplus/dev/docs/resources/3_fuzz_target.drawio.svg "Fuzzing the target")
### Managing the fuzzing campaign
For more information, click on the following image and select a step.
![Managing the fuzzing campaign](https://raw.githubusercontent.com/AFLplusplus/AFLplusplus/dev/docs/resources/4_manage_campaign.drawio.svg "Managing the fuzzing campaign")
## Fuzzing other targets
To learn about fuzzing other targets, see:
* Binary-only: [fuzzing_binary-only_targets.md](fuzzing_binary-only_targets.md)
* GUI programs:
[best_practices.md#fuzzing-a-gui-program](best_practices.md#fuzzing-a-gui-program)
* Libraries: [frida_mode/README.md](../frida_mode/README.md)
* Network services:
[best_practices.md#fuzzing-a-network-service](best_practices.md#fuzzing-a-network-service)
* Non-linux: [unicorn_mode/README.md](../unicorn_mode/README.md)
## Additional information
* Tools that help fuzzing with AFL++:
[third_party_tools.md](third_party_tools.md)
* Tutorials: [tutorials.md](tutorials.md)

View File

@ -40,7 +40,7 @@ superior to blind fuzzing or coverage-only tools.
This section provides an overview of the status screen - plus tips for
troubleshooting any warnings and red text shown in the UI.
For the general instruction manual, see [README.md](../README.md).
For the general instruction manual, see [README.md](README.md).
### A note about colors

View File

@ -116,7 +116,7 @@ allows you to define network state with different type of data packets.
### Improving stability
For fuzzing a 100% stable target that covers all edges is the best case. A 90%
For fuzzing, a 100% stable target that covers all edges is the best case. A 90%
stable target that covers all edges is, however, better than a 100% stable
target that ignores 10% of the edges.
@ -189,4 +189,4 @@ coding and/or disassembly and is effectively possible only with `afl-clang-fast`
Recompile, fuzz it, be happy :)
This link explains this process for
[Fuzzbench](https://github.com/google/fuzzbench/issues/677).
[Fuzzbench](https://github.com/google/fuzzbench/issues/677).

View File

@ -1,122 +0,0 @@
# Restructure AFL++'s documentation
## About us
We are dedicated to everything around fuzzing, our main and most well known
contribution is the fuzzer `AFL++` which is part of all major Unix
distributions (e.g. Debian, Arch, FreeBSD, etc.) and is deployed on Google's
oss-fuzz and clusterfuzz. It is rated the top fuzzer on Google's fuzzbench.
We are four individuals from Europe supported by a large community.
All our tools are open source.
## About the AFL++ fuzzer project
AFL++ inherited it's documentation from the original Google AFL project.
Since then it has been massively improved - feature and performance wise -
and although the documenation has likewise been continued it has grown out
of proportion.
The documentation is done by non-natives to the English language, plus
none of us has a writer background.
We see questions on AFL++ usage on mailing lists (e.g. afl-users), discord
channels, web forums and as issues in our repository.
This only increases as AFL++ has been on the top of Google's fuzzbench
statistics (which measures the performance of fuzzers) and is now being
integrated in Google's oss-fuzz and clusterfuzz - and is in many Unix
packaging repositories, e.g. Debian, FreeBSD, etc.
AFL++ now has 44 (!) documentation files with 13k total lines of content.
This is way too much.
Hence AFL++ needs a complete overhaul of it's documentation, both on a
organisation/structural level as well as the content.
Overall the following actions have to be performed:
* Create a better structure of documentation so it is easier to find the
information that is being looked for, combining and/or splitting up the
existing documents as needed.
* Rewrite some documentation to remove duplication. Several information is
present several times in the documentation. These should be removed to
where needed so that we have as little bloat as possible.
* The documents have been written and modified by a lot of different people,
most of them non-native English speaker. Hence an overall review where
parts should be rewritten has to be performed and then the rewrite done.
* Create a cheat-sheet for a very short best-setup build and run of AFL++
* Pictures explain more than 1000 words. We need at least 4 images that
explain the workflow with AFL++:
- the build workflow
- the fuzzing workflow
- the fuzzing campaign management workflow
- the overall workflow that is an overview of the above
- maybe more? where the technical writes seems it necessary for
understanding.
Requirements:
* Documentation has to be in Markdown format
* Images have to be either in SVG or PNG format.
* All documentation should be (moved) in(to) docs/
The project does not require writing new documentation or tutorials beside the
cheat sheet. The technical information for the cheat sheet will be provided by
us.
## Metrics
AFL++ is a the highest performant fuzzer publicly available - but is also the
most feature rich and complex. With the publicity of AFL++' success and
deployment in Google projects internally and externally and availability as
a package on most Linux distributions we see more and more issues being
created and help requests on our Discord channel that would not be
necessary if people would have read through all our documentation - which
is unrealistic.
We expect the the new documenation after this project to be cleaner, easier
accessible and lighter to digest by our users, resulting in much less
help requests. On the other hand the amount of users using AFL++ should
increase as well as it will be more accessible which would also increase
questions again - but overall resulting in a reduction of help requests.
In numbers: we currently have per week on average 5 issues on Github,
10 questions on discord and 1 on mailing lists that would not be necessary
with perfect documentation and perfect people.
We would consider this project a success if afterwards we only have
2 issues on Github and 3 questions on discord anymore that would be answered
by reading the documentation. The mailing list is usually used by the most
novice users and we don't expect any less questions there.
## Project Budget
We have zero experience with technical writers, so this is very hard for us
to calculate. We expect it to be a lot of work though because of the amount
of documentation we have that needs to be restructured and partially rewritten
(44 documents with 13k total lines of content).
We assume the daily rate of a very good and experienced technical writer in
times of a pandemic to be ~500$ (according to web research), and calculate
the overall amout of work to be around 20 days for everything incl. the
graphics (but again - this is basically just guessing).
Technical Writer 10000$
Volunteer stipends 0$ (waved)
T-Shirts for the top 10 contributors and helpers to this documentation project:
10 AFL++ logo t-shirts 20$ each 200$
10 shipping cost of t-shirts 10$ each 100$
Total: 10.300$
(in the submission form 10.280$ was entered)
## Additional Information
We have participated in Google Summer of Code in 2020 and hope to be selected
again in 2021.
We have no experience with a technical writer, but we will support that person
with video calls, chats, emails and messaging, provide all necessary information
and write technical contents that is required for the success of this project.
It is clear to us that a technical writer knows how to write, but cannot know
the technical details in a complex tooling like in AFL++. This guidance, input,
etc. has to come from us.

View File

@ -1,124 +0,0 @@
# Restructure AFL++'s documentation - Case Study
## Problem statement
AFL++ inherited it's documentation from the original Google AFL project.
Since then it has been massively improved - feature and performance wise -
and although the documenation has likewise been continued it has grown out
of proportion.
The documentation is done by non-natives to the English language, plus
none of us has a writer background.
We see questions on AFL++ usage on mailing lists (e.g. afl-users), discord
channels, web forums and as issues in our repository.
Most of them could be answered if people would read through all the
documentation.
This only increases as AFL++ has been on the top of Google's fuzzbench
statistics (which measures the performance of fuzzers) and has been
integrated in Google's oss-fuzz and clusterfuzz - and is in many Unix
packaging repositories, e.g. Debian, FreeBSD, etc.
AFL++ had 44 (!) documentation files with 13k total lines of content.
This was way too much.
## Proposal abstract
AFL++'s documentatin needs a complete overhaul, both on a
organisation/structural level as well as the content.
Overall the following actions have to be performed:
* Create a better structure of documentation so it is easier to find the
information that is being looked for, combining and/or splitting up the
existing documents as needed.
* Rewrite some documentation to remove duplication. Several information is
present several times in the documentation. These should be removed to
where needed so that we have as little bloat as possible.
* The documents have been written and modified by a lot of different people,
most of them non-native English speaker. Hence an overall review where
parts should be rewritten has to be performed and then the rewrite done.
* Create a cheat-sheet for a very short best-setup build and run of AFL++
* Pictures explain more than 1000 words. We need at least 4 images that
explain the workflow with AFL++:
- the build workflow
- the fuzzing workflow
- the fuzzing campaign management workflow
- the overall workflow that is an overview of the above
- maybe more? where the technical writes seems it necessary for
understanding.
Requirements:
* Documentation has to be in Markdown format
* Images have to be either in SVG or PNG format.
* All documentation should be (moved) in(to) docs/
## Project description
We created our proposal by discussing in the team what the issues are and
what was needed to fix it.
This resulted in the [project proposal](https://github.com/AFLplusplus/AFLplusplus/blob/stable/docs/docs.md).
We did not want to be selected by a writer but select a writer ourselves, so
we combed through the list and reviewed every single one of them.
We were not looking for coders writing technical documentation, but rather
someone who is an experienced writer and has documented experience with
structuring documentation.
Few fit that profile and we sent out messages to 6 people.
We finally decided on Jana because she had a strong background in technical
documentation and structuring information.
She had no technical experience in fuzzing whatsoever, but we saw that as
a plus - of course this made the whole process longer to explain details,
but overall ensured that the documentation can be read by (mostly) everyone.
We communicated via video calls every few weeks and she kept a public kanban
board about her todos, additional we used a Signal channel.
Her changes were imported via PRs where we discussed details.
The project was off to a good start, but then Jana got pregnant with serious
side effects that made working impossible for her for a longer time, hence
the schedule was thrown back.
She offered to rescind the payment and we select a new writer, but we saw
little opportunity in that, as that would mean a new selection of a writer,
someone else with a different vision on how the result should look like so
basically a full restart of the project and a large impact on our own time.
So we agreed on - after discussion with the Google GSoD team - that she
continues the project after the GSoD completion deadline as best as she can.
End of November she took one week off from work and fully dedicated her time
for the documenation which brought the project a big step forward.
Originally the project should have been ended begin of October, but now - at
nearing the end of November, we are at about 85% completion, with the end
being expected around mid of December.
## Metrics
We merged most of the changes in our development branch and are getting
close to a state where the user documentation part is completed and we
can create a new release. Only then the new documentatin is actually visible
to users. Therefore no metrics could be collected so far.
We plan on a user-assisted QA review end of November/begin of December.
The documentation was reviewed by a few test users so far however who gave
it a thumbs up.
## Summary
The GSoD project itself is great. It helps to get the documentation back in
line.
It was and is a larger time investment from our side, but we expected that.
When the project is done, the documentation will be more accessible by users
and also need less maintenance by us.
There is still follow-up work to be done by us afterwards (web site for the
docs, etc.).
Not sure what we would do differently next time. I think we prepared best as
possible and reacted best as possible to the unexpected.
Recommendations for other organizations who would like to participate in GSoD:
- expect the process to take a larger part of your time. the writer needs
your full support.
- have someone dedicated from the dev/org side to support, educate and
supervice the writer
- set clear goals and expectations

View File

@ -105,7 +105,8 @@ fairly broad use of environment variables instead:
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
cause an abort if any memory is leaked (you can combine this with the
`LSAN_OPTIONS=...` suppression option to suppress some known leaks).
`__AFL_LSAN_OFF();` and `__AFL_LSAN_ON();` macros to avoid checking for
memory leaks from memory allocated between these two calls.
- `AFL_USE_MSAN=1` - activates the memory sanitizer (uninitialized memory)
- `AFL_USE_TSAN=1` - activates the thread sanitizer to find thread race
conditions
@ -283,12 +284,24 @@ mode.
TMPDIR=$PWD/assembly_here AFL_KEEP_ASSEMBLY=1 make clean all
```
- GCC_PLUGIN mode only: Setting `AFL_GCC_INSTRUMENT_FILE` with a filename will
only instrument those files that match the names listed in this file (one
filename per line). See
- GCC_PLUGIN mode only: Setting `AFL_GCC_INSTRUMENT_FILE` or
`AFL_GCC_ALLOWLIST` with a filename will only instrument those files that
match the names listed in this file (one filename per line).
Setting `AFL_GCC_DENYLIST` or `AFL_GCC_BLOCKLIST` with a file name and/or
function will only skip those files that match the names listed in the
specified file. See
[instrumentation/README.instrument_list.md](../instrumentation/README.instrument_list.md)
for more information.
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.
Setting `AFL_GCC_SKIP_NEVERZERO=1` will not implement the skip zero test. If
the target performs only a few loops, then this will give a small
performance boost.
## 4) Settings for afl-fuzz
The main fuzzer binary accepts several options that disable a couple of sanity
@ -397,7 +410,7 @@ checks or alter some of the more exotic semantics of the tool:
target. This must be equal or larger than the size the target was compiled
with.
- Setting `AFL_MAX_DET_EXRAS` will change the threshold at what number of
- Setting `AFL_MAX_DET_EXTRAS` will change the threshold at what number of
elements in the `-x` dictionary and LTO autodict (combined) the
probabilistic mode will kick off. In probabilistic mode, not all dictionary
entries will be used all of the time for fuzzing mutations to not slow down

View File

@ -1,39 +1,96 @@
# Important features of AFL++
AFL++ supports llvm from 3.8 up to version 12, very fast binary fuzzing with
QEMU 5.1 with laf-intel and redqueen, FRIDA mode, unicorn mode, gcc plugin, full
QEMU 5.1 with laf-intel and Redqueen, FRIDA mode, unicorn mode, gcc plugin, full
*BSD, Mac OS, Solaris and Android support and much, much, much more.
| Feature/Instrumentation | afl-gcc | llvm | gcc_plugin | FRIDA mode(9) | QEMU mode(10) |unicorn_mode(10) |coresight_mode(11)|
| -------------------------|:-------:|:---------:|:----------:|:----------------:|:----------------:|:----------------:|:----------------:|
| Threadsafe counters | | x(3) | | | | | |
| NeverZero | x86[_64]| x(1) | x | x | x | x | |
| Persistent Mode | | x | x | x86[_64]/arm64 | x86[_64]/arm[64] | x | |
| LAF-Intel / CompCov | | x | | | x86[_64]/arm[64] | x86[_64]/arm[64] | |
| CmpLog | | x | | x86[_64]/arm64 | x86[_64]/arm[64] | | |
| Selective Instrumentation| | x | x | x | x | | |
| Non-Colliding Coverage | | x(4) | | | (x)(5) | | |
| Ngram prev_loc Coverage | | x(6) | | | | | |
| Context Coverage | | x(6) | | | | | |
| Auto Dictionary | | x(7) | | | | | |
| Snapshot LKM Support | | (x)(8) | (x)(8) | | (x)(5) | | |
| Shared Memory Test cases | | x | x | x86[_64]/arm64 | x | x | |
## Features and instrumentation
1. default for LLVM >= 9.0, environment variable for older version due an
| 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 | | 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
A. Default is not thread-safe coverage counter updates for better performance,
see [instrumentation/README.llvm.md](../instrumentation/README.llvm.md)
B. On wrapping coverage counters (255 + 1), skip the 0 value and jump to 1
instead. This has shown to give better coverage data and is the default; see
[instrumentation/README.llvm.md](../instrumentation/README.llvm.md).
C. Instead of forking, reiterate the fuzz target function in a loop (like
`LLVMFuzzerTestOneInput`. Great speed increase but only works with target
functions that do not keep state, leak memory, or exit; see
[instrumentation/README.persistent_mode.md](../instrumentation/README.persistent_mode.md)
D. Split any non-8-bit comparison to 8-bit comparison; see
[instrumentation/README.laf-intel.md](../instrumentation/README.laf-intel.md)
E. CmpLog is our enhanced
[Redqueen](https://www.ndss-symposium.org/ndss-paper/redqueen-fuzzing-with-input-to-state-correspondence/)
implementation, see
[instrumentation/README.cmplog.md](../instrumentation/README.cmplog.md)
F. Similar and compatible to clang 13+ sancov sanitize-coverage-allow/deny but
for all llvm versions and all our compile modes, only instrument what should
be instrumented, for more speed, directed fuzzing and less instability; see
[instrumentation/README.instrument_list.md](../instrumentation/README.instrument_list.md)
G. Vanilla AFL uses coverage where edges could collide to the same coverage
bytes the larger the target is. Our default instrumentation in LTO and
afl-clang-fast (PCGUARD) uses non-colliding coverage that also makes it
faster. Vanilla AFL style is available with `AFL_LLVM_INSTRUMENT=AFL`; see
[instrumentation/README.llvm.md](../instrumentation/README.llvm.md).
H.+I. Alternative coverage based on previous edges (NGRAM) or depending on the
caller (CTX), based on
[https://www.usenix.org/system/files/raid2019-wang-jinghan.pdf](https://www.usenix.org/system/files/raid2019-wang-jinghan.pdf);
see [instrumentation/README.llvm.md](../instrumentation/README.llvm.md).
J. An LTO feature that creates a fuzzing dictionary based on comparisons found
during compilation/instrumentation. Automatic feature :) See
[instrumentation/README.lto.md](../instrumentation/README.lto.md)
K. The snapshot feature requires a kernel module that was a lot of work to get
right and maintained so it is no longer supported. We have
[nyx_mode](../nyx_mode/README.md) instead.
L. Faster fuzzing and less kernel syscall overhead by in-memory fuzz testcase
delivery, see
[instrumentation/README.persistent_mode.md](../instrumentation/README.persistent_mode.md)
## More information about instrumentation
1. Default for LLVM >= 9.0, environment variable for older version due an
efficiency bug in previous llvm versions
2. GCC creates non-performant code, hence it is disabled in gcc_plugin
3. with `AFL_LLVM_THREADSAFE_INST`, disables NeverZero
4. with pcguard mode and LTO mode for LLVM 11 and newer
5. upcoming, development in the branch
6. not compatible with LTO instrumentation and needs at least LLVM v4.1
7. automatic in LTO mode with LLVM 11 and newer, an extra pass for all LLVM
3. With `AFL_LLVM_THREADSAFE_INST`, disables NeverZero
4. With pcguard mode and LTO mode for LLVM 11 and newer
5. Upcoming, development in the branch
6. Not compatible with LTO instrumentation and needs at least LLVM v4.1
7. Automatic in LTO mode with LLVM 11 and newer, an extra pass for all LLVM
versions that write to a file to use with afl-fuzz' `-x`
8. the snapshot LKM is currently unmaintained due to too many kernel changes
8. The snapshot LKM is currently unmaintained due to too many kernel changes
coming too fast :-(
9. FRIDA mode is supported on Linux and MacOS for Intel and ARM
10. QEMU/Unicorn is only supported on Linux
11. Coresight mode is only available on AARCH64 Linux with a CPU with Coresight
extension
12. Nyx mode is only supported on Linux and currently restricted to x86_x64
## Integrated features and patches
Among others, the following features and patches have been integrated:
@ -43,7 +100,7 @@ Among others, the following features and patches have been integrated:
* Unicorn mode which allows fuzzing of binaries from completely different
platforms (integration provided by domenukk)
* The new CmpLog instrumentation for LLVM and QEMU inspired by
[Redqueen](https://www.syssec.ruhr-uni-bochum.de/media/emma/veroeffentlichungen/2018/12/17/NDSS19-Redqueen.pdf)
[Redqueen](https://github.com/RUB-SysSec/redqueen)
* Win32 PE binary-only fuzzing with QEMU and Wine
* AFLfast's power schedules by Marcel Böhme:
[https://github.com/mboehme/aflfast](https://github.com/mboehme/aflfast)

View File

@ -12,11 +12,11 @@ fuzzed with AFL++.
## TL;DR:
QEMU mode in persistent mode is the fastest - if the stability is high enough.
Otherwise, try RetroWrite, Dyninst, and if these fail, too, then try standard
QEMU mode with `AFL_ENTRYPOINT` to where you need it.
FRIDA mode and QEMU mode in persistent mode are the fastest - if persistent mode
is possible and the stability is high enough.
If your target is a library, then use FRIDA mode.
Otherwise, try Zafl, RetroWrite, Dyninst, and if these fail, too, then try
standard FRIDA/QEMU mode with `AFL_ENTRYPOINT` to where you need it.
If your target is non-linux, then use unicorn_mode.
@ -92,7 +92,7 @@ For more information, see
### FRIDA mode
In FRIDA mode, you can fuzz binary-only targets as easily as with QEMU mode.
FRIDA mode is sometimes faster and sometimes slower than QEMU mode. It is also
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).
@ -100,7 +100,7 @@ To build FRIDA mode:
```shell
cd frida_mode
make
gmake
```
For additional instructions and caveats, see
@ -126,6 +126,16 @@ to check out our sister project libafl which supports Frida, too:
[https://github.com/AFLplusplus/LibAFL](https://github.com/AFLplusplus/LibAFL).
Working examples already exist :-)
### Nyx mode
Nyx is a full system emulation fuzzing environment with snapshot support that is
built upon KVM and QEMU. It is only available on Linux and currently restricted
to x86_x64.
For binary-only fuzzing a special 5.10 kernel is required.
See [nyx_mode/README.md](../nyx_mode/README.md).
### Unicorn
Unicorn is a fork of QEMU. The instrumentation is, therefore, very similar. In
@ -189,12 +199,15 @@ afl-clang-fast's.
### RetroWrite
If you have an x86/x86_64 binary that still has its symbols, is compiled with
position independent code (PIC/PIE), and does not use most of the C++ features,
then the RetroWrite solution might be for you. It decompiles to ASM files which
can then be instrumented with afl-gcc.
RetroWrite is a static binary rewriter that can be combined with AFL++. If you
have an x86_64 binary that still has its symbols (i.e., not stripped binary), is
compiled with position independent code (PIC/PIE), and does not contain C++
exceptions, then the RetroWrite solution might be for you. It decompiles to ASM
files which can then be instrumented with afl-gcc.
It is at about 80-85% performance.
Binaries that are statically instrumented for fuzzing using RetroWrite are close
in performance to compiler-instrumented binaries and outperform the QEMU-based
instrumentation.
[https://github.com/HexHive/retrowrite](https://github.com/HexHive/retrowrite)
@ -293,4 +306,4 @@ some are very hard to set-up...
## Closing words
That's it! News, corrections, updates? Send an email to vh@thc.org.
That's it! News, corrections, updates? Send an email to vh@thc.org.

View File

@ -55,7 +55,7 @@ tasks, fuzzing may put a strain on your hardware and on the OS. In particular:
### a) Selecting the best AFL++ compiler for instrumenting the target
AFL++ comes with a central compiler `afl-cc` that incorporates various different
kinds of compiler targets and and instrumentation options. The following
kinds of compiler targets and instrumentation options. The following
evaluation flow will help you to select the best possible.
It is highly recommended to have the newest llvm version possible installed,
@ -95,38 +95,43 @@ Clickable README links for the chosen compiler:
* 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:
1. use a symlink to afl-cc: afl-gcc, afl-g++, afl-clang, afl-clang++,
afl-clang-fast, afl-clang-fast++, afl-clang-lto, afl-clang-lto++,
afl-gcc-fast, afl-g++-fast (recommended!)
2. using the environment variable AFL_CC_COMPILER with MODE
3. passing --afl-MODE command line options to the compiler via
CFLAGS/CXXFLAGS/CPPFLAGS
You can select the mode for the afl-cc compiler by one of the following methods:
MODE can be one of: LTO (afl-clang-lto*), LLVM (afl-clang-fast*), GCC_PLUGIN
(afl-g*-fast) or GCC (afl-gcc/afl-g++) or CLANG(afl-clang/afl-clang++).
* Using a symlink to afl-cc: afl-gcc, afl-g++, afl-clang, afl-clang++,
afl-clang-fast, afl-clang-fast++, afl-clang-lto, afl-clang-lto++,
afl-gcc-fast, afl-g++-fast (recommended!).
* Using the environment variable `AFL_CC_COMPILER` with `MODE`.
* Passing --afl-`MODE` command line options to the compiler via
`CFLAGS`/`CXXFLAGS`/`CPPFLAGS`.
`MODE` can be one of the following:
* LTO (afl-clang-lto*)
* LLVM (afl-clang-fast*)
* GCC_PLUGIN (afl-g*-fast) or GCC (afl-gcc/afl-g++)
* CLANG(afl-clang/afl-clang++)
Because no AFL++ specific command-line options are accepted (beside the
--afl-MODE command), the compile-time tools make fairly broad use of environment
variables, which can be listed with `afl-cc -hh` or by reading
variables, which can be listed with `afl-cc -hh` or looked up in
[env_variables.md](env_variables.md).
### b) Selecting instrumentation options
The following options are available when you instrument with LTO mode
(afl-clang-fast/afl-clang-lto):
If you instrument with LTO mode (afl-clang-fast/afl-clang-lto), the following
options are available:
* Splitting integer, string, float and switch comparisons so AFL++ can easier
* Splitting integer, string, float, and switch comparisons so AFL++ can easier
solve these. This is an important option if you do not have a very good and
large input corpus. This technique is called laf-intel or COMPCOV. To use this
set the following environment variable before compiling the target: `export
AFL_LLVM_LAF_ALL=1` You can read more about this in
large input corpus. This technique is called laf-intel or COMPCOV. To use
this, set the following environment variable before compiling the target:
`export AFL_LLVM_LAF_ALL=1`. You can read more about this in
[instrumentation/README.laf-intel.md](../instrumentation/README.laf-intel.md).
* A different technique (and usually a better one than laf-intel) is to
instrument the target so that any compare values in the target are sent to
AFL++ which then tries to put these values into the fuzzing data at different
locations. This technique is very fast and good - if the target does not
transform input data before comparison. Therefore this technique is called
transform input data before comparison. Therefore, this technique is called
`input to state` or `redqueen`. If you want to use this technique, then you
have to compile the target twice, once specifically with/for this mode by
setting `AFL_LLVM_CMPLOG=1`, and pass this binary to afl-fuzz via the `-c`
@ -135,24 +140,49 @@ The following options are available when you instrument with LTO mode
about this in
[instrumentation/README.cmplog.md](../instrumentation/README.cmplog.md).
If you use LTO, LLVM or GCC_PLUGIN mode
(afl-clang-fast/afl-clang-lto/afl-gcc-fast) you have the option to selectively
only instrument parts of the target that you are interested in:
If you use LTO, LLVM, or GCC_PLUGIN mode
(afl-clang-fast/afl-clang-lto/afl-gcc-fast), you have the option to selectively
instrument _parts_ of the target that you are interested in. For afl-clang-fast,
you have to use an llvm version newer than 10.0.0 or a mode other than
DEFAULT/PCGUARD.
* To instrument only those parts of the target that you are interested in create
a file with all the filenames of the source code that should be instrumented.
For afl-clang-lto and afl-gcc-fast - or afl-clang-fast if a mode other than
DEFAULT/PCGUARD is used or you have llvm > 10.0.0 - just put one filename or
function per line (no directory information necessary for filenames9, and
either set `export AFL_LLVM_ALLOWLIST=allowlist.txt` **or** `export
AFL_LLVM_DENYLIST=denylist.txt` - depending on if you want per default to
instrument unless noted (DENYLIST) or not perform instrumentation unless
requested (ALLOWLIST). **NOTE:** During optimization functions might be
inlined and then would not match! See
[instrumentation/README.instrument_list.md](../instrumentation/README.instrument_list.md)
This step can be done either by explicitly including parts to be instrumented or
by explicitly excluding parts from instrumentation.
* To instrument _only specified parts_, create a file (e.g., `allowlist.txt`)
with all the filenames and/or functions of the source code that should be
instrumented and then:
1. Just put one filename or function (prefixing with `fun: `) per line (no
directory information necessary for filenames) in the file `allowlist.txt`.
Example:
```
foo.cpp # will match foo/foo.cpp, bar/foo.cpp, barfoo.cpp etc.
fun: foo_func # will match the function foo_func
```
2. Set `export AFL_LLVM_ALLOWLIST=allowlist.txt` to enable selective positive
instrumentation.
* Similarly to _exclude_ specified parts from instrumentation, create a file
(e.g., `denylist.txt`) with all the filenames of the source code that should
be skipped during instrumentation and then:
1. Same as above. Just put one filename or function per line in the file
`denylist.txt`.
2. Set `export AFL_LLVM_DENYLIST=denylist.txt` to enable selective negative
instrumentation.
**NOTE:** During optimization functions might be
inlined and then would not match the list! See
[instrumentation/README.instrument_list.md](../instrumentation/README.instrument_list.md).
There are many more options and modes available, however, these are most of the
time less effective. See:
* [instrumentation/README.llvm.md#6) AFL++ Context Sensitive Branch Coverage](../instrumentation/README.llvm.md#6-afl-context-sensitive-branch-coverage)
* [instrumentation/README.llvm.md#7) AFL++ N-Gram Branch Coverage](../instrumentation/README.llvm.md#7-afl-n-gram-branch-coverage)
@ -166,26 +196,27 @@ It is possible to use sanitizers when instrumenting targets for fuzzing, which
allows you to find bugs that would not necessarily result in a crash.
Note that sanitizers have a huge impact on CPU (= less executions per second)
and RAM usage. Also you should only run one afl-fuzz instance per sanitizer
type. This is enough because a use-after-free bug will be picked up, e.g., by
ASAN (address sanitizer) anyway when syncing to other fuzzing instances, so not
all fuzzing instances need to be instrumented with ASAN.
and RAM usage. Also, you should only run one afl-fuzz instance per sanitizer
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.
The following sanitizers have built-in support in AFL++:
* ASAN = Address SANitizer, finds memory corruption vulnerabilities like
use-after-free, NULL pointer dereference, buffer overruns, etc. Enabled with
`export AFL_USE_ASAN=1` before compiling.
* MSAN = Memory SANitizer, finds read access to uninitialized memory, e.g., a
* MSAN = Memory SANitizer, finds read accesses to uninitialized memory, e.g., a
local variable that is defined and read before it is even set. Enabled with
`export AFL_USE_MSAN=1` before compiling.
* UBSAN = Undefined Behavior SANitizer, finds instances where - by the C and C++
standards - undefined behavior happens, e.g., adding two signed integers
together where the result is larger than a signed integer can hold. Enabled
with `export AFL_USE_UBSAN=1` before compiling.
standards - undefined behavior happens, e.g., adding two signed integers where
the result is larger than what a signed integer can hold. Enabled with `export
AFL_USE_UBSAN=1` before compiling.
* CFISAN = Control Flow Integrity SANitizer, finds instances where the control
flow is found to be illegal. Originally this was rather to prevent return
oriented programming exploit chains from functioning, in fuzzing this is
mostly reduced to detecting type confusion vulnerabilities - which is,
oriented programming (ROP) exploit chains from functioning. In fuzzing, this
is mostly reduced to detecting type confusion vulnerabilities - which is,
however, one of the most important and dangerous C++ memory corruption
classes! Enabled with `export AFL_USE_CFISAN=1` before compiling.
* TSAN = Thread SANitizer, finds thread race conditions. Enabled with `export
@ -194,7 +225,10 @@ The following sanitizers have built-in support in AFL++:
security issue, but for developers this can be very valuable. Note that unlike
the other sanitizers above this needs `__AFL_LEAK_CHECK();` added to all areas
of the target source code where you find a leak check necessary! Enabled with
`export AFL_USE_LSAN=1` before compiling.
`export AFL_USE_LSAN=1` before compiling. To ignore the memory-leaking check
for certain allocations, `__AFL_LSAN_OFF();` can be used before memory is
allocated, and `__AFL_LSAN_ON();` afterwards. Memory allocated between these
two macros will not be checked for memory leaks.
It is possible to further modify the behavior of the sanitizers at run-time by
setting `ASAN_OPTIONS=...`, `LSAN_OPTIONS` etc. - the available parameters can
@ -227,20 +261,20 @@ All AFL++ compilers will set this preprocessor definition automatically.
### e) Instrumenting the target
In this step the target source code is compiled so that it can be fuzzed.
In this step, the target source code is compiled so that it can be fuzzed.
Basically you have to tell the target build system that the selected AFL++
Basically, you have to tell the target build system that the selected AFL++
compiler is used. Also - if possible - you should always configure the build
system such that the target is compiled statically and not dynamically. How to
do this is described below.
system in such way that the target is compiled statically and not dynamically.
How to do this is described below.
The #1 rule when instrumenting a target is: avoid instrumenting shared libraries
at all cost. You would need to set LD_LIBRARY_PATH to point to these, you could
accidentally type "make install" and install them system wide - so don't. Really
don't. **Always compile libraries you want to have instrumented as static and
link these to the target program!**
at all cost. You would need to set `LD_LIBRARY_PATH` to point to these, you
could accidentally type "make install" and install them system wide - so don't.
Really don't. **Always compile libraries you want to have instrumented as static
and link these to the target program!**
Then build the target. (Usually with `make`)
Then build the target. (Usually with `make`.)
**NOTES**
@ -254,45 +288,54 @@ Then build the target. (Usually with `make`)
3. In case the configure/build system complains about AFL++'s compiler and
aborts, then set `export AFL_NOOPT=1` which will then just behave like the
real compiler. This option has to be unset again before building the target!
real compiler and run the configure step separately. For building the target
afterwards this option has to be unset again!
#### configure
For `configure` build systems this is usually done by:
For `configure` build systems, this is usually done by:
`CC=afl-clang-fast CXX=afl-clang-fast++ ./configure --disable-shared`
```
CC=afl-clang-fast CXX=afl-clang-fast++ ./configure --disable-shared
```
Note that if you are using the (better) afl-clang-lto compiler, you also have to
set `AR` to llvm-ar[-VERSION] and `RANLIB` to llvm-ranlib[-VERSION] - as is
described in [instrumentation/README.lto.md](../instrumentation/README.lto.md).
#### CMake
For CMake build systems, this is usually done by:
```
mkdir build; cd build; cmake -DCMAKE_C_COMPILER=afl-cc -DCMAKE_CXX_COMPILER=afl-c++ ..
```
Note that if you are using the (better) afl-clang-lto compiler you also have to
set AR to llvm-ar[-VERSION] and RANLIB to llvm-ranlib[-VERSION] - as is
described in [instrumentation/README.lto.md](../instrumentation/README.lto.md).
#### cmake
#### Meson Build System
For `cmake` build systems this is usually done by:
For the Meson Build System, you have to set the AFL++ compiler with the very
first command!
`mkdir build; cd build; cmake -DCMAKE_C_COMPILER=afl-cc -DCMAKE_CXX_COMPILER=afl-c++ ..`
```
CC=afl-cc CXX=afl-c++ meson
```
Note that if you are using the (better) afl-clang-lto compiler you also have to
set AR to llvm-ar[-VERSION] and RANLIB to llvm-ranlib[-VERSION] - as is
described in [instrumentation/README.lto.md](../instrumentation/README.lto.md).
#### Other build systems or if configure/cmake didn't work
#### meson
For meson you have to set the AFL++ compiler with the very first command!
`CC=afl-cc CXX=afl-c++ meson`
#### other build systems or if configure/cmake didn't work
Sometimes cmake and configure do not pick up the AFL++ compiler, or the
ranlib/ar that is needed - because this was just not foreseen by the developer
of the target. Or they have non-standard options. Figure out if there is a
non-standard way to set this, otherwise set up the build normally and edit the
generated build environment afterwards manually to point it to the right
compiler (and/or ranlib and ar).
Sometimes `cmake` and `configure` do not pick up the AFL++ compiler or the
`RANLIB`/`AR` that is needed - because this was just not foreseen by the
developer of the target. Or they have non-standard options. Figure out if there
is a non-standard way to set this, otherwise set up the build normally and edit
the generated build environment afterwards manually to point it to the right
compiler (and/or `RANLIB` and `AR`).
### f) Better instrumentation
If you just fuzz a target program as-is you are wasting a great opportunity for
If you just fuzz a target program as-is, you are wasting a great opportunity for
much more fuzzing speed.
This variant requires the usage of afl-clang-lto, afl-clang-fast or
@ -304,7 +347,7 @@ that you want to fuzz, plus a few specific AFL++ functions around it. See
[instrumentation/README.persistent_mode.md](../instrumentation/README.persistent_mode.md)
for details.
Basically if you do not fuzz a target in persistent mode, then you are just
Basically, if you do not fuzz a target in persistent mode, then you are just
doing it for a hobby and not professionally :-).
### g) libfuzzer fuzzer harnesses with LLVMFuzzerTestOneInput()
@ -319,7 +362,7 @@ afl-clang-fast++ -fsanitize=fuzzer -o harness harness.cpp targetlib.a
```
You can even use advanced libfuzzer features like `FuzzedDataProvider`,
`LLVMFuzzerMutate()` etc. and they will work!
`LLVMFuzzerInitialize()` etc. and they will work!
The generated binary is fuzzed with afl-fuzz like any other fuzz target.
@ -354,22 +397,28 @@ You can find many good examples of starting files in the
### b) Making the input corpus unique
Use the AFL++ tool `afl-cmin` to remove inputs from the corpus that do not
produce a new path/coverage in the target.
produce a new path/coverage in the target:
Put all files from step a) into one directory, e.g., INPUTS.
1. Put all files from [step a](#a-collecting-inputs) into one directory, e.g.,
`INPUTS`.
2. Run afl-cmin:
* If the target program is to be called by fuzzing as `bin/target INPUTFILE`,
replace the INPUTFILE argument that the target program would read from with
`@@`:
If the target program is to be called by fuzzing as `bin/target -d INPUTFILE`
the run afl-cmin like this:
```
afl-cmin -i INPUTS -o INPUTS_UNIQUE -- bin/target -someopt @@
```
`afl-cmin -i INPUTS -o INPUTS_UNIQUE -- bin/target -d @@`
* If the target reads from stdin (standard input) instead, just omit the `@@`
as this is the default:
Note that the INPUTFILE argument that the target program would read from has to
be set as `@@`.
```
afl-cmin -i INPUTS -o INPUTS_UNIQUE -- bin/target -someopt
```
If the target reads from stdin instead, just omit the `@@` as this is the
default.
This step is highly recommended!
This step is highly recommended, because afterwards the testcase corpus is not
bloated with duplicates anymore, which would slow down the fuzzing progress!
### c) Minimizing all corpus files
@ -381,18 +430,20 @@ however, it is a long process as this has to be done for every file:
mkdir input
cd INPUTS_UNIQUE
for i in *; do
afl-tmin -i "$i" -o "../input/$i" -- bin/target -d @@
afl-tmin -i "$i" -o "../input/$i" -- bin/target -someopt @@
done
```
This step can also be parallelized, e.g., with `parallel`. Note that this step
is rather optional though.
This step can also be parallelized, e.g., with `parallel`.
Note that this step is rather optional though.
### Done!
The INPUTS_UNIQUE/ directory from step b) - or even better the directory input/
if you minimized the corpus in step c) - is the resulting input corpus directory
to be used in fuzzing! :-)
The INPUTS_UNIQUE/ directory from [step b](#b-making-the-input-corpus-unique) -
or even better the directory input/ if you minimized the corpus in
[step c](#c-minimizing-all-corpus-files) - is the resulting input corpus
directory to be used in fuzzing! :-)
## 3. Fuzzing the target
@ -400,77 +451,90 @@ In this final step, fuzz the target. There are not that many important options
to run the target - unless you want to use many CPU cores/threads for the
fuzzing, which will make the fuzzing much more useful.
If you just use one CPU for fuzzing, then you are fuzzing just for fun and not
seriously :-)
If you just use one instance for fuzzing, then you are fuzzing just for fun and
not seriously :-)
### a) Running afl-fuzz
Before you do even a test run of afl-fuzz execute `sudo afl-system-config` (on
the host if you execute afl-fuzz in a docker container). This reconfigures the
Before you do even a test run of afl-fuzz, execute `sudo afl-system-config` (on
the host if you execute afl-fuzz in a Docker container). This reconfigures the
system for optimal speed - which afl-fuzz checks and bails otherwise. Set
`export AFL_SKIP_CPUFREQ=1` for afl-fuzz to skip this check if you cannot run
afl-system-config with root privileges on the host for whatever reason.
Note there is also `sudo afl-persistent-config` which sets additional permanent
boot options for a much better fuzzing performance.
Note:
Note that both scripts improve your fuzzing performance but also decrease your
system protection against attacks! So set strong firewall rules and only expose
SSH as a network service if you use these (which is highly recommended).
* There is also `sudo afl-persistent-config` which sets additional permanent
boot options for a much better fuzzing performance.
* Both scripts improve your fuzzing performance but also decrease your system
protection against attacks! So set strong firewall rules and only expose SSH
as a network service if you use these (which is highly recommended).
If you have an input corpus from step 2, then specify this directory with the
`-i` option. Otherwise, create a new directory and create a file with any
content as test data in there.
If you have an input corpus from [step 2](#2-preparing-the-fuzzing-campaign),
then specify this directory with the `-i` option. Otherwise, create a new
directory and create a file with any content as test data in there.
If you do not want anything special, the defaults are already usually best,
hence all you need is to specify the seed input directory with the result of
step [2a) Collect inputs](#a-collect-inputs):
step [2a) Collecting inputs](#a-collecting-inputs):
`afl-fuzz -i input -o output -- bin/target -d @@`
```
afl-fuzz -i input -o output -- bin/target -someopt @@
```
Note that the directory specified with `-o` will be created if it does not
exist.
It can be valuable to run afl-fuzz in a screen or tmux shell so you can log off,
or afl-fuzz is not aborted if you are running it in a remote ssh session where
the connection fails in between. Only do that though once you have verified that
your fuzzing setup works! Run it like `screen -dmS afl-main -- afl-fuzz -M
main-$HOSTNAME -i ...` and it will start away in a screen session. To enter this
session, type `screen -r afl-main`. You see - it makes sense to name the screen
session same as the afl-fuzz -M/-S naming :-) For more information on screen or
tmux, check their documentation.
It can be valuable to run afl-fuzz in a `screen` or `tmux` shell so you can log
off, or afl-fuzz is not aborted if you are running it in a remote ssh session
where the connection fails in between. Only do that though once you have
verified that your fuzzing setup works! Run it like `screen -dmS afl-main --
afl-fuzz -M main-$HOSTNAME -i ...` and it will start away in a screen session.
To enter this session, type `screen -r afl-main`. You see - it makes sense to
name the screen session same as the afl-fuzz `-M`/`-S` naming :-) For more
information on screen or tmux, check their documentation.
If you need to stop and re-start the fuzzing, use the same command line options
(or even change them by selecting a different power schedule or another mutation
mode!) and switch the input directory with a dash (`-`):
`afl-fuzz -i - -o output -- bin/target -d @@`
```
afl-fuzz -i - -o output -- bin/target -someopt @@
```
Adding a dictionary is helpful. See the directory
[dictionaries/](../dictionaries/) if something is already included for your data
format, and tell afl-fuzz to load that dictionary by adding `-x
dictionaries/FORMAT.dict`. With afl-clang-lto, you have an autodictionary
generation for which you need to do nothing except to use afl-clang-lto as the
compiler. You also have the option to generate a dictionary yourself, see
[utils/libtokencap/README.md](../utils/libtokencap/README.md).
Adding a dictionary is helpful. You have to following options:
* See the directory
[dictionaries/](../dictionaries/), if something is already included for your
data format, and tell afl-fuzz to load that dictionary by adding `-x
dictionaries/FORMAT.dict`.
* With `afl-clang-lto`, you have an autodictionary generation for which you need
to do nothing except to use afl-clang-lto as the compiler.
* With `afl-clang-fast`, you can set
`AFL_LLVM_DICT2FILE=/full/path/to/new/file.dic` to automatically generate a
dictionary during target compilation.
* You also have the option to generate a dictionary yourself during an
independent run of the target, see
[utils/libtokencap/README.md](../utils/libtokencap/README.md).
* Finally, you can also write a dictionary file manually, of course.
afl-fuzz has a variety of options that help to workaround target quirks like
specific locations for the input file (`-f`), performing deterministic fuzzing
(`-D`) and many more. Check out `afl-fuzz -h`.
very specific locations for the input file (`-f`), performing deterministic
fuzzing (`-D`) and many more. Check out `afl-fuzz -h`.
We highly recommend that you set a memory limit for running the target with `-m`
which defines the maximum memory in MB. This prevents a potential out-of-memory
problem for your system plus helps you detect missing `malloc()` failure
handling in the target. Play around with various -m values until you find one
handling in the target. Play around with various `-m` values until you find one
that safely works for all your input seeds (if you have good ones and then
double or quadruple that.
double or quadruple that).
By default, afl-fuzz never stops fuzzing. To terminate AFL++, press Control-C or
send a signal SIGINT. You can limit the number of executions or approximate
runtime in seconds with options also.
When you start afl-fuzz you will see a user interface that shows what the status
is:
When you start afl-fuzz, you will see a user interface that shows what the
status is:
![resources/screenshot.png](resources/screenshot.png)
@ -514,8 +578,8 @@ can set the cache size (in MB) by setting the environment variable
There should be one main fuzzer (`-M main-$HOSTNAME` option) and as many
secondary fuzzers (e.g., `-S variant1`) as you have cores that you use. Every
-M/-S entry needs a unique name (that can be whatever), however, the same -o
output directory location has to be used for all instances.
`-M`/`-S` entry needs a unique name (that can be whatever), however, the same
`-o` output directory location has to be used for all instances.
For every secondary fuzzer there should be a variation, e.g.:
* one should fuzz the target that was compiled differently: with sanitizers
@ -530,9 +594,10 @@ For every secondary fuzzer there should be a variation, e.g.:
All other secondaries should be used like this:
* a quarter to a third with the MOpt mutator enabled: `-L 0`
* run with a different power schedule, recommended are:
`fast (default), explore, coe, lin, quad, exploit and rare` which you can set
with, e.g., `-p explore`
* run with a different power schedule, recommended are: `fast` (default),
`explore`, `coe`, `lin`, `quad`, `exploit`, and `rare` which you can set with
the `-p` option, e.g., `-p explore`. See the
[FAQ](FAQ.md#what-are-power-schedules) for details.
* a few instances should use the old queue cycling with `-Z`
Also, it is recommended to set `export AFL_IMPORT_FIRST=1` to load test cases
@ -556,7 +621,7 @@ A long list can be found at
[https://github.com/Microsvuln/Awesome-AFL](https://github.com/Microsvuln/Awesome-AFL).
However, you can also sync AFL++ with honggfuzz, libfuzzer with `-entropic=1`,
etc. Just show the main fuzzer (-M) with the `-F` option where the queue/work
etc. Just show the main fuzzer (`-M`) with the `-F` option where the queue/work
directory of a different fuzzer is, e.g., `-F /src/target/honggfuzz`. Using
honggfuzz (with `-n 1` or `-n 2`) and libfuzzer in parallel is highly
recommended!
@ -575,7 +640,7 @@ Now there are three strategies on how you can sync between the servers:
* regularly (~4h): this ensures that all fuzzing campaigns on the servers "see"
the same thing. It is like fuzzing on a huge server.
* in intervals of 1/10th of the overall expected runtime of the fuzzing you
sync. This tries a bit to combine both. have some individuality of the paths
sync. This tries a bit to combine both. Have some individuality of the paths
each campaign on a server explores, on the other hand if one gets stuck where
another found progress this is handed over making it unstuck.
@ -596,7 +661,8 @@ done
```
You can run this manually, per cron job - as you need it. There is a more
complex and configurable script in `utils/distributed_fuzzing`.
complex and configurable script in
[utils/distributed_fuzzing](../utils/distributed_fuzzing).
### e) The status of the fuzz campaign
@ -612,7 +678,7 @@ If you have multiple servers, then use the command after a sync or you have to
execute this script per server.
Another tool to inspect the current state and history of a specific instance is
afl-plot, which generates an index.html file and a graphs that show how the
afl-plot, which generates an index.html file and graphs that show how the
fuzzing instance is performing. The syntax is `afl-plot instance_dir web_dir`,
e.g., `afl-plot out/default /srv/www/htdocs/plot`.
@ -623,7 +689,7 @@ To stop an afl-fuzz run, press Control-C.
To restart an afl-fuzz run, just reuse the same command line but replace the `-i
directory` with `-i -` or set `AFL_AUTORESUME=1`.
If you want to add new seeds to a fuzzing campaign you can run a temporary
If you want to add new seeds to a fuzzing campaign, you can run a temporary
fuzzing instance, e.g., when your main fuzzer is using `-o out` and the new
seeds are in `newseeds/` directory:
@ -686,21 +752,21 @@ or honggfuzz.
### i) Improve the speed!
* Use [persistent mode](../instrumentation/README.persistent_mode.md) (x2-x20
speed increase)
speed increase).
* If you do not use shmem persistent mode, use `AFL_TMPDIR` to point the input
file on a tempfs location, see [env_variables.md](env_variables.md)
file on a tempfs location, see [env_variables.md](env_variables.md).
* Linux: Improve kernel performance: modify `/etc/default/grub`, set
`GRUB_CMDLINE_LINUX_DEFAULT="ibpb=off ibrs=off kpti=off l1tf=off mds=off
mitigations=off no_stf_barrier noibpb noibrs nopcid nopti
nospec_store_bypass_disable nospectre_v1 nospectre_v2 pcid=off pti=off
spec_store_bypass_disable=off spectre_v2=off stf_barrier=off"`; then
`update-grub` and `reboot` (warning: makes the system more insecure) - you can
also just run `sudo afl-persistent-config`
also just run `sudo afl-persistent-config`.
* Linux: Running on an `ext2` filesystem with `noatime` mount option will be a
bit faster than on any other journaling filesystem
* Use your cores! [3c) Using multiple cores](#c-using-multiple-cores)
bit faster than on any other journaling filesystem.
* Use your cores! See [3c) Using multiple cores](#c-using-multiple-cores).
* Run `sudo afl-system-config` before starting the first afl-fuzz instance after
a reboot
a reboot.
### j) Going beyond crashes
@ -774,7 +840,7 @@ making it easier to diagnose faults.
Having said that, it's important to acknowledge that some fuzzing crashes can be
difficult to quickly evaluate for exploitability without a lot of debugging and
code analysis work. To assist with this task, afl-fuzz supports a very unique
"crash exploration" mode enabled with the -C flag.
"crash exploration" mode enabled with the `-C` flag.
In this mode, the fuzzer takes one or more crashing test cases as the input and
uses its feedback-driven fuzzing strategies to very quickly enumerate all code
@ -800,30 +866,30 @@ mode, it will happily accept instrumented and non-instrumented binaries. In the
non-crashing mode, the minimizer relies on standard AFL++ instrumentation to
make the file simpler without altering the execution path.
The minimizer accepts the -m, -t, -f and @@ syntax in a manner compatible with
afl-fuzz.
The minimizer accepts the `-m`, `-t`, `-f`, and `@@` syntax in a manner
compatible with afl-fuzz.
Another tool in AFL++ is the afl-analyze tool. It takes an input file, attempts
to sequentially flip bytes, and observes the behavior of the tested program. It
then color-codes the input based on which sections appear to be critical, and
to sequentially flip bytes and observes the behavior of the tested program. It
then color-codes the input based on which sections appear to be critical and
which are not; while not bulletproof, it can often offer quick insights into
complex file formats.
## 5. CI fuzzing
Some notes on CI fuzzing - this fuzzing is different to normal fuzzing campaigns
as these are much shorter runnings.
Some notes on continuous integration (CI) fuzzing - this fuzzing is different to
normal fuzzing campaigns as these are much shorter runnings.
1. Always:
* LTO has a much longer compile time which is diametrical to short fuzzing -
hence use afl-clang-fast instead.
* If you compile with CMPLOG, then you can save fuzzing time and reuse that
compiled target for both the `-c` option and the main fuzz target. This
will impact the speed by ~15% though.
* `AFL_FAST_CAL` - Enable fast calibration, this halves the time the
* If you compile with CMPLOG, then you can save compilation time and reuse
that compiled target with the `-c` option and as the main fuzz target.
This will impact the speed by ~15% though.
* `AFL_FAST_CAL` - enables fast calibration, this halves the time the
saturated corpus needs to be loaded.
* `AFL_CMPLOG_ONLY_NEW` - only perform cmplog on new finds, not the
initial corpus as this very likely has been done for them already.
* `AFL_CMPLOG_ONLY_NEW` - only perform cmplog on new finds, not the initial
corpus as this very likely has been done for them already.
* Keep the generated corpus, use afl-cmin and reuse it every time!
2. Additionally randomize the AFL++ compilation options, e.g.:
@ -849,8 +915,8 @@ and
## The End
Check out the [FAQ](FAQ.md) if it maybe answers your question (that you might
not even have known you had ;-) ).
Check out the [FAQ](FAQ.md). Maybe it answers your question (that you might not
even have known you had ;-) ).
This is basically all you need to know to professionally run fuzzing campaigns.
If you want to know more, the tons of texts in [docs/](./) will have you
@ -858,4 +924,4 @@ covered.
Note that there are also a lot of tools out there that help fuzzing with AFL++
(some might be deprecated or unsupported), see
[third_party_tools.md](third_party_tools.md).
[third_party_tools.md](third_party_tools.md).

View File

@ -19,17 +19,17 @@ Mentor: vanhauser-thc
## WASM Instrumentation
Currently, AFL++ can be used for source code fuzzing and traditional binaries.
With the rise of WASM as compile target, however, a novel way of instrumentation
With the rise of WASM as a compile target, however, a novel way of instrumentation
needs to be implemented for binaries compiled to Webassembly. This can either be
done by inserting instrumentation directly into the WASM AST, or by patching
feedback into a WASM VMs of choice, similar to the current Unicorn
feedback into a WASM VM of choice, similar to the current Unicorn
instrumentation.
Mentor: any
## Support other programming languages
Other programming languages also use llvm hence they could (easily?) supported
Other programming languages also use llvm hence they could be (easily?) supported
for fuzzing, e.g., mono, swift, go, kotlin native, fortran, ...
GCC also supports: Objective-C, Fortran, Ada, Go, and D (according to
@ -54,4 +54,4 @@ Mentor: domenukk
## Your idea!
Finally, we are open to proposals! Create an issue at
https://github.com/AFLplusplus/AFLplusplus/issues and let's discuss :-)
https://github.com/AFLplusplus/AFLplusplus/issues and let's discuss :-)

View File

@ -5,24 +5,25 @@ changes.
## From version 3.00 onwards
With AFL++ 3.13-3.20, we introduce FRIDA mode (`-O`) to have an alternative for
binary-only fuzzing. It is slower than QEMU mode but works on MacOS, Android,
iOS etc.
With AFL++ 4.00, we introduced the following changes from previous behaviors:
* the complete documentation was overhauled and restructured thanks to @llzmb!
* a new CMPLOG target format requires recompiling CMPLOG targets for use with
AFL++ 4.0 onwards
* better naming for several fields in the UI
With AFL++ 3.15, we introduced the following changes from previous behaviors:
* Also -M main mode does not do deterministic fuzzing by default anymore
* afl-cmin and afl-showmap -Ci now descent into subdirectories like afl-fuzz
-i does (but note that afl-cmin.bash does not)
* afl-cmin and afl-showmap `-Ci` now descend into subdirectories like afl-fuzz
`-i` does (but note that afl-cmin.bash does not)
With AFL++ 3.14, we introduced the following changes from previous behaviors:
* afl-fuzz: deterministic fuzzing it not a default for -M main anymore
* afl-fuzz: deterministic fuzzing is not a default for `-M main` anymore
* afl-cmin/afl-showmap -i now descends into subdirectories (afl-cmin.bash,
however, does not)
With AFL++ 3.10, we introduced the following changes from previous behaviors:
* The '+' feature of the '-t' option now means to auto-calculate the timeout
* The '+' feature of the `-t` option now means to auto-calculate the timeout
with the value given being the maximum timeout. The original meaning of
"skipping timeouts instead of abort" is now inherent to the -t option.
"skipping timeouts instead of abort" is now inherent to the `-t` option.
With AFL++ 3.00, we introduced changes that break some previous AFL and AFL++
behaviors and defaults:
@ -40,19 +41,20 @@ behaviors and defaults:
if any were given. This allows to fuzz targets build regularly like those
for debug or release versions.
* afl-fuzz:
* if neither -M or -S is specified, `-S default` is assumed, so more fuzzers
can easily be added later
* if neither `-M` or `-S` is specified, `-S default` is assumed, so more
fuzzers can easily be added later
* `-i` input directory option now descends into subdirectories. It also does
not fatal on crashes and too large files, instead it skips them and uses
not fail on crashes and too large files, instead it skips them and uses
them for splicing mutations
* -m none is now default, set memory limits (in MB) with, e.g., -m 250
* deterministic fuzzing is now disabled by default (unless using -M) and can
be enabled with -D
* `-m` none is now the default, set memory limits (in MB) with, e.g., `-m
250`
* deterministic fuzzing is now disabled by default (unless using `-M`) and
can be enabled with `-D`
* a caching of test cases can now be performed and can be modified by
editing config.h for TESTCASE_CACHE or by specifying the environment
editing config.h for `TESTCASE_CACHE` or by specifying the environment
variable `AFL_TESTCACHE_SIZE` (in MB). Good values are between 50-500
(default: 50).
* -M mains do not perform trimming
* examples/ got renamed to utils/
* libtokencap/ libdislocator/ and qdbi_mode/ were moved to utils/
* afl-cmin/afl-cmin.bash now search first in PATH and last in AFL_PATH
* `-M` mains do not perform trimming
* `examples/` got renamed to `utils/`
* `libtokencap/`, `libdislocator/`, and `qdbi_mode/` were moved to `utils/`
* afl-cmin/afl-cmin.bash now search first in `PATH` and last in `AFL_PATH`

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 32 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 14 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 10 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 11 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 13 KiB

View File

@ -424,7 +424,7 @@
"steppedLine": false,
"targets": [
{
"expr": "fuzzing{type=\"unique_crashes\"}",
"expr": "fuzzing{type=\"saved_crashes\"}",
"interval": "",
"legendFormat": "",
"refId": "A"
@ -519,7 +519,7 @@
"steppedLine": false,
"targets": [
{
"expr": "fuzzing{type=\"unique_hangs\"}",
"expr": "fuzzing{type=\"saved_hangs\"}",
"interval": "",
"legendFormat": "",
"refId": "A"

Binary file not shown.

Before

Width:  |  Height:  |  Size: 114 KiB

After

Width:  |  Height:  |  Size: 141 KiB

View File

@ -45,6 +45,8 @@ Deployment, management, monitoring, reporting
parallelize afl-tmin, startup, and data collection.
Crash processing
* [AFLTriage](https://github.com/quic/AFLTriage) -
triage crashing input files using gdb.
* [afl-crash-analyzer](https://github.com/floyd-fuh/afl-crash-analyzer) -
another crash analyzer for AFL.
* [fuzzer-utils](https://github.com/ThePatrickStar/fuzzer-utils) - a set of
@ -54,4 +56,4 @@ Crash processing
* [AFLize](https://github.com/d33tah/aflize) - a tool that automatically
generates builds of debian packages suitable for AFL.
* [afl-fid](https://github.com/FoRTE-Research/afl-fid) - a set of tools for
working with input data.
working with input data.

View File

@ -9,6 +9,7 @@ Here are some good write-ups to show how to effectively use AFL++:
* [https://securitylab.github.com/research/fuzzing-sockets-FTP](https://securitylab.github.com/research/fuzzing-sockets-FTP)
* [https://securitylab.github.com/research/fuzzing-sockets-FreeRDP](https://securitylab.github.com/research/fuzzing-sockets-FreeRDP)
* [https://securitylab.github.com/research/fuzzing-apache-1](https://securitylab.github.com/research/fuzzing-apache-1)
* [https://mmmds.pl/fuzzing-map-parser-part-1-teeworlds/](https://mmmds.pl/fuzzing-map-parser-part-1-teeworlds/)
If you do not want to follow a tutorial but rather try an exercise type of
training, then we can highly recommend the following:
@ -18,13 +19,22 @@ training, then we can highly recommend the following:
If you are interested in fuzzing structured data (where you define what the
structure is), these links have you covered:
* Superion for AFL++:
[https://github.com/adrian-rt/superion-mutator](https://github.com/adrian-rt/superion-mutator)
* libprotobuf for AFL++:
[https://github.com/P1umer/AFLplusplus-protobuf-mutator](https://github.com/P1umer/AFLplusplus-protobuf-mutator)
* libprotobuf raw:
[https://github.com/bruce30262/libprotobuf-mutator_fuzzing_learning/tree/master/4_libprotobuf_aflpp_custom_mutator](https://github.com/bruce30262/libprotobuf-mutator_fuzzing_learning/tree/master/4_libprotobuf_aflpp_custom_mutator)
* libprotobuf for old AFL++ API:
[https://github.com/thebabush/afl-libprotobuf-mutator](https://github.com/thebabush/afl-libprotobuf-mutator)
* Superion for AFL++:
[https://github.com/adrian-rt/superion-mutator](https://github.com/adrian-rt/superion-mutator)
If you find other good ones, please send them to us :-)
## Video Tutorials
* [Install AFL++ Ubuntu](https://www.youtube.com/watch?v=5dCvhkbi3RA)
* [[Fuzzing with AFLplusplus] Installing AFLPlusplus and fuzzing a simple C program](https://www.youtube.com/watch?v=9wRVo0kYSlc)
* [[Fuzzing with AFLplusplus] How to fuzz a binary with no source code on Linux in persistent mode](https://www.youtube.com/watch?v=LGPJdEO02p4)
* [Blackbox Fuzzing #1: Start Binary-Only Fuzzing using AFL++ QEMU mode](https://www.youtube.com/watch?v=sjLFf9q2NRc)
* [HOPE 2020 (2020): Hunting Bugs in Your Sleep - How to Fuzz (Almost) Anything With AFL/AFL++](https://www.youtube.com/watch?v=A8ex1hqaQ7E)
* [How Fuzzing with AFL works!](https://www.youtube.com/watch?v=COHUWuLTbdk)
* [WOOT '20 - AFL++ : Combining Incremental Steps of Fuzzing Research](https://www.youtube.com/watch?v=cZidm6I7KWU)
If you find other good ones, please send them to us :-)

View File

@ -118,16 +118,15 @@ GUM_DEVKIT_FILENAME=frida-gumjs-devkit-$(GUM_DEVKIT_VERSION)-$(OS)-$(ARCH).tar.x
GUM_DEVKIT_URL="https://github.com/frida/frida/releases/download/$(GUM_DEVKIT_VERSION)/$(GUM_DEVKIT_FILENAME)"
GUM_DEVKIT_TARBALL:=$(FRIDA_BUILD_DIR)$(GUM_DEVKIT_FILENAME)
ifdef FRIDA_SOURCE
GUM_DEVIT_LIBRARY=$(FRIDA_DIR)build/frida-linux-$(ARCH)/lib/libfrida-gumjs-1.0.a
else
GUM_DEVIT_LIBRARY=$(FRIDA_BUILD_DIR)libfrida-gumjs.a
endif
GUM_DEVIT_HEADER=$(FRIDA_BUILD_DIR)frida-gumjs.h
FRIDA_DIR:=$(PWD)build/frida-source/
FRIDA_MAKEFILE:=$(FRIDA_DIR)Makefile
FRIDA_GUM:=$(FRIDA_DIR)build/frida-linux-x86_64/lib/libfrida-gumjs-1.0.a
FRIDA_GUM_DEVKIT_DIR:=$(FRIDA_DIR)build/gum-devkit/
FRIDA_GUM_DEVKIT_HEADER:=$(FRIDA_GUM_DEVKIT_DIR)frida-gumjs.h
FRIDA_GUM_DEVKIT_TARBALL:=$(FRIDA_DIR)build/frida-gumjs-devkit-$(GUM_DEVKIT_VERSION)-$(OS)-$(ARCH).tar
FRIDA_GUM_DEVKIT_COMPRESSED_TARBALL:=$(FRIDA_DIR)build/$(GUM_DEVKIT_FILENAME)
AFL_COMPILER_RT_SRC:=$(ROOT)instrumentation/afl-compiler-rt.o.c
AFL_COMPILER_RT_OBJ:=$(OBJ_DIR)afl-compiler-rt.o
@ -142,14 +141,20 @@ AFLPP_FRIDA_DRIVER_HOOK_OBJ=$(BUILD_DIR)frida_hook.so
AFLPP_QEMU_DRIVER_HOOK_SRC:=$(HOOK_DIR)qemu_hook.c
AFLPP_QEMU_DRIVER_HOOK_OBJ:=$(BUILD_DIR)qemu_hook.so
ifneq "$(shell uname)" "Darwin"
ADDR_DIR:=$(PWD)addr/
ADDR_SRC:=$(ADDR_DIR)addr.c
ADDR_BIN:=$(BUILD_DIR)addr
endif
BIN2C:=$(BUILD_DIR)bin2c
BIN2C_SRC:=$(PWD)util/bin2c.c
.PHONY: all 32 clean format hook $(FRIDA_GUM)
.PHONY: all 32 clean format hook addr $(FRIDA_GUM)
############################## ALL #############################################
all: $(FRIDA_TRACE) $(AFLPP_FRIDA_DRIVER_HOOK_OBJ) $(AFLPP_QEMU_DRIVER_HOOK_OBJ)
all: $(FRIDA_TRACE) $(AFLPP_FRIDA_DRIVER_HOOK_OBJ) $(AFLPP_QEMU_DRIVER_HOOK_OBJ) $(ADDR_BIN)
32:
CFLAGS="-m32" LDFLAGS="-m32" ARCH="x86" make all
@ -160,44 +165,101 @@ $(BUILD_DIR):
$(OBJ_DIR): | $(BUILD_DIR)
mkdir -p $@
############################# FRIDA ############################################
$(FRIDA_MAKEFILE): | $(BUILD_DIR)
git clone --recursive https://github.com/frida/frida.git $(FRIDA_DIR)
$(FRIDA_GUM): $(FRIDA_MAKEFILE)
cd $(FRIDA_DIR) && make gum-linux-$(ARCH)
$(FRIDA_GUM_DEVKIT_HEADER): $(FRIDA_GUM)
$(FRIDA_DIR)releng/devkit.py frida-gumjs linux-$(ARCH) $(FRIDA_DIR)build/gum-devkit/
$(FRIDA_GUM_DEVKIT_TARBALL): $(FRIDA_GUM_DEVKIT_HEADER)
cd $(FRIDA_GUM_DEVKIT_DIR) && tar cvf $(FRIDA_GUM_DEVKIT_TARBALL) .
$(FRIDA_GUM_DEVKIT_COMPRESSED_TARBALL): $(FRIDA_GUM_DEVKIT_TARBALL)
xz -k -f -0 $(FRIDA_GUM_DEVKIT_TARBALL)
############################# DEVKIT ###########################################
$(FRIDA_BUILD_DIR): | $(BUILD_DIR)
mkdir -p $@
ifdef FRIDA_SOURCE
$(GUM_DEVKIT_TARBALL): $(FRIDA_GUM_DEVKIT_COMPRESSED_TARBALL)| $(FRIDA_BUILD_DIR)
cp -v $< $@
$(FRIDA_MAKEFILE): | $(BUILD_DIR)
git clone --recursive https://github.com/frida/frida.git $(FRIDA_DIR)
.PHONY: $(GUM_DEVIT_LIBRARY)
$(GUM_DEVIT_LIBRARY): $(FRIDA_MAKEFILE)
cd $(FRIDA_DIR) && make gum-linux-$(ARCH)
$(GUM_DEVIT_HEADER): $(FRIDA_MAKEFILE) | $(FRIDA_BUILD_DIR)
echo "#include <stdio.h>" > $@
echo "#include <unistd.h>" >> $@
echo "#include <gum/gumreturnaddress.h>" >> $@
echo "#include <gum/gumbacktracer.h>" >> $@
echo "#include <gum/gumsymbolutil.h>" >> $@
echo "#include <gum/gumstalker.h>" >> $@
echo "#include <gum/gumlibc.h>" >> $@
echo "#include <gumjs/gumscriptbackend.h>" >> $@
ifeq "$(ARCH)" "arm64"
CFLAGS+=-I $(FRIDA_DIR)build/frida_thin-linux-$(ARCH)/include/frida-1.0 \
-I $(FRIDA_DIR)build/frida_thin-sdk-linux-$(ARCH)/include/glib-2.0/ \
-I $(FRIDA_DIR)build/frida_thin-sdk-linux-$(ARCH)/lib/glib-2.0/include/ \
-I $(FRIDA_DIR)build/frida_thin-sdk-linux-$(ARCH)/include/capstone/ \
-I $(FRIDA_DIR)build/frida_thin-sdk-linux-$(ARCH)/include/json-glib-1.0/ \
TRACE_LDFLAGS+=$(FRIDA_DIR)build/frida-linux-$(ARCH)/lib/libfrida-gum-1.0.a \
$(FRIDA_DIR)build/frida_thin-sdk-linux-$(ARCH)/lib/libsoup-2.4.a \
$(FRIDA_DIR)build/frida_thin-sdk-linux-$(ARCH)/lib/libsqlite3.a \
$(FRIDA_DIR)build/frida_thin-sdk-linux-$(ARCH)/lib/libtcc.a \
$(FRIDA_DIR)build/frida_thin-sdk-linux-$(ARCH)/lib/libjson-glib-1.0.a \
$(FRIDA_DIR)build/frida_thin-sdk-linux-$(ARCH)/lib/libquickjs.a \
$(FRIDA_DIR)build/frida_thin-sdk-linux-$(ARCH)/lib/libcapstone.a \
$(FRIDA_DIR)build/frida_thin-sdk-linux-$(ARCH)/lib/libunwind-*.a \
$(FRIDA_DIR)build/frida_thin-sdk-linux-$(ARCH)/lib/libunwind.a \
$(FRIDA_DIR)build/frida_thin-sdk-linux-$(ARCH)/lib/libffi.a \
$(FRIDA_DIR)build/frida_thin-sdk-linux-$(ARCH)/lib/libdwarf.a \
$(FRIDA_DIR)build/frida_thin-sdk-linux-$(ARCH)/lib/libelf.a \
$(FRIDA_DIR)build/frida_thin-sdk-linux-$(ARCH)/lib/libgio-2.0.a \
$(FRIDA_DIR)build/frida_thin-sdk-linux-$(ARCH)/lib/libgobject-2.0.a \
$(FRIDA_DIR)build/frida_thin-sdk-linux-$(ARCH)/lib/libglib-2.0.a \
$(FRIDA_DIR)build/frida_thin-sdk-linux-$(ARCH)/lib/liblzma.a \
$(FRIDA_DIR)build/frida_thin-sdk-linux-$(ARCH)/lib/libz.a \
else
CFLAGS+=-I $(FRIDA_DIR)build/frida-linux-$(ARCH)/include/frida-1.0 \
-I $(FRIDA_DIR)build/sdk-linux-$(ARCH)/include/glib-2.0/ \
-I $(FRIDA_DIR)build/sdk-linux-$(ARCH)/lib/glib-2.0/include/ \
-I $(FRIDA_DIR)build/sdk-linux-$(ARCH)/include/capstone/ \
-I $(FRIDA_DIR)build/sdk-linux-$(ARCH)/include/json-glib-1.0/ \
TRACE_LDFLAGS+=$(FRIDA_DIR)build/frida-linux-$(ARCH)/lib/libfrida-gum-1.0.a \
$(FRIDA_DIR)build/sdk-linux-$(ARCH)/lib/libsoup-2.4.a \
$(FRIDA_DIR)build/sdk-linux-$(ARCH)/lib/libsqlite3.a \
$(FRIDA_DIR)build/sdk-linux-$(ARCH)/lib/libtcc.a \
$(FRIDA_DIR)build/sdk-linux-$(ARCH)/lib/libjson-glib-1.0.a \
$(FRIDA_DIR)build/sdk-linux-$(ARCH)/lib/libquickjs.a \
$(FRIDA_DIR)build/sdk-linux-$(ARCH)/lib/libcapstone.a \
$(FRIDA_DIR)build/sdk-linux-$(ARCH)/lib/libunwind-*.a \
$(FRIDA_DIR)build/sdk-linux-$(ARCH)/lib/libunwind.a \
$(FRIDA_DIR)build/sdk-linux-$(ARCH)/lib/libffi.a \
$(FRIDA_DIR)build/sdk-linux-$(ARCH)/lib/libdwarf.a \
$(FRIDA_DIR)build/sdk-linux-$(ARCH)/lib/libelf.a \
$(FRIDA_DIR)build/sdk-linux-$(ARCH)/lib/libgio-2.0.a \
$(FRIDA_DIR)build/sdk-linux-$(ARCH)/lib/libgobject-2.0.a \
$(FRIDA_DIR)build/sdk-linux-$(ARCH)/lib/libglib-2.0.a \
$(FRIDA_DIR)build/sdk-linux-$(ARCH)/lib/liblzma.a \
$(FRIDA_DIR)build/sdk-linux-$(ARCH)/lib/libz.a \
endif
else
$(GUM_DEVKIT_TARBALL): | $(FRIDA_BUILD_DIR)
wget -O $@ $(GUM_DEVKIT_URL) || curl -L -o $@ $(GUM_DEVKIT_URL)
endif
$(GUM_DEVIT_LIBRARY): $(GUM_DEVKIT_TARBALL)
tar Jxvfm $(GUM_DEVKIT_TARBALL) -C $(FRIDA_BUILD_DIR)
$(GUM_DEVIT_HEADER): $(GUM_DEVKIT_TARBALL)
tar Jxvfm $(GUM_DEVKIT_TARBALL) -C $(FRIDA_BUILD_DIR)
endif
############################## AFL #############################################
$(AFL_COMPILER_RT_OBJ): $(AFL_COMPILER_RT_SRC)
$(AFL_COMPILER_RT_OBJ): $(AFL_COMPILER_RT_SRC) $(ROOT)include/config.h
$(TARGET_CC) \
$(CFLAGS) \
$(AFL_CFLAGS) \
@ -235,7 +297,7 @@ $(JS_OBJ): $(JS_SRC) GNUmakefile
############################# SOURCE ###########################################
define BUILD_SOURCE
$(2): $(1) $(INCLUDES) GNUmakefile | $(OBJ_DIR)
$(2): $(1) $(INCLUDES) $(GUM_DEVIT_HEADER) | $(OBJ_DIR)
$(TARGET_CC) \
$(CFLAGS) \
-I $(ROOT)include \
@ -256,6 +318,7 @@ $(FRIDA_TRACE): $(GUM_DEVIT_LIBRARY) $(GUM_DEVIT_HEADER) $(OBJS) $(JS_OBJ) $(AFL
$(GUM_DEVIT_LIBRARY) \
$(AFL_COMPILER_RT_OBJ) \
$(AFL_PERFORMANCE_OBJ) \
$(TRACE_LDFLAGS) \
$(LDFLAGS) \
$(LDSCRIPT) \
-o $@ \
@ -272,13 +335,30 @@ $(AFLPP_QEMU_DRIVER_HOOK_OBJ): $(AFLPP_QEMU_DRIVER_HOOK_SRC) | $(BUILD_DIR)
hook: $(AFLPP_FRIDA_DRIVER_HOOK_OBJ) $(AFLPP_QEMU_DRIVER_HOOK_OBJ)
############################# ADDR #############################################
$(ADDR_BIN): $(ADDR_SRC) | $(BUILD_DIR)
-$(TARGET_CC) \
$(CFLAGS) \
-Werror \
-Wall \
-Wextra \
-Wpointer-arith \
-z noexecstack \
-Wl,--gc-sections \
-Wl,--exclude-libs,ALL \
-ldl \
-lrt \
$< -o $@
addr: $(ADDR_BIN)
############################# CLEAN ############################################
clean:
rm -rf $(BUILD_DIR)
############################# FORMAT ###########################################
format:
cd $(ROOT) && echo $(SOURCES) $(AFLPP_FRIDA_DRIVER_HOOK_SRC) $(BIN2C_SRC) | xargs -L1 ./.custom-format.py -i
cd $(ROOT) && echo $(SOURCES) $(AFLPP_FRIDA_DRIVER_HOOK_SRC) $(BIN2C_SRC) $(ADDR_BIN ) | xargs -L1 ./.custom-format.py -i
cd $(ROOT) && echo $(INCLUDES) | xargs -L1 ./.custom-format.py -i
############################# RUN #############################################

View File

@ -176,9 +176,6 @@ instances run CMPLOG mode and instrumentation of the binary is less frequent
* `AFL_FRIDA_INST_NO_OPTIMIZE` - Don't use optimized inline assembly coverage
instrumentation (the default where available). Required to use
`AFL_FRIDA_INST_TRACE`.
* `AFL_FRIDA_INST_NO_BACKPATCH` - Disable backpatching. At the end of executing
each block, control will return to FRIDA to identify the next block to
execute.
* `AFL_FRIDA_INST_NO_PREFETCH` - Disable prefetching. By default, the child will
report instrumented blocks back to the parent so that it can also instrument
them and they be inherited by the next child on fork, implies
@ -227,6 +224,9 @@ instances run CMPLOG mode and instrumentation of the binary is less frequent
* `AFL_FRIDA_STALKER_IC_ENTRIES` - Configure the number of inline cache entries
stored along-side branch instructions which provide a cache to avoid having to
call back into FRIDA to find the next block. Default is 32.
* `AFL_FRIDA_STALKER_NO_BACKPATCH` - Disable backpatching. At the end of executing
each block, control will return to FRIDA to identify the next block to
execute.
* `AFL_FRIDA_STATS_FILE` - Write statistics information about the code being
instrumented to the given file name. The statistics are written only for the
child process when new block is instrumented (when the
@ -307,6 +307,7 @@ instances run CMPLOG mode and instrumentation of the binary is less frequent
core dump of the instrumented target. Note that in order to capture the core
dump you must set a sufficient timeout (using `-t`) to avoid `afl-fuzz`
killing the process whilst it is being dumped.
* `AFL_FRIDA_VERBOSE` - Enable verbose output from FRIDA mode.
## FASAN - FRIDA Address Sanitizer mode
@ -376,4 +377,4 @@ Should you encounter problems with FRIDA mode, refer to
The next features to be added are Aarch32 support as well as looking at
potential performance improvements. The intention is to achieve feature parity
with QEMU mode in due course. Contributions are welcome, but please get in touch
to ensure that efforts are deconflicted.
to ensure that efforts are deconflicted.

View File

@ -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-2020 AFLplusplus Project. All rights reserved.
Copyright 2019-2022 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:
@ -782,7 +782,7 @@ class Afl {
Afl.jsApiWrite(STDOUT_FILENO, buf, log.length);
}
/**
* See `AFL_FRIDA_INST_NO_BACKPATCH`.
* See `AFL_FRIDA_STALKER_NO_BACKPATCH`.
*/
static setBackpatchDisable() {
Afl.jsApiSetBackpatchDisable();
@ -995,4 +995,4 @@ class Afl {
return Afl.module.getExportByName(name);
}
}
```
```

39
frida_mode/addr/addr.c Normal file
View File

@ -0,0 +1,39 @@
#include <errno.h>
#include <link.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/personality.h>
#define UNUSED_PARAMETER(x) (void)(x)
int phdr_callback(struct dl_phdr_info *info, size_t size, void *data)
{
UNUSED_PARAMETER (size);
ElfW(Addr) * base = data;
if (info->dlpi_name[0] == 0) { *base = info->dlpi_addr; }
return 0;
}
int main (int argc, char** argv, char** envp) {
UNUSED_PARAMETER (argc);
ElfW(Addr) base = 0;
int persona = personality(ADDR_NO_RANDOMIZE);
if (persona == -1) {
printf("Failed to set ADDR_NO_RANDOMIZE: %d", errno);
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;
}

View File

@ -37,6 +37,7 @@
js_api_set_stderr;
js_api_set_stdout;
js_api_set_traceable;
js_api_set_verbose;
local:
*;

View File

@ -5,14 +5,13 @@
#include "config.h"
extern char * instrument_debug_filename;
extern char * instrument_coverage_filename;
extern gboolean instrument_tracing;
extern gboolean instrument_optimize;
extern gboolean instrument_unique;
extern __thread guint64 instrument_previous_pc;
extern guint64 instrument_hash_zero;
extern char * instrument_coverage_unstable_filename;
extern char * instrument_debug_filename;
extern char * instrument_coverage_filename;
extern gboolean instrument_tracing;
extern gboolean instrument_optimize;
extern gboolean instrument_unique;
extern guint64 instrument_hash_zero;
extern char * instrument_coverage_unstable_filename;
extern gboolean instrument_use_fixed_seed;
extern guint64 instrument_fixed_seed;
@ -20,6 +19,8 @@ extern guint64 instrument_fixed_seed;
extern uint8_t *__afl_area_ptr;
extern uint32_t __afl_map_size;
extern __thread guint64 *instrument_previous_pc_addr;
void instrument_config(void);
void instrument_init(void);
@ -51,7 +52,7 @@ void instrument_coverage_unstable(guint64 edge, guint64 previous_rip,
guint64 previous_end, guint64 current_rip,
guint64 current_end);
void instrument_on_fork();
void instrument_on_fork(void);
guint64 instrument_get_offset_hash(GumAddress current_rip);

View File

@ -8,9 +8,12 @@
#define UNUSED_PARAMETER(x) (void)(x)
#define IGNORED_RETURN(x) (void)!(x)
extern gboolean util_verbose;
guint64 util_read_address(char *key, guint64 default_value);
guint64 util_read_num(char *key, guint64 default_value);
gboolean util_output_enabled(void);
gboolean util_verbose_enabled(void);
gsize util_rotate(gsize val, gsize shift, gsize size);
gsize util_log2(gsize val);
@ -19,7 +22,8 @@ gsize util_log2(gsize val);
\
if (!util_output_enabled()) { break; } \
\
OKF(x); \
SAYF(cLGN "[F] " cRST x); \
SAYF(cRST "\n"); \
\
} while (0)
@ -37,5 +41,15 @@ gsize util_log2(gsize val);
\
} while (0)
#define FVERBOSE(x...) \
do { \
\
if (!util_verbose_enabled()) { break; } \
\
SAYF(cGRA "[F] " x); \
SAYF(cRST "\n"); \
\
} while (0)
#endif

View File

@ -9,21 +9,15 @@ gboolean asan_initialized = FALSE;
void asan_config(void) {
if (getenv("AFL_USE_FASAN") != NULL) {
FOKF("Frida ASAN mode enabled");
asan_enabled = TRUE;
} else {
FOKF("Frida ASAN mode disabled");
}
if (getenv("AFL_USE_FASAN") != NULL) { asan_enabled = TRUE; }
}
void asan_init(void) {
FOKF(cBLU "Instrumentation" cRST " - " cGRN "asan:" cYEL " [%c]",
asan_enabled ? 'X' : ' ');
if (asan_enabled) {
asan_arch_init();

View File

@ -54,7 +54,7 @@ static gint cmplog_sort(gconstpointer a, gconstpointer b) {
static void cmplog_get_ranges(void) {
FOKF("CMPLOG - Collecting ranges");
FVERBOSE("CMPLOG - Collecting ranges");
cmplog_ranges = g_array_sized_new(false, false, sizeof(GumMemoryRange), 100);
gum_process_enumerate_ranges(GUM_PAGE_READ, cmplog_range, cmplog_ranges);
@ -68,18 +68,21 @@ void cmplog_config(void) {
void cmplog_init(void) {
FOKF("CMPLOG - Enabled [%c]", __afl_cmp_map == NULL ? ' ' : 'X');
FOKF(cBLU "Instrumentation" cRST " - " cGRN "cmplog:" cYEL " [%c]",
__afl_cmp_map == NULL ? ' ' : 'X');
if (__afl_cmp_map == NULL) { return; }
cmplog_get_ranges();
FVERBOSE("Cmplog Ranges");
for (guint i = 0; i < cmplog_ranges->len; i++) {
GumMemoryRange *range = &g_array_index(cmplog_ranges, GumMemoryRange, i);
FOKF("CMPLOG Range - %3u: 0x%016" G_GINT64_MODIFIER
"X - 0x%016" G_GINT64_MODIFIER "X",
i, range->base_address, range->base_address + range->size);
FVERBOSE("\t%3u: 0x%016" G_GINT64_MODIFIER "X - 0x%016" G_GINT64_MODIFIER
"X",
i, range->base_address, range->base_address + range->size);
}

View File

@ -24,7 +24,7 @@ gboolean entry_run = FALSE;
static void entry_launch(void) {
FOKF("Entry point reached");
FVERBOSE("Entry point reached");
__afl_manual_init();
/* Child here */
@ -69,8 +69,8 @@ void entry_config(void) {
void entry_init(void) {
FOKF("entry_point: 0x%016" G_GINT64_MODIFIER "X", entry_point);
FOKF("dumpable: [%c]", traceable ? 'X' : ' ');
FVERBOSE("Entry Point: 0x%016" G_GINT64_MODIFIER "X", entry_point);
FVERBOSE("Dumpable: [%c]", traceable ? 'X' : ' ');
if (dlopen(NULL, RTLD_NOW) == NULL) { FFATAL("Failed to dlopen: %d", errno); }
@ -94,7 +94,7 @@ static void entry_callout(GumCpuContext *cpu_context, gpointer user_data) {
void entry_prologue(GumStalkerIterator *iterator, GumStalkerOutput *output) {
UNUSED_PARAMETER(output);
FOKF("AFL_ENTRYPOINT reached");
FVERBOSE("AFL_ENTRYPOINT reached");
if (persistent_start == 0) {

View File

@ -32,12 +32,13 @@ char * instrument_coverage_unstable_filename = NULL;
static GumStalkerTransformer *transformer = NULL;
__thread guint64 instrument_previous_pc = 0;
static GumAddress previous_rip = 0;
static GumAddress previous_end = 0;
static u8 * edges_notified = NULL;
__thread guint64 instrument_previous_pc;
__thread guint64 *instrument_previous_pc_addr = NULL;
typedef struct {
GumAddress address;
@ -105,8 +106,14 @@ __attribute__((hot)) static void on_basic_block(GumCpuContext *context,
guint16 current_end = ctx->end;
guint64 current_pc = instrument_get_offset_hash(current_rip);
guint64 edge;
if (instrument_previous_pc_addr == NULL) {
edge = current_pc ^ instrument_previous_pc;
instrument_previous_pc_addr = &instrument_previous_pc;
*instrument_previous_pc_addr = instrument_hash_zero;
}
edge = current_pc ^ *instrument_previous_pc_addr;
instrument_increment_map(edge);
@ -136,7 +143,7 @@ __attribute__((hot)) static void on_basic_block(GumCpuContext *context,
previous_end = current_end;
gsize map_size_pow2 = util_log2(__afl_map_size);
instrument_previous_pc = util_rotate(current_pc, 1, map_size_pow2);
*instrument_previous_pc_addr = util_rotate(current_pc, 1, map_size_pow2);
}
@ -274,14 +281,19 @@ void instrument_init(void) {
if (!instrument_is_coverage_optimize_supported()) instrument_optimize = false;
FOKF("Instrumentation - optimize [%c]", instrument_optimize ? 'X' : ' ');
FOKF("Instrumentation - tracing [%c]", instrument_tracing ? 'X' : ' ');
FOKF("Instrumentation - unique [%c]", instrument_unique ? 'X' : ' ');
FOKF("Instrumentation - fixed seed [%c] [0x%016" G_GINT64_MODIFIER "x]",
FOKF(cBLU "Instrumentation" cRST " - " cGRN "optimize:" cYEL " [%c]",
instrument_optimize ? 'X' : ' ');
FOKF(cBLU "Instrumentation" cRST " - " cGRN "tracing:" cYEL " [%c]",
instrument_tracing ? 'X' : ' ');
FOKF(cBLU "Instrumentation" cRST " - " cGRN "unique:" cYEL " [%c]",
instrument_unique ? 'X' : ' ');
FOKF(cBLU "Instrumentation" cRST " - " cGRN "fixed seed:" cYEL
" [%c] [0x%016" G_GINT64_MODIFIER "x]",
instrument_use_fixed_seed ? 'X' : ' ', instrument_fixed_seed);
FOKF("Instrumentation - unstable coverage [%c] [%s]",
instrument_coverage_unstable_filename == NULL ? ' ' : 'X',
instrument_coverage_unstable_filename);
FOKF(cBLU "Instrumentation" cRST " - " cGRN "unstable coverage:" cYEL " [%s]",
instrument_coverage_unstable_filename == NULL
? " "
: instrument_coverage_unstable_filename);
if (instrument_tracing && instrument_optimize) {
@ -306,12 +318,6 @@ void instrument_init(void) {
if (instrument_unique) { instrument_tracing = TRUE; }
if (__afl_map_size != 0x10000) {
FATAL("Bad map size: 0x%08x", __afl_map_size);
}
transformer = gum_stalker_transformer_make_from_callback(
instrument_basic_block, NULL, NULL);
@ -366,15 +372,16 @@ void instrument_init(void) {
}
FOKF("Instrumentation - seed [0x%016" G_GINT64_MODIFIER "x]",
FOKF(cBLU "Instrumentation" cRST " - " cGRN "seed:" cYEL
" [0x%016" G_GINT64_MODIFIER "x]",
instrument_hash_seed);
instrument_hash_zero = instrument_get_offset_hash(0);
instrument_coverage_optimize_init();
instrument_debug_init();
instrument_coverage_init();
asan_init();
cmplog_init();
instrument_coverage_init();
instrument_coverage_optimize_init();
instrument_debug_init();
}
@ -387,7 +394,11 @@ GumStalkerTransformer *instrument_get_transformer(void) {
void instrument_on_fork() {
instrument_previous_pc = instrument_hash_zero;
if (instrument_previous_pc_addr != NULL) {
*instrument_previous_pc_addr = instrument_hash_zero;
}
}

View File

@ -1,50 +1,118 @@
#include <stddef.h>
#include "frida-gumjs.h"
#include "config.h"
#include "instrument.h"
#include "ranges.h"
#include "stalker.h"
#include "util.h"
#define G_MININT33 ((gssize)0xffffffff00000000)
#define G_MAXINT33 ((gssize)0x00000000ffffffff)
#define PAGE_MASK (~(GUM_ADDRESS(0xfff)))
#define PAGE_ALIGNED(x) ((GUM_ADDRESS(x) & PAGE_MASK) == GUM_ADDRESS(x))
#if defined(__aarch64__)
static GumAddress current_log_impl = GUM_ADDRESS(0);
__attribute__((aligned(0x1000))) static guint8 area_ptr_dummy[MAP_SIZE];
static const guint8 afl_log_code[] = {
#pragma pack(push, 1)
typedef struct {
// __afl_area_ptr[current_pc ^ previous_pc]++;
// previous_pc = current_pc ROR 1;
0xE1, 0x0B, 0xBF, 0xA9, // stp x1, x2, [sp, -0x10]!
0xE3, 0x13, 0xBF, 0xA9, // stp x3, x4, [sp, -0x10]!
// cur_location = (block_address >> 4) ^ (block_address << 8);
// shared_mem[cur_location ^ prev_location]++;
// prev_location = cur_location >> 1;
// x0 = current_pc
0x21, 0x02, 0x00, 0x58, // ldr x1, #0x44, =&__afl_area_ptr
0x21, 0x00, 0x40, 0xf9, // ldr x1, [x1] (=__afl_area_ptr)
// stp x0, x1, [sp, #-160]
// adrp x0, 0x7fb7738000
// ldr x1, [x0]
// mov x0, #0x18b8
// eor x0, x1, x0
// adrp x1, 0x7fb7d73000
// add x0, x1, x0
// ldrb w1, [x0]
// add w1, w1, #0x1
// add x1, x1, x1, lsr #8
// strb w1, [x0]
// adrp x0, 0x7fb7738000
// mov x1, #0xc5c
// str x1, [x0]
// ldp x0, x1, [sp, #-160]
// b 0x7fb6f0dee4
// ldp x16, x17, [sp], #144
0x22, 0x02, 0x00, 0x58, // ldr x2, #0x44, =&previous_pc
0x42, 0x00, 0x40, 0xf9, // ldr x2, [x2] (=previous_pc)
uint32_t stp_x0_x1; /* stp x0, x1, [sp, #-0xa0] */
// __afl_area_ptr[current_pc ^ previous_pc]++;
0x42, 0x00, 0x00, 0xca, // eor x2, x2, x0
0x23, 0x68, 0x62, 0xf8, // ldr x3, [x1, x2]
0x63, 0x04, 0x00, 0x91, // add x3, x3, #1
0x63, 0x00, 0x1f, 0x9a, // adc x3, x3, xzr
0x23, 0x68, 0x22, 0xf8, // str x3, [x1, x2]
uint32_t adrp_x0_prev_loc1; /* adrp x0, #0xXXXX */
uint32_t ldr_x1_ptr_x0; /* ldr x1, [x0] */
// previous_pc = current_pc ROR 1;
0xe4, 0x07, 0x40, 0x8b, // add x4, xzr, x0, LSR #1
0xe0, 0xff, 0x00, 0x8b, // add x0, xzr, x0, LSL #63
0x80, 0xc0, 0x40, 0x8b, // add x0, x4, x0, LSR #48
uint32_t mov_x0_curr_loc; /* movz x0, #0xXXXX */
uint32_t eor_x0_x1_x0; /* eor x0, x1, x0 */
uint32_t adrp_x1_area_ptr; /* adrp x1, #0xXXXX */
uint32_t add_x0_x1_x0; /* add x0, x1, x0 */
0xe2, 0x00, 0x00, 0x58, // ldr x2, #0x1c, =&previous_pc
0x40, 0x00, 0x00, 0xf9, // str x0, [x2]
uint32_t ldrb_w1_x0; /* ldrb w1, [x0] */
uint32_t add_w1_w1_1; /* add w1, w1, #1 */
uint32_t add_w1_w1_w1_lsr_8; /* add x1, x1, x1, lsr #8 */
0xE3, 0x13, 0xc1, 0xA8, // ldp x3, x4, [sp], #0x10
0xE1, 0x0B, 0xc1, 0xA8, // ldp x1, x2, [sp], #0x10
0xC0, 0x03, 0x5F, 0xD6, // ret
uint32_t strb_w1_ptr_x0; /* strb w1, [x0] */
// &afl_area_ptr_ptr
// &afl_prev_loc_ptr
uint32_t adrp_x0_prev_loc2; /* adrp x0, #0xXXXX */
uint32_t mov_x1_curr_loc_shr_1; /* movz x1, #0xXXXX */
uint32_t str_x1_ptr_x0; /* str x1, [x0] */
};
uint32_t ldp_x0_x1; /* ldp x0, x1, [sp, #-0xa0] */
uint32_t b_imm8; /* br #8 */
uint32_t restoration_prolog; /* ldp x16, x17, [sp], #0x90 */
} afl_log_code_asm_t;
#pragma pack(pop)
typedef union {
afl_log_code_asm_t code;
uint8_t bytes[0];
} afl_log_code;
static const afl_log_code_asm_t template =
{
.stp_x0_x1 = 0xa93607e0,
.adrp_x0_prev_loc1 = 0x90000000,
.ldr_x1_ptr_x0 = 0xf9400001,
.mov_x0_curr_loc = 0xd2800000,
.eor_x0_x1_x0 = 0xca000020,
.adrp_x1_area_ptr = 0x90000001,
.add_x0_x1_x0 = 0x8b000020,
.ldrb_w1_x0 = 0x39400001,
.add_w1_w1_1 = 0x11000421,
.add_w1_w1_w1_lsr_8 = 0x8b412021,
.strb_w1_ptr_x0 = 0x39000001,
.adrp_x0_prev_loc2 = 0x90000000,
.mov_x1_curr_loc_shr_1 = 0xd2800001,
.str_x1_ptr_x0 = 0xf9000001,
.ldp_x0_x1 = 0xa97607e0,
.b_imm8 = 0x14000002,
.restoration_prolog = 0xa8c947f0,
}
;
gboolean instrument_is_coverage_optimize_supported(void) {
@ -52,50 +120,111 @@ gboolean instrument_is_coverage_optimize_supported(void) {
}
void instrument_coverage_optimize(const cs_insn * instr,
GumStalkerOutput *output) {
static gboolean instrument_coverage_in_range(gssize offset) {
guint64 current_pc = instr->address;
guint64 area_offset = instrument_get_offset_hash(GUM_ADDRESS(instr->address));
GumArm64Writer *cw = output->writer.arm64;
return (offset >= G_MININT33 && offset <= G_MAXINT33);
if (current_log_impl == 0 ||
!gum_arm64_writer_can_branch_directly_between(cw, cw->pc,
current_log_impl) ||
!gum_arm64_writer_can_branch_directly_between(cw, cw->pc + 128,
current_log_impl)) {
}
gconstpointer after_log_impl = cw->code + 1;
static void instrument_patch_ardp(guint32 *patch, GumAddress insn,
GumAddress target) {
gum_arm64_writer_put_b_label(cw, after_log_impl);
if (!PAGE_ALIGNED(target)) { FATAL("Target not page aligned"); }
current_log_impl = cw->pc;
gum_arm64_writer_put_bytes(cw, afl_log_code, sizeof(afl_log_code));
gssize distance = target - (GUM_ADDRESS(insn) & PAGE_MASK);
if (!instrument_coverage_in_range(distance)) {
uint8_t **afl_area_ptr_ptr = &__afl_area_ptr;
uint64_t *afl_prev_loc_ptr = &instrument_previous_pc;
gum_arm64_writer_put_bytes(cw, (const guint8 *)&afl_area_ptr_ptr,
sizeof(afl_area_ptr_ptr));
gum_arm64_writer_put_bytes(cw, (const guint8 *)&afl_prev_loc_ptr,
sizeof(afl_prev_loc_ptr));
gum_arm64_writer_put_label(cw, after_log_impl);
FATAL("Patch out of range 0x%016lX->0x%016lX = 0x%016lX", insn, target,
distance);
}
gum_arm64_writer_put_stp_reg_reg_reg_offset(
cw, ARM64_REG_LR, ARM64_REG_X0, ARM64_REG_SP, -(16 + GUM_RED_ZONE_SIZE),
GUM_INDEX_PRE_ADJUST);
gum_arm64_writer_put_ldr_reg_u64(cw, ARM64_REG_X0, area_offset);
gum_arm64_writer_put_bl_imm(cw, current_log_impl);
gum_arm64_writer_put_ldp_reg_reg_reg_offset(
cw, ARM64_REG_LR, ARM64_REG_X0, ARM64_REG_SP, 16 + GUM_RED_ZONE_SIZE,
GUM_INDEX_POST_ADJUST);
guint32 imm_low = ((distance >> 12) & 0x3) << 29;
guint32 imm_high = ((distance >> 14) & 0x7FFFF) << 5;
*patch |= imm_low;
*patch |= imm_high;
}
void instrument_coverage_optimize(const cs_insn * instr,
GumStalkerOutput *output) {
afl_log_code code = {0};
GumArm64Writer *cw = output->writer.arm64;
guint64 area_offset = instrument_get_offset_hash(GUM_ADDRESS(instr->address));
gsize map_size_pow2;
gsize area_offset_ror;
GumAddress code_addr = 0;
if (instrument_previous_pc_addr == NULL) {
GumAddressSpec spec = {.near_address = cw->code,
.max_distance = 1ULL << 30};
instrument_previous_pc_addr = gum_memory_allocate_near(
&spec, sizeof(guint64), 0x1000, GUM_PAGE_READ | GUM_PAGE_WRITE);
*instrument_previous_pc_addr = instrument_hash_zero;
FVERBOSE("instrument_previous_pc_addr: %p", instrument_previous_pc_addr);
FVERBOSE("code_addr: %p", cw->code);
}
// gum_arm64_writer_put_brk_imm(cw, 0x0);
code_addr = cw->pc;
code.code = template;
/*
* Given our map is allocated on a 64KB boundary and our map is a multiple of
* 64KB in size, then it should also end on a 64 KB boundary. It is followed
* by our previous_pc, so this too should be 64KB aligned.
*/
g_assert(PAGE_ALIGNED(instrument_previous_pc_addr));
g_assert(PAGE_ALIGNED(__afl_area_ptr));
instrument_patch_ardp(
&code.code.adrp_x0_prev_loc1,
code_addr + offsetof(afl_log_code, code.adrp_x0_prev_loc1),
GUM_ADDRESS(instrument_previous_pc_addr));
code.code.mov_x0_curr_loc |= area_offset << 5;
instrument_patch_ardp(
&code.code.adrp_x1_area_ptr,
code_addr + offsetof(afl_log_code, code.adrp_x1_area_ptr),
GUM_ADDRESS(__afl_area_ptr));
map_size_pow2 = util_log2(__afl_map_size);
area_offset_ror = util_rotate(area_offset, 1, map_size_pow2);
instrument_patch_ardp(
&code.code.adrp_x0_prev_loc2,
code_addr + offsetof(afl_log_code, code.adrp_x0_prev_loc2),
GUM_ADDRESS(instrument_previous_pc_addr));
code.code.mov_x1_curr_loc_shr_1 |= (area_offset_ror << 5);
gum_arm64_writer_put_bytes(cw, code.bytes, sizeof(afl_log_code));
}
void instrument_coverage_optimize_init(void) {
char *shm_env = getenv(SHM_ENV_VAR);
FVERBOSE("SHM_ENV_VAR: %s", shm_env);
if (shm_env == NULL) {
FWARNF("SHM_ENV_VAR not set, using dummy for debugging purposes");
__afl_area_ptr = area_ptr_dummy;
memset(area_ptr_dummy, '\0', sizeof(area_ptr_dummy));
}
FVERBOSE("__afl_area_ptr: %p", __afl_area_ptr);
}
void instrument_flush(GumStalkerOutput *output) {

View File

@ -659,17 +659,17 @@ void instrument_coverage_config(void) {
void instrument_coverage_normal_init(void) {
FOKF("Coverage - enabled [%c]",
instrument_coverage_filename == NULL ? ' ' : 'X');
FOKF(cBLU "Instrumentation" cRST " - " cGRN "coverage:" cYEL " [%s]",
instrument_coverage_filename == NULL ? " "
: instrument_coverage_filename);
if (instrument_coverage_filename == NULL) { return; }
FOKF("Coverage - file [%s]", instrument_coverage_filename);
char *path = g_canonicalize_filename(instrument_coverage_filename,
g_get_current_dir());
FOKF("Coverage - path [%s]", path);
FOKF(cBLU "Instrumentation" cRST " - " cGRN "coverage path:" cYEL " [%s]",
path);
normal_coverage_fd = open(path, O_RDWR | O_CREAT | O_TRUNC,
S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
@ -718,7 +718,7 @@ void instrument_coverage_unstable_find_output(void) {
GDir *dir = g_dir_open(fds_name, 0, NULL);
FOKF("Coverage Unstable - fds: %s", fds_name);
FVERBOSE("Coverage Unstable - fds: %s", fds_name);
for (const gchar *filename = g_dir_read_name(dir); filename != NULL;
filename = g_dir_read_name(dir)) {
@ -782,18 +782,24 @@ void instrument_coverage_unstable_find_output(void) {
}
FOKF("Fuzzer stats: %s", unstable_coverage_fuzzer_stats);
FVERBOSE("Fuzzer stats: %s", unstable_coverage_fuzzer_stats);
}
void instrument_coverage_unstable_init(void) {
FOKF(cBLU "Instrumentation" cRST " - " cGRN "unstable coverage:" cYEL " [%s]",
instrument_coverage_unstable_filename == NULL
? " "
: instrument_coverage_unstable_filename);
if (instrument_coverage_unstable_filename == NULL) { return; }
char *path = g_canonicalize_filename(instrument_coverage_unstable_filename,
g_get_current_dir());
FOKF("Coverage - unstable path [%s]", instrument_coverage_unstable_filename);
FOKF(cBLU "Instrumentation" cRST " - " cGRN "unstable coverage path:" cYEL
" [%s]",
path == NULL ? " " : path);
unstable_coverage_fd = open(path, O_RDWR | O_CREAT | O_TRUNC,
S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);

View File

@ -35,6 +35,10 @@ static void instrument_debug(char *format, ...) {
static void instrument_disasm(guint8 *start, guint8 *end,
GumStalkerOutput *output) {
#if !defined(__arm__)
UNUSED_PARAMETER(output);
#endif
csh capstone;
cs_err err;
cs_mode mode;
@ -50,9 +54,7 @@ static void instrument_disasm(guint8 *start, guint8 *end,
if (output->encoding == GUM_INSTRUCTION_SPECIAL) { mode |= CS_MODE_THUMB; }
#endif
err = cs_open(GUM_DEFAULT_CS_ARCH,
CS_MODE_THUMB | GUM_DEFAULT_CS_MODE | GUM_DEFAULT_CS_ENDIAN,
&capstone);
err = cs_open(GUM_DEFAULT_CS_ARCH, mode, &capstone);
g_assert(err == CS_ERR_OK);
size = GPOINTER_TO_SIZE(end) - GPOINTER_TO_SIZE(start);
@ -96,19 +98,15 @@ void instrument_debug_config(void) {
void instrument_debug_init(void) {
FOKF("Instrumentation debugging - enabled [%c]",
instrument_debug_filename == NULL ? ' ' : 'X');
if (instrument_debug_filename == NULL) { return; }
FOKF("Instrumentation debugging - file [%s]", instrument_debug_filename);
FOKF(cBLU "Instrumentation" cRST " - " cGRN "debugging:" cYEL " [%s]",
instrument_debug_filename == NULL ? " " : instrument_debug_filename);
if (instrument_debug_filename == NULL) { return; }
char *path =
g_canonicalize_filename(instrument_debug_filename, g_get_current_dir());
FOKF("Instrumentation debugging - path [%s]", path);
FOKF(cBLU "Instrumentation" cRST " - " cGRN "path:" cYEL " [%s]", path);
debugging_fd = open(path, O_RDWR | O_CREAT | O_TRUNC,
S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);

View File

@ -216,6 +216,8 @@ static gboolean instrument_coverage_find_low(const GumRangeDetails *details,
static GumAddress last_limit = (64ULL << 10);
gpointer * address = (gpointer *)user_data;
last_limit = GUM_ALIGN_SIZE(last_limit, __afl_map_size);
if ((details->range->base_address - last_limit) > __afl_map_size) {
*address = GSIZE_TO_POINTER(last_limit);
@ -235,7 +237,7 @@ static gboolean instrument_coverage_find_low(const GumRangeDetails *details,
* current block ID.
*/
last_limit = GUM_ALIGN_SIZE(
details->range->base_address + details->range->size, (64ULL << 10));
details->range->base_address + details->range->size, __afl_map_size);
return TRUE;
}
@ -323,10 +325,10 @@ void instrument_coverage_optimize_init(void) {
gum_process_enumerate_ranges(GUM_PAGE_NO_ACCESS, instrument_coverage_find_low,
&low_address);
FOKF("Low address: %p", low_address);
FVERBOSE("Low address: %p", low_address);
if (low_address == 0 ||
GPOINTER_TO_SIZE(low_address) > ((2UL << 20) - __afl_map_size)) {
GPOINTER_TO_SIZE(low_address) > ((2UL << 30) - __afl_map_size)) {
FATAL("Invalid low_address: %p", low_address);
@ -335,7 +337,7 @@ void instrument_coverage_optimize_init(void) {
ranges_print_debug_maps();
char *shm_env = getenv(SHM_ENV_VAR);
FOKF("SHM_ENV_VAR: %s", shm_env);
FVERBOSE("SHM_ENV_VAR: %s", shm_env);
if (shm_env == NULL) {
@ -359,8 +361,7 @@ void instrument_coverage_optimize_init(void) {
}
FOKF("__afl_area_ptr: %p", __afl_area_ptr);
FOKF("instrument_previous_pc: %p", &instrument_previous_pc);
FVERBOSE("__afl_area_ptr: %p", __afl_area_ptr);
}
@ -439,6 +440,18 @@ void instrument_coverage_optimize(const cs_insn * instr,
gsize map_size_pow2;
gsize area_offset_ror;
GumAddress code_addr = 0;
if (instrument_previous_pc_addr == NULL) {
GumAddressSpec spec = {.near_address = cw->code,
.max_distance = 1ULL << 30};
instrument_previous_pc_addr = gum_memory_allocate_near(
&spec, sizeof(guint64), 0x1000, GUM_PAGE_READ | GUM_PAGE_WRITE);
*instrument_previous_pc_addr = instrument_hash_zero;
FVERBOSE("instrument_previous_pc_addr: %p", instrument_previous_pc_addr);
FVERBOSE("code_addr: %p", cw->code);
}
instrument_coverage_suppress_init();
@ -462,7 +475,7 @@ void instrument_coverage_optimize(const cs_insn * instr,
*((guint32 *)&code.bytes[curr_loc_shr_1_offset]) = (guint32)(area_offset_ror);
gssize prev_loc_value =
GPOINTER_TO_SIZE(&instrument_previous_pc) -
GPOINTER_TO_SIZE(instrument_previous_pc_addr) -
(code_addr + offsetof(afl_log_code, code.mov_prev_loc_curr_loc_shr1) +
sizeof(code.code.mov_prev_loc_curr_loc_shr1));
gssize prev_loc_value_offset =
@ -478,7 +491,7 @@ void instrument_coverage_optimize(const cs_insn * instr,
*((gint *)&code.bytes[prev_loc_value_offset]) = (gint)prev_loc_value;
gssize prev_loc_value2 =
GPOINTER_TO_SIZE(&instrument_previous_pc) -
GPOINTER_TO_SIZE(instrument_previous_pc_addr) -
(code_addr + offsetof(afl_log_code, code.mov_eax_prev_loc) +
sizeof(code.code.mov_eax_prev_loc));
gssize prev_loc_value_offset2 =

View File

@ -153,6 +153,19 @@ void instrument_coverage_optimize(const cs_insn * instr,
gsize map_size_pow2;
gsize area_offset_ror;
if (instrument_previous_pc_addr == NULL) {
GumAddressSpec spec = {.near_address = cw->code,
.max_distance = 1ULL << 30};
instrument_previous_pc_addr = gum_memory_allocate_near(
&spec, sizeof(guint64), 0x1000, GUM_PAGE_READ | GUM_PAGE_WRITE);
*instrument_previous_pc_addr = instrument_hash_zero;
FVERBOSE("instrument_previous_pc_addr: %p", instrument_previous_pc_addr);
FVERBOSE("code_addr: %p", cw->code);
}
code.code = template;
instrument_coverage_suppress_init();
@ -170,7 +183,7 @@ void instrument_coverage_optimize(const cs_insn * instr,
sizeof(code.code.mov_eax_prev_loc) - sizeof(gint);
*((gint *)&code.bytes[prev_loc_value_offset2]) =
(gint)GPOINTER_TO_SIZE(&instrument_previous_pc);
(gint)GPOINTER_TO_SIZE(instrument_previous_pc_addr);
gssize curr_loc_shr_1_offset =
offsetof(afl_log_code, code.mov_prev_loc_curr_loc_shr1) +
@ -187,7 +200,7 @@ void instrument_coverage_optimize(const cs_insn * instr,
sizeof(guint32);
*((gint *)&code.bytes[prev_loc_value_offset]) =
(gint)GPOINTER_TO_SIZE(&instrument_previous_pc);
(gint)GPOINTER_TO_SIZE(instrument_previous_pc_addr);
gssize xor_curr_loc_offset = offsetof(afl_log_code, code.xor_eax_curr_loc) +
sizeof(code.code.xor_eax_curr_loc) -

View File

@ -63,7 +63,7 @@ class Afl {
Afl.jsApiWrite(STDOUT_FILENO, buf, log.length);
}
/**
* See `AFL_FRIDA_INST_NO_BACKPATCH`.
* See `AFL_FRIDA_STALKER_NO_BACKPATCH`.
*/
static setBackpatchDisable() {
Afl.jsApiSetBackpatchDisable();
@ -268,6 +268,12 @@ class Afl {
static setTraceable() {
Afl.jsApiSetTraceable();
}
/**
* See `AFL_FRIDA_VERBOSE`
*/
static setVerbose() {
Afl.jsApiSetVerbose();
}
static jsApiGetFunction(name, retType, argTypes) {
const addr = Afl.module.getExportByName(name);
return new NativeFunction(addr, retType, argTypes);
@ -315,6 +321,7 @@ Afl.jsApiSetStatsInterval = Afl.jsApiGetFunction("js_api_set_stats_interval", "v
Afl.jsApiSetStdErr = Afl.jsApiGetFunction("js_api_set_stderr", "void", ["pointer"]);
Afl.jsApiSetStdOut = Afl.jsApiGetFunction("js_api_set_stdout", "void", ["pointer"]);
Afl.jsApiSetTraceable = Afl.jsApiGetFunction("js_api_set_traceable", "void", []);
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"]);

View File

@ -55,7 +55,10 @@ static gchar *js_get_script() {
} else {
FOKF("Loaded AFL script: %s, %" G_GSIZE_MODIFIER "d bytes", filename,
FOKF(cBLU "Javascript" cRST " - " cGRN "script:" cYEL " [%s]",
filename == NULL ? " " : filename);
FOKF(cBLU "Javascript" cRST " - " cGRN "size: " cYEL "%" G_GSIZE_MODIFIER
"d bytes",
length);
gchar *source = g_malloc0(api_js_len + length + 1);
@ -74,7 +77,7 @@ static void js_print_script(gchar *source) {
for (size_t i = 0; split[i] != NULL; i++) {
FOKF("%3" G_GSIZE_MODIFIER "d. %s", i + 1, split[i]);
FVERBOSE("%3" G_GSIZE_MODIFIER "d. %s", i + 1, split[i]);
}

View File

@ -262,3 +262,9 @@ __attribute__((visibility("default"))) void js_api_set_js_main_hook(
}
__attribute__((visibility("default"))) void js_api_set_verbose(void) {
util_verbose = TRUE;
}

View File

@ -93,17 +93,18 @@ static void lib_read_text_section(lib_details_t *lib_details, Elf_Ehdr *hdr) {
}
FOKF("Image preferred load address 0x%016" G_GSIZE_MODIFIER "x",
preferred_base);
FVERBOSE("\tpreferred load address: 0x%016" G_GSIZE_MODIFIER "x",
preferred_base);
shdr = (Elf_Shdr *)((char *)hdr + hdr->e_shoff);
shstrtab = &shdr[hdr->e_shstrndx];
shstr = (char *)hdr + shstrtab->sh_offset;
FOKF("shdr: %p", shdr);
FOKF("shstrtab: %p", shstrtab);
FOKF("shstr: %p", shstr);
FVERBOSE("\tshdr: %p", shdr);
FVERBOSE("\tshstrtab: %p", shstrtab);
FVERBOSE("\tshstr: %p", shstr);
FVERBOSE("Sections:");
for (size_t i = 0; i < hdr->e_shnum; i++) {
curr = &shdr[i];
@ -111,21 +112,23 @@ static void lib_read_text_section(lib_details_t *lib_details, Elf_Ehdr *hdr) {
if (curr->sh_name == 0) continue;
section_name = &shstr[curr->sh_name];
FOKF("Section: %2" G_GSIZE_MODIFIER "u - base: 0x%016" G_GSIZE_MODIFIER
"X size: 0x%016" G_GSIZE_MODIFIER "X %s",
i, curr->sh_addr, curr->sh_size, section_name);
FVERBOSE("\t%2" G_GSIZE_MODIFIER "u - base: 0x%016" G_GSIZE_MODIFIER
"X size: 0x%016" G_GSIZE_MODIFIER "X %s",
i, curr->sh_addr, curr->sh_size, section_name);
if (memcmp(section_name, text_name, sizeof(text_name)) == 0 &&
text_base == 0) {
text_base = lib_details->base_address + curr->sh_addr - preferred_base;
text_limit = text_base + curr->sh_size;
FOKF("> text_addr: 0x%016" G_GINT64_MODIFIER "X", text_base);
FOKF("> text_limit: 0x%016" G_GINT64_MODIFIER "X", text_limit);
}
}
FVERBOSE(".text\n");
FVERBOSE("\taddr: 0x%016" G_GINT64_MODIFIER "X", text_base);
FVERBOSE("\tlimit: 0x%016" G_GINT64_MODIFIER "X", text_limit);
}
static void lib_get_text_section(lib_details_t *details) {
@ -141,7 +144,7 @@ static void lib_get_text_section(lib_details_t *details) {
if (len == (off_t)-1) { FFATAL("Failed to lseek %s", details->path); }
FOKF("len: %ld", len);
FVERBOSE("\tlength: %ld", len);
hdr = (Elf_Ehdr *)mmap(NULL, len, PROT_READ, MAP_PRIVATE, fd, 0);
if (hdr == MAP_FAILED) { FFATAL("Failed to map %s", details->path); }
@ -162,8 +165,10 @@ void lib_init(void) {
lib_details_t lib_details;
gum_process_enumerate_modules(lib_find_exe, &lib_details);
FOKF("Executable: 0x%016" G_GINT64_MODIFIER "x - %s",
lib_details.base_address, lib_details.path);
FVERBOSE("Image");
FVERBOSE("\tbase: 0x%016" G_GINT64_MODIFIER "x",
lib_details.base_address);
FVERBOSE("\tpath: %s", lib_details.path);
lib_get_text_section(&lib_details);
}

View File

@ -20,7 +20,7 @@ static gboolean lib_get_main_module(const GumModuleDetails *details,
details->path, mach_task_self(), details->range->base_address,
GUM_DARWIN_MODULE_FLAGS_NONE, NULL);
FOKF("Found main module: %s", module->name);
FVERBOSE("Found main module: %s", module->name);
*ret = module;
@ -35,21 +35,23 @@ gboolean lib_get_text_section(const GumDarwinSectionDetails *details,
static size_t idx = 0;
char text_name[] = "__text";
FOKF("Section: %2lu - base: 0x%016" G_GINT64_MODIFIER
"X size: 0x%016" G_GINT64_MODIFIER "X %s",
idx++, details->vm_address, details->vm_address + details->size,
details->section_name);
FVERBOSE("\t%2lu - base: 0x%016" G_GINT64_MODIFIER
"X size: 0x%016" G_GINT64_MODIFIER "X %s",
idx++, details->vm_address, details->vm_address + details->size,
details->section_name);
if (memcmp(details->section_name, text_name, sizeof(text_name)) == 0 &&
text_base == 0) {
text_base = details->vm_address;
text_limit = details->vm_address + details->size;
FOKF("> text_addr: 0x%016" G_GINT64_MODIFIER "X", text_base);
FOKF("> text_limit: 0x%016" G_GINT64_MODIFIER "X", text_limit);
}
FVERBOSE(".text\n");
FVERBOSE("\taddr: 0x%016" G_GINT64_MODIFIER "X", text_base);
FVERBOSE("\tlimit: 0x%016" G_GINT64_MODIFIER "X", text_limit);
return TRUE;
}
@ -62,6 +64,8 @@ void lib_init(void) {
GumDarwinModule *module = NULL;
gum_darwin_enumerate_modules(mach_task_self(), lib_get_main_module, &module);
FVERBOSE("Sections:");
gum_darwin_module_enumerate_sections(module, lib_get_text_section, NULL);
}

View File

@ -111,11 +111,13 @@ static void afl_print_cmdline(void) {
int idx = 0;
FVERBOSE("Command Line");
for (ssize_t i = 0; i < bytes_read; i++) {
if (i == 0 || buffer[i - 1] == '\0') {
FOKF("AFL - COMMANDLINE: argv[%d] = %s", idx++, &buffer[i]);
FVERBOSE("\targv[%d] = %s", idx++, &buffer[i]);
}
@ -131,7 +133,7 @@ static void afl_print_cmdline(void) {
for (idx = 0; idx < nargv; idx++) {
FOKF("AFL - COMMANDLINE: argv[%d] = %s", idx, argv[idx]);
FVERBOSE("\targv[%d] = %s", idx, argv[idx]);
}
@ -161,11 +163,12 @@ static void afl_print_env(void) {
int idx = 0;
FVERBOSE("ENVIRONMENT");
for (ssize_t i = 0; i < bytes_read; i++) {
if (i == 0 || buffer[i - 1] == '\0') {
FOKF("AFL - ENVIRONMENT %3d: %s", idx++, &buffer[i]);
FVERBOSE("\t%3d: %s", idx++, &buffer[i]);
}
@ -179,6 +182,13 @@ static void afl_print_env(void) {
__attribute__((visibility("default"))) void afl_frida_start(void) {
FOKF(cRED "**********************");
FOKF(cRED "* " cYEL "******************" cRED " *");
FOKF(cRED "* " cYEL "* " cGRN "**************" cYEL " *" cRED " *");
FOKF(cRED "* " cYEL "* " cGRN "* FRIDA MODE *" cYEL " *" cRED " *");
FOKF(cRED "* " cYEL "* " cGRN "**************" cYEL " *" cRED " *");
FOKF(cRED "* " cYEL "******************" cRED " *");
FOKF(cRED "**********************");
afl_print_cmdline();
afl_print_env();
@ -255,9 +265,9 @@ static void intercept_main(void) {
static void intercept_main(void) {
mach_port_t task = mach_task_self();
FOKF("Task Id: %u", task);
FVERBOSE("Task Id: %u", task);
GumAddress entry = gum_darwin_find_entrypoint(task);
FOKF("Entry Point: 0x%016" G_GINT64_MODIFIER "x", entry);
FVERBOSE("Entry Point: 0x%016" G_GINT64_MODIFIER "x", entry);
void *main = GSIZE_TO_POINTER(entry);
main_fn = main;
intercept_hook(main, on_main, NULL);

View File

@ -18,7 +18,7 @@ static void output_redirect(int fd, char *filename) {
path = g_canonicalize_filename(filename, g_get_current_dir());
FOKF("Redirect %d -> '%s'", fd, path);
FVERBOSE("Redirect %d -> '%s'", fd, path);
int output_fd = open(path, O_RDWR | O_CREAT | O_TRUNC,
S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
@ -46,8 +46,10 @@ void output_config(void) {
void output_init(void) {
FOKF("Output - StdOut: %s", output_stdout);
FOKF("Output - StdErr: %s", output_stderr);
FOKF(cBLU "Output" cRST " - " cGRN "stdout:" cYEL " [%s]",
output_stdout == NULL ? " " : output_stdout);
FOKF(cBLU "Output" cRST " - " cGRN "stderr:" cYEL " [%s]",
output_stderr == NULL ? " " : output_stderr);
output_redirect(STDOUT_FILENO, output_stdout);
output_redirect(STDERR_FILENO, output_stderr);

View File

@ -72,13 +72,16 @@ void persistent_config(void) {
void persistent_init(void) {
FOKF("Instrumentation - persistent mode [%c] (0x%016" G_GINT64_MODIFIER "X)",
FOKF(cBLU "Instrumentation" cRST " - " cGRN "persistent mode:" cYEL
" [%c] (0x%016" G_GINT64_MODIFIER "X)",
persistent_start == 0 ? ' ' : 'X', persistent_start);
FOKF("Instrumentation - persistent count [%c] (%" G_GINT64_MODIFIER "d)",
FOKF(cBLU "Instrumentation" cRST " - " cGRN "persistent count:" cYEL
" [%c] (%" G_GINT64_MODIFIER "d)",
persistent_start == 0 ? ' ' : 'X', persistent_count);
FOKF("Instrumentation - hook [%s]", hook_name);
FOKF(cBLU "Instrumentation" cRST " - " cGRN "hook:" cYEL " [%s]", hook_name);
FOKF("Instrumentation - persistent ret [%c] (0x%016" G_GINT64_MODIFIER "X)",
FOKF(cBLU "Instrumentation" cRST " - " cGRN "persistent ret:" cYEL
" [%c] (0x%016" G_GINT64_MODIFIER "X)",
persistent_ret == 0 ? ' ' : 'X', persistent_ret);
if (persistent_hook != NULL) { __afl_sharedmem_fuzzing = 1; }
@ -87,7 +90,7 @@ void persistent_init(void) {
void persistent_prologue(GumStalkerOutput *output) {
FOKF("AFL_FRIDA_PERSISTENT_ADDR reached");
FVERBOSE("AFL_FRIDA_PERSISTENT_ADDR reached");
entry_compiled = TRUE;
ranges_exclude();
stalker_trust();
@ -97,7 +100,7 @@ void persistent_prologue(GumStalkerOutput *output) {
void persistent_epilogue(GumStalkerOutput *output) {
FOKF("AFL_FRIDA_PERSISTENT_RET reached");
FVERBOSE("AFL_FRIDA_PERSISTENT_RET reached");
persistent_epilogue_arch(output);
}

View File

@ -89,7 +89,7 @@ static void instrument_persitent_save_regs(GumArm64Writer * cw,
/* LR (x30) */
gum_arm64_writer_put_str_reg_reg_offset(cw, ARM64_REG_X30, ARM64_REG_X0,
offsetof(GumCpuContext, x[30]));
offsetof(GumCpuContext, lr));
/* PC & Adjusted SP (31) */
gum_arm64_writer_put_ldr_reg_address(cw, ARM64_REG_X2,
@ -189,7 +189,7 @@ static void instrument_persitent_restore_regs(GumArm64Writer * cw,
/* LR (x30) */
gum_arm64_writer_put_ldr_reg_reg_offset(cw, ARM64_REG_X30, ARM64_REG_X0,
offsetof(GumCpuContext, x[30]));
offsetof(GumCpuContext, lr));
/* Adjusted SP (31) (use x1 as clobber)*/
gum_arm64_writer_put_ldr_reg_reg_offset(cw, ARM64_REG_X1, ARM64_REG_X0,
@ -236,7 +236,13 @@ static void instrument_exit(GumArm64Writer *cw) {
static int instrument_afl_persistent_loop_func(void) {
int ret = __afl_persistent_loop(persistent_count);
instrument_previous_pc = instrument_hash_zero;
if (instrument_previous_pc_addr == NULL) {
FATAL("instrument_previous_pc_addr uninitialized");
}
*instrument_previous_pc_addr = instrument_hash_zero;
return ret;
}
@ -264,8 +270,7 @@ static void persistent_prologue_hook(GumArm64Writer * cw,
gum_arm64_writer_put_ldr_reg_reg_offset(cw, ARM64_REG_X2, ARM64_REG_X2, 0);
gum_arm64_writer_put_ldr_reg_reg_offset(cw, ARM64_REG_X2, ARM64_REG_X2, 0);
gum_arm64_writer_put_and_reg_reg_imm(cw, ARM64_REG_X2, ARM64_REG_X2,
G_MAXULONG);
gum_arm64_writer_put_mov_reg_reg(cw, ARM64_REG_W2, ARM64_REG_W2);
gum_arm64_writer_put_ldr_reg_address(cw, ARM64_REG_X1,
GUM_ADDRESS(&__afl_fuzz_ptr));
@ -324,7 +329,7 @@ void persistent_prologue_arch(GumStalkerOutput *output) {
gconstpointer loop = cw->code + 1;
FOKF("Persistent loop reached");
FVERBOSE("Persistent loop reached");
instrument_persitent_save_regs(cw, &saved_regs);

View File

@ -173,7 +173,13 @@ static void instrument_exit(GumX86Writer *cw) {
static int instrument_afl_persistent_loop_func(void) {
int ret = __afl_persistent_loop(persistent_count);
instrument_previous_pc = instrument_hash_zero;
if (instrument_previous_pc_addr == NULL) {
FATAL("instrument_previous_pc_addr uninitialized");
}
*instrument_previous_pc_addr = instrument_hash_zero;
return ret;
}
@ -269,7 +275,7 @@ void persistent_prologue_arch(GumStalkerOutput *output) {
gconstpointer loop = cw->code + 1;
FOKF("Persistent loop reached");
FVERBOSE("Persistent loop reached");
/* Pop the return value */
gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_REG_RSP, GUM_REG_RSP, 8);

View File

@ -130,7 +130,13 @@ static void instrument_exit(GumX86Writer *cw) {
static int instrument_afl_persistent_loop_func(void) {
int ret = __afl_persistent_loop(persistent_count);
instrument_previous_pc = instrument_hash_zero;
if (instrument_previous_pc_addr == NULL) {
FATAL("instrument_previous_pc_addr uninitialized");
}
*instrument_previous_pc_addr = instrument_hash_zero;
return ret;
}
@ -210,7 +216,7 @@ void persistent_prologue_arch(GumStalkerOutput *output) {
gconstpointer loop = cw->code + 1;
FOKF("Persistent loop reached");
FVERBOSE("Persistent loop reached");
/* Pop the return value */
gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_REG_ESP, GUM_REG_ESP, 4);

View File

@ -178,8 +178,10 @@ static void prefetch_hook_fork(void) {
void prefetch_init(void) {
FOKF("Instrumentation - prefetch [%c]", prefetch_enable ? 'X' : ' ');
FOKF("Instrumentation - prefetch_backpatch [%c]",
FOKF(cBLU "Instrumentation" cRST " - " cGRN "prefetch:" cYEL " [%c]",
prefetch_enable ? 'X' : ' ');
FOKF(cBLU "Instrumentation" cRST " - " cGRN "prefetch_backpatch:" cYEL
" [%c]",
prefetch_backpatch ? 'X' : ' ');
if (!prefetch_enable) { return; }

View File

@ -122,10 +122,10 @@ static gboolean convert_name_token_for_module(const GumModuleDetails *details,
if (!g_str_has_suffix(details->path, ctx->suffix)) { return true; };
FOKF("Found module - prefix: %s, 0x%016" G_GINT64_MODIFIER
"x-0x%016" G_GINT64_MODIFIER "x %s",
ctx->suffix, details->range->base_address,
details->range->base_address + details->range->size, details->path);
FVERBOSE("Found module - prefix: %s, 0x%016" G_GINT64_MODIFIER
"x-0x%016" G_GINT64_MODIFIER "x %s",
ctx->suffix, details->range->base_address,
details->range->base_address + details->range->size, details->path);
*ctx->range = *details->range;
ctx->done = true;
@ -158,9 +158,9 @@ static void convert_token(gchar *token, GumMemoryRange *range) {
}
FOKF("Converted token: %s -> 0x%016" G_GINT64_MODIFIER
"x-0x%016" G_GINT64_MODIFIER "x\n",
token, range->base_address, range->base_address + range->size);
FVERBOSE("Converted token: %s -> 0x%016" G_GINT64_MODIFIER
"x-0x%016" G_GINT64_MODIFIER "x\n",
token, range->base_address, range->base_address + range->size);
}
@ -192,24 +192,24 @@ static gboolean print_ranges_callback(const GumRangeDetails *details,
if (details->file == NULL) {
FOKF("MAP - 0x%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' : '-');
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' : '-');
} else {
FOKF("MAP - 0x%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);
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);
}
@ -219,14 +219,14 @@ static gboolean print_ranges_callback(const GumRangeDetails *details,
static void print_ranges(char *key, GArray *ranges) {
FOKF("Range: %s Length: %d", key, ranges->len);
FVERBOSE("Range: [%s], Length: %d", key, ranges->len);
for (guint i = 0; i < ranges->len; i++) {
GumMemoryRange *curr = &g_array_index(ranges, GumMemoryRange, i);
GumAddress curr_limit = curr->base_address + curr->size;
FOKF("Range: %s Idx: %3d - 0x%016" G_GINT64_MODIFIER
"x-0x%016" G_GINT64_MODIFIER "x",
key, i, curr->base_address, curr_limit);
FVERBOSE("\t%3d - 0x%016" G_GINT64_MODIFIER "x-0x%016" G_GINT64_MODIFIER
"x",
i, curr->base_address, curr_limit);
}
@ -248,7 +248,7 @@ static GArray *collect_module_ranges(void) {
result = g_array_new(false, false, sizeof(GumMemoryRange));
gum_process_enumerate_ranges(GUM_PAGE_NO_ACCESS,
collect_module_ranges_callback, result);
print_ranges("Modules", result);
print_ranges("modules", result);
return result;
}
@ -348,7 +348,7 @@ static GArray *collect_libs_ranges(void) {
g_array_append_val(result, range);
print_ranges("AFL_INST_LIBS", result);
print_ranges("libs", result);
return result;
@ -382,7 +382,7 @@ static GArray *collect_jit_ranges(void) {
}
print_ranges("JIT", result);
print_ranges("jit", result);
return result;
}
@ -564,6 +564,7 @@ static GArray *merge_ranges(GArray *a) {
void ranges_print_debug_maps(void) {
FVERBOSE("Maps");
gum_process_enumerate_ranges(GUM_PAGE_NO_ACCESS, print_ranges_callback, NULL);
}
@ -590,16 +591,15 @@ void ranges_init(void) {
GArray * step4;
GArray * step5;
FOKF("Ranges - Instrument jit [%c]", ranges_inst_jit ? 'X' : ' ');
FOKF("Ranges - Instrument libraries [%c]", ranges_inst_libs ? 'X' : ' ');
FOKF(cBLU "Ranges" cRST " - " cGRN "instrument jit:" cYEL " [%c]",
ranges_inst_jit ? 'X' : ' ');
FOKF(cBLU "Ranges" cRST " - " cGRN "instrument libraries:" cYEL " [%c]",
ranges_inst_libs ? 'X' : ' ');
FOKF(cBLU "Ranges" cRST " - " cGRN "instrument libraries:" cYEL " [%c]",
ranges_inst_libs ? 'X' : ' ');
print_ranges("AFL_FRIDA_INST_RANGES", include_ranges);
print_ranges("AFL_FRIDA_EXCLUDE_RANGES", exclude_ranges);
FOKF("Ranges - Instrument libraries [%c]", ranges_inst_libs ? 'X' : ' ');
print_ranges("AFL_FRIDA_INST_RANGES", include_ranges);
print_ranges("AFL_FRIDA_EXCLUDE_RANGES", exclude_ranges);
print_ranges("include", include_ranges);
print_ranges("exclude", exclude_ranges);
module_ranges = collect_module_ranges();
libs_ranges = collect_libs_ranges();
@ -673,7 +673,7 @@ void ranges_exclude() {
GumMemoryRange *r;
GumStalker * stalker = stalker_get();
FOKF("Excluding ranges");
FVERBOSE("Excluding ranges");
for (guint i = 0; i < ranges->len; i++) {

View File

@ -25,7 +25,8 @@ void seccomp_config(void) {
void seccomp_init(void) {
FOKF("Seccomp - file [%s]", seccomp_filename);
FOKF(cBLU "Seccomp" cRST " - " cGRN "file:" cYEL " [%s]",
seccomp_filename == NULL ? " " : seccomp_filename);
if (seccomp_filename == NULL) { return; }

View File

@ -124,7 +124,7 @@ void seccomp_callback_initialize(void) {
path = g_canonicalize_filename(seccomp_filename, g_get_current_dir());
FOKF("Seccomp - path [%s]", path);
FVERBOSE("Seccomp - path [%s]", path);
fd = open(path, O_RDWR | O_CREAT | O_TRUNC,
S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);

View File

@ -258,7 +258,7 @@ void seccomp_filter_run(int fd, seccomp_filter_callback_t callback) {
if (ioctl(fd, SECCOMP_IOCTL_NOTIF_SEND, resp) < 0) {
if (errno == ENOENT) { continue; }
FOKF("SECCOMP_IOCTL_NOTIF_SEND");
FVERBOSE("SECCOMP_IOCTL_NOTIF_SEND");
continue;
}

View File

@ -93,10 +93,12 @@ static gboolean stalker_exclude_self(const GumRangeDetails *details,
void stalker_init(void) {
FOKF("Instrumentation - backpatch [%c]", backpatch_enable ? 'X' : ' ');
FOKF("Stalker - ic_entries [%u]", stalker_ic_entries);
FOKF("Stalker - adjacent_blocks [%u]", stalker_adjacent_blocks);
FOKF(cBLU "Stalker" cRST " - " cGRN "backpatch:" cYEL " [%c]",
backpatch_enable ? 'X' : ' ');
FOKF(cBLU "Stalker" cRST " - " cGRN "ic_entries:" cYEL " [%u]",
stalker_ic_entries);
FOKF(cBLU "Stalker" cRST " - " cGRN "adjacent_blocks:" cYEL " [%u]",
stalker_adjacent_blocks);
#if !(defined(__x86_64__) || defined(__i386__))
if (getenv("AFL_FRIDA_STALKER_IC_ENTRIES") != NULL) {

View File

@ -329,8 +329,11 @@ void stats_config(void) {
void stats_init(void) {
FOKF("Stats - file [%s]", stats_filename);
FOKF("Stats - interval [%" G_GINT64_MODIFIER "u]", stats_interval);
FOKF(cBLU "Stats" cRST " - " cGRN "file:" cYEL " [%s]",
stats_filename == NULL ? " " : stats_filename);
FOKF(cBLU "Stats" cRST " - " cGRN "interval:" cYEL " [%" G_GINT64_MODIFIER
"u]",
stats_interval);
if (getenv("AFL_FRIDA_STATS_INTERVAL") != NULL &&
getenv("AFL_FRIDA_STATS_FILE") == NULL) {
@ -347,7 +350,8 @@ void stats_init(void) {
char *path = g_canonicalize_filename(stats_filename, g_get_current_dir());
FOKF("Stats - path [%s]", path);
FOKF(cBLU "Stats" cRST " - " cGRN "path:" cYEL " [%s]",
path == NULL ? " " : path);
stats_fd = open(path, O_RDWR | O_CREAT | O_TRUNC,
S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);

View File

@ -1,5 +1,7 @@
#include "util.h"
gboolean util_verbose = FALSE;
guint64 util_read_address(char *key, guint64 default_value) {
char *value_str = getenv(key);
@ -66,7 +68,7 @@ guint64 util_read_num(char *key, guint64 default_value) {
errno = 0;
guint64 value = g_ascii_strtoull(value_str, NULL, 10);
guint64 value = g_ascii_strtoull(value_str, &end_ptr, 10);
if (errno != 0) {
@ -87,12 +89,13 @@ guint64 util_read_num(char *key, guint64 default_value) {
gboolean util_output_enabled(void) {
static gboolean initialized = FALSE;
static gboolean enabled = TRUE;
static gboolean enabled = FALSE;
if (!initialized) {
initialized = TRUE;
if (getenv("AFL_DEBUG_CHILD") == NULL) { enabled = FALSE; }
if (getenv("AFL_DEBUG_CHILD") != NULL) { enabled = TRUE; }
if (util_verbose_enabled()) { enabled = TRUE; }
}
@ -100,6 +103,21 @@ gboolean util_output_enabled(void) {
}
gboolean util_verbose_enabled(void) {
static gboolean initialized = FALSE;
if (!initialized) {
initialized = TRUE;
if (getenv("AFL_FRIDA_VERBOSE") != NULL) { util_verbose = TRUE; }
}
return util_verbose;
}
gsize util_rotate(gsize val, gsize shift, gsize size) {
if (shift == 0) { return val; }

View File

@ -34,20 +34,22 @@ ifeq "$(ARCH)" "i686"
endif
endif
ADDR_BIN:=$(ROOT)frida_mode/build/addr
GET_SYMBOL_ADDR:=$(ROOT)frida_mode/util/get_symbol_addr.sh
AFL_QEMU_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TEST_BIN) LLVMFuzzerTestOneInput 0x4000000000)
AFL_FRIDA_BASE_ADDR:=$(shell $(ADDR_BIN))
AFL_FRIDA_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TEST_BIN) LLVMFuzzerTestOneInput $(AFL_FRIDA_BASE_ADDR))
ifeq "$(ARCH)" "aarch64"
AFL_FRIDA_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TEST_BIN) LLVMFuzzerTestOneInput 0x0000aaaaaaaaa000)
ifeq "$(ARCH)" "arm64"
AFL_QEMU_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TEST_BIN) LLVMFuzzerTestOneInput 0x5500000000)
endif
ifeq "$(ARCH)" "x86_64"
AFL_FRIDA_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TEST_BIN) LLVMFuzzerTestOneInput 0x0000555555554000)
AFL_QEMU_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TEST_BIN) LLVMFuzzerTestOneInput 0x4000000000)
endif
ifeq "$(ARCH)" "x86"
AFL_FRIDA_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TEST_BIN) LLVMFuzzerTestOneInput 0x56555000)
AFL_QEMU_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TEST_BIN) LLVMFuzzerTestOneInput 0x4000000000)
endif
.PHONY: all clean frida hook

View File

@ -1,36 +0,0 @@
#!/usr/bin/python3
import argparse
from elftools.elf.elffile import ELFFile
def process_file(file, symbol, base):
with open(file, 'rb') as f:
elf = ELFFile(f)
symtab = elf.get_section_by_name('.symtab')
mains = symtab.get_symbol_by_name(symbol)
if len(mains) != 1:
print ("Failed to find main")
return 1
main_addr = mains[0]['st_value']
main = base + main_addr
print ("0x%016x" % main)
return 0
def hex_value(x):
return int(x, 16)
def main():
parser = argparse.ArgumentParser(description='Process some integers.')
parser.add_argument('-f', '--file', dest='file', type=str,
help='elf file name', required=True)
parser.add_argument('-s', '--symbol', dest='symbol', type=str,
help='symbol name', required=True)
parser.add_argument('-b', '--base', dest='base', type=hex_value,
help='elf base address', required=True)
args = parser.parse_args()
return process_file (args.file, args.symbol, args.base)
if __name__ == "__main__":
ret = main()
exit(ret)

View File

@ -2,7 +2,7 @@
//
// Author: Mateusz Jurczyk (mjurczyk@google.com)
//
// Copyright 2019-2020 Google LLC
// Copyright 2019-2022 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.

View File

@ -3,7 +3,7 @@
--------------------------------------------------------
Originally written by Michal Zalewski
Copyright 2014 Google Inc. All rights reserved.
Copyright 2019-2020 AFLplusplus Project. All rights reserved.
Copyright 2019-2022 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:

View File

@ -3,7 +3,7 @@
--------------------------------------------------------
Originally written by Michal Zalewski
Copyright 2014 Google Inc. All rights reserved.
Copyright 2019-2020 AFLplusplus Project. All rights reserved.
Copyright 2019-2022 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:

View File

@ -3,7 +3,7 @@
--------------------------------------------------------
Originally written by Michal Zalewski
Copyright 2014 Google Inc. All rights reserved.
Copyright 2019-2020 AFLplusplus Project. All rights reserved.
Copyright 2019-2022 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:

View File

@ -47,6 +47,7 @@ endif
TEST_DATA_DIR:=$(BUILD_DIR)in/
TEST_DATA_FILE:=$(TEST_DATA_DIR)default_seed
AFLPP_DRIVER_DUMMY_INPUT:=$(BUILD_DIR)dummy.dat
FRIDA_OUT:=$(BUILD_DIR)frida-out
QEMU_OUT:=$(BUILD_DIR)qemu-out
@ -62,20 +63,22 @@ ifeq "$(ARCH)" "i686"
endif
endif
ADDR_BIN:=$(ROOT)frida_mode/build/addr
GET_SYMBOL_ADDR:=$(ROOT)frida_mode/util/get_symbol_addr.sh
AFL_QEMU_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TEST_BIN) LLVMFuzzerTestOneInput 0x4000000000)
AFL_FRIDA_BASE_ADDR:=$(shell $(ADDR_BIN))
AFL_FRIDA_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TEST_BIN) LLVMFuzzerTestOneInput $(AFL_FRIDA_BASE_ADDR))
ifeq "$(ARCH)" "aarch64"
AFL_FRIDA_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TEST_BIN) LLVMFuzzerTestOneInput 0x0000aaaaaaaaa000)
ifeq "$(ARCH)" "arm64"
AFL_QEMU_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TEST_BIN) LLVMFuzzerTestOneInput 0x5500000000)
endif
ifeq "$(ARCH)" "x86_64"
AFL_FRIDA_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TEST_BIN) LLVMFuzzerTestOneInput 0x0000555555554000)
AFL_QEMU_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TEST_BIN) LLVMFuzzerTestOneInput 0x4000000000)
endif
ifeq "$(ARCH)" "x86"
AFL_FRIDA_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TEST_BIN) LLVMFuzzerTestOneInput 0x56555000)
AFL_QEMU_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TEST_BIN) LLVMFuzzerTestOneInput 0x4000000000)
endif
.PHONY: all clean frida hook
@ -154,6 +157,9 @@ $(TEST_DATA_DIR): | $(TRT_DIR)
cp $(TRT_DIR)fonts/TestGLYFOne.ttf $@
$(TEST_DATA_FILE): | $(TEST_DATA_DIR)
echo "hi" > $@
$(AFLPP_DRIVER_DUMMY_INPUT): | $(BUILD_DIR)
dd if=/dev/zero bs=1048576 count=1 of=$@
###### TEST DATA #######
@ -161,7 +167,7 @@ $(TEST_DATA_FILE): | $(TEST_DATA_DIR)
clean:
rm -rf $(BUILD_DIR)
frida: $(TEST_BIN) $(AFLPP_FRIDA_DRIVER_HOOK_OBJ) $(TEST_DATA_FILE)
frida: $(TEST_BIN) $(AFLPP_FRIDA_DRIVER_HOOK_OBJ) $(TEST_DATA_FILE) $(AFLPP_DRIVER_DUMMY_INPUT)
AFL_FRIDA_PERSISTENT_CNT=1000000 \
AFL_FRIDA_PERSISTENT_HOOK=$(AFLPP_FRIDA_DRIVER_HOOK_OBJ) \
AFL_FRIDA_PERSISTENT_ADDR=$(AFL_FRIDA_PERSISTENT_ADDR) \
@ -174,9 +180,9 @@ frida: $(TEST_BIN) $(AFLPP_FRIDA_DRIVER_HOOK_OBJ) $(TEST_DATA_FILE)
-O \
-V 30 \
-- \
$(TEST_BIN) $(TEST_DATA_FILE)
$(TEST_BIN) $(AFLPP_DRIVER_DUMMY_INPUT)
qemu: $(TEST_BIN) $(AFLPP_QEMU_DRIVER_HOOK_OBJ) $(TEST_DATA_FILE)
qemu: $(TEST_BIN) $(AFLPP_QEMU_DRIVER_HOOK_OBJ) $(TEST_DATA_FILE) $(AFLPP_DRIVER_DUMMY_INPUT)
AFL_QEMU_PERSISTENT_CNT=1000000 \
AFL_QEMU_PERSISTENT_HOOK=$(AFLPP_QEMU_DRIVER_HOOK_OBJ) \
AFL_QEMU_PERSISTENT_ADDR=$(AFL_QEMU_PERSISTENT_ADDR) \
@ -189,4 +195,4 @@ qemu: $(TEST_BIN) $(AFLPP_QEMU_DRIVER_HOOK_OBJ) $(TEST_DATA_FILE)
-Q \
-V 30 \
-- \
$(TEST_BIN) $(TEST_DATA_FILE)
$(TEST_BIN) $(AFLPP_DRIVER_DUMMY_INPUT)

View File

@ -1,36 +0,0 @@
#!/usr/bin/python3
import argparse
from elftools.elf.elffile import ELFFile
def process_file(file, symbol, base):
with open(file, 'rb') as f:
elf = ELFFile(f)
symtab = elf.get_section_by_name('.symtab')
mains = symtab.get_symbol_by_name(symbol)
if len(mains) != 1:
print ("Failed to find main")
return 1
main_addr = mains[0]['st_value']
main = base + main_addr
print ("0x%016x" % main)
return 0
def hex_value(x):
return int(x, 16)
def main():
parser = argparse.ArgumentParser(description='Process some integers.')
parser.add_argument('-f', '--file', dest='file', type=str,
help='elf file name', required=True)
parser.add_argument('-s', '--symbol', dest='symbol', type=str,
help='symbol name', required=True)
parser.add_argument('-b', '--base', dest='base', type=hex_value,
help='elf base address', required=True)
args = parser.parse_args()
return process_file (args.file, args.symbol, args.base)
if __name__ == "__main__":
ret = main()
exit(ret)

View File

@ -46,19 +46,11 @@ ifeq "$(ARCH)" "i686"
endif
endif
ADDR_BIN:=$(ROOT)frida_mode/build/addr
GET_SYMBOL_ADDR:=$(ROOT)frida_mode/util/get_symbol_addr.sh
ifeq "$(ARCH)" "aarch64"
AFL_FRIDA_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TEST_BIN) LLVMFuzzerTestOneInput 0x0000aaaaaaaaa000)
endif
ifeq "$(ARCH)" "x86_64"
AFL_FRIDA_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TEST_BIN) LLVMFuzzerTestOneInput 0x0000555555554000)
endif
ifeq "$(ARCH)" "x86"
AFL_FRIDA_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TEST_BIN) LLVMFuzzerTestOneInput 0x56555000)
endif
AFL_FRIDA_BASE_ADDR:=$(shell $(ADDR_BIN))
AFL_FRIDA_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TEST_BIN) LLVMFuzzerTestOneInput $(AFL_FRIDA_BASE_ADDR))
.PHONY: all clean frida hook

View File

@ -1,36 +0,0 @@
#!/usr/bin/python3
import argparse
from elftools.elf.elffile import ELFFile
def process_file(file, symbol, base):
with open(file, 'rb') as f:
elf = ELFFile(f)
symtab = elf.get_section_by_name('.symtab')
mains = symtab.get_symbol_by_name(symbol)
if len(mains) != 1:
print ("Failed to find main")
return 1
main_addr = mains[0]['st_value']
main = base + main_addr
print ("0x%016x" % main)
return 0
def hex_value(x):
return int(x, 16)
def main():
parser = argparse.ArgumentParser(description='Process some integers.')
parser.add_argument('-f', '--file', dest='file', type=str,
help='elf file name', required=True)
parser.add_argument('-s', '--symbol', dest='symbol', type=str,
help='symbol name', required=True)
parser.add_argument('-b', '--base', dest='base', type=hex_value,
help='elf base address', required=True)
args = parser.parse_args()
return process_file (args.file, args.symbol, args.base)
if __name__ == "__main__":
ret = main()
exit(ret)

View File

@ -3,7 +3,7 @@
--------------------------------------------------------
Originally written by Michal Zalewski
Copyright 2014 Google Inc. All rights reserved.
Copyright 2019-2020 AFLplusplus Project. All rights reserved.
Copyright 2019-2022 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:

View File

@ -3,7 +3,7 @@
--------------------------------------------------------
Originally written by Michal Zalewski
Copyright 2014 Google Inc. All rights reserved.
Copyright 2019-2020 AFLplusplus Project. All rights reserved.
Copyright 2019-2022 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:

View File

@ -55,20 +55,22 @@ ifeq "$(ARCH)" "i686"
endif
endif
ADDR_BIN:=$(ROOT)frida_mode/build/addr
GET_SYMBOL_ADDR:=$(ROOT)frida_mode/util/get_symbol_addr.sh
AFL_QEMU_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TEST_BIN) LLVMFuzzerTestOneInput 0x4000000000)
AFL_FRIDA_BASE_ADDR:=$(shell $(ADDR_BIN))
AFL_FRIDA_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TEST_BIN) LLVMFuzzerTestOneInput $(AFL_FRIDA_BASE_ADDR))
ifeq "$(ARCH)" "arm64"
AFL_FRIDA_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TEST_BIN) LLVMFuzzerTestOneInput 0x0000aaaaaaaaa000)
AFL_QEMU_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TEST_BIN) LLVMFuzzerTestOneInput 0x5500000000)
endif
ifeq "$(ARCH)" "x86_64"
AFL_FRIDA_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TEST_BIN) LLVMFuzzerTestOneInput 0x0000555555554000)
AFL_QEMU_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TEST_BIN) LLVMFuzzerTestOneInput 0x4000000000)
endif
ifeq "$(ARCH)" "x86"
AFL_FRIDA_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TEST_BIN) LLVMFuzzerTestOneInput 0x56555000)
AFL_QEMU_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TEST_BIN) LLVMFuzzerTestOneInput 0x4000000000)
endif
.PHONY: all clean qemu frida hook

View File

@ -42,21 +42,11 @@ ifeq "$(ARCH)" "i686"
endif
endif
ADDR_BIN:=$(ROOT)frida_mode/build/addr
GET_SYMBOL_ADDR:=$(ROOT)frida_mode/util/get_symbol_addr.sh
AFL_QEMU_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TEST_BIN) LLVMFuzzerTestOneInput 0x4000000000)
ifeq "$(ARCH)" "aarch64"
AFL_FRIDA_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TEST_BIN) LLVMFuzzerTestOneInput 0x0000aaaaaaaaa000)
endif
ifeq "$(ARCH)" "x86_64"
AFL_FRIDA_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TEST_BIN) LLVMFuzzerTestOneInput 0x0000555555554000)
endif
ifeq "$(ARCH)" "x86"
AFL_FRIDA_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TEST_BIN) LLVMFuzzerTestOneInput 0x56555000)
endif
AFL_FRIDA_BASE_ADDR:=$(shell $(ADDR_BIN))
AFL_FRIDA_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TEST_BIN) LLVMFuzzerTestOneInput $(AFL_FRIDA_BASE_ADDR))
.PHONY: all clean frida hook
@ -134,7 +124,7 @@ $(TEST_DATA_DIR): | $(BUILD_DIR)
mkdir -p $@
$(TEST_DATA_FILE): | $(TEST_DATA_DIR)
dd if=/dev/zero bs=1048576 count=1 of=$@
echo "hi" > $@
###### #######

View File

@ -1,36 +0,0 @@
#!/usr/bin/python3
import argparse
from elftools.elf.elffile import ELFFile
def process_file(file, symbol, base):
with open(file, 'rb') as f:
elf = ELFFile(f)
symtab = elf.get_section_by_name('.symtab')
mains = symtab.get_symbol_by_name(symbol)
if len(mains) != 1:
print ("Failed to find main")
return 1
main_addr = mains[0]['st_value']
main = base + main_addr
print ("0x%016x" % main)
return 0
def hex_value(x):
return int(x, 16)
def main():
parser = argparse.ArgumentParser(description='Process some integers.')
parser.add_argument('-f', '--file', dest='file', type=str,
help='elf file name', required=True)
parser.add_argument('-s', '--symbol', dest='symbol', type=str,
help='symbol name', required=True)
parser.add_argument('-b', '--base', dest='base', type=hex_value,
help='elf base address', required=True)
args = parser.parse_args()
return process_file (args.file, args.symbol, args.base)
if __name__ == "__main__":
ret = main()
exit(ret)

View File

@ -0,0 +1,177 @@
PWD:=$(shell pwd)/
ROOT:=$(PWD)../../../
BUILD_DIR:=$(PWD)build/
AFLPP_FRIDA_DRIVER_HOOK_OBJ=$(ROOT)frida_mode/build/frida_hook.so
AFLPP_QEMU_DRIVER_HOOK_OBJ=$(ROOT)frida_mode/build/qemu_hook.so
LIBFUZZER_LIB:=/usr/lib/llvm-12/lib/libFuzzer.a
LIBXSLT_GIT_REPO:=https://gitlab.gnome.org/GNOME/libxslt.git
LIBXSLT_DIR:=$(BUILD_DIR)libxslt/
LIBXSLT_LIB:=$(LIBXSLT_DIR)libxslt/.libs/libxslt.a
LIBZXML2_GIT_REPO:=https://gitlab.gnome.org/GNOME/libxml2.git
LIBXML2_DIR:=$(BUILD_DIR)libxml2/
LIBXML2_LIB:=$(LIBXML2_DIR).libs/libxml2.a
TEST_BIN:=$(BUILD_DIR)test
XPATH_XML:=$(BUILD_DIR)xpath.xml
ifeq "$(shell uname)" "Darwin"
TEST_BIN_LDFLAGS:=-undefined dynamic_lookup -Wl,-no_pie
endif
TEST_DATA_DIR:=$(BUILD_DIR)in/
TEST_DATA_SRC:=$(LIBXSLT_DIR)tests/testdata/fuzz_corpus/
DUMMY_DATA_FILE:=$(BUILD_DIR)default_seed
FRIDA_OUT:=$(BUILD_DIR)frida-out
QEMU_OUT:=$(BUILD_DIR)qemu-out
ifndef ARCH
ARCH=$(shell uname -m)
ifeq "$(ARCH)" "aarch64"
ARCH:=arm64
endif
ifeq "$(ARCH)" "i686"
ARCH:=x86
endif
endif
ADDR_BIN:=$(ROOT)frida_mode/build/addr
GET_SYMBOL_ADDR:=$(ROOT)frida_mode/util/get_symbol_addr.sh
AFL_FRIDA_BASE_ADDR:=$(shell $(ADDR_BIN))
AFL_FRIDA_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TEST_BIN) LLVMFuzzerTestOneInput $(AFL_FRIDA_BASE_ADDR))
ifeq "$(ARCH)" "arm64"
AFL_QEMU_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TEST_BIN) LLVMFuzzerTestOneInput 0x5500000000)
endif
ifeq "$(ARCH)" "x86_64"
AFL_QEMU_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TEST_BIN) LLVMFuzzerTestOneInput 0x4000000000)
endif
ifeq "$(ARCH)" "x86"
AFL_QEMU_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TEST_BIN) LLVMFuzzerTestOneInput 0x4000000000)
endif
.PHONY: all clean frida hook
all: $(TEST_BIN)
make -C $(ROOT)frida_mode/
32:
CXXFLAGS="-m32" LDFLAGS="-m32" ARCH="x86" make all
$(BUILD_DIR):
mkdir -p $@
########## LIBXML2 #######
$(LIBXML2_DIR): | $(BUILD_DIR)
git clone --depth 1 $(LIBZXML2_GIT_REPO) $@
$(LIBXML2_LIB): | $(LIBXML2_DIR)
cd $(LIBXML2_DIR) && ./autogen.sh \
--disable-shared \
--without-c14n \
--without-legacy \
--without-push \
--without-python \
--without-reader \
--without-regexps \
--without-sax1 \
--without-schemas \
--without-schematron \
--without-valid \
--without-writer \
--without-zlib \
--without-lzma
cd $(LIBXML2_DIR) && make -j$(nproc) V=1
libxml2: $(LIBXML2_LIB)
########## LIBZXSLT #######
$(LIBXSLT_DIR): | $(BUILD_DIR)
git clone --depth 1 $(LIBXSLT_GIT_REPO) $@
$(LIBXSLT_LIB): | $(LIBXSLT_DIR) $(LIBXML2_DIR)
cd $(LIBXSLT_DIR) && ./autogen.sh \
--with-libxml-src=../libxml2 \
--disable-shared \
--without-python \
--with-crypto \
--without-debug \
--without-debugger \
--without-profiler
cd $(LIBXSLT_DIR) && make -j$(nproc) V=1
libxslt: $(LIBXSLT_LIB)
$(TEST_BIN): $(LIBXSLT_LIB) $(LIBXML2_LIB)
clang \
-o $@ \
-fsanitize=fuzzer \
-I $(LIBXSLT_DIR) \
-I $(LIBXML2_DIR)include \
$(LIBXSLT_DIR)tests/fuzz/xpath.c \
$(LIBXSLT_DIR)tests/fuzz/fuzz.c \
$(LIBXSLT_DIR)libxslt/.libs/libxslt.a \
$(LIBXSLT_DIR)libexslt/.libs/libexslt.a \
$(LIBXML2_LIB) \
-lgcrypt
test: $(TEST_BIN)
########## DUMMY #######
$(DUMMY_DATA_FILE): | $(TEST_DATA_DIR)
dd if=/dev/zero bs=1048576 count=1 of=$@
###### TEST DATA #######
$(TEST_DATA_DIR): | $(LIBXSLT_DIR) $(BUILD_DIR)
cp -av $(LIBXSLT_DIR)tests/fuzz/seed/* $@
$(XPATH_XML): | $(LIBXSLT_DIR)
cp $(LIBXSLT_DIR)tests/fuzz/xpath.xml $@
clean:
rm -rf $(BUILD_DIR)
frida: $(TEST_BIN) $(AFLPP_FRIDA_DRIVER_HOOK_OBJ) $(TEST_DATA_FILE) $(DUMMY_DATA_FILE) $(XPATH_XML)
AFL_FRIDA_PERSISTENT_CNT=1000000 \
AFL_FRIDA_PERSISTENT_HOOK=$(AFLPP_FRIDA_DRIVER_HOOK_OBJ) \
AFL_FRIDA_PERSISTENT_ADDR=$(AFL_FRIDA_PERSISTENT_ADDR) \
AFL_ENTRYPOINT=$(AFL_FRIDA_PERSISTENT_ADDR) \
$(ROOT)afl-fuzz \
-i $(TEST_DATA_DIR) \
-o $(FRIDA_OUT) \
-m none \
-d \
-O \
-V 30 \
-- \
$(TEST_BIN) $(DUMMY_DATA_FILE)
qemu: $(TEST_BIN) $(AFLPP_QEMU_DRIVER_HOOK_OBJ) $(TEST_DATA_FILE) $(DUMMY_DATA_FILE) $(XPATH_XML)
AFL_QEMU_PERSISTENT_CNT=1000000 \
AFL_QEMU_PERSISTENT_HOOK=$(AFLPP_QEMU_DRIVER_HOOK_OBJ) \
AFL_QEMU_PERSISTENT_ADDR=$(AFL_QEMU_PERSISTENT_ADDR) \
AFL_ENTRYPOINT=$(AFL_QEMU_PERSISTENT_ADDR) \
$(ROOT)afl-fuzz \
-i $(TEST_DATA_DIR) \
-o $(QEMU_OUT) \
-m none \
-d \
-Q \
-V 30 \
-- \
$(TEST_BIN) $(DUMMY_DATA_FILE)

View File

@ -0,0 +1,13 @@
all:
@echo trying to use GNU make...
@gmake all || echo please install GNUmake
32:
@echo trying to use GNU make...
@gmake 32 || echo please install GNUmake
clean:
@gmake clean
frida:
@gmake frida

View File

@ -3,7 +3,7 @@
--------------------------------------------------------
Originally written by Michal Zalewski
Copyright 2014 Google Inc. All rights reserved.
Copyright 2019-2020 AFLplusplus Project. All rights reserved.
Copyright 2019-2022 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:

View File

@ -14,6 +14,10 @@ FRIDA_OUT:=$(BUILD_DIR)frida-out
AFLPP_FRIDA_DRIVER_HOOK_OBJ=$(ROOT)frida_mode/build/frida_hook.so
AFLPP_QEMU_DRIVER_HOOK_OBJ=$(ROOT)frida_mode/build/qemu_hook.so
AFLPP_DRIVER_DUMMY_INPUT:=$(BUILD_DIR)dummy.dat
QEMU_OUT:=$(BUILD_DIR)qemu-out
FRIDA_OUT:=$(BUILD_DIR)frida-out
ifndef ARCH
ARCH=$(shell uname -m)
@ -26,20 +30,22 @@ ifeq "$(ARCH)" "i686"
endif
endif
ADDR_BIN:=$(ROOT)frida_mode/build/addr
GET_SYMBOL_ADDR:=$(ROOT)frida_mode/util/get_symbol_addr.sh
AFL_QEMU_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TEST_BIN) LLVMFuzzerTestOneInput 0x4000000000)
AFL_FRIDA_BASE_ADDR:=$(shell $(ADDR_BIN))
AFL_FRIDA_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TEST_BIN) LLVMFuzzerTestOneInput $(AFL_FRIDA_BASE_ADDR))
ifeq "$(ARCH)" "arm64"
AFL_FRIDA_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TEST_BIN) LLVMFuzzerTestOneInput 0x0000aaaaaaaaa000)
AFL_QEMU_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TEST_BIN) LLVMFuzzerTestOneInput 0x5500000000)
endif
ifeq "$(ARCH)" "x86_64"
AFL_FRIDA_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TEST_BIN) LLVMFuzzerTestOneInput 0x0000555555554000)
AFL_QEMU_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TEST_BIN) LLVMFuzzerTestOneInput 0x4000000000)
endif
ifeq "$(ARCH)" "x86"
AFL_FRIDA_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TEST_BIN) LLVMFuzzerTestOneInput 0x56555000)
AFL_QEMU_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TEST_BIN) LLVMFuzzerTestOneInput 0x4000000000)
endif
@ -70,10 +76,13 @@ $(TEST_DATA_DIR): | $(BUILD_DIR)
mkdir -p $@
$(TEST_DATA_FILE): | $(TEST_DATA_DIR)
echo "hi" > $@
$(AFLPP_DRIVER_DUMMY_INPUT): | $(BUILD_DIR)
dd if=/dev/zero bs=1048576 count=1 of=$@
qemu: $(TEST_BIN) $(TEST_DATA_FILE)
qemu: $(TEST_BIN) $(TEST_DATA_FILE) $(AFLPP_DRIVER_DUMMY_INPUT)
AFL_QEMU_PERSISTENT_CNT=1000000 \
AFL_QEMU_PERSISTENT_HOOK=$(AFLPP_QEMU_DRIVER_HOOK_OBJ) \
AFL_QEMU_PERSISTENT_ADDR=$(AFL_QEMU_PERSISTENT_ADDR) \
@ -86,9 +95,9 @@ qemu: $(TEST_BIN) $(TEST_DATA_FILE)
-o $(QEMU_OUT) \
-V 10 \
-- \
$(TEST_BIN) $(TEST_DATA_FILE)
$(TEST_BIN) $(AFLPP_DRIVER_DUMMY_INPUT)
frida: $(TEST_BIN) $(TEST_DATA_FILE)
frida: $(TEST_BIN) $(TEST_DATA_FILE) $(AFLPP_DRIVER_DUMMY_INPUT)
AFL_FRIDA_PERSISTENT_CNT=1000000 \
AFL_FRIDA_PERSISTENT_HOOK=$(AFLPP_FRIDA_DRIVER_HOOK_OBJ) \
AFL_FRIDA_PERSISTENT_ADDR=$(AFL_FRIDA_PERSISTENT_ADDR) \
@ -98,9 +107,9 @@ frida: $(TEST_BIN) $(TEST_DATA_FILE)
-O \
-i $(TEST_DATA_DIR) \
-o $(FRIDA_OUT) \
-V 10 \
-t 1000+ \
-- \
$(TEST_BIN) $(TEST_DATA_FILE)
$(TEST_BIN) $(AFLPP_DRIVER_DUMMY_INPUT)
debug:
echo $(AFL_FRIDA_PERSISTENT_ADDR)

View File

@ -3,7 +3,7 @@
--------------------------------------------------------
Originally written by Michal Zalewski
Copyright 2014 Google Inc. All rights reserved.
Copyright 2019-2020 AFLplusplus Project. All rights reserved.
Copyright 2019-2022 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:

View File

@ -22,27 +22,16 @@ ifeq "$(ARCH)" "i686"
endif
endif
ADDR_BIN:=$(ROOT)frida_mode/build/addr
GET_SYMBOL_ADDR:=$(ROOT)frida_mode/util/get_symbol_addr.sh
ifeq "$(shell uname)" "Darwin"
TEST_BIN_LDFLAGS:=-Wl,-no_pie
endif
ARCH=$(shell uname -m)
ifeq "$(ARCH)" "aarch64"
AFL_FRIDA_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TESTINSTBIN) main 0x0000aaaaaaaaa000)
AFL_FRIDA_PERSISTENT_RET=$(shell $(GET_SYMBOL_ADDR) $(TESTINSTBIN) slow 0x0000aaaaaaaaa000)
endif
ifeq "$(ARCH)" "x86_64"
AFL_FRIDA_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TESTINSTBIN) main 0x0000555555554000)
AFL_FRIDA_PERSISTENT_RET=$(shell $(GET_SYMBOL_ADDR) $(TESTINSTBIN) slow 0x0000555555554000)
endif
ifeq "$(ARCH)" "x86"
AFL_FRIDA_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TESTINSTBIN) main 0x56555000)
AFL_FRIDA_PERSISTENT_RET=$(shell $(GET_SYMBOL_ADDR) $(TESTINSTBIN) slow 0x56555000)
endif
AFL_FRIDA_BASE_ADDR:=$(shell $(ADDR_BIN))
AFL_FRIDA_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TESTINSTBIN) main $(AFL_FRIDA_BASE_ADDR))
AFL_FRIDA_PERSISTENT_RET=$(shell $(GET_SYMBOL_ADDR) $(TESTINSTBIN) slow $(AFL_FRIDA_BASE_ADDR))
ifeq "$(shell uname)" "Darwin"
AFL_PRELOAD=/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation

View File

@ -3,7 +3,7 @@
--------------------------------------------------------
Originally written by Michal Zalewski
Copyright 2014 Google Inc. All rights reserved.
Copyright 2019-2020 AFLplusplus Project. All rights reserved.
Copyright 2019-2022 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:

View File

@ -21,20 +21,22 @@ ifeq "$(ARCH)" "i686"
endif
endif
ADDR_BIN:=$(ROOT)frida_mode/build/addr
GET_SYMBOL_ADDR:=$(ROOT)frida_mode/util/get_symbol_addr.sh
AFL_QEMU_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TEST_BIN) main 0x4000000000)
AFL_FRIDA_BASE_ADDR:=$(shell $(ADDR_BIN))
AFL_FRIDA_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TEST_BIN) LLVMFuzzerTestOneInput $(AFL_FRIDA_BASE_ADDR))
ifeq "$(ARCH)" "arm64"
AFL_FRIDA_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TEST_BIN) main 0x0000aaaaaaaaa000)
AFL_QEMU_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TEST_BIN) LLVMFuzzerTestOneInput 0x5500000000)
endif
ifeq "$(ARCH)" "x86_64"
AFL_FRIDA_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TEST_BIN) main 0x0000555555554000)
AFL_QEMU_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TEST_BIN) LLVMFuzzerTestOneInput 0x4000000000)
endif
ifeq "$(ARCH)" "x86"
AFL_FRIDA_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TEST_BIN) main 0x56555000)
AFL_QEMU_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TEST_BIN) LLVMFuzzerTestOneInput 0x4000000000)
endif
.PHONY: all 32 clean qemu qemu_entry frida frida_entry

View File

@ -32,20 +32,22 @@ ifeq "$(ARCH)" "i686"
endif
endif
ADDR_BIN:=$(ROOT)frida_mode/build/addr
GET_SYMBOL_ADDR:=$(ROOT)frida_mode/util/get_symbol_addr.sh
AFL_QEMU_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TEST_BIN) LLVMFuzzerTestOneInput 0x4000000000)
AFL_FRIDA_BASE_ADDR:=$(shell $(ADDR_BIN))
AFL_FRIDA_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TEST_BIN) LLVMFuzzerTestOneInput $(AFL_FRIDA_BASE_ADDR))
ifeq "$(ARCH)" "arm64"
AFL_FRIDA_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TEST_BIN) LLVMFuzzerTestOneInput 0x0000aaaaaaaaa000)
AFL_QEMU_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TEST_BIN) LLVMFuzzerTestOneInput 0x5500000000)
endif
ifeq "$(ARCH)" "x86_64"
AFL_FRIDA_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TEST_BIN) LLVMFuzzerTestOneInput 0x0000555555554000)
AFL_QEMU_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TEST_BIN) LLVMFuzzerTestOneInput 0x4000000000)
endif
ifeq "$(ARCH)" "x86"
AFL_FRIDA_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TEST_BIN) LLVMFuzzerTestOneInput 0x56555000)
AFL_QEMU_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TEST_BIN) LLVMFuzzerTestOneInput 0x4000000000)
endif
ifeq "$(shell uname)" "Darwin"

Some files were not shown because too many files have changed in this diff Show More