Compare commits

...

34 Commits

Author SHA1 Message Date
1ce165147f remove range analysis 2021-07-05 11:57:30 +02:00
f92ab77ab4 remove alias analysis 2021-07-02 14:54:23 +02:00
67be563672 reenable mixed violations 2021-06-17 13:50:11 +02:00
3927f81e1d no unusual trim 2021-06-16 10:30:40 +02:00
fa23e52459 stats 2021-06-16 10:01:51 +02:00
b053ecd176 remove mixed violations 2021-06-16 09:58:29 +02:00
9b28c1dc36 fix 2021-06-15 17:27:06 +02:00
b9189db55b learn at each fuzz one 2021-06-15 17:22:26 +02:00
f6ccdf13e0 learn on calibration 2021-06-15 16:30:22 +02:00
b382566227 remove print 2021-06-15 16:12:10 +02:00
fd0311572e cleanup 2021-06-15 16:07:12 +02:00
04a4e1b0b7 fixes 2021-06-15 15:20:16 +02:00
b17d03b8b0 Merge branch 'unusual_values' of github.com:AFLplusplus/AFLplusplus into unusual_values 2021-06-14 23:33:25 +02:00
5830ec4718 ptr invs 2021-06-14 23:33:22 +02:00
7b9fc8c6d3 unusual crash dedup 2021-06-14 23:32:19 +02:00
4444b457d9 stability 2021-06-14 11:02:07 +02:00
e76c563178 fix bugs & swap between learning when we have a cycle without findings 2021-06-08 11:30:43 +02:00
0b0d928374 fix bugs 2021-06-08 11:14:07 +02:00
9425acf073 unusual forkserver 2021-06-07 17:31:06 +02:00
fa84e71be2 instrument values without comparability set too 2021-06-04 16:35:05 +02:00
46f95c8db9 checks on range analysis and hotpatch again on INV_ALL 2021-06-03 22:12:15 +02:00
6d1b0d9812 remove logs 2021-06-03 21:23:27 +02:00
bede2597de fix afl-cc 2021-06-03 21:11:34 +02:00
c8f1366e3f AFL_NO_SINGLE_UNUSUAL_VALUES 2021-06-03 20:45:01 +02:00
703b545211 merge 2021-06-03 19:27:49 +02:00
803bfabd2b format 2021-06-03 19:25:39 +02:00
4c583a2450 alias analysis to avoid to log const mem and recognize useless invariants using range analysis 2021-06-03 19:24:31 +02:00
48bca6e51c oneof invariants, filtering with range analysis and hotpatching useless checks 2021-06-03 16:36:37 +02:00
afc2abd5d6 check invariants only between a pair of vars 2021-06-02 17:25:29 +02:00
754c9d8b53 naive on demand invariant learning 2021-06-02 14:43:31 +02:00
bfaf6ed790 working welford 2021-06-02 10:56:19 +02:00
a9ca2136ca Merge remote-tracking branch 'upstream/stable' into main 2021-06-02 10:19:34 +02:00
a321d4102b push to stable (#953)
* use atomic read-modify-write increment for LLVM CLASSIC

* Change other LLVM modes to atomic increments

* sync (#886)

* Create FUNDING.yml

* Update FUNDING.yml

* moved custom_mutator examples

* unicorn speedtest makefile cleanup

* fixed example location

* fix qdbi

* update util readme

* work in progress: not working correctly yet

* Frida persistent (#880)

* Added x64 support for persistent mode (function call only), in-memory teest cases and complog

* Review changes, fix NeverZero and code to parse the .text section of the main executable. Excluded ranges TBC

* Various minor fixes and finished support for AFL_INST_LIBS

* Review changes

Co-authored-by: Your Name <you@example.com>

* nits

* fix frida mode

* Integer overflow/underflow fixes in libdislocator (#889)

* libdislocator: fixing integer overflow in 'max_mem' variable and setting 'max_mem' type to 'size_t'

* libdislocator: fixing potential integer underflow in 'total_mem' variable due to its different values in different threads

* Bumped warnings up to the max and fixed remaining issues (#890)

Co-authored-by: Your Name <you@example.com>

* nits

* frida mode - support non-pie

* nits

* nit

* update grammar mutator

* Fixes for aarch64, OSX and other minor issues (#891)

Co-authored-by: Your Name <you@example.com>

* nits

* nits

* fix PCGUARD, build aflpp_driver with fPIC

* Added representative fuzzbench test and test for libxml (#893)

* Added representative fuzzbench test and test for libxml

* Added support for building FRIDA from source with FRIDA_SOURCE=1

Co-authored-by: Your Name <you@example.com>

* nits

* update changelog

* typos

* still not working

* fixed potential double free in custom trim (#881)

* error handling, freeing mem

* frida: complog -> cmplog

* fix statsd writing

* let aflpp_qemu_driver_hook.so build fail gracefully

* fix stdin trimming

* Support for AFL_ENTRYPOINT (#898)

Co-authored-by: Your Name <you@example.com>

* remove the input file .cur_input at the end of the fuzzing, if AFL_TMPDIR is used

* reverse push (#901)

* Create FUNDING.yml

* Update FUNDING.yml

* disable QEMU static pie

Co-authored-by: Andrea Fioraldi <andreafioraldi@gmail.com>

* clarify that no modifications are required.

* add new test for frida_mode (please review)

* typos

* fix persistent mode (64-bit)

* set ARCH for linux intel 32-bit for frida-gum-devkit

* prepare for 32-bit support (later)

* not on qemu 3 anymore

* unicorn mips fixes

* instrumentation further move to C++11 (#900)

* unicorn fixes

* first working NeverZero implementation

* more unicorn fixes

* Fix memory errors when trim causes testcase growth (#881) (#903)

* Revert "fixed potential double free in custom trim (#881)"

This reverts commit e9d2f72382.

* Revert "fix custom trim for increasing data"

This reverts commit 86a8ef168d.

* Fix memory errors when trim causes testcase growth

Modify trim_case_custom to avoid writing into in_buf because
some custom mutators can cause the testcase to grow rather than
shrink.

Instead of modifying in_buf directly, we write the update out
to the disk when trimming is complete, and then the caller is
responsible for refreshing the in-memory buffer from the file.

This is still a bit sketchy because it does need to modify q->len in
order to notify the upper layers that something changed, and it could
end up telling upper layer code that the q->len is *bigger* than
the buffer (q->testcase_buf) that contains it, which is asking
for trouble down the line somewhere...

* Fix an unlikely situation

Put back some `unlikely()` calls that were in
the e9d2f72382 commit that was
reverted.

* add some comments

* typo

* Exit on time (#904)

* Variable AFL_EXIT_ON_TIME description has been added.
Variables AFL_EXIT_ON_TIME and afl_exit_on_time has been added.
afl->exit_on_time variable initialization has been added.
The asignment of a value to the afl->afl_env.afl_exit_on_time variable from
environment variables has been added.
Code to exit on timeout if new path not found has been added.

* Type of afl_exit_on_time variable has been changed.
Variable exit_on_time has been added to the afl_state_t structure.

* Command `export AFL_EXIT_WHEN_DONE=1` has been added.

* Millisecond to second conversion has been added.
Call get_cur_time() has been added.

* Revert to using the saved current time value.

* Useless check has been removed.

* fix new path to custom-mutators

* ensure crashes/README.txt exists

* fix

* Changes to bump FRIDA version and to clone FRIDA repo in to build directory rather than use a submodule as the FRIDA build scripts don't like it (#906)

Co-authored-by: Your Name <you@example.com>

* Fix numeric overflow in cmplog implementation (#907)

Co-authored-by: Your Name <you@example.com>

* testcase fixes for unicorn

* remove merge conflict artifacts

* fix afl-plot

* Changes to remove binaries from frida_mode (#913)

Co-authored-by: Your Name <you@example.com>

* Frida cmplog fail fast (#914)

* Changes to remove binaries from frida_mode

* Changes to make cmplog fail fast

Co-authored-by: Your Name <you@example.com>

* afl-plot: relative time

* arch linux and mac os support for afl-system-config

* typo

* code-format

* update documentation

* github workflow for qemu

* OSX-specific improvements (#912)

* Fix afl-cc to work correctly by default on OSX using xcode

- CLANG_ENV_VAR must be set for afl-as to work
- Use clang mode by default if no specific compiler selected

* Add OSX-specific documentation for configuring shared memory

* Fixes to memory operands for complog (#916)

Co-authored-by: Your Name <you@example.com>

* fix a few cur_time uses

* added bounds check to pivot_inputs (fixes #921)

* additional safety checks for restarts

* restrict afl-showmap in_file size

* fix seed crash disable

* add warning for afl-showmap partial read

* no core dumps

* AFL_PRINT_FILENAMES added

* more documentation for AFL_EXIT_ON_TIME

* Flushing for AFL_PRINT_FILENAMES

* FASAN Support (#918)

* FASAN Support

* Fix handling of Address Sanitizer DSO

* Changes to identification of Address Sanitizer DSO

Co-authored-by: Your Name <you@example.com>

* Support for x86 (#920)

Co-authored-by: Your Name <you@example.com>

* Update frida_mode readme (#925)

* libqasan: use syscalls for read and write

* update readme

* Minor integration tweaks (#926)

Co-authored-by: Your Name <you@example.com>

* merge

* fix afl-fuzz.c frida preload

* cleaned up AFL_PRINT_FILENAMES env

* Changes to have persistent mode exit at the end of the loop (#928)

Co-authored-by: Your Name <you@example.com>

* fix llvm-dict2file

* push to stable (#931) (#932)

* sync (#886)

* Create FUNDING.yml

* Update FUNDING.yml

* moved custom_mutator examples

* unicorn speedtest makefile cleanup

* fixed example location

* fix qdbi

* update util readme

* Frida persistent (#880)

* Added x64 support for persistent mode (function call only), in-memory teest cases and complog

* Review changes, fix NeverZero and code to parse the .text section of the main executable. Excluded ranges TBC

* Various minor fixes and finished support for AFL_INST_LIBS

* Review changes

Co-authored-by: Your Name <you@example.com>

* nits

* fix frida mode

* Integer overflow/underflow fixes in libdislocator (#889)

* libdislocator: fixing integer overflow in 'max_mem' variable and setting 'max_mem' type to 'size_t'

* libdislocator: fixing potential integer underflow in 'total_mem' variable due to its different values in different threads

* Bumped warnings up to the max and fixed remaining issues (#890)

Co-authored-by: Your Name <you@example.com>

* nits

* frida mode - support non-pie

* nits

* nit

* update grammar mutator

* Fixes for aarch64, OSX and other minor issues (#891)

Co-authored-by: Your Name <you@example.com>

* nits

* nits

* fix PCGUARD, build aflpp_driver with fPIC

* Added representative fuzzbench test and test for libxml (#893)

* Added representative fuzzbench test and test for libxml

* Added support for building FRIDA from source with FRIDA_SOURCE=1

Co-authored-by: Your Name <you@example.com>

* nits

* update changelog

* typos

* fixed potential double free in custom trim (#881)

* error handling, freeing mem

* frida: complog -> cmplog

* fix statsd writing

* let aflpp_qemu_driver_hook.so build fail gracefully

* fix stdin trimming

* Support for AFL_ENTRYPOINT (#898)

Co-authored-by: Your Name <you@example.com>

* remove the input file .cur_input at the end of the fuzzing, if AFL_TMPDIR is used

* reverse push (#901)

* Create FUNDING.yml

* Update FUNDING.yml

* disable QEMU static pie

Co-authored-by: Andrea Fioraldi <andreafioraldi@gmail.com>

* clarify that no modifications are required.

* add new test for frida_mode (please review)

* typos

* fix persistent mode (64-bit)

* set ARCH for linux intel 32-bit for frida-gum-devkit

* prepare for 32-bit support (later)

* not on qemu 3 anymore

* unicorn mips fixes

* instrumentation further move to C++11 (#900)

* unicorn fixes

* more unicorn fixes

* Fix memory errors when trim causes testcase growth (#881) (#903)

* Revert "fixed potential double free in custom trim (#881)"

This reverts commit e9d2f72382.

* Revert "fix custom trim for increasing data"

This reverts commit 86a8ef168d.

* Fix memory errors when trim causes testcase growth

Modify trim_case_custom to avoid writing into in_buf because
some custom mutators can cause the testcase to grow rather than
shrink.

Instead of modifying in_buf directly, we write the update out
to the disk when trimming is complete, and then the caller is
responsible for refreshing the in-memory buffer from the file.

This is still a bit sketchy because it does need to modify q->len in
order to notify the upper layers that something changed, and it could
end up telling upper layer code that the q->len is *bigger* than
the buffer (q->testcase_buf) that contains it, which is asking
for trouble down the line somewhere...

* Fix an unlikely situation

Put back some `unlikely()` calls that were in
the e9d2f72382 commit that was
reverted.

* typo

* Exit on time (#904)

* Variable AFL_EXIT_ON_TIME description has been added.
Variables AFL_EXIT_ON_TIME and afl_exit_on_time has been added.
afl->exit_on_time variable initialization has been added.
The asignment of a value to the afl->afl_env.afl_exit_on_time variable from
environment variables has been added.
Code to exit on timeout if new path not found has been added.

* Type of afl_exit_on_time variable has been changed.
Variable exit_on_time has been added to the afl_state_t structure.

* Command `export AFL_EXIT_WHEN_DONE=1` has been added.

* Millisecond to second conversion has been added.
Call get_cur_time() has been added.

* Revert to using the saved current time value.

* Useless check has been removed.

* fix new path to custom-mutators

* ensure crashes/README.txt exists

* fix

* Changes to bump FRIDA version and to clone FRIDA repo in to build directory rather than use a submodule as the FRIDA build scripts don't like it (#906)

Co-authored-by: Your Name <you@example.com>

* Fix numeric overflow in cmplog implementation (#907)

Co-authored-by: Your Name <you@example.com>

* testcase fixes for unicorn

* remove merge conflict artifacts

* fix afl-plot

* Changes to remove binaries from frida_mode (#913)

Co-authored-by: Your Name <you@example.com>

* Frida cmplog fail fast (#914)

* Changes to remove binaries from frida_mode

* Changes to make cmplog fail fast

Co-authored-by: Your Name <you@example.com>

* afl-plot: relative time

* arch linux and mac os support for afl-system-config

* typo

* code-format

* update documentation

* github workflow for qemu

* OSX-specific improvements (#912)

* Fix afl-cc to work correctly by default on OSX using xcode

- CLANG_ENV_VAR must be set for afl-as to work
- Use clang mode by default if no specific compiler selected

* Add OSX-specific documentation for configuring shared memory

* Fixes to memory operands for complog (#916)

Co-authored-by: Your Name <you@example.com>

* fix a few cur_time uses

* added bounds check to pivot_inputs (fixes #921)

* additional safety checks for restarts

* restrict afl-showmap in_file size

* fix seed crash disable

* add warning for afl-showmap partial read

* no core dumps

* AFL_PRINT_FILENAMES added

* more documentation for AFL_EXIT_ON_TIME

* Flushing for AFL_PRINT_FILENAMES

* FASAN Support (#918)

* FASAN Support

* Fix handling of Address Sanitizer DSO

* Changes to identification of Address Sanitizer DSO

Co-authored-by: Your Name <you@example.com>

* Support for x86 (#920)

Co-authored-by: Your Name <you@example.com>

* Update frida_mode readme (#925)

* libqasan: use syscalls for read and write

* update readme

* Minor integration tweaks (#926)

Co-authored-by: Your Name <you@example.com>

* merge

* fix afl-fuzz.c frida preload

* cleaned up AFL_PRINT_FILENAMES env

* Changes to have persistent mode exit at the end of the loop (#928)

Co-authored-by: Your Name <you@example.com>

* fix llvm-dict2file

Co-authored-by: Dominik Maier <domenukk@gmail.com>
Co-authored-by: WorksButNotTested <62701594+WorksButNotTested@users.noreply.github.com>
Co-authored-by: Your Name <you@example.com>
Co-authored-by: Dmitry Zheregelya <zheregelya.d@gmail.com>
Co-authored-by: hexcoder <hexcoder-@users.noreply.github.com>
Co-authored-by: hexcoder- <heiko@hexco.de>
Co-authored-by: Andrea Fioraldi <andreafioraldi@gmail.com>
Co-authored-by: David CARLIER <devnexen@gmail.com>
Co-authored-by: realmadsci <71108352+realmadsci@users.noreply.github.com>
Co-authored-by: Roman M. Iudichev <SecNotice@ya.ru>
Co-authored-by: Dustin Spicuzza <dustin@virtualroadside.com>

Co-authored-by: Dominik Maier <domenukk@gmail.com>
Co-authored-by: WorksButNotTested <62701594+WorksButNotTested@users.noreply.github.com>
Co-authored-by: Your Name <you@example.com>
Co-authored-by: Dmitry Zheregelya <zheregelya.d@gmail.com>
Co-authored-by: hexcoder <hexcoder-@users.noreply.github.com>
Co-authored-by: hexcoder- <heiko@hexco.de>
Co-authored-by: Andrea Fioraldi <andreafioraldi@gmail.com>
Co-authored-by: David CARLIER <devnexen@gmail.com>
Co-authored-by: realmadsci <71108352+realmadsci@users.noreply.github.com>
Co-authored-by: Roman M. Iudichev <SecNotice@ya.ru>
Co-authored-by: Dustin Spicuzza <dustin@virtualroadside.com>

* improve error msg

* Added documentation for wine LoadLibrary workaround (#933)

* Fix cmake target compilation command example (#934)

- Fix typo DCMAKE_C_COMPILERC -> DCMAKE_C_COMPILER.
- Add `cd build` after `mkdir build`.

* showmap passes queue items in alphabetical order

* added tmp files to gitignore

* lenient dict parsing, no map size enum for binary fuzzing

* added info about showmap queue directions

* update binary-only doc

* turn off map size detection if skip_bin_check is set

* Typo

* update docs

* update afl-system-config

* Set kill signal before using it in afl-showmap (#935)

* fix afl-cc help output

* add libafl to binary-only doc

* update docs

* less executions on variable paths

* AFL_SKIP_CRASHES is obsolete since 3.0

* add AFL_TRY_AFFINITY

* Typo

* Typo

* Typo/wording

* tweaks

* typos

* fix afl-whatsup help output

* fix afl-plot output

* fix for MacOS

* fix cmpcov doc for qemu

* fix tmpfile removal

* update dockerfile

* Frida (#940)

* Added re2 test

* Added libpcap test

* Fix validation of setting of ADDR_NO_RANDOMIZE

* Added support for printing original and instrumented code

Co-authored-by: Your Name <you@example.com>

* Support for AFL_FRIDA_PERSISTENT_RET (#941)

Co-authored-by: Your Name <you@example.com>

* Changes to add missing exclusion of ranges (#943)

Co-authored-by: Your Name <you@example.com>

* add --afl-noopt to afl-cc

* docs: fix link to README in QuickStartGuide (#946)

* Support writing Stalker stats (#945)

* Support writing Stalker stats

* Fixed string handling in print functions

Co-authored-by: Your Name <you@example.com>

* afl-cmin help fix, aflpp_driver - + @@ support

* fix for afl-showmap

* support new env var AFL_LLVM_THREADSAFE_INST to enable atomic counters.
add new test case for that.

* add documentation for AFL_LLVM_THREADSAFE_INST

* add support for AFL_LLVM_THREADSAFE_INST to other LLVM passes

* add missing include for _exit()

* threadsafe doc fixes, code format

* Wording: "never zero" -> NeverZero

* fix afl_custom_post_process with multiple custom mutators

* fix docs

* debug ck_write

* fixed potential diff by 0

* fixes

* fix classic threadsafe counters

* v3.13c release

* back push (#952)

* Dev (#949)

* use atomic read-modify-write increment for LLVM CLASSIC

* Change other LLVM modes to atomic increments

* sync (#886)

* Create FUNDING.yml

* Update FUNDING.yml

* moved custom_mutator examples

* unicorn speedtest makefile cleanup

* fixed example location

* fix qdbi

* update util readme

* work in progress: not working correctly yet

* Frida persistent (#880)

* Added x64 support for persistent mode (function call only), in-memory teest cases and complog

* Review changes, fix NeverZero and code to parse the .text section of the main executable. Excluded ranges TBC

* Various minor fixes and finished support for AFL_INST_LIBS

* Review changes

Co-authored-by: Your Name <you@example.com>

* nits

* fix frida mode

* Integer overflow/underflow fixes in libdislocator (#889)

* libdislocator: fixing integer overflow in 'max_mem' variable and setting 'max_mem' type to 'size_t'

* libdislocator: fixing potential integer underflow in 'total_mem' variable due to its different values in different threads

* Bumped warnings up to the max and fixed remaining issues (#890)

Co-authored-by: Your Name <you@example.com>

* nits

* frida mode - support non-pie

* nits

* nit

* update grammar mutator

* Fixes for aarch64, OSX and other minor issues (#891)

Co-authored-by: Your Name <you@example.com>

* nits

* nits

* fix PCGUARD, build aflpp_driver with fPIC

* Added representative fuzzbench test and test for libxml (#893)

* Added representative fuzzbench test and test for libxml

* Added support for building FRIDA from source with FRIDA_SOURCE=1

Co-authored-by: Your Name <you@example.com>

* nits

* update changelog

* typos

* still not working

* fixed potential double free in custom trim (#881)

* error handling, freeing mem

* frida: complog -> cmplog

* fix statsd writing

* let aflpp_qemu_driver_hook.so build fail gracefully

* fix stdin trimming

* Support for AFL_ENTRYPOINT (#898)

Co-authored-by: Your Name <you@example.com>

* remove the input file .cur_input at the end of the fuzzing, if AFL_TMPDIR is used

* reverse push (#901)

* Create FUNDING.yml

* Update FUNDING.yml

* disable QEMU static pie

Co-authored-by: Andrea Fioraldi <andreafioraldi@gmail.com>

* clarify that no modifications are required.

* add new test for frida_mode (please review)

* typos

* fix persistent mode (64-bit)

* set ARCH for linux intel 32-bit for frida-gum-devkit

* prepare for 32-bit support (later)

* not on qemu 3 anymore

* unicorn mips fixes

* instrumentation further move to C++11 (#900)

* unicorn fixes

* first working NeverZero implementation

* more unicorn fixes

* Fix memory errors when trim causes testcase growth (#881) (#903)

* Revert "fixed potential double free in custom trim (#881)"

This reverts commit e9d2f72382.

* Revert "fix custom trim for increasing data"

This reverts commit 86a8ef168d.

* Fix memory errors when trim causes testcase growth

Modify trim_case_custom to avoid writing into in_buf because
some custom mutators can cause the testcase to grow rather than
shrink.

Instead of modifying in_buf directly, we write the update out
to the disk when trimming is complete, and then the caller is
responsible for refreshing the in-memory buffer from the file.

This is still a bit sketchy because it does need to modify q->len in
order to notify the upper layers that something changed, and it could
end up telling upper layer code that the q->len is *bigger* than
the buffer (q->testcase_buf) that contains it, which is asking
for trouble down the line somewhere...

* Fix an unlikely situation

Put back some `unlikely()` calls that were in
the e9d2f72382 commit that was
reverted.

* add some comments

* typo

* Exit on time (#904)

* Variable AFL_EXIT_ON_TIME description has been added.
Variables AFL_EXIT_ON_TIME and afl_exit_on_time has been added.
afl->exit_on_time variable initialization has been added.
The asignment of a value to the afl->afl_env.afl_exit_on_time variable from
environment variables has been added.
Code to exit on timeout if new path not found has been added.

* Type of afl_exit_on_time variable has been changed.
Variable exit_on_time has been added to the afl_state_t structure.

* Command `export AFL_EXIT_WHEN_DONE=1` has been added.

* Millisecond to second conversion has been added.
Call get_cur_time() has been added.

* Revert to using the saved current time value.

* Useless check has been removed.

* fix new path to custom-mutators

* ensure crashes/README.txt exists

* fix

* Changes to bump FRIDA version and to clone FRIDA repo in to build directory rather than use a submodule as the FRIDA build scripts don't like it (#906)

Co-authored-by: Your Name <you@example.com>

* Fix numeric overflow in cmplog implementation (#907)

Co-authored-by: Your Name <you@example.com>

* testcase fixes for unicorn

* remove merge conflict artifacts

* fix afl-plot

* Changes to remove binaries from frida_mode (#913)

Co-authored-by: Your Name <you@example.com>

* Frida cmplog fail fast (#914)

* Changes to remove binaries from frida_mode

* Changes to make cmplog fail fast

Co-authored-by: Your Name <you@example.com>

* afl-plot: relative time

* arch linux and mac os support for afl-system-config

* typo

* code-format

* update documentation

* github workflow for qemu

* OSX-specific improvements (#912)

* Fix afl-cc to work correctly by default on OSX using xcode

- CLANG_ENV_VAR must be set for afl-as to work
- Use clang mode by default if no specific compiler selected

* Add OSX-specific documentation for configuring shared memory

* Fixes to memory operands for complog (#916)

Co-authored-by: Your Name <you@example.com>

* fix a few cur_time uses

* added bounds check to pivot_inputs (fixes #921)

* additional safety checks for restarts

* restrict afl-showmap in_file size

* fix seed crash disable

* add warning for afl-showmap partial read

* no core dumps

* AFL_PRINT_FILENAMES added

* more documentation for AFL_EXIT_ON_TIME

* Flushing for AFL_PRINT_FILENAMES

* FASAN Support (#918)

* FASAN Support

* Fix handling of Address Sanitizer DSO

* Changes to identification of Address Sanitizer DSO

Co-authored-by: Your Name <you@example.com>

* Support for x86 (#920)

Co-authored-by: Your Name <you@example.com>

* Update frida_mode readme (#925)

* libqasan: use syscalls for read and write

* update readme

* Minor integration tweaks (#926)

Co-authored-by: Your Name <you@example.com>

* merge

* fix afl-fuzz.c frida preload

* cleaned up AFL_PRINT_FILENAMES env

* Changes to have persistent mode exit at the end of the loop (#928)

Co-authored-by: Your Name <you@example.com>

* fix llvm-dict2file

* push to stable (#931) (#932)

* sync (#886)

* Create FUNDING.yml

* Update FUNDING.yml

* moved custom_mutator examples

* unicorn speedtest makefile cleanup

* fixed example location

* fix qdbi

* update util readme

* Frida persistent (#880)

* Added x64 support for persistent mode (function call only), in-memory teest cases and complog

* Review changes, fix NeverZero and code to parse the .text section of the main executable. Excluded ranges TBC

* Various minor fixes and finished support for AFL_INST_LIBS

* Review changes

Co-authored-by: Your Name <you@example.com>

* nits

* fix frida mode

* Integer overflow/underflow fixes in libdislocator (#889)

* libdislocator: fixing integer overflow in 'max_mem' variable and setting 'max_mem' type to 'size_t'

* libdislocator: fixing potential integer underflow in 'total_mem' variable due to its different values in different threads

* Bumped warnings up to the max and fixed remaining issues (#890)

Co-authored-by: Your Name <you@example.com>

* nits

* frida mode - support non-pie

* nits

* nit

* update grammar mutator

* Fixes for aarch64, OSX and other minor issues (#891)

Co-authored-by: Your Name <you@example.com>

* nits

* nits

* fix PCGUARD, build aflpp_driver with fPIC

* Added representative fuzzbench test and test for libxml (#893)

* Added representative fuzzbench test and test for libxml

* Added support for building FRIDA from source with FRIDA_SOURCE=1

Co-authored-by: Your Name <you@example.com>

* nits

* update changelog

* typos

* fixed potential double free in custom trim (#881)

* error handling, freeing mem

* frida: complog -> cmplog

* fix statsd writing

* let aflpp_qemu_driver_hook.so build fail gracefully

* fix stdin trimming

* Support for AFL_ENTRYPOINT (#898)

Co-authored-by: Your Name <you@example.com>

* remove the input file .cur_input at the end of the fuzzing, if AFL_TMPDIR is used

* reverse push (#901)

* Create FUNDING.yml

* Update FUNDING.yml

* disable QEMU static pie

Co-authored-by: Andrea Fioraldi <andreafioraldi@gmail.com>

* clarify that no modifications are required.

* add new test for frida_mode (please review)

* typos

* fix persistent mode (64-bit)

* set ARCH for linux intel 32-bit for frida-gum-devkit

* prepare for 32-bit support (later)

* not on qemu 3 anymore

* unicorn mips fixes

* instrumentation further move to C++11 (#900)

* unicorn fixes

* more unicorn fixes

* Fix memory errors when trim causes testcase growth (#881) (#903)

* Revert "fixed potential double free in custom trim (#881)"

This reverts commit e9d2f72382.

* Revert "fix custom trim for increasing data"

This reverts commit 86a8ef168d.

* Fix memory errors when trim causes testcase growth

Modify trim_case_custom to avoid writing into in_buf because
some custom mutators can cause the testcase to grow rather than
shrink.

Instead of modifying in_buf directly, we write the update out
to the disk when trimming is complete, and then the caller is
responsible for refreshing the in-memory buffer from the file.

This is still a bit sketchy because it does need to modify q->len in
order to notify the upper layers that something changed, and it could
end up telling upper layer code that the q->len is *bigger* than
the buffer (q->testcase_buf) that contains it, which is asking
for trouble down the line somewhere...

* Fix an unlikely situation

Put back some `unlikely()` calls that were in
the e9d2f72382 commit that was
reverted.

* typo

* Exit on time (#904)

* Variable AFL_EXIT_ON_TIME description has been added.
Variables AFL_EXIT_ON_TIME and afl_exit_on_time has been added.
afl->exit_on_time variable initialization has been added.
The asignment of a value to the afl->afl_env.afl_exit_on_time variable from
environment variables has been added.
Code to exit on timeout if new path not found has been added.

* Type of afl_exit_on_time variable has been changed.
Variable exit_on_time has been added to the afl_state_t structure.

* Command `export AFL_EXIT_WHEN_DONE=1` has been added.

* Millisecond to second conversion has been added.
Call get_cur_time() has been added.

* Revert to using the saved current time value.

* Useless check has been removed.

* fix new path to custom-mutators

* ensure crashes/README.txt exists

* fix

* Changes to bump FRIDA version and to clone FRIDA repo in to build directory rather than use a submodule as the FRIDA build scripts don't like it (#906)

Co-authored-by: Your Name <you@example.com>

* Fix numeric overflow in cmplog implementation (#907)

Co-authored-by: Your Name <you@example.com>

* testcase fixes for unicorn

* remove merge conflict artifacts

* fix afl-plot

* Changes to remove binaries from frida_mode (#913)

Co-authored-by: Your Name <you@example.com>

* Frida cmplog fail fast (#914)

* Changes to remove binaries from frida_mode

* Changes to make cmplog fail fast

Co-authored-by: Your Name <you@example.com>

* afl-plot: relative time

* arch linux and mac os support for afl-system-config

* typo

* code-format

* update documentation

* github workflow for qemu

* OSX-specific improvements (#912)

* Fix afl-cc to work correctly by default on OSX using xcode

- CLANG_ENV_VAR must be set for afl-as to work
- Use clang mode by default if no specific compiler selected

* Add OSX-specific documentation for configuring shared memory

* Fixes to memory operands for complog (#916)

Co-authored-by: Your Name <you@example.com>

* fix a few cur_time uses

* added bounds check to pivot_inputs (fixes #921)

* additional safety checks for restarts

* restrict afl-showmap in_file size

* fix seed crash disable

* add warning for afl-showmap partial read

* no core dumps

* AFL_PRINT_FILENAMES added

* more documentation for AFL_EXIT_ON_TIME

* Flushing for AFL_PRINT_FILENAMES

* FASAN Support (#918)

* FASAN Support

* Fix handling of Address Sanitizer DSO

* Changes to identification of Address Sanitizer DSO

Co-authored-by: Your Name <you@example.com>

* Support for x86 (#920)

Co-authored-by: Your Name <you@example.com>

* Update frida_mode readme (#925)

* libqasan: use syscalls for read and write

* update readme

* Minor integration tweaks (#926)

Co-authored-by: Your Name <you@example.com>

* merge

* fix afl-fuzz.c frida preload

* cleaned up AFL_PRINT_FILENAMES env

* Changes to have persistent mode exit at the end of the loop (#928)

Co-authored-by: Your Name <you@example.com>

* fix llvm-dict2file

Co-authored-by: Dominik Maier <domenukk@gmail.com>
Co-authored-by: WorksButNotTested <62701594+WorksButNotTested@users.noreply.github.com>
Co-authored-by: Your Name <you@example.com>
Co-authored-by: Dmitry Zheregelya <zheregelya.d@gmail.com>
Co-authored-by: hexcoder <hexcoder-@users.noreply.github.com>
Co-authored-by: hexcoder- <heiko@hexco.de>
Co-authored-by: Andrea Fioraldi <andreafioraldi@gmail.com>
Co-authored-by: David CARLIER <devnexen@gmail.com>
Co-authored-by: realmadsci <71108352+realmadsci@users.noreply.github.com>
Co-authored-by: Roman M. Iudichev <SecNotice@ya.ru>
Co-authored-by: Dustin Spicuzza <dustin@virtualroadside.com>

Co-authored-by: Dominik Maier <domenukk@gmail.com>
Co-authored-by: WorksButNotTested <62701594+WorksButNotTested@users.noreply.github.com>
Co-authored-by: Your Name <you@example.com>
Co-authored-by: Dmitry Zheregelya <zheregelya.d@gmail.com>
Co-authored-by: hexcoder <hexcoder-@users.noreply.github.com>
Co-authored-by: hexcoder- <heiko@hexco.de>
Co-authored-by: Andrea Fioraldi <andreafioraldi@gmail.com>
Co-authored-by: David CARLIER <devnexen@gmail.com>
Co-authored-by: realmadsci <71108352+realmadsci@users.noreply.github.com>
Co-authored-by: Roman M. Iudichev <SecNotice@ya.ru>
Co-authored-by: Dustin Spicuzza <dustin@virtualroadside.com>

* improve error msg

* Added documentation for wine LoadLibrary workaround (#933)

* Fix cmake target compilation command example (#934)

- Fix typo DCMAKE_C_COMPILERC -> DCMAKE_C_COMPILER.
- Add `cd build` after `mkdir build`.

* showmap passes queue items in alphabetical order

* added tmp files to gitignore

* lenient dict parsing, no map size enum for binary fuzzing

* added info about showmap queue directions

* update binary-only doc

* turn off map size detection if skip_bin_check is set

* Typo

* update docs

* update afl-system-config

* Set kill signal before using it in afl-showmap (#935)

* fix afl-cc help output

* add libafl to binary-only doc

* update docs

* less executions on variable paths

* AFL_SKIP_CRASHES is obsolete since 3.0

* add AFL_TRY_AFFINITY

* Typo

* Typo

* Typo/wording

* tweaks

* typos

* fix afl-whatsup help output

* fix afl-plot output

* fix for MacOS

* fix cmpcov doc for qemu

* fix tmpfile removal

* update dockerfile

* Frida (#940)

* Added re2 test

* Added libpcap test

* Fix validation of setting of ADDR_NO_RANDOMIZE

* Added support for printing original and instrumented code

Co-authored-by: Your Name <you@example.com>

* Support for AFL_FRIDA_PERSISTENT_RET (#941)

Co-authored-by: Your Name <you@example.com>

* Changes to add missing exclusion of ranges (#943)

Co-authored-by: Your Name <you@example.com>

* add --afl-noopt to afl-cc

* docs: fix link to README in QuickStartGuide (#946)

* Support writing Stalker stats (#945)

* Support writing Stalker stats

* Fixed string handling in print functions

Co-authored-by: Your Name <you@example.com>

* afl-cmin help fix, aflpp_driver - + @@ support

* fix for afl-showmap

* support new env var AFL_LLVM_THREADSAFE_INST to enable atomic counters.
add new test case for that.

* add documentation for AFL_LLVM_THREADSAFE_INST

* add support for AFL_LLVM_THREADSAFE_INST to other LLVM passes

* add missing include for _exit()

* threadsafe doc fixes, code format

* Wording: "never zero" -> NeverZero

* fix afl_custom_post_process with multiple custom mutators

* fix docs

* debug ck_write

* fixed potential diff by 0

* fixes

* fix classic threadsafe counters

Co-authored-by: van Hauser <vh@thc.org>
Co-authored-by: Dominik Maier <domenukk@gmail.com>
Co-authored-by: WorksButNotTested <62701594+WorksButNotTested@users.noreply.github.com>
Co-authored-by: Your Name <you@example.com>
Co-authored-by: Dmitry Zheregelya <zheregelya.d@gmail.com>
Co-authored-by: Andrea Fioraldi <andreafioraldi@gmail.com>
Co-authored-by: David CARLIER <devnexen@gmail.com>
Co-authored-by: realmadsci <71108352+realmadsci@users.noreply.github.com>
Co-authored-by: Roman M. Iudichev <SecNotice@ya.ru>
Co-authored-by: Dustin Spicuzza <dustin@virtualroadside.com>
Co-authored-by: 0x4d5a-ctf <51098072+0x4d5a-ctf@users.noreply.github.com>
Co-authored-by: Tommy Chiang <oToToT@users.noreply.github.com>
Co-authored-by: buherator <buherator@silentsignal.hu>
Co-authored-by: Dag Heyman Kajevic <dag.heyman@gmail.com>

* v3.13c release (#950)

* use atomic read-modify-write increment for LLVM CLASSIC

* Change other LLVM modes to atomic increments

* sync (#886)

* Create FUNDING.yml

* Update FUNDING.yml

* moved custom_mutator examples

* unicorn speedtest makefile cleanup

* fixed example location

* fix qdbi

* update util readme

* work in progress: not working correctly yet

* Frida persistent (#880)

* Added x64 support for persistent mode (function call only), in-memory teest cases and complog

* Review changes, fix NeverZero and code to parse the .text section of the main executable. Excluded ranges TBC

* Various minor fixes and finished support for AFL_INST_LIBS

* Review changes

Co-authored-by: Your Name <you@example.com>

* nits

* fix frida mode

* Integer overflow/underflow fixes in libdislocator (#889)

* libdislocator: fixing integer overflow in 'max_mem' variable and setting 'max_mem' type to 'size_t'

* libdislocator: fixing potential integer underflow in 'total_mem' variable due to its different values in different threads

* Bumped warnings up to the max and fixed remaining issues (#890)

Co-authored-by: Your Name <you@example.com>

* nits

* frida mode - support non-pie

* nits

* nit

* update grammar mutator

* Fixes for aarch64, OSX and other minor issues (#891)

Co-authored-by: Your Name <you@example.com>

* nits

* nits

* fix PCGUARD, build aflpp_driver with fPIC

* Added representative fuzzbench test and test for libxml (#893)

* Added representative fuzzbench test and test for libxml

* Added support for building FRIDA from source with FRIDA_SOURCE=1

Co-authored-by: Your Name <you@example.com>

* nits

* update changelog

* typos

* still not working

* fixed potential double free in custom trim (#881)

* error handling, freeing mem

* frida: complog -> cmplog

* fix statsd writing

* let aflpp_qemu_driver_hook.so build fail gracefully

* fix stdin trimming

* Support for AFL_ENTRYPOINT (#898)

Co-authored-by: Your Name <you@example.com>

* remove the input file .cur_input at the end of the fuzzing, if AFL_TMPDIR is used

* reverse push (#901)

* Create FUNDING.yml

* Update FUNDING.yml

* disable QEMU static pie

Co-authored-by: Andrea Fioraldi <andreafioraldi@gmail.com>

* clarify that no modifications are required.

* add new test for frida_mode (please review)

* typos

* fix persistent mode (64-bit)

* set ARCH for linux intel 32-bit for frida-gum-devkit

* prepare for 32-bit support (later)

* not on qemu 3 anymore

* unicorn mips fixes

* instrumentation further move to C++11 (#900)

* unicorn fixes

* first working NeverZero implementation

* more unicorn fixes

* Fix memory errors when trim causes testcase growth (#881) (#903)

* Revert "fixed potential double free in custom trim (#881)"

This reverts commit e9d2f72382.

* Revert "fix custom trim for increasing data"

This reverts commit 86a8ef168d.

* Fix memory errors when trim causes testcase growth

Modify trim_case_custom to avoid writing into in_buf because
some custom mutators can cause the testcase to grow rather than
shrink.

Instead of modifying in_buf directly, we write the update out
to the disk when trimming is complete, and then the caller is
responsible for refreshing the in-memory buffer from the file.

This is still a bit sketchy because it does need to modify q->len in
order to notify the upper layers that something changed, and it could
end up telling upper layer code that the q->len is *bigger* than
the buffer (q->testcase_buf) that contains it, which is asking
for trouble down the line somewhere...

* Fix an unlikely situation

Put back some `unlikely()` calls that were in
the e9d2f72382 commit that was
reverted.

* add some comments

* typo

* Exit on time (#904)

* Variable AFL_EXIT_ON_TIME description has been added.
Variables AFL_EXIT_ON_TIME and afl_exit_on_time has been added.
afl->exit_on_time variable initialization has been added.
The asignment of a value to the afl->afl_env.afl_exit_on_time variable from
environment variables has been added.
Code to exit on timeout if new path not found has been added.

* Type of afl_exit_on_time variable has been changed.
Variable exit_on_time has been added to the afl_state_t structure.

* Command `export AFL_EXIT_WHEN_DONE=1` has been added.

* Millisecond to second conversion has been added.
Call get_cur_time() has been added.

* Revert to using the saved current time value.

* Useless check has been removed.

* fix new path to custom-mutators

* ensure crashes/README.txt exists

* fix

* Changes to bump FRIDA version and to clone FRIDA repo in to build directory rather than use a submodule as the FRIDA build scripts don't like it (#906)

Co-authored-by: Your Name <you@example.com>

* Fix numeric overflow in cmplog implementation (#907)

Co-authored-by: Your Name <you@example.com>

* testcase fixes for unicorn

* remove merge conflict artifacts

* fix afl-plot

* Changes to remove binaries from frida_mode (#913)

Co-authored-by: Your Name <you@example.com>

* Frida cmplog fail fast (#914)

* Changes to remove binaries from frida_mode

* Changes to make cmplog fail fast

Co-authored-by: Your Name <you@example.com>

* afl-plot: relative time

* arch linux and mac os support for afl-system-config

* typo

* code-format

* update documentation

* github workflow for qemu

* OSX-specific improvements (#912)

* Fix afl-cc to work correctly by default on OSX using xcode

- CLANG_ENV_VAR must be set for afl-as to work
- Use clang mode by default if no specific compiler selected

* Add OSX-specific documentation for configuring shared memory

* Fixes to memory operands for complog (#916)

Co-authored-by: Your Name <you@example.com>

* fix a few cur_time uses

* added bounds check to pivot_inputs (fixes #921)

* additional safety checks for restarts

* restrict afl-showmap in_file size

* fix seed crash disable

* add warning for afl-showmap partial read

* no core dumps

* AFL_PRINT_FILENAMES added

* more documentation for AFL_EXIT_ON_TIME

* Flushing for AFL_PRINT_FILENAMES

* FASAN Support (#918)

* FASAN Support

* Fix handling of Address Sanitizer DSO

* Changes to identification of Address Sanitizer DSO

Co-authored-by: Your Name <you@example.com>

* Support for x86 (#920)

Co-authored-by: Your Name <you@example.com>

* Update frida_mode readme (#925)

* libqasan: use syscalls for read and write

* update readme

* Minor integration tweaks (#926)

Co-authored-by: Your Name <you@example.com>

* merge

* fix afl-fuzz.c frida preload

* cleaned up AFL_PRINT_FILENAMES env

* Changes to have persistent mode exit at the end of the loop (#928)

Co-authored-by: Your Name <you@example.com>

* fix llvm-dict2file

* push to stable (#931) (#932)

* sync (#886)

* Create FUNDING.yml

* Update FUNDING.yml

* moved custom_mutator examples

* unicorn speedtest makefile cleanup

* fixed example location

* fix qdbi

* update util readme

* Frida persistent (#880)

* Added x64 support for persistent mode (function call only), in-memory teest cases and complog

* Review changes, fix NeverZero and code to parse the .text section of the main executable. Excluded ranges TBC

* Various minor fixes and finished support for AFL_INST_LIBS

* Review changes

Co-authored-by: Your Name <you@example.com>

* nits

* fix frida mode

* Integer overflow/underflow fixes in libdislocator (#889)

* libdislocator: fixing integer overflow in 'max_mem' variable and setting 'max_mem' type to 'size_t'

* libdislocator: fixing potential integer underflow in 'total_mem' variable due to its different values in different threads

* Bumped warnings up to the max and fixed remaining issues (#890)

Co-authored-by: Your Name <you@example.com>

* nits

* frida mode - support non-pie

* nits

* nit

* update grammar mutator

* Fixes for aarch64, OSX and other minor issues (#891)

Co-authored-by: Your Name <you@example.com>

* nits

* nits

* fix PCGUARD, build aflpp_driver with fPIC

* Added representative fuzzbench test and test for libxml (#893)

* Added representative fuzzbench test and test for libxml

* Added support for building FRIDA from source with FRIDA_SOURCE=1

Co-authored-by: Your Name <you@example.com>

* nits

* update changelog

* typos

* fixed potential double free in custom trim (#881)

* error handling, freeing mem

* frida: complog -> cmplog

* fix statsd writing

* let aflpp_qemu_driver_hook.so build fail gracefully

* fix stdin trimming

* Support for AFL_ENTRYPOINT (#898)

Co-authored-by: Your Name <you@example.com>

* remove the input file .cur_input at the end of the fuzzing, if AFL_TMPDIR is used

* reverse push (#901)

* Create FUNDING.yml

* Update FUNDING.yml

* disable QEMU static pie

Co-authored-by: Andrea Fioraldi <andreafioraldi@gmail.com>

* clarify that no modifications are required.

* add new test for frida_mode (please review)

* typos

* fix persistent mode (64-bit)

* set ARCH for linux intel 32-bit for frida-gum-devkit

* prepare for 32-bit support (later)

* not on qemu 3 anymore

* unicorn mips fixes

* instrumentation further move to C++11 (#900)

* unicorn fixes

* more unicorn fixes

* Fix memory errors when trim causes testcase growth (#881) (#903)

* Revert "fixed potential double free in custom trim (#881)"

This reverts commit e9d2f72382.

* Revert "fix custom trim for increasing data"

This reverts commit 86a8ef168d.

* Fix memory errors when trim causes testcase growth

Modify trim_case_custom to avoid writing into in_buf because
some custom mutators can cause the testcase to grow rather than
shrink.

Instead of modifying in_buf directly, we write the update out
to the disk when trimming is complete, and then the caller is
responsible for refreshing the in-memory buffer from the file.

This is still a bit sketchy because it does need to modify q->len in
order to notify the upper layers that something changed, and it could
end up telling upper layer code that the q->len is *bigger* than
the buffer (q->testcase_buf) that contains it, which is asking
for trouble down the line somewhere...

* Fix an unlikely situation

Put back some `unlikely()` calls that were in
the e9d2f72382 commit that was
reverted.

* typo

* Exit on time (#904)

* Variable AFL_EXIT_ON_TIME description has been added.
Variables AFL_EXIT_ON_TIME and afl_exit_on_time has been added.
afl->exit_on_time variable initialization has been added.
The asignment of a value to the afl->afl_env.afl_exit_on_time variable from
environment variables has been added.
Code to exit on timeout if new path not found has been added.

* Type of afl_exit_on_time variable has been changed.
Variable exit_on_time has been added to the afl_state_t structure.

* Command `export AFL_EXIT_WHEN_DONE=1` has been added.

* Millisecond to second conversion has been added.
Call get_cur_time() has been added.

* Revert to using the saved current time value.

* Useless check has been removed.

* fix new path to custom-mutators

* ensure crashes/README.txt exists

* fix

* Changes to bump FRIDA version and to clone FRIDA repo in to build directory rather than use a submodule as the FRIDA build scripts don't like it (#906)

Co-authored-by: Your Name <you@example.com>

* Fix numeric overflow in cmplog implementation (#907)

Co-authored-by: Your Name <you@example.com>

* testcase fixes for unicorn

* remove merge conflict artifacts

* fix afl-plot

* Changes to remove binaries from frida_mode (#913)

Co-authored-by: Your Name <you@example.com>

* Frida cmplog fail fast (#914)

* Changes to remove binaries from frida_mode

* Changes to make cmplog fail fast

Co-authored-by: Your Name <you@example.com>

* afl-plot: relative time

* arch linux and mac os support for afl-system-config

* typo

* code-format

* update documentation

* github workflow for qemu

* OSX-specific improvements (#912)

* Fix afl-cc to work correctly by default on OSX using xcode

- CLANG_ENV_VAR must be set for afl-as to work
- Use clang mode by default if no specific compiler selected

* Add OSX-specific documentation for configuring shared memory

* Fixes to memory operands for complog (#916)

Co-authored-by: Your Name <you@example.com>

* fix a few cur_time uses

* added bounds check to pivot_inputs (fixes #921)

* additional safety checks for restarts

* restrict afl-showmap in_file size

* fix seed crash disable

* add warning for afl-showmap partial read

* no core dumps

* AFL_PRINT_FILENAMES added

* more documentation for AFL_EXIT_ON_TIME

* Flushing for AFL_PRINT_FILENAMES

* FASAN Support (#918)

* FASAN Support

* Fix handling of Address Sanitizer DSO

* Changes to identification of Address Sanitizer DSO

Co-authored-by: Your Name <you@example.com>

* Support for x86 (#920)

Co-authored-by: Your Name <you@example.com>

* Update frida_mode readme (#925)

* libqasan: use syscalls for read and write

* update readme

* Minor integration tweaks (#926)

Co-authored-by: Your Name <you@example.com>

* merge

* fix afl-fuzz.c frida preload

* cleaned up AFL_PRINT_FILENAMES env

* Changes to have persistent mode exit at the end of the loop (#928)

Co-authored-by: Your Name <you@example.com>

* fix llvm-dict2file

Co-authored-by: Dominik Maier <domenukk@gmail.com>
Co-authored-by: WorksButNotTested <62701594+WorksButNotTested@users.noreply.github.com>
Co-authored-by: Your Name <you@example.com>
Co-authored-by: Dmitry Zheregelya <zheregelya.d@gmail.com>
Co-authored-by: hexcoder <hexcoder-@users.noreply.github.com>
Co-authored-by: hexcoder- <heiko@hexco.de>
Co-authored-by: Andrea Fioraldi <andreafioraldi@gmail.com>
Co-authored-by: David CARLIER <devnexen@gmail.com>
Co-authored-by: realmadsci <71108352+realmadsci@users.noreply.github.com>
Co-authored-by: Roman M. Iudichev <SecNotice@ya.ru>
Co-authored-by: Dustin Spicuzza <dustin@virtualroadside.com>

Co-authored-by: Dominik Maier <domenukk@gmail.com>
Co-authored-by: WorksButNotTested <62701594+WorksButNotTested@users.noreply.github.com>
Co-authored-by: Your Name <you@example.com>
Co-authored-by: Dmitry Zheregelya <zheregelya.d@gmail.com>
Co-authored-by: hexcoder <hexcoder-@users.noreply.github.com>
Co-authored-by: hexcoder- <heiko@hexco.de>
Co-authored-by: Andrea Fioraldi <andreafioraldi@gmail.com>
Co-authored-by: David CARLIER <devnexen@gmail.com>
Co-authored-by: realmadsci <71108352+realmadsci@users.noreply.github.com>
Co-authored-by: Roman M. Iudichev <SecNotice@ya.ru>
Co-authored-by: Dustin Spicuzza <dustin@virtualroadside.com>

* improve error msg

* Added documentation for wine LoadLibrary workaround (#933)

* Fix cmake target compilation command example (#934)

- Fix typo DCMAKE_C_COMPILERC -> DCMAKE_C_COMPILER.
- Add `cd build` after `mkdir build`.

* showmap passes queue items in alphabetical order

* added tmp files to gitignore

* lenient dict parsing, no map size enum for binary fuzzing

* added info about showmap queue directions

* update binary-only doc

* turn off map size detection if skip_bin_check is set

* Typo

* update docs

* update afl-system-config

* Set kill signal before using it in afl-showmap (#935)

* fix afl-cc help output

* add libafl to binary-only doc

* update docs

* less executions on variable paths

* AFL_SKIP_CRASHES is obsolete since 3.0

* add AFL_TRY_AFFINITY

* Typo

* Typo

* Typo/wording

* tweaks

* typos

* fix afl-whatsup help output

* fix afl-plot output

* fix for MacOS

* fix cmpcov doc for qemu

* fix tmpfile removal

* update dockerfile

* Frida (#940)

* Added re2 test

* Added libpcap test

* Fix validation of setting of ADDR_NO_RANDOMIZE

* Added support for printing original and instrumented code

Co-authored-by: Your Name <you@example.com>

* Support for AFL_FRIDA_PERSISTENT_RET (#941)

Co-authored-by: Your Name <you@example.com>

* Changes to add missing exclusion of ranges (#943)

Co-authored-by: Your Name <you@example.com>

* add --afl-noopt to afl-cc

* docs: fix link to README in QuickStartGuide (#946)

* Support writing Stalker stats (#945)

* Support writing Stalker stats

* Fixed string handling in print functions

Co-authored-by: Your Name <you@example.com>

* afl-cmin help fix, aflpp_driver - + @@ support

* fix for afl-showmap

* support new env var AFL_LLVM_THREADSAFE_INST to enable atomic counters.
add new test case for that.

* add documentation for AFL_LLVM_THREADSAFE_INST

* add support for AFL_LLVM_THREADSAFE_INST to other LLVM passes

* add missing include for _exit()

* threadsafe doc fixes, code format

* Wording: "never zero" -> NeverZero

* fix afl_custom_post_process with multiple custom mutators

* fix docs

* debug ck_write

* fixed potential diff by 0

* fixes

* fix classic threadsafe counters

* v3.13c release

Co-authored-by: hexcoder- <heiko@hexco.de>
Co-authored-by: Dominik Maier <domenukk@gmail.com>
Co-authored-by: WorksButNotTested <62701594+WorksButNotTested@users.noreply.github.com>
Co-authored-by: Your Name <you@example.com>
Co-authored-by: Dmitry Zheregelya <zheregelya.d@gmail.com>
Co-authored-by: hexcoder <hexcoder-@users.noreply.github.com>
Co-authored-by: Andrea Fioraldi <andreafioraldi@gmail.com>
Co-authored-by: David CARLIER <devnexen@gmail.com>
Co-authored-by: realmadsci <71108352+realmadsci@users.noreply.github.com>
Co-authored-by: Roman M. Iudichev <SecNotice@ya.ru>
Co-authored-by: Dustin Spicuzza <dustin@virtualroadside.com>
Co-authored-by: 0x4d5a-ctf <51098072+0x4d5a-ctf@users.noreply.github.com>
Co-authored-by: Tommy Chiang <oToToT@users.noreply.github.com>
Co-authored-by: buherator <buherator@silentsignal.hu>
Co-authored-by: Dag Heyman Kajevic <dag.heyman@gmail.com>

Co-authored-by: hexcoder <hexcoder-@users.noreply.github.com>
Co-authored-by: Dominik Maier <domenukk@gmail.com>
Co-authored-by: WorksButNotTested <62701594+WorksButNotTested@users.noreply.github.com>
Co-authored-by: Your Name <you@example.com>
Co-authored-by: Dmitry Zheregelya <zheregelya.d@gmail.com>
Co-authored-by: Andrea Fioraldi <andreafioraldi@gmail.com>
Co-authored-by: David CARLIER <devnexen@gmail.com>
Co-authored-by: realmadsci <71108352+realmadsci@users.noreply.github.com>
Co-authored-by: Roman M. Iudichev <SecNotice@ya.ru>
Co-authored-by: Dustin Spicuzza <dustin@virtualroadside.com>
Co-authored-by: 0x4d5a-ctf <51098072+0x4d5a-ctf@users.noreply.github.com>
Co-authored-by: Tommy Chiang <oToToT@users.noreply.github.com>
Co-authored-by: buherator <buherator@silentsignal.hu>
Co-authored-by: Dag Heyman Kajevic <dag.heyman@gmail.com>
Co-authored-by: hexcoder- <heiko@hexco.de>

* v3.14a init

* remove redundant unsetenv (#947)

* update MacOS Install information

* add missing clean action for frida_mode

* ensure memory is there before free

* adapt to incompatible LLVM 13 API

* fix stupid typos

* add fix info

Co-authored-by: hexcoder- <heiko@hexco.de>
Co-authored-by: Dominik Maier <domenukk@gmail.com>
Co-authored-by: WorksButNotTested <62701594+WorksButNotTested@users.noreply.github.com>
Co-authored-by: Your Name <you@example.com>
Co-authored-by: Dmitry Zheregelya <zheregelya.d@gmail.com>
Co-authored-by: hexcoder <hexcoder-@users.noreply.github.com>
Co-authored-by: Andrea Fioraldi <andreafioraldi@gmail.com>
Co-authored-by: David CARLIER <devnexen@gmail.com>
Co-authored-by: realmadsci <71108352+realmadsci@users.noreply.github.com>
Co-authored-by: Roman M. Iudichev <SecNotice@ya.ru>
Co-authored-by: Dustin Spicuzza <dustin@virtualroadside.com>
Co-authored-by: 0x4d5a-ctf <51098072+0x4d5a-ctf@users.noreply.github.com>
Co-authored-by: Tommy Chiang <oToToT@users.noreply.github.com>
Co-authored-by: buherator <buherator@silentsignal.hu>
Co-authored-by: Dag Heyman Kajevic <dag.heyman@gmail.com>
Co-authored-by: terrynini <terrynini38514@gmail.com>
2021-06-01 18:55:25 +02:00
db43ec9000 welford one var compiles 2021-06-01 18:29:41 +02:00
29 changed files with 7648 additions and 68 deletions

View File

@ -305,8 +305,8 @@ ifeq "$(TEST_MMAP)" "1"
LDFLAGS += -Wno-deprecated-declarations
endif
PROGS_ALWAYS = ./afl-cc ./afl-compiler-rt.o ./afl-compiler-rt-32.o ./afl-compiler-rt-64.o
PROGS = $(PROGS_ALWAYS) ./afl-llvm-pass.so ./SanitizerCoveragePCGUARD.so ./split-compares-pass.so ./split-switches-pass.so ./cmplog-routines-pass.so ./cmplog-instructions-pass.so ./afl-llvm-dict2file.so ./compare-transform-pass.so ./afl-ld-lto ./afl-llvm-lto-instrumentlist.so ./afl-llvm-lto-instrumentation.so ./SanitizerCoverageLTO.so
PROGS_ALWAYS = ./afl-cc ./afl-compiler-rt.o ./afl-compiler-rt-32.o ./afl-compiler-rt-64.o
PROGS = $(PROGS_ALWAYS) ./afl-llvm-pass.so ./SanitizerCoveragePCGUARD.so ./split-compares-pass.so ./split-switches-pass.so ./cmplog-routines-pass.so ./cmplog-instructions-pass.so ./afl-unusual-pass.so ./afl-llvm-dict2file.so ./compare-transform-pass.so ./afl-ld-lto ./afl-llvm-lto-instrumentlist.so ./afl-llvm-lto-instrumentation.so ./SanitizerCoverageLTO.so ./afl-unusual-pass.so ./afl-unusual-rt.o ./afl-unusual-rt-32.o ./afl-unusual-rt-64.o
# If prerequisites are not given, warn, do not build anything, and exit with code 0
ifeq "$(LLVMVER)" ""
@ -433,6 +433,9 @@ endif
./cmplog-instructions-pass.so: instrumentation/cmplog-instructions-pass.cc instrumentation/afl-llvm-common.o | test_deps
$(CXX) $(CLANG_CPPFL) -shared $< -o $@ $(CLANG_LFL) instrumentation/afl-llvm-common.o
afl-unusual-pass.so: instrumentation/afl-unusual-pass.so.cc instrumentation/afl-llvm-common.o | test_deps
$(CXX) $(CLANG_CPPFL) -shared $^ -o $@ $(CLANG_LFL)
afl-llvm-dict2file.so: instrumentation/afl-llvm-dict2file.so.cc instrumentation/afl-llvm-common.o | test_deps
$(CXX) $(CLANG_CPPFL) -shared $< -o $@ $(CLANG_LFL) instrumentation/afl-llvm-common.o
@ -453,6 +456,18 @@ document:
@printf "[*] Building 64-bit variant of the runtime (-m64)... "
@$(CC) $(CLANG_CFL) $(CFLAGS_SAFE) $(CPPFLAGS) -O3 -Wno-unused-result -m64 -fPIC -c $< -o $@ 2>/dev/null; if [ "$$?" = "0" ]; then echo "success!"; ln -sf afl-compiler-rt-64.o afl-llvm-rt-64.o; else echo "failed (that's fine)"; fi
./afl-unusual-rt.o: instrumentation/afl-unusual-rt.o.c
$(CC) $(CLANG_CFL) $(CFLAGS_SAFE) $(CPPFLAGS) -fno-math-errno -ffast-math -O3 -Wno-unused-result -fPIC -c $< -o $@
./afl-unusual-rt-32.o: instrumentation/afl-unusual-rt.o.c
@printf "[*] Building 32-bit variant of the runtime (-m32)... "
@$(CC) $(CLANG_CFL) $(CFLAGS_SAFE) $(CPPFLAGS) -fno-math-errno -ffast-math -O3 -Wno-unused-result -m32 -fPIC -c $< -o $@ 2>/dev/null; if [ "$$?" = "0" ]; then echo "success!"; ln -sf afl-unusual-rt-32.o afl-llvm-rt-32.o; else echo "failed (that's fine)"; fi
./afl-unusual-rt-64.o: instrumentation/afl-unusual-rt.o.c
@printf "[*] Building 64-bit variant of the runtime (-m64)... "
@$(CC) $(CLANG_CFL) $(CFLAGS_SAFE) $(CPPFLAGS) -fno-math-errno -ffast-math -O3 -Wno-unused-result -m64 -fPIC -c $< -o $@ 2>/dev/null; if [ "$$?" = "0" ]; then echo "success!"; ln -sf afl-unusual-rt-64.o afl-llvm-rt-64.o; else echo "failed (that's fine)"; fi
.PHONY: test_build
test_build: $(PROGS)
@echo "[*] Testing the CC wrapper and instrumentation output..."
@ -475,10 +490,13 @@ install: all
@if [ -f ./afl-cc ]; then set -e; install -m 755 ./afl-cc $${DESTDIR}$(BIN_PATH); ln -sf afl-cc $${DESTDIR}$(BIN_PATH)/afl-c++; fi
@rm -f $${DESTDIR}$(HELPER_PATH)/afl-llvm-rt*.o $${DESTDIR}$(HELPER_PATH)/afl-gcc-rt*.o
@if [ -f ./afl-compiler-rt.o ]; then set -e; install -m 755 ./afl-compiler-rt.o $${DESTDIR}$(HELPER_PATH); ln -sf afl-compiler-rt.o $${DESTDIR}$(HELPER_PATH)/afl-llvm-rt.o ;fi
@if [ -f ./afl-unusual-rt.o ]; then set -e; install -m 755 ./afl-unusual-rt.o $${DESTDIR}$(HELPER_PATH); ln -sf afl-unusual-rt.o $${DESTDIR}$(HELPER_PATH)/afl-llvm-rt.o ;fi
@if [ -f ./afl-lto ]; then set -e; ln -sf afl-cc $${DESTDIR}$(BIN_PATH)/afl-lto; ln -sf afl-cc $${DESTDIR}$(BIN_PATH)/afl-lto++; ln -sf afl-cc $${DESTDIR}$(BIN_PATH)/afl-clang-lto; ln -sf afl-cc $${DESTDIR}$(BIN_PATH)/afl-clang-lto++; install -m 755 ./afl-llvm-lto-instrumentation.so ./afl-llvm-rt-lto*.o ./afl-llvm-lto-instrumentlist.so $${DESTDIR}$(HELPER_PATH); fi
@if [ -f ./afl-ld-lto ]; then set -e; install -m 755 ./afl-ld-lto $${DESTDIR}$(BIN_PATH); fi
@if [ -f ./afl-compiler-rt-32.o ]; then set -e; install -m 755 ./afl-compiler-rt-32.o $${DESTDIR}$(HELPER_PATH); ln -sf afl-compiler-rt-32.o $${DESTDIR}$(HELPER_PATH)/afl-llvm-rt-32.o ;fi
@if [ -f ./afl-compiler-rt-64.o ]; then set -e; install -m 755 ./afl-compiler-rt-64.o $${DESTDIR}$(HELPER_PATH); ln -sf afl-compiler-rt-64.o $${DESTDIR}$(HELPER_PATH)/afl-llvm-rt-64.o ; fi
@if [ -f ./afl-unusual-rt-32.o ]; then set -e; install -m 755 ./afl-unusual-rt-32.o $${DESTDIR}$(HELPER_PATH); ln -sf afl-unusual-rt-32.o $${DESTDIR}$(HELPER_PATH)/afl-llvm-rt-32.o ;fi
@if [ -f ./afl-unusual-rt-64.o ]; then set -e; install -m 755 ./afl-unusual-rt-64.o $${DESTDIR}$(HELPER_PATH); ln -sf afl-unusual-rt-64.o $${DESTDIR}$(HELPER_PATH)/afl-llvm-rt-64.o ; fi
@if [ -f ./compare-transform-pass.so ]; then set -e; install -m 755 ./*.so $${DESTDIR}$(HELPER_PATH); fi
@if [ -f ./compare-transform-pass.so ]; then set -e; ln -sf afl-cc $${DESTDIR}$(BIN_PATH)/afl-clang-fast ; ln -sf ./afl-c++ $${DESTDIR}$(BIN_PATH)/afl-clang-fast++ ; ln -sf afl-cc $${DESTDIR}$(BIN_PATH)/afl-clang ; ln -sf ./afl-c++ $${DESTDIR}$(BIN_PATH)/afl-clang++ ; fi
@if [ -f ./SanitizerCoverageLTO.so ]; then set -e; ln -sf afl-cc $${DESTDIR}$(BIN_PATH)/afl-clang-lto ; ln -sf ./afl-c++ $${DESTDIR}$(BIN_PATH)/afl-clang-lto++ ; fi

View File

@ -166,7 +166,8 @@ struct queue_entry {
favored, /* Currently favored? */
fs_redundant, /* Marked as redundant in the fs? */
is_ascii, /* Is the input just ascii text? */
disabled; /* Is disabled from fuzz selection */
disabled, /* Is disabled from fuzz selection */
has_unusual; /* Triggers an unusual value */
u32 bitmap_size, /* Number of bits set in bitmap */
fuzz_level, /* Number of fuzzing iterations */
@ -629,6 +630,9 @@ typedef struct afl_state {
struct queue_entry **queue_buf;
struct queue_entry **top_rated; /* Top entries for bitmap bytes */
struct queue_entry **top_rated_unusual; /* Top entries for unusual */
u8 *unusual_item_changed;
struct extra_data *extras; /* Extra tokens to fuzz with */
u32 extras_cnt; /* Total number of tokens read */
@ -644,6 +648,11 @@ typedef struct afl_state {
char * cmplog_binary;
afl_forkserver_t cmplog_fsrv; /* cmplog has its own little forkserver */
/* Unusual */
char * unusual_binary;
afl_forkserver_t unusual_fsrv; /* unusual has its own little forkserver */
/* Custom mutators */
struct custom_mutator *mutator;
@ -1056,7 +1065,7 @@ void minimize_bits(afl_state_t *, u8 *, u8 *);
#ifndef SIMPLE_FILES
u8 *describe_op(afl_state_t *, u8, size_t);
#endif
u8 save_if_interesting(afl_state_t *, void *, u32, u8);
u8 save_if_interesting(afl_state_t *, void *, u32, u8, u8);
u8 has_new_bits(afl_state_t *, u8 *);
u8 has_new_bits_unclassified(afl_state_t *, u8 *);
@ -1081,6 +1090,13 @@ void maybe_update_plot_file(afl_state_t *, u32, double, double);
void show_stats(afl_state_t *);
void show_init_stats(afl_state_t *);
static inline u64 total_execs_all(afl_state_t *afl) {
return afl->fsrv.total_execs +
/*afl->cmplog_fsrv.total_execs +*/ afl->unusual_fsrv.total_execs;
}
/* StatsD */
void statsd_setup_format(afl_state_t *afl);
@ -1141,6 +1157,10 @@ void write_crash_readme(afl_state_t *afl);
u8 common_fuzz_cmplog_stuff(afl_state_t *afl, u8 *out_buf, u32 len);
/* Unusual */
u8 common_fuzz_unusual_stuff(afl_state_t *afl, u8 *out_buf, u32 len);
/* RedQueen */
u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len);

View File

@ -462,6 +462,8 @@
#define CMPLOG_SHM_ENV_VAR "__AFL_CMPLOG_SHM_ID"
#define UNUSUAL_SHM_ENV_VAR "__AFL_UNUSUAL_SHM_ID"
/* CPU Affinity lockfile env var */
#define CPU_AFFINITY_ENV_VAR "__AFL_LOCKFILE"

View File

@ -204,6 +204,11 @@ static char *afl_environment_variables[] = {
"AFL_USE_FASAN",
"AFL_USE_QASAN",
"AFL_PRINT_FILENAMES",
"AFL_UNUSUAL_VALUES",
"AFL_LLVM_UNUSUAL_VALUES",
"AFL_NO_SINGLE_UNUSUAL_VALUES",
"AFL_SKIP_START_LEARNING",
"AFL_LLVM_RAND_SEED",
NULL
};

View File

@ -97,6 +97,7 @@ typedef struct afl_forkserver {
u8 *shmem_fuzz; /* allocated memory for fuzzing */
char *cmplog_binary; /* the name of the cmplog binary */
char *unusual_binary; /* the name of the unusual binary */
/* persistent mode replay functionality */
u32 persistent_record; /* persistent replay setting */

View File

@ -29,6 +29,7 @@
#define __AFL_SHAREDMEM_H
#include "types.h"
#include "unusual.h"
typedef struct sharedmem {
@ -44,13 +45,15 @@ typedef struct sharedmem {
#else
s32 shm_id; /* ID of the SHM region */
s32 cmplog_shm_id;
s32 unusual_shm_id;
#endif
u8 *map; /* shared memory region */
u8 * map; /* shared memory region */
struct unusual_values_state *unusual;
size_t map_size; /* actual allocated size */
int cmplog_mode;
int cmplog_mode, unusual_mode;
int shmemfuzz_mode;
struct cmp_map *cmp_map;

105
include/unusual.h Normal file
View File

@ -0,0 +1,105 @@
/*
american fuzzy lop++ - unusual values header
--------------------------------------------
Written by Andrea Fioraldi <andreafioraldi@gmail.com>
Copyright 2021 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:
http://www.apache.org/licenses/LICENSE-2.0
*/
#ifndef _AFL_UNUSUAL_H
#define _AFL_UNUSUAL_H
#include "config.h"
#include "types.h"
#include <string.h>
#define UNUSUAL_MAP_SIZE 65536
#define INV_ONEOF_MAX_NUM_VALS 8
#define INV_EXECS_MIN_BOUND 32
enum {
INV_NONE = 0,
INV_LT,
INV_LE,
INV_GT,
INV_GE,
INV_EQ,
INV_NE,
INV_ONEOF,
INV_ALL,
// ptr invariants (reuse INV_EQ)
INV_GE_PAGE, // greater equal than PAGE_SIZE
INV_LT_PAGE, // greater than PAGE_SIZE
INV_HEAP, // future use, maybe with sbrk(0)
INV_STACK, // check if below __builtin_frame_address(0)
};
struct single_var_invariant {
u64 vals[INV_ONEOF_MAX_NUM_VALS];
u8 num_vals;
u8 execs;
u8 invariant;
};
struct single_ptr_invariant {
u8 execs;
u8 invariant;
};
struct __attribute__((__packed__)) pair_vars_invariant {
u8 invariant;
u8 execs;
};
struct unusual_values_state {
u8 map[UNUSUAL_MAP_SIZE / 8];
u8 virgin[UNUSUAL_MAP_SIZE / 8];
u8 crash[UNUSUAL_MAP_SIZE / 8];
struct single_var_invariant single_invariants[UNUSUAL_MAP_SIZE];
struct pair_vars_invariant pair_invariants[UNUSUAL_MAP_SIZE];
u8 learning;
};
static inline void unusual_values_state_init(struct unusual_values_state *state) {
// memset(state->map, 0, UNUSUAL_MAP_SIZE / 8);
memset(state->virgin, 0xff, UNUSUAL_MAP_SIZE / 8);
memset(state->crash, 0xff, UNUSUAL_MAP_SIZE / 8);
// state->learning = 1;
}
static inline void unusual_values_state_reset(struct unusual_values_state *state) {
memset(state->map, 0, UNUSUAL_MAP_SIZE / 8);
}
/* Execs the child */
struct afl_forkserver;
void unusual_exec_child(struct afl_forkserver *fsrv, char **argv);
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -20,6 +20,7 @@
#include "config.h"
#include "types.h"
#include "cmplog.h"
#include "unusual.h"
#include "llvm-alternative-coverage.h"
#include <stdio.h>
@ -32,6 +33,7 @@
#include <stddef.h>
#include <limits.h>
#include <errno.h>
#include <math.h>
#include <sys/mman.h>
#ifndef __HAIKU__
@ -83,15 +85,15 @@ extern ssize_t _kern_write(int fd, off_t pos, const void *buffer,
size_t bufferSize);
#endif // HAIKU
static u8 __afl_area_initial[MAP_INITIAL_SIZE];
static u8 * __afl_area_ptr_dummy = __afl_area_initial;
static u8 * __afl_area_ptr_backup = __afl_area_initial;
static u8 __afl_area_initial[MAP_INITIAL_SIZE];
static u8 *__afl_area_ptr_dummy = __afl_area_initial;
static u8 *__afl_area_ptr_backup = __afl_area_initial;
u8 * __afl_area_ptr = __afl_area_initial;
u8 * __afl_dictionary;
u8 * __afl_fuzz_ptr;
static u32 __afl_fuzz_len_dummy;
u32 *__afl_fuzz_len = &__afl_fuzz_len_dummy;
u8 * __afl_area_ptr = __afl_area_initial;
u8 * __afl_dictionary;
u8 * __afl_fuzz_ptr;
static u32 __afl_fuzz_len_dummy;
u32 * __afl_fuzz_len = &__afl_fuzz_len_dummy;
u32 __afl_final_loc;
u32 __afl_map_size = MAP_SIZE;
@ -99,8 +101,8 @@ u32 __afl_dictionary_len;
u64 __afl_map_addr;
// for the __AFL_COVERAGE_ON/__AFL_COVERAGE_OFF features to work:
int __afl_selective_coverage __attribute__((weak));
int __afl_selective_coverage_start_off __attribute__((weak));
int __afl_selective_coverage __attribute__((weak));
int __afl_selective_coverage_start_off __attribute__((weak));
static int __afl_selective_coverage_temp = 1;
#if defined(__ANDROID__) || defined(__HAIKU__)
@ -118,6 +120,8 @@ int __afl_sharedmem_fuzzing __attribute__((weak));
struct cmp_map *__afl_cmp_map;
struct cmp_map *__afl_cmp_map_backup;
struct unusual_values_state *__afl_unusual __attribute__((weak));
/* Child pid? */
static s32 child_pid;
@ -576,6 +580,26 @@ static void __afl_map_shm(void) {
}
id_str = getenv(UNUSUAL_SHM_ENV_VAR);
if (id_str) {
u32 shm_id = atoi(id_str);
// TODO set this for mmap too
__afl_unusual = (struct unusual_values_state *)shmat(shm_id, NULL, 0);
if (!__afl_unusual || __afl_unusual == (void *)-1) {
perror("shmat for unusual");
send_forkserver_error(FS_ERROR_SHM_OPEN);
_exit(1);
}
}
}
/* unmap SHM. */
@ -1015,6 +1039,7 @@ static void __afl_start_forkserver(void) {
close(FORKSRV_FD);
close(FORKSRV_FD + 1);
return;
}

View File

@ -133,9 +133,20 @@ bool AFLCoverage::runOnModule(Module &M) {
u32 rand_seed;
unsigned int cur_loc = 0;
/* Setup random() so we get Actually Random(TM) outputs from AFL_R() */
gettimeofday(&tv, &tz);
rand_seed = tv.tv_sec ^ tv.tv_usec ^ getpid();
if (getenv("AFL_LLVM_RAND_SEED")) {
std::fstream seed_file(getenv("AFL_LLVM_RAND_SEED"), std::ios_base::in);
seed_file >> rand_seed;
seed_file.close();
} else {
/* Setup random() so we get Actually Random(TM) outputs from AFL_R() */
gettimeofday(&tv, &tz);
rand_seed = tv.tv_sec ^ tv.tv_usec ^ getpid();
}
AFL_SR(rand_seed);
/* Show a banner */
@ -676,7 +687,7 @@ bool AFLCoverage::runOnModule(Module &M) {
todo.push_back(MapPtrIdx);
} else {
*/
IRB.CreateAtomicRMW(llvm::AtomicRMWInst::BinOp::Add, MapPtrIdx, One,
#if LLVM_VERSION_MAJOR >= 13
@ -947,6 +958,15 @@ bool AFLCoverage::runOnModule(Module &M) {
*/
if (getenv("AFL_LLVM_RAND_SEED")) {
std::fstream seed_file(getenv("AFL_LLVM_RAND_SEED"),
std::ios_base::out | std::ios::trunc);
seed_file << AFL_R((u32)-1);
seed_file.close();
}
/* Say something nice. */
if (!be_quiet) {

View File

@ -0,0 +1,720 @@
#define AFL_LLVM_PASS
#include "config.h"
#include "debug.h"
#include "unusual.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <list>
#include <string>
#include <fstream>
#include <vector>
#include <map>
#include <set>
#include <algorithm>
#include <sys/time.h>
#include "llvm/Config/llvm-config.h"
#if LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR < 5
typedef long double max_align_t;
#endif
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/LegacyPassManager.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Dominators.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Transforms/IPO/PassManagerBuilder.h"
#if LLVM_VERSION_MAJOR > 3 || \
(LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR > 4)
#include "llvm/IR/DebugInfo.h"
#include "llvm/IR/CFG.h"
#else
#include "llvm/DebugInfo.h"
#include "llvm/Support/CFG.h"
#endif
#include "afl-llvm-common.h"
//#include "RangeAnalysis.h"
using namespace llvm;
//using namespace RangeAnalysis;
/*
static size_t TypeSizeToSizeIndex(uint32_t TypeSize) {
if (TypeSize == 1) TypeSize = 8;
size_t Res = countTrailingZeros(TypeSize / 8);
return Res;
}
*/
namespace {
struct AFLUnusual {
AFLUnusual(Module &_M, Function &_F, DominatorTree &_DT)
//IntraProceduralRA<Cousot> &_RA)
: M(_M), F(_F), DT(_DT) {
initialize();
}
static bool isBlacklisted(const Function *F) {
static const char *Blacklist[] = {
"asan.", "llvm.", "sancov.", "__ubsan_handle_", "ign.", "__afl_",
"_fini", "__libc_csu", "__asan", "__msan", "msan."
};
for (auto const &BlacklistFunc : Blacklist) {
if (F->getName().startswith(BlacklistFunc)) return true;
}
// if (F->getName() == "main") return true;
if (F->getName() == "_start") return true;
return false;
}
void initialize();
bool instrumentFunction();
Type *VoidTy, *Int8Ty, *Int16Ty, *Int32Ty, *Int64Ty, *FloatTy, *DoubleTy,
*StructTy, *Int8PTy, *Int16PTy, *Int32PTy, *Int64PTy, *FloatPTy,
*DoublePTy, *StructPTy, *FuncTy;
Type *IntTypeSized[4];
Function *dbgDeclareFn;
FunctionCallee unusualValuesFns[6];
FunctionCallee unusualValuesPtrFn;
FunctionCallee unusualValuesLogFn;
bool noSingle = false;
bool noPtrs = false;
LLVMContext *C;
Module & M;
Function & F;
DominatorTree & DT;
//IntraProceduralRA<Cousot> &RA;
int LongSize;
std::map<Value *, int> Comp;
int CompID = 0;
std::vector<DILocalVariable *> DbgVars;
};
} // namespace
void AFLUnusual::initialize() {
C = &(M.getContext());
LongSize = M.getDataLayout().getPointerSizeInBits();
VoidTy = Type::getVoidTy(*C);
Int8Ty = IntegerType::get(*C, 8);
Int16Ty = IntegerType::get(*C, 16);
Int32Ty = IntegerType::get(*C, 32);
Int64Ty = IntegerType::get(*C, 64);
FloatTy = Type::getFloatTy(*C);
DoubleTy = Type::getDoubleTy(*C);
StructTy = StructType::create(*C);
Int8PTy = PointerType::get(Int8Ty, 0);
Int16PTy = PointerType::get(Int16Ty, 0);
Int32PTy = PointerType::get(Int32Ty, 0);
Int64PTy = PointerType::get(Int64Ty, 0);
FloatPTy = PointerType::get(FloatTy, 0);
DoublePTy = PointerType::get(DoubleTy, 0);
StructPTy = PointerType::get(StructTy, 0);
FuncTy = FunctionType::get(VoidTy, true);
dbgDeclareFn = M.getFunction("llvm.dbg.declare");
IntTypeSized[0] = Int8Ty;
IntTypeSized[1] = Int16Ty;
IntTypeSized[2] = Int32Ty;
IntTypeSized[3] = Int64Ty;
unusualValuesFns[0] = M.getOrInsertFunction("__afl_unusual_values_1", Int32Ty,
Int32Ty, Int64Ty, Int8Ty);
unusualValuesFns[1] = M.getOrInsertFunction("__afl_unusual_values_2", Int32Ty,
Int32Ty, Int64Ty, Int64Ty);
unusualValuesFns[2] = M.getOrInsertFunction(
"__afl_unusual_values_3", Int32Ty, Int32Ty, Int64Ty, Int64Ty, Int64Ty);
unusualValuesPtrFn = M.getOrInsertFunction("__afl_unusual_values_ptr", Int32Ty, Int32Ty, Int8PTy, Int8Ty);
unusualValuesLogFn =
M.getOrInsertFunction("__afl_unusual_values_log", VoidTy, Int32Ty);
/* Show a banner */
setvbuf(stdout, NULL, _IONBF, 0);
if (getenv("AFL_DEBUG")) debug = 1;
if ((isatty(2) && !getenv("AFL_QUIET")) || getenv("AFL_DEBUG") != NULL) {
SAYF(cCYA "afl-unusual-pass" VERSION cRST
" by <andreafioraldi@gmail.com>\n");
} else
be_quiet = 1;
noSingle = !!getenv("AFL_NO_SINGLE_UNUSUAL_VALUES");
noPtrs = !!getenv("AFL_NO_PTR_UNUSUAL_VALUES");
}
static void AddComp(std::map<Value *, int> &Comp, int &CompID, Value *A) {
bool hasA = Comp.find(A) != Comp.end();
if (!hasA) {
Comp[A] = CompID;
++CompID;
}
}
static void MergeComp(std::map<Value *, int> &Comp, int &CompID, Value *A,
Value *B) {
bool hasA = Comp.find(A) != Comp.end();
bool hasB = Comp.find(B) != Comp.end();
if (hasA && !hasB)
Comp[B] = Comp[A];
else if (!hasA && hasB)
Comp[A] = Comp[B];
else if (!hasA && !hasB) {
Comp[A] = CompID;
Comp[B] = CompID;
++CompID;
} else {
int AID = Comp[A];
int BID = Comp[B];
for (auto &K : Comp) {
if (K.second == BID) K.second = AID;
}
}
}
static bool IsAlloca(Value* V) {
// we assume it is a ptr instruction
if (isa<AllocaInst>(V)) return true;
if (auto C = dyn_cast<CastInst>(V)) {
return IsAlloca(C->getOperand(0));
}
return false;
}
bool AFLUnusual::instrumentFunction() {
bool FunctionModified = false;
if (isBlacklisted(&F)) return FunctionModified; // not supported
struct timeval tv;
struct timezone tz;
/* Setup random() so we get Actually Random(TM) outputs from AFL_R() */
gettimeofday(&tv, &tz);
AFL_SR(tv.tv_sec ^ tv.tv_usec ^ getpid());
std::set<Value *> LocVals;
std::vector<BasicBlock *> Blocks;
unsigned Calls1 = 0, Calls2 = 0;
unsigned Key = 0;
for (Function::arg_iterator it = F.arg_begin(); it != F.arg_end(); ++it) {
Argument *A = &*it;
Value * V = static_cast<Value *>(A);
if (LocVals.find(V) == LocVals.end()) LocVals.insert(V);
AddComp(Comp, CompID, V);
}
std::function<void(BasicBlock *)> VisitBlock = [&](BasicBlock *BB) {
Blocks.push_back(BB);
SmallVector<BasicBlock *, 3> Doms;
DT.getDescendants(BB, Doms);
for (auto DBB : Doms) {
if (std::find(Blocks.begin(), Blocks.end(), DBB) == Blocks.end())
VisitBlock(DBB);
}
};
VisitBlock(&F.getEntryBlock());
for (auto BB : Blocks) {
for (auto &I : *BB) {
if (auto *L = dyn_cast<LoadInst>(&I)) {
AddComp(Comp, CompID, L);
AddComp(Comp, CompID, L->getPointerOperand());
} else if (auto ST = dyn_cast<StoreInst>(&I)) {
AddComp(Comp, CompID, ST->getPointerOperand());
AddComp(Comp, CompID, ST->getValueOperand());
} else if (auto *DbgValue = dyn_cast<DbgValueInst>(&I)) {
Value *V = DbgValue->getValue();
if (V && !isa<Constant>(V)) {
if (LocVals.find(V) == LocVals.end()) LocVals.insert(V);
AddComp(Comp, CompID, V);
}
} else if (auto *RI = dyn_cast<ReturnInst>(&I)) {
Value *V = RI->getReturnValue();
if (V && !isa<Constant>(V)) {
if (LocVals.find(V) == LocVals.end()) LocVals.insert(V);
AddComp(Comp, CompID, V);
}
}
}
}
for (auto BB : Blocks) {
for (auto &I : *BB) {
if (UnaryOperator *O = dyn_cast<UnaryOperator>(&I)) {
MergeComp(Comp, CompID, O, O->getOperand(0));
} else if (BinaryOperator *O = dyn_cast<BinaryOperator>(&I)) {
MergeComp(Comp, CompID, O->getOperand(0), O->getOperand(1));
MergeComp(Comp, CompID, O, O->getOperand(1));
} else if (CastInst *C = dyn_cast<CastInst>(&I)) {
MergeComp(Comp, CompID, C, C->getOperand(0));
} else if (GetElementPtrInst *G = dyn_cast<GetElementPtrInst>(&I)) {
MergeComp(Comp, CompID, G, G->getPointerOperand());
Value *First = nullptr;
for (auto Idx = G->idx_begin(); Idx != G->idx_end(); ++Idx) {
if (Idx->get() && !isa<ConstantInt>(Idx->get())) {
if (First)
MergeComp(Comp, CompID, First, Idx->get());
else
First = Idx->get();
}
}
}
}
}
std::set<Value *> Dumpeds1;
std::set<std::pair<Value *, Value *>> Dumpeds2;
for (auto &BB : Blocks) {
std::map<int, std::set<Value *>> CompArgs;
std::set<Value *> Rets;
Value* Hash = nullptr;
IRBuilder<> IRB(BB->getTerminator());
auto GroupVar = [&](Value *V) {
Type *T = V->getType();
int CompID = -1;
if (Comp.find(V) != Comp.end()) CompID = Comp[V];
if (T->getTypeID() == Type::IntegerTyID) {
TypeSize BitsNum = T->getPrimitiveSizeInBits();
if (BitsNum <= 64) {
// Value *I = IRB.CreateSExtOrBitCast(V, Int64Ty);
// CompArgs[CompID].insert(I);
CompArgs[CompID].insert(V);
return true;
}
} else if (!noPtrs && T->getTypeID() == Type::PointerTyID) {
//if (!AA.pointsToConstantMemory(V)) {
// TODO get pointer values but avoid to emit checks that compare
// pointers to integers
// to check single invariants on pointers emit a different check
// routine that see if it is NULL or a stack or heap ptr
CompArgs[CompID].insert(V);
return true;
//}
}
return false;
};
for (auto &I : *BB) {
if (I.getMetadata(M.getMDKindID("nosanitize"))) continue;
if (isa<PHINode>(&I)) continue;
for (auto op = I.op_begin(); op != I.op_end(); ++op) {
Value *V = op->get();
if (LocVals.find(V) != LocVals.end()) GroupVar(V);
}
// ATM remove GEP as interesting instruction
/* if (auto GEP = dyn_cast<GetElementPtrInst>(&I)) {
if (!isa<PointerType>(GEP->getSourceElementType())) continue;
if (!GEP->hasIndices()) continue;
GroupVar(GEP->getPointerOperand());
for (auto Idx = GEP->idx_begin(); Idx != GEP->idx_end(); ++Idx) {
if (Idx->get() && !isa<ConstantInt>(Idx->get())) GroupVar(Idx->get());
}
} else */
if (auto LD = dyn_cast<LoadInst>(&I)) {
GroupVar(LD->getPointerOperand());
GroupVar(LD);
} else if (auto ST = dyn_cast<StoreInst>(&I)) {
GroupVar(ST->getPointerOperand());
GroupVar(ST->getValueOperand());
}
}
int SingleCnt = 0;
for (auto P : CompArgs) {
// if (P.first == -1) continue;
// if (P.second.size() <= 1) continue;
for (auto X : P.second) {
Value *XB = nullptr;
if (isa<Constant>(X)) {
// errs() << "COSNT VAL " << *X << "\n";
Dumpeds1.insert(X);
}
if (X->getType()->getTypeID() == Type::PointerTyID && IsAlloca(X)) {
Dumpeds1.insert(X);
}
/*if (LoadInst *L = dyn_cast<LoadInst>(X)) {
// Skip load from constant mem
if (AA.pointsToConstantMemory(L->getPointerOperand())) {
// errs() << "COSNT MEM " << *L << "\n";
Dumpeds1.insert(X);
}
}*/
if (!noSingle && Dumpeds1.find(X) == Dumpeds1.end()) {
//Range Rng = RA.getRange(X);
bool MustCheck = false;
u8 always_true = INV_ALL;
u8 always_ptr_true = INV_ALL;
MustCheck = true;
/*if (!Rng.isUnknown() && !Rng.isEmpty()) {
bool HasMin = Rng.getLower().getActiveBits() <= 64;
bool HasMax = Rng.getUpper().getActiveBits() <= 64;
if (HasMin && HasMax) {
int64_t A = (int64_t)Rng.getLower().getSExtValue();
int64_t B = (int64_t)Rng.getUpper().getSExtValue();
// errs() << "Range " << A << " - " << B << "\n";
if (A > 0 && B > 0) always_true = INV_GT;
if (A >= 0 && B > 0) always_true = INV_GE;
if (A < 0 && B < 0) always_true = INV_LT;
if (A < 0 && B <= 0) always_true = INV_LE;
if ((uint64_t)A >= 4096) always_ptr_true = INV_GE_PAGE;
// if (!((A > 0 && B > 0) || (A < 0 && B < 0) || (A == B))) {
if (A != B) { MustCheck = true; } // else
// errs() << "SKIP " << A << " - " << B << "\n";
}
} else {
MustCheck = true;
}*/
if (MustCheck) {
CallInst *CI;
Key = AFL_R(UNUSUAL_MAP_SIZE);
if (X->getType()->getTypeID() == Type::IntegerTyID) {
XB = IRB.CreateSExtOrBitCast(X, Int64Ty);
//XB->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(*C, None));
CI = IRB.CreateCall(
unusualValuesFns[0],
ArrayRef<Value *>{ConstantInt::get(Int32Ty, Key, true), XB,
ConstantInt::get(Int8Ty, always_true, true)});
} else { // Pointer
auto* XP = IRB.CreateBitCast(X, Int8PTy);
//XP->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(*C, None));
CI = IRB.CreateCall(
unusualValuesPtrFn,
ArrayRef<Value *>{ConstantInt::get(Int32Ty, Key, true), XP,
ConstantInt::get(Int8Ty, always_ptr_true, true)});
}
CI->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(*C, None));
++Calls1;
++SingleCnt;
Rets.insert(CI);
if (Hash == nullptr) Hash = CI;
else Hash = IRB.CreateXor(Hash, CI);
}
Dumpeds1.insert(X);
}
// if (P.first == -1) continue;
for (auto O : CompArgs) {
if (P.first != -1 && P.first != O.first) continue;
for (auto Y : O.second) {
if (X == Y ||
X->getType()->getTypeID() != Y->getType()->getTypeID() ||
Dumpeds2.find(std::make_pair(X, Y)) != Dumpeds2.end() ||
Dumpeds2.find(std::make_pair(Y, X)) != Dumpeds2.end())
continue;
if (X->getType()->getTypeID() == Type::PointerTyID && IsAlloca(X) && IsAlloca(Y)) continue;
CallInst *CI;
Key = AFL_R(UNUSUAL_MAP_SIZE);
if (XB == nullptr) {
XB = IRB.CreateSExtOrBitCast(X, Int64Ty);
//XB->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(*C, None));
}
auto *YB = IRB.CreateSExtOrBitCast(Y, Int64Ty);
CI = IRB.CreateCall(
unusualValuesFns[1],
ArrayRef<Value *>{ConstantInt::get(Int32Ty, Key, true), XB,
YB});
CI->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(*C, None));
++Calls2;
Rets.insert(CI);
if (Hash == nullptr) Hash = CI;
else Hash = IRB.CreateXor(Hash, CI);
Dumpeds2.insert(std::make_pair(X, Y));
}
}
}
}
if (Rets.size() && !(SingleCnt == 1 && Rets.size() == 1)) {
FunctionModified = true;
CallInst *CI =
IRB.CreateCall(unusualValuesLogFn, ArrayRef<Value *>{Hash});
CI->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(*C, None));
}
}
if (FunctionModified && !be_quiet) {
OKF("Inserted %d calls to log single values, %d to log pairs.", Calls1,
Calls2);
}
return FunctionModified;
}
class AFLUnusualFunctionPass : public FunctionPass {
public:
static char ID;
explicit AFLUnusualFunctionPass() : FunctionPass(ID) {
}
void getAnalysisUsage(AnalysisUsage &AU) const override {
AU.setPreservesCFG();
AU.addRequired<DominatorTreeWrapperPass>();
//AU.addRequired<IntraProceduralRA<Cousot>>();
//AU.addRequired<AAResultsWrapperPass>();
}
StringRef getPassName() const override {
return "AFLUnusualPass";
}
bool runOnFunction(Function &F) override {
Module & M = *F.getParent();
DominatorTree &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();
//IntraProceduralRA<Cousot> &RA = getAnalysis<IntraProceduralRA<Cousot>>();
AFLUnusual DI(M, F, DT);
bool r = DI.instrumentFunction();
// verifyFunction(F);
return r;
}
};
char AFLUnusualFunctionPass::ID = 0;
// For RangeAnalysis
//template <class CGT>
//char IntraProceduralRA<CGT>::ID;
static void registerAFLUnusualPass(const PassManagerBuilder &,
legacy::PassManagerBase &PM) {
PM.add(new AFLUnusualFunctionPass());
}
static RegisterStandardPasses RegisterAFLUnusualPass(
PassManagerBuilder::EP_OptimizerLast, registerAFLUnusualPass);
static RegisterStandardPasses RegisterAFLUnusualPass0(
PassManagerBuilder::EP_EnabledOnOptLevel0, registerAFLUnusualPass);
static RegisterPass<AFLUnusualFunctionPass> X("afl-unusual", "AFLUnusualPass",
false, false);

View File

@ -0,0 +1,753 @@
/*
american fuzzy lop++ - LLVM instrumentation bootstrap
-----------------------------------------------------
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:
http://www.apache.org/licenses/LICENSE-2.0
*/
#include "unusual.h"
#include <string.h>
#include <unistd.h>
#include <sys/mman.h>
#include <stdio.h>
struct unusual_values_state __afl_unusual_dummy;
// Override the weak symbol
struct unusual_values_state *__afl_unusual = &__afl_unusual_dummy;
#define GET_BIT(_ar, _b) !!((((u8 *)(_ar))[(_b) >> 3] & (128 >> ((_b)&7))))
#define SET_BIT(_ar, _b) \
do { \
\
u8 *_arf = (u8 *)(_ar); \
u32 _bf = (_b); \
_arf[(_bf) >> 3] |= (128 >> ((_bf)&7)); \
\
} while (0)
#define UNSET_BIT(_ar, _b) \
do { \
\
u8 *_arf = (u8 *)(_ar); \
u32 _bf = (_b); \
_arf[(_bf) >> 3] &= ~(128 >> ((_bf)&7)); \
\
} while (0)
#define FLIP_BIT(_ar, _b) \
do { \
\
u8 *_arf = (u8 *)(_ar); \
u32 _bf = (_b); \
_arf[(_bf) >> 3] ^= (128 >> ((_bf)&7)); \
\
} while (0)
#define UPDATE_MAP(k) SET_BIT(__afl_unusual->map, k)
#define UPDATE_VIRGIN(k) \
{ \
\
SET_BIT(__afl_unusual->virgin, k); \
SET_BIT(__afl_unusual->crash, k); \
\
}
// #define UPDATE_VIRGIN(k)
static void patch_caller(uint8_t *retaddr) {
#ifdef __x86_64__
if (retaddr[-5] == 0xe8) { // Near call
uint8_t *caller = &retaddr[-5];
long page_size = sysconf(_SC_PAGE_SIZE);
uint8_t *page = (uint8_t *)((uintptr_t)caller & ~(page_size - 1));
if (page + page_size <= retaddr) {
// it crosses a boundary
page_size *= 2;
}
mprotect(page, page_size, PROT_READ | PROT_WRITE | PROT_EXEC);
// The patched stub must return 0
// 4831c0 xor rax, rax
caller[0] = 0x48;
caller[1] = 0x31;
caller[2] = 0xc0;
// 90 nop
caller[3] = 0x90;
caller[4] = 0x90;
mprotect(page, page_size, PROT_READ | PROT_EXEC);
}
#endif
}
static u32 unusual_values_single(uint8_t *retaddr, u32 k, u64 x,
u8 always_true) {
u32 ret = 0;
int learning = __afl_unusual->learning;
struct single_var_invariant *inv = &__afl_unusual->single_invariants[k];
// u8 old = inv->invariant;
switch (inv->invariant) {
case INV_NONE: {
if (learning) {
// inv->num_vals = 0;
inv->vals[inv->num_vals++] = x;
inv->invariant = INV_ONEOF;
UPDATE_VIRGIN(k);
}
break;
}
case INV_LT: {
if ((s64)x < 0) break;
if (learning) {
if (x == 0)
inv->invariant = INV_LE;
else
inv->invariant = INV_NE;
UPDATE_VIRGIN(k);
if (always_true == inv->invariant) {
inv->invariant = INV_ALL;
patch_caller(retaddr);
}
} else if (inv->execs >= INV_EXECS_MIN_BOUND) {
ret = k;
}
break;
}
case INV_LE: {
if ((s64)x <= 0) break;
if (learning) {
inv->invariant = INV_ALL;
UPDATE_VIRGIN(k);
patch_caller(retaddr);
} else if (inv->execs >= INV_EXECS_MIN_BOUND) {
ret = k;
}
break;
}
case INV_GT: {
if ((s64)x > 0) break;
if (learning) {
if (x == 0)
inv->invariant = INV_GE;
else
inv->invariant = INV_NE;
UPDATE_VIRGIN(k);
if (always_true == inv->invariant) {
inv->invariant = INV_ALL;
patch_caller(retaddr);
}
} else if (inv->execs >= INV_EXECS_MIN_BOUND) {
ret = k;
}
break;
}
case INV_GE: {
if ((s64)x >= 0) break;
if (learning) {
inv->invariant = INV_ALL;
UPDATE_VIRGIN(k);
patch_caller(retaddr);
} else if (inv->execs >= INV_EXECS_MIN_BOUND) {
ret = k;
}
break;
}
case INV_EQ: {
if (x == 0) break;
if (learning) {
if ((s64)x > 0)
inv->invariant = INV_GE;
else
inv->invariant = INV_LE;
UPDATE_VIRGIN(k);
if (always_true == inv->invariant) {
inv->invariant = INV_ALL;
patch_caller(retaddr);
}
} else if (inv->execs >= INV_EXECS_MIN_BOUND) {
ret = k;
}
break;
}
case INV_NE: {
if (x != 0) break;
if (learning) {
inv->invariant = INV_ALL;
UPDATE_VIRGIN(k);
patch_caller(retaddr);
} else if (inv->execs >= INV_EXECS_MIN_BOUND) {
ret = k;
}
break;
}
case INV_ONEOF: {
int oneof = 1;
size_t i;
for (i = 0; i < inv->num_vals; ++i) {
if (inv->vals[i] != x) oneof = 0;
}
if (oneof) break;
if (learning) {
if (inv->num_vals < INV_ONEOF_MAX_NUM_VALS) {
inv->vals[inv->num_vals++] = x;
} else {
int lt = 0, gt = 0, eq = 0;
for (i = 0; i < INV_ONEOF_MAX_NUM_VALS; ++i) {
if ((s64)inv->vals[i] < 0)
++lt;
else if ((s64)inv->vals[i] > 0)
++gt;
else if ((s64)inv->vals[i] == 0)
++eq;
}
if (lt && !gt && !eq)
inv->invariant = INV_LT;
else if (lt && !gt && eq)
inv->invariant = INV_LE;
else if (!lt && gt && !eq)
inv->invariant = INV_GT;
else if (!lt && gt && eq)
inv->invariant = INV_GE;
else if (lt && gt && !eq)
inv->invariant = INV_NE;
else { // if (lt && gt && eq)
inv->invariant = INV_ALL;
patch_caller(retaddr);
}
if (always_true == inv->invariant) {
inv->invariant = INV_ALL;
patch_caller(retaddr);
}
}
UPDATE_VIRGIN(k);
} else if (inv->execs >= INV_EXECS_MIN_BOUND) {
ret = k;
}
break;
}
case INV_ALL: {
patch_caller(retaddr);
break;
}
default:
break;
}
if (learning) ++inv->execs;
// if (old != inv->invariant) fprintf(stderr, "LEARNING %x %d -- %d %d\n", k, inv->execs, old, inv->invariant);
return ret;
}
static u32 unusual_values_pair(uint8_t *retaddr, u32 k, u64 x, u64 y) {
u32 ret = 0;
int learning = __afl_unusual->learning;
struct pair_vars_invariant *inv = &__afl_unusual->pair_invariants[k];
switch (inv->invariant) {
case INV_NONE: {
if (learning) {
if (x == y)
inv->invariant = INV_EQ;
else if ((s64)x > (s64)y)
inv->invariant = INV_GT;
else // if ((s64)x < (s64)y)
inv->invariant = INV_LT;
UPDATE_VIRGIN(k);
}
break;
}
case INV_LT: {
if ((s64)x < (s64)y) break;
if (learning) {
if (x == y)
inv->invariant = INV_LE;
else
inv->invariant = INV_NE;
UPDATE_VIRGIN(k);
} else if (inv->execs >= INV_EXECS_MIN_BOUND) {
ret = k;
}
break;
}
case INV_LE: {
if ((s64)x <= (s64)y) break;
if (learning) {
inv->invariant = INV_ALL;
UPDATE_VIRGIN(k);
patch_caller(retaddr);
} else if (inv->execs >= INV_EXECS_MIN_BOUND) {
ret = k;
}
break;
}
case INV_GT: {
if ((s64)x > (s64)y) break;
if (learning) {
if (x == y)
inv->invariant = INV_GE;
else
inv->invariant = INV_NE;
UPDATE_VIRGIN(k);
} else if (inv->execs >= INV_EXECS_MIN_BOUND) {
ret = k;
}
break;
}
case INV_GE: {
if ((s64)x >= (s64)y) break;
if (learning) {
inv->invariant = INV_ALL;
UPDATE_VIRGIN(k);
patch_caller(retaddr);
} else if (inv->execs >= INV_EXECS_MIN_BOUND) {
ret = k;
}
break;
}
case INV_EQ: {
if (x == y) break;
if (learning) {
if ((s64)x > (s64)y)
inv->invariant = INV_GE;
else
inv->invariant = INV_LE;
UPDATE_VIRGIN(k);
} else if (inv->execs >= INV_EXECS_MIN_BOUND) {
ret = k;
}
break;
}
case INV_NE: {
if (x != y) break;
if (learning) {
inv->invariant = INV_ALL;
UPDATE_VIRGIN(k);
patch_caller(retaddr);
} else if (inv->execs >= INV_EXECS_MIN_BOUND) {
ret = k;
}
break;
}
default:
break;
}
if (learning) ++inv->execs;
return ret;
}
static uintptr_t stack_end = UINTPTR_MAX;
__attribute__((constructor)) void register_stack_end(void) {
int dummy;
long page_size = sysconf(_SC_PAGE_SIZE);
stack_end = (uintptr_t)&dummy & ~(page_size - 1) + page_size;
}
static int is_stack(uintptr_t p) {
int dummy;
uintptr_t sp = (uintptr_t)&dummy;
long page_size = sysconf(_SC_PAGE_SIZE);
uintptr_t page = sp & ~(page_size - 1);
return p >= page && p < stack_end;
}
static u32 unusual_values_ptr(uint8_t *retaddr, u32 k, uintptr_t x, u8 always_true) {
u32 ret = 0;
uintptr_t first_page = (uintptr_t)sysconf(_SC_PAGE_SIZE);
int learning = __afl_unusual->learning;
struct single_var_invariant *inv = &__afl_unusual->single_invariants[k];
switch (inv->invariant) {
case INV_NONE: {
if (learning) {
if (x == 0) inv->invariant = INV_EQ;
else if (is_stack(x)) inv->invariant = INV_STACK;
else if (x >= first_page) inv->invariant = INV_GE_PAGE;
else if (x < first_page) inv->invariant = INV_LT_PAGE;
else inv->invariant = INV_ALL;
if (always_true == inv->invariant || INV_ALL == inv->invariant) {
inv->invariant = INV_ALL;
patch_caller(retaddr);
}
UPDATE_VIRGIN(k);
}
break;
}
case INV_EQ: {
if (x == 0) break;
if (learning) {
if (x < first_page) inv->invariant = INV_LT_PAGE;
else inv->invariant = INV_ALL;
if (always_true == inv->invariant || INV_ALL == inv->invariant) {
inv->invariant = INV_ALL;
patch_caller(retaddr);
}
UPDATE_VIRGIN(k);
} else if (inv->execs >= INV_EXECS_MIN_BOUND) {
ret = k;
}
break;
}
case INV_LT_PAGE: {
if (x < first_page) break;
if (learning) {
inv->invariant = INV_ALL;
UPDATE_VIRGIN(k);
patch_caller(retaddr);
} else if (inv->execs >= INV_EXECS_MIN_BOUND) {
ret = k;
}
break;
}
case INV_GE_PAGE: {
if (x >= first_page) break;
if (learning) {
inv->invariant = INV_ALL;
UPDATE_VIRGIN(k);
patch_caller(retaddr);
} else if (inv->execs >= INV_EXECS_MIN_BOUND) {
ret = k;
}
break;
}
case INV_STACK: {
if (is_stack(x)) break;
if (learning) {
if (x >= first_page) inv->invariant = INV_GE_PAGE;
else inv->invariant = INV_ALL;
if (always_true == inv->invariant || INV_ALL == inv->invariant) {
inv->invariant = INV_ALL;
patch_caller(retaddr);
}
} else if (inv->execs >= INV_EXECS_MIN_BOUND) {
ret = k;
}
break;
}
case INV_ALL: {
patch_caller(retaddr);
break;
}
default:
break;
}
if (learning) ++inv->execs;
return ret;
}
u32 __afl_unusual_values_1(u32 k, u64 x, u8 always_true) {
// if (!__afl_unusual) return 0;
u32 r = unusual_values_single((uint8_t *)__builtin_return_address(0), k, x,
always_true);
//if (r && GET_BIT(__afl_unusual->virgin, r)) fprintf(stderr, "VIOLATED 1 %x\n", r);
UPDATE_MAP(r);
// if (unusual)
// fprintf(stderr, "(%x) unusual = %d, x = %llu\n", k, unusual,
// (unsigned long long)x);
return r;
}
u32 __afl_unusual_values_2(u32 k, u64 x, u64 y) {
// if (!__afl_unusual) return 0;
u32 r = unusual_values_pair((uint8_t *)__builtin_return_address(0), k, x, y);
//if (r && GET_BIT(__afl_unusual->virgin, r)) fprintf(stderr, "VIOLATED 2 %x\n", r);
UPDATE_MAP(r);
// if (unusual)
// fprintf(stderr, "(%x) unusual = %d, x = %llu, y = %llu\n", k, unusual,
// (unsigned long long)x, (unsigned long long)y);
return r;
}
u32 __afl_unusual_values_ptr(u32 k, uintptr_t x, u8 always_true) {
// if (!__afl_unusual) return 0;
u32 r = unusual_values_ptr((uint8_t *)__builtin_return_address(0), k, x,
always_true);
//if (r && GET_BIT(__afl_unusual->virgin, r)) fprintf(stderr, "VIOLATED P %x\n", r);
UPDATE_MAP(r);
// if (unusual)
// fprintf(stderr, "(%x) unusual = %d, x = %llu\n", k, unusual,
// (unsigned long long)x);
return r;
}
extern u8 *__afl_area_ptr;
void __afl_unusual_values_log(u32 k) {
k &= UNUSUAL_MAP_SIZE -1;
//if (k && GET_BIT(__afl_unusual->virgin, k)) fprintf(stderr, "FILLING %x\n", k);
// if (!__afl_unusual->learning) __afl_area_ptr[k]++;
UPDATE_MAP(k);
}

View File

@ -57,6 +57,7 @@ static u8 * lto_flag = AFL_CLANG_FLTO, *argvnull;
static u8 debug;
static u8 cwd[4096];
static u8 cmplog_mode;
static u8 unusual_mode;
u8 use_stdin; /* dummy */
// static u8 *march_opt = CFLAGS_OPT;
@ -642,6 +643,25 @@ static void edit_params(u32 argc, char **argv, char **envp) {
}
}
if (unusual_mode) {
if (lto_mode && !have_c) {
cc_params[cc_par_cnt++] =
alloc_printf("-Wl,-mllvm=-load=%s/afl-unusual-pass.so", obj_path);
} else {
cc_params[cc_par_cnt++] = "-Xclang";
cc_params[cc_par_cnt++] = "-load";
cc_params[cc_par_cnt++] = "-Xclang";
cc_params[cc_par_cnt++] =
alloc_printf("%s/afl-unusual-pass.so", obj_path);
}
}
// cc_params[cc_par_cnt++] = "-Qunused-arguments";
@ -998,9 +1018,16 @@ static void edit_params(u32 argc, char **argv, char **envp) {
switch (bit_mode) {
case 0:
if (!shared_linking && !partial_linking)
if (!shared_linking && !partial_linking) {
cc_params[cc_par_cnt++] =
alloc_printf("%s/afl-compiler-rt.o", obj_path);
if (unusual_mode)
cc_params[cc_par_cnt++] =
alloc_printf("%s/afl-unusual-rt.o", obj_path);
}
if (lto_mode)
cc_params[cc_par_cnt++] =
alloc_printf("%s/afl-llvm-rt-lto.o", obj_path);
@ -1013,6 +1040,9 @@ static void edit_params(u32 argc, char **argv, char **envp) {
alloc_printf("%s/afl-compiler-rt-32.o", obj_path);
if (access(cc_params[cc_par_cnt - 1], R_OK))
FATAL("-m32 is not supported by your compiler");
if (unusual_mode)
cc_params[cc_par_cnt++] =
alloc_printf("%s/afl-unusual-rt-32.o", obj_path);
}
@ -1034,6 +1064,9 @@ static void edit_params(u32 argc, char **argv, char **envp) {
alloc_printf("%s/afl-compiler-rt-64.o", obj_path);
if (access(cc_params[cc_par_cnt - 1], R_OK))
FATAL("-m64 is not supported by your compiler");
if (unusual_mode)
cc_params[cc_par_cnt++] =
alloc_printf("%s/afl-unusual-rt-64.o", obj_path);
}
@ -2033,6 +2066,11 @@ int main(int argc, char **argv, char **envp) {
if (!be_quiet && cmplog_mode)
printf("CmpLog mode by <andreafioraldi@gmail.com>\n");
unusual_mode =
getenv("AFL_UNUSUAL_VALUES") || getenv("AFL_LLVM_UNUSUAL_VALUES");
if (!be_quiet && unusual_mode)
printf("Unusual Values mode by <andreafioraldi@gmail.com>\n");
#if !defined(__ANDROID__) && !defined(ANDROID)
ptr = find_object("afl-compiler-rt.o", argv[0]);

View File

@ -423,6 +423,13 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
}
if (!fsrv->unusual_binary && fsrv->qemu_mode == false &&
fsrv->frida_mode == false) {
unsetenv(UNUSUAL_SHM_ENV_VAR); // we do not want that in non-unusual fsrv
}
/* Umpf. On OpenBSD, the default fd limit for root users is set to
soft 128. Let's try to fix that... */
if (!getrlimit(RLIMIT_NOFILE, &r) && r.rlim_cur < FORKSRV_FD + 2) {

View File

@ -384,7 +384,8 @@ u8 *describe_op(afl_state_t *afl, u8 new_bits, size_t max_description_len) {
}
if (new_bits == 2) { strcat(ret, ",+cov"); }
if (new_bits == 2 || new_bits == 5) { strcat(ret, ",+cov"); }
if (new_bits >= 3) { strcat(ret, ",+un"); }
if (unlikely(strlen(ret) >= max_description_len))
FATAL("describe string is too long");
@ -450,12 +451,101 @@ void write_crash_readme(afl_state_t *afl) {
}
u8 is_unusual(afl_state_t *afl) {
if (unlikely(!afl->shm.unusual_mode)) { return 0; }
u64 *current_begin = (u64 *)afl->shm.unusual->map;
u64 *current = current_begin;
u64 *current_end =
(u64 *)(afl->shm.unusual->map + sizeof(afl->shm.unusual->map));
u64 *virgin = (u64 *)afl->shm.unusual->virgin;
u8 has_new = 0;
for (; current < current_end; virgin += 8, current += 8) {
\
#define GET_BIT(_ar, _b) !!((((u8 *)(_ar))[(_b) >> 3] & (128 >> ((_b)&7))))
#define UNROLL(idx) \
if (current[idx] & virgin[idx]) { \
\
if (GET_BIT(current, 0)) \
afl->unusual_item_changed[(&current[idx] - current_begin) + 0] = 1; \
if (GET_BIT(current, 1)) \
afl->unusual_item_changed[(&current[idx] - current_begin) + 1] = 1; \
if (GET_BIT(current, 2)) \
afl->unusual_item_changed[(&current[idx] - current_begin) + 2] = 1; \
if (GET_BIT(current, 3)) \
afl->unusual_item_changed[(&current[idx] - current_begin) + 3] = 1; \
if (GET_BIT(current, 4)) \
afl->unusual_item_changed[(&current[idx] - current_begin) + 4] = 1; \
if (GET_BIT(current, 5)) \
afl->unusual_item_changed[(&current[idx] - current_begin) + 5] = 1; \
if (GET_BIT(current, 6)) \
afl->unusual_item_changed[(&current[idx] - current_begin) + 6] = 1; \
if (GET_BIT(current, 7)) \
afl->unusual_item_changed[(&current[idx] - current_begin) + 7] = 1; \
has_new = 1; \
virgin[idx] &= ~current[idx]; \
\
}
UNROLL(0)
UNROLL(1)
UNROLL(2)
UNROLL(3)
UNROLL(4)
UNROLL(5)
UNROLL(6)
UNROLL(7)
#undef UNROLL
#undef GET_BIT
}
return has_new;
}
u8 is_unusual_crash(afl_state_t *afl) {
if (unlikely(!afl->shm.unusual_mode)) { return 0; }
u64 *current_begin = (u64 *)afl->shm.unusual->map;
u64 *current = current_begin;
u64 *current_end =
(u64 *)(afl->shm.unusual->map + sizeof(afl->shm.unusual->map));
u64 *virgin = (u64 *)afl->shm.unusual->crash;
u8 has_new = 0;
for (; current < current_end; virgin += 8, current += 8) {
\
#define UNROLL(idx) \
if (current[idx] & virgin[idx]) { \
\
has_new = 1; \
virgin[idx] &= ~current[idx]; \
\
}
UNROLL(0)
UNROLL(1)
UNROLL(2)
UNROLL(3)
UNROLL(4)
UNROLL(5)
UNROLL(6)
UNROLL(7)
#undef UNROLL
}
return has_new;
}
/* Check if the result of an execve() during routine fuzzing is interesting,
save or queue the input test case for further analysis if so. Returns 1 if
entry is saved, 0 otherwise. */
u8 __attribute__((hot))
save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) {
save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault,
u8 check_unusual) {
if (unlikely(len == 0)) { return 0; }
@ -488,6 +578,13 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) {
new_bits = has_new_bits_unclassified(afl, afl->virgin_bits);
if (check_unusual && is_unusual(afl)) {
if (!new_bits) classify_counts(&afl->fsrv);
new_bits += 3;
}
if (likely(!new_bits)) {
if (unlikely(afl->crash_mode)) { ++afl->total_crashes; }
@ -550,6 +647,12 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) {
++afl->queued_with_cov;
}
if (new_bits >= 3) {
afl->queue_top->has_unusual = 1;
}
if (cksum)
afl->queue_top->exec_cksum = cksum;
@ -705,7 +808,13 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) {
simplify_trace(afl, afl->fsrv.trace_bits);
if (!has_new_bits(afl, afl->virgin_crash)) { return keeping; }
u8 has_new = has_new_bits(afl, afl->virgin_crash);
if (!has_new && check_unusual && is_unusual_crash(afl)) has_new = 1;
// if (!has_new_bits(afl, afl->virgin_crash)) { return keeping; }
if (!has_new) { return keeping; }
}
@ -768,7 +877,7 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) {
}
afl->last_crash_time = get_cur_time();
afl->last_crash_execs = afl->fsrv.total_execs;
afl->last_crash_execs = total_execs_all(afl);
break;

View File

@ -620,7 +620,7 @@ void read_foreign_testcases(afl_state_t *afl, int first) {
fault = fuzz_run_target(afl, &afl->fsrv, afl->fsrv.exec_tmout);
afl->syncing_party = foreign_name;
afl->queued_imported +=
save_if_interesting(afl, mem, st.st_size, fault);
save_if_interesting(afl, mem, st.st_size, fault, 0);
afl->syncing_party = 0;
munmap(mem, st.st_size);
close(fd);

View File

@ -504,7 +504,7 @@ u8 fuzz_one_original(afl_state_t *afl) {
************/
if (unlikely(!afl->non_instrumented_mode && !afl->queue_cur->trim_done &&
!afl->disable_trim)) {
!afl->disable_trim && !afl->queue_cur->has_unusual)) {
u32 old_len = afl->queue_cur->len;
@ -549,6 +549,18 @@ u8 fuzz_one_original(afl_state_t *afl) {
if (unlikely(perf_score <= 0)) { goto abandon_entry; }
// Unusual learning phase
/*if (afl->shm.unusual_mode) {
afl->shm.unusual->learning = 1;
common_fuzz_unusual_stuff(afl, out_buf, len);
afl->shm.unusual->learning = 0;
}*/
if (unlikely(afl->shm.cmplog_mode &&
afl->queue_cur->colorized < afl->cmplog_lvl &&
(u32)len <= afl->cmplog_max_filesize)) {
@ -562,7 +574,7 @@ u8 fuzz_one_original(afl_state_t *afl) {
if (afl->cmplog_lvl == 3 ||
(afl->cmplog_lvl == 2 && afl->queue_cur->tc_ref) ||
afl->queue_cur->favored ||
!(afl->fsrv.total_execs % afl->queued_paths) ||
!(total_execs_all(afl) % afl->queued_paths) ||
get_cur_time() - afl->last_path_time > 300000) { // 300 seconds
if (input_to_state_stage(afl, in_buf, out_buf, len)) {
@ -3004,7 +3016,7 @@ static u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) {
************/
if (unlikely(!afl->non_instrumented_mode && !afl->queue_cur->trim_done &&
!afl->disable_trim)) {
!afl->disable_trim && !afl->queue_cur->has_unusual)) {
u32 old_len = afl->queue_cur->len;
@ -3060,7 +3072,7 @@ static u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) {
if (afl->cmplog_lvl == 3 ||
(afl->cmplog_lvl == 2 && afl->queue_cur->tc_ref) ||
!(afl->fsrv.total_execs % afl->queued_paths) ||
!(total_execs_all(afl) % afl->queued_paths) ||
get_cur_time() - afl->last_path_time > 300000) { // 300 seconds
if (input_to_state_stage(afl, in_buf, out_buf, len)) {

View File

@ -23,6 +23,7 @@
*/
#include "afl-fuzz.h"
#include "unusual.h"
#include <limits.h>
#include <ctype.h>
#include <math.h>
@ -550,6 +551,23 @@ void update_bitmap_score(afl_state_t *afl, struct queue_entry *q) {
}
if (afl->shm.unusual_mode && !afl->shm.unusual->learning) {
for (i = 0; i < UNUSUAL_MAP_SIZE; i++) {
if (afl->unusual_item_changed[i]) {
/* Insert ourselves as the new winner. */
afl->top_rated_unusual[i] = q;
afl->score_changed = 1;
afl->unusual_item_changed[i] = 0;
}
}
}
/* For every byte set in afl->fsrv.trace_bits[], see if there is a previous
winner, and how it compares to us. */
for (i = 0; i < afl->fsrv.map_size; ++i) {
@ -663,6 +681,31 @@ void cull_queue(afl_state_t *afl) {
}
if (afl->shm.unusual_mode) {
for (i = 0; i < UNUSUAL_MAP_SIZE; i++) {
if (afl->top_rated_unusual[i]) {
/* if top rated for any i, will be favored */
u8 was_favored_already = afl->top_rated_unusual[i]->favored;
afl->top_rated_unusual[i]->favored = 1;
/* increments counts only if not also favored for another i */
if (!was_favored_already) {
afl->queued_favored++;
if (!afl->top_rated_unusual[i]->was_fuzzed) afl->pending_favored++;
}
}
}
}
/* Let's see if anything in the bitmap isn't captured in temp_v.
If yes, and if it has a afl->top_rated[] contender, let's use it. */
@ -956,7 +999,7 @@ u32 calculate_score(afl_state_t *afl, struct queue_entry *q) {
// the more often fuzz result paths are equal to this queue entry,
// reduce its value
perf_score *= (1 - (double)((double)afl->n_fuzz[q->n_fuzz_entry] /
(double)afl->fsrv.total_execs));
(double)total_execs_all(afl)));
break;

View File

@ -2563,10 +2563,10 @@ u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len) {
// Start insertion loop
u64 orig_hit_cnt, new_hit_cnt;
u64 orig_execs = afl->fsrv.total_execs;
u64 orig_execs = total_execs_all(afl);
orig_hit_cnt = afl->queued_paths + afl->unique_crashes;
u64 screen_update = 100000 / afl->queue_cur->exec_us,
execs = afl->fsrv.total_execs;
execs = total_execs_all(afl);
afl->stage_name = "input-to-state";
afl->stage_short = "its";
@ -2646,9 +2646,9 @@ u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len) {
}
if (afl->fsrv.total_execs - execs > screen_update) {
if (total_execs_all(afl) - execs > screen_update) {
execs = afl->fsrv.total_execs;
execs = total_execs_all(afl);
show_stats(afl);
}
@ -2750,7 +2750,7 @@ exit_its:
new_hit_cnt = afl->queued_paths + afl->unique_crashes;
afl->stage_finds[STAGE_ITS] += new_hit_cnt - orig_hit_cnt;
afl->stage_cycles[STAGE_ITS] += afl->fsrv.total_execs - orig_execs;
afl->stage_cycles[STAGE_ITS] += total_execs_all(afl) - orig_execs;
#if defined(_DEBUG) || defined(CMPLOG_INTROSPECTION)
FILE *f = stderr;

View File

@ -351,6 +351,31 @@ u8 calibrate_case(afl_state_t *afl, struct queue_entry *q, u8 *use_mem,
}
if (afl->shm.unusual_mode /*&& afl->shm.unusual->learning*/) {
afl->shm.unusual->learning = 1;
write_to_testcase(afl, use_mem, q->len);
fuzz_run_target(afl, &afl->unusual_fsrv, use_tmout);
afl->shm.unusual->learning = 0;
/* afl->stop_soon is set by the handler for Ctrl+C. When it's pressed,
we want to bail out quickly. */
if (afl->stop_soon || fault != afl->crash_mode) { goto abort_calibration; }
if (!afl->non_instrumented_mode && !afl->stage_cur &&
!count_bytes(afl, afl->unusual_fsrv.trace_bits)) {
fault = FSRV_RUN_NOINST;
goto abort_calibration;
}
}
start_us = get_cur_time_us();
for (afl->stage_cur = 0; afl->stage_cur < afl->stage_max; ++afl->stage_cur) {
@ -654,13 +679,17 @@ void sync_fuzzers(afl_state_t *afl) {
write_to_testcase(afl, mem, st.st_size);
fault = fuzz_run_target(afl, &afl->fsrv, afl->fsrv.exec_tmout);
if (afl->shm.unusual_mode && afl->shm.unusual->learning)
fault =
fuzz_run_target(afl, &afl->unusual_fsrv, afl->fsrv.exec_tmout);
else
fault = fuzz_run_target(afl, &afl->fsrv, afl->fsrv.exec_tmout);
if (afl->stop_soon) { goto close_sync; }
afl->syncing_party = sd_ent->d_name;
afl->queued_imported +=
save_if_interesting(afl, mem, st.st_size, fault);
save_if_interesting(afl, mem, st.st_size, fault, 0);
afl->syncing_party = 0;
munmap(mem, st.st_size);
@ -895,6 +924,10 @@ common_fuzz_stuff(afl_state_t *afl, u8 *out_buf, u32 len) {
u8 fault;
//if (afl->shm.unusual_mode && afl->shm.unusual->learning == 0)
if (afl->shm.unusual_mode && rand_below(afl, 16) == 0)
return common_fuzz_unusual_stuff(afl, out_buf, len);
write_to_testcase(afl, out_buf, len);
fault = fuzz_run_target(afl, &afl->fsrv, afl->fsrv.exec_tmout);
@ -929,7 +962,7 @@ common_fuzz_stuff(afl_state_t *afl, u8 *out_buf, u32 len) {
/* This handles FAULT_ERROR for us: */
afl->queued_discovered += save_if_interesting(afl, out_buf, len, fault);
afl->queued_discovered += save_if_interesting(afl, out_buf, len, fault, 0);
if (!(afl->stage_cur % afl->stats_update_freq) ||
afl->stage_cur + 1 == afl->stage_max) {

View File

@ -24,6 +24,7 @@
*/
#include "afl-fuzz.h"
#include "unusual.h"
#include "envs.h"
s8 interesting_8[] = {INTERESTING_8};
@ -119,6 +120,8 @@ void afl_state_init(afl_state_t *afl, uint32_t map_size) {
afl->virgin_crash = ck_alloc(map_size);
afl->var_bytes = ck_alloc(map_size);
afl->top_rated = ck_alloc(map_size * sizeof(void *));
afl->top_rated_unusual = ck_alloc(UNUSUAL_MAP_SIZE * sizeof(void *));
afl->unusual_item_changed = ck_alloc(UNUSUAL_MAP_SIZE);
afl->clean_trace = ck_alloc(map_size);
afl->clean_trace_custom = ck_alloc(map_size);
afl->first_trace = ck_alloc(map_size);
@ -555,6 +558,8 @@ void afl_state_deinit(afl_state_t *afl) {
ck_free(afl->virgin_crash);
ck_free(afl->var_bytes);
ck_free(afl->top_rated);
ck_free(afl->top_rated_unusual);
ck_free(afl->unusual_item_changed);
ck_free(afl->clean_trace);
ck_free(afl->clean_trace_custom);
ck_free(afl->first_trace);

View File

@ -221,9 +221,9 @@ void write_stats_file(afl_state_t *afl, u32 t_bytes, double bitmap_cvg,
cur_time - afl->last_avg_exec_update >= 60000))) {
afl->last_avg_execs_saved =
(double)(1000 * (afl->fsrv.total_execs - afl->last_avg_execs)) /
(double)(1000 * (total_execs_all(afl) - afl->last_avg_execs)) /
(double)(cur_time - afl->last_avg_exec_update);
afl->last_avg_execs = afl->fsrv.total_execs;
afl->last_avg_execs = total_execs_all(afl);
afl->last_avg_exec_update = cur_time;
}
@ -277,8 +277,8 @@ void write_stats_file(afl_state_t *afl, u32 t_bytes, double bitmap_cvg,
(afl->start_time - afl->prev_run_time) / 1000, cur_time / 1000,
(afl->prev_run_time + cur_time - afl->start_time) / 1000,
(u32)getpid(), afl->queue_cycle ? (afl->queue_cycle - 1) : 0,
afl->cycles_wo_finds, afl->fsrv.total_execs,
afl->fsrv.total_execs /
afl->cycles_wo_finds, total_execs_all(afl),
total_execs_all(afl) /
((double)(afl->prev_run_time + get_cur_time() - afl->start_time) /
1000),
afl->last_avg_execs_saved, afl->queued_paths, afl->queued_favored,
@ -287,7 +287,7 @@ void write_stats_file(afl_state_t *afl, u32 t_bytes, double bitmap_cvg,
afl->queued_variable, stability, bitmap_cvg, afl->unique_crashes,
afl->unique_hangs, afl->last_path_time / 1000,
afl->last_crash_time / 1000, afl->last_hang_time / 1000,
afl->fsrv.total_execs - afl->last_crash_execs, afl->fsrv.exec_tmout,
total_execs_all(afl) - afl->last_crash_execs, afl->fsrv.exec_tmout,
afl->slowest_exec_ms,
#ifndef __HAIKU__
#ifdef __APPLE__
@ -367,7 +367,7 @@ void maybe_update_plot_file(afl_state_t *afl, u32 t_bytes, double bitmap_cvg,
afl->plot_prev_uc == afl->unique_crashes &&
afl->plot_prev_uh == afl->unique_hangs &&
afl->plot_prev_md == afl->max_depth &&
afl->plot_prev_ed == afl->fsrv.total_execs) ||
afl->plot_prev_ed == total_execs_all(afl)) ||
!afl->queue_cycle ||
get_cur_time() - afl->start_time <= 60000))) {
@ -383,7 +383,7 @@ void maybe_update_plot_file(afl_state_t *afl, u32 t_bytes, double bitmap_cvg,
afl->plot_prev_uc = afl->unique_crashes;
afl->plot_prev_uh = afl->unique_hangs;
afl->plot_prev_md = afl->max_depth;
afl->plot_prev_ed = afl->fsrv.total_execs;
afl->plot_prev_ed = total_execs_all(afl);
/* Fields in the file:
@ -451,7 +451,7 @@ void show_stats(afl_state_t *afl) {
if (afl->most_execs_key == 1) {
if (afl->most_execs <= afl->fsrv.total_execs) {
if (afl->most_execs <= total_execs_all(afl)) {
afl->most_execs_key = 2;
afl->stop_soon = 2;
@ -479,7 +479,7 @@ void show_stats(afl_state_t *afl) {
if (likely(cur_ms != afl->start_time)) {
afl->stats_avg_exec = ((double)afl->fsrv.total_execs) * 1000 /
afl->stats_avg_exec = ((double)total_execs_all(afl)) * 1000 /
(afl->prev_run_time + cur_ms - afl->start_time);
}
@ -489,7 +489,7 @@ void show_stats(afl_state_t *afl) {
if (likely(cur_ms != afl->stats_last_ms)) {
double cur_avg =
((double)(afl->fsrv.total_execs - afl->stats_last_execs)) * 1000 /
((double)(total_execs_all(afl) - afl->stats_last_execs)) * 1000 /
(cur_ms - afl->stats_last_ms);
/* If there is a dramatic (5x+) jump in speed, reset the indicator
@ -510,7 +510,7 @@ void show_stats(afl_state_t *afl) {
}
afl->stats_last_ms = cur_ms;
afl->stats_last_execs = afl->fsrv.total_execs;
afl->stats_last_execs = total_execs_all(afl);
/* Tell the callers when to contact us (as measured in execs). */
@ -518,6 +518,29 @@ void show_stats(afl_state_t *afl) {
if (!afl->stats_update_freq) { afl->stats_update_freq = 1; }
/* Do some bitmap stats. */
u32 t_unusual_bits = 0, t_unusual_fav = 0;
double t_unusual_ratio = 0.0;
double t_unusual_fav_ratio = 0.0;
if (afl->shm.unusual_mode) {
u64 *current_begin = (u64 *)afl->shm.unusual->virgin;
u64 *current = current_begin;
u64 *current_end =
(u64 *)(afl->shm.unusual->virgin + sizeof(afl->shm.unusual->virgin));
for (; current < current_end; current += 8) {
t_unusual_bits += __builtin_popcountll(~(long long)*current);
}
t_unusual_ratio = ((double)t_unusual_bits * 100) / UNUSUAL_MAP_SIZE;
u32 i;
for (i = 0; i < UNUSUAL_MAP_SIZE; i++) {
if (afl->top_rated_unusual[i]) ++t_unusual_fav;
}
t_unusual_fav_ratio = ((double)t_unusual_fav * 100) / UNUSUAL_MAP_SIZE;
}
t_bytes = count_non_255_bytes(afl, afl->virgin_bits);
t_byte_ratio = ((double)t_bytes * 100) / afl->fsrv.map_size;
@ -635,17 +658,26 @@ void show_stats(afl_state_t *afl) {
banner_pad = (79 - banner_len) / 2;
memset(tmp, ' ', banner_pad);
char *learning_str = "", *learning_pad = " ";
if (afl->shm.unusual_mode && afl->shm.unusual->learning) {
learning_str = ", learning";
learning_pad = "";
}
#ifdef HAVE_AFFINITY
sprintf(
tmp + banner_pad,
"%s " cLCY VERSION cLGN " (%s) " cPIN "[%s]" cBLU " {%d}",
"%s " cLCY VERSION cLGN " (%s) " cPIN "[%s%s]" cBLU " {%d}%s",
afl->crash_mode ? cPIN "peruvian were-rabbit" : cYEL "american fuzzy lop",
afl->use_banner, afl->power_name, afl->cpu_aff);
afl->use_banner, afl->power_name, learning_str, afl->cpu_aff,
learning_pad);
#else
sprintf(
tmp + banner_pad, "%s " cLCY VERSION cLGN " (%s) " cPIN "[%s]",
tmp + banner_pad, "%s " cLCY VERSION cLGN " (%s) " cPIN "[%s%s]%s",
afl->crash_mode ? cPIN "peruvian were-rabbit" : cYEL "american fuzzy lop",
afl->use_banner, afl->power_name);
afl->use_banner, afl->power_name, learning_str, learning_pad);
#endif /* HAVE_AFFINITY */
SAYF("\n%s\n", tmp);
@ -780,9 +812,9 @@ void show_stats(afl_state_t *afl) {
SAYF(bV bSTOP " now processing : " cRST "%-16s " bSTG bV bSTOP, tmp);
sprintf(tmp, "%0.02f%% / %0.02f%%",
sprintf(tmp, "%0.02f%% / %0.02f%% - %0.02f%% %0.02f%%",
((double)afl->queue_cur->bitmap_size) * 100 / afl->fsrv.map_size,
t_byte_ratio);
t_byte_ratio, t_unusual_ratio, t_unusual_fav_ratio);
SAYF(" map density : %s%-21s" bSTG bV "\n",
t_byte_ratio > 70
@ -839,13 +871,13 @@ void show_stats(afl_state_t *afl) {
SAYF(bV bSTOP " total execs : " cRST "%-20s " bSTG bV bSTOP
" new crashes : %s%-22s" bSTG bV "\n",
u_stringify_int(IB(0), afl->fsrv.total_execs), crash_color, tmp);
u_stringify_int(IB(0), total_execs_all(afl)), crash_color, tmp);
} else {
SAYF(bV bSTOP " total execs : " cRST "%-20s " bSTG bV bSTOP
" total crashes : %s%-22s" bSTG bV "\n",
u_stringify_int(IB(0), afl->fsrv.total_execs), crash_color, tmp);
u_stringify_int(IB(0), total_execs_all(afl)), crash_color, tmp);
}

View File

@ -234,8 +234,8 @@ int statsd_format_metric(afl_state_t *afl, char *buff, size_t bufflen) {
snprintf(
buff, bufflen, afl->statsd_metric_format,
afl->queue_cycle ? (afl->queue_cycle - 1) : 0, tags,
afl->cycles_wo_finds, tags, afl->fsrv.total_execs, tags,
afl->fsrv.total_execs /
afl->cycles_wo_finds, tags, total_execs_all(afl), tags,
total_execs_all(afl) /
((double)(get_cur_time() + afl->prev_run_time - afl->start_time) /
1000),
tags, afl->queued_paths, tags, afl->queued_favored, tags,
@ -252,8 +252,8 @@ int statsd_format_metric(afl_state_t *afl, char *buff, size_t bufflen) {
snprintf(
buff, bufflen, afl->statsd_metric_format, tags,
afl->queue_cycle ? (afl->queue_cycle - 1) : 0, tags,
afl->cycles_wo_finds, tags, afl->fsrv.total_execs, tags,
afl->fsrv.total_execs /
afl->cycles_wo_finds, tags, total_execs_all(afl), tags,
total_execs_all(afl) /
((double)(get_cur_time() + afl->prev_run_time - afl->start_time) /
1000),
tags, afl->queued_paths, tags, afl->queued_favored, tags,

101
src/afl-fuzz-unusual.c Normal file
View File

@ -0,0 +1,101 @@
/*
american fuzzy lop++ - unusual execution routines
-------------------------------------------------
Originally written by Michal Zalewski
Forkserver design by Jann Horn <jannhorn@googlemail.com>
Now maintained by by Marc Heuse <mh@mh-sec.de>,
Heiko Eißfeldt <heiko.eissfeldt@hexco.de> and
Andrea Fioraldi <andreafioraldi@gmail.com>
Copyright 2016, 2017 Google Inc. All rights reserved.
Copyright 2019-2020 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:
http://www.apache.org/licenses/LICENSE-2.0
Shared code to handle the shared memory. This is used by the fuzzer
as well the other components like afl-tmin, afl-showmap, etc...
*/
#include <sys/select.h>
#include "afl-fuzz.h"
void unusual_exec_child(afl_forkserver_t *fsrv, char **argv) {
setenv("___AFL_DREI_VIER_GRENADIER___", "1", 1);
if (fsrv->qemu_mode) { setenv("AFL_DISABLE_LLVM_INSTRUMENTATION", "1", 0); }
if (!fsrv->qemu_mode && !fsrv->frida_mode &&
argv[0] != fsrv->unusual_binary) {
argv[0] = fsrv->unusual_binary;
}
execv(argv[0], argv);
}
u8 common_fuzz_unusual_stuff(afl_state_t *afl, u8 *out_buf, u32 len) {
u8 fault;
unusual_values_state_reset(afl->shm.unusual);
write_to_testcase(afl, out_buf, len);
fault = fuzz_run_target(afl, &afl->unusual_fsrv, afl->fsrv.exec_tmout);
if (afl->stop_soon) { return 1; }
if (fault == FSRV_RUN_TMOUT) {
if (afl->subseq_tmouts++ > TMOUT_LIMIT) {
++afl->cur_skipped_paths;
return 1;
}
} else {
afl->subseq_tmouts = 0;
}
/* Users can hit us with SIGUSR1 to request the current input
to be abandoned. */
if (afl->skip_requested) {
afl->skip_requested = 0;
++afl->cur_skipped_paths;
return 1;
}
/* This handles FAULT_ERROR for us: */
afl->queued_discovered += save_if_interesting(afl, out_buf, len, fault,
!afl->shm.unusual->learning);
if (!(afl->stage_cur % afl->stats_update_freq) ||
afl->stage_cur + 1 == afl->stage_max) {
show_stats(afl);
}
return 0;
}

View File

@ -25,6 +25,7 @@
#include "afl-fuzz.h"
#include "cmplog.h"
#include "unusual.h"
#include <limits.h>
#include <stdlib.h>
#ifndef USEMMAP
@ -46,7 +47,8 @@ extern u64 time_spent_working;
static void at_exit() {
s32 i, pid1 = 0, pid2 = 0;
char *list[4] = {SHM_ENV_VAR, SHM_FUZZ_ENV_VAR, CMPLOG_SHM_ENV_VAR, NULL};
char *list[] = {SHM_ENV_VAR, SHM_FUZZ_ENV_VAR, CMPLOG_SHM_ENV_VAR,
UNUSUAL_SHM_ENV_VAR, NULL};
char *ptr;
ptr = getenv(CPU_AFFINITY_ENV_VAR);
@ -433,7 +435,8 @@ int main(int argc, char **argv_orig, char **envp) {
while ((opt = getopt(
argc, argv,
"+b:B:c:CdDe:E:hi:I:f:F:l:L:m:M:nNOo:p:RQs:S:t:T:UV:Wx:Z")) > 0) {
"+b:B:c:u:CdDe:E:hi:I:f:F:l:L:m:M:nNOo:p:RQs:S:t:T:UV:Wx:Z")) >
0) {
switch (opt) {
@ -467,6 +470,14 @@ int main(int argc, char **argv_orig, char **envp) {
}
case 'u': {
afl->shm.unusual_mode = 1;
afl->unusual_binary = ck_strdup(optarg);
break;
}
case 's': {
if (optarg == NULL) { FATAL("No valid seed provided. Got NULL."); }
@ -1658,6 +1669,20 @@ int main(int argc, char **argv_orig, char **envp) {
}
if (afl->unusual_binary) {
if (afl->unicorn_mode || afl->fsrv.qemu_mode || afl->fsrv.frida_mode) {
FATAL(
"CmpLog and Unicorn/QEMU/Frida mode are not compatible at the "
"moment, sorry");
}
if (!afl->non_instrumented_mode) { check_binary(afl, afl->unusual_binary); }
}
check_binary(afl, argv[optind]);
#ifdef AFL_PERSISTENT_RECORD
@ -1836,6 +1861,84 @@ int main(int argc, char **argv_orig, char **envp) {
}
if (afl->unusual_binary) {
ACTF("Spawning unusual forkserver");
afl_fsrv_init_dup(&afl->unusual_fsrv, &afl->fsrv);
// TODO: this is semi-nice
afl->unusual_fsrv.trace_bits = afl->fsrv.trace_bits;
afl->unusual_fsrv.qemu_mode = afl->fsrv.qemu_mode;
afl->unusual_fsrv.frida_mode = afl->fsrv.frida_mode;
afl->unusual_fsrv.unusual_binary = afl->unusual_binary;
afl->unusual_fsrv.init_child_func = unusual_exec_child;
if ((map_size <= DEFAULT_SHMEM_SIZE ||
afl->unusual_fsrv.map_size < map_size) &&
!afl->non_instrumented_mode && !afl->fsrv.qemu_mode &&
!afl->fsrv.frida_mode && !afl->unicorn_mode &&
!afl->afl_env.afl_skip_bin_check) {
afl->unusual_fsrv.map_size = MAX(map_size, (u32)DEFAULT_SHMEM_SIZE);
char vbuf[16];
snprintf(vbuf, sizeof(vbuf), "%u", afl->unusual_fsrv.map_size);
setenv("AFL_MAP_SIZE", vbuf, 1);
}
u32 new_map_size =
afl_fsrv_get_mapsize(&afl->unusual_fsrv, afl->argv, &afl->stop_soon,
afl->afl_env.afl_debug_child);
// only reinitialize when it needs to be larger
if (map_size < new_map_size) {
OKF("Re-initializing maps to %u bytes due unusual", new_map_size);
afl->virgin_bits = ck_realloc(afl->virgin_bits, new_map_size);
afl->virgin_tmout = ck_realloc(afl->virgin_tmout, new_map_size);
afl->virgin_crash = ck_realloc(afl->virgin_crash, new_map_size);
afl->var_bytes = ck_realloc(afl->var_bytes, new_map_size);
afl->top_rated =
ck_realloc(afl->top_rated, new_map_size * sizeof(void *));
afl->clean_trace = ck_realloc(afl->clean_trace, new_map_size);
afl->clean_trace_custom =
ck_realloc(afl->clean_trace_custom, new_map_size);
afl->first_trace = ck_realloc(afl->first_trace, new_map_size);
afl->map_tmp_buf = ck_realloc(afl->map_tmp_buf, new_map_size);
afl_fsrv_kill(&afl->fsrv);
if (afl->cmplog_binary) afl_fsrv_kill(&afl->cmplog_fsrv);
afl_fsrv_kill(&afl->unusual_fsrv);
afl_shm_deinit(&afl->shm);
afl->unusual_fsrv.map_size = new_map_size; // non-unusual stays the same
map_size = new_map_size;
setenv("AFL_NO_AUTODICT", "1", 1); // loaded already
afl->fsrv.trace_bits =
afl_shm_init(&afl->shm, new_map_size, afl->non_instrumented_mode);
if (afl->cmplog_binary)
afl->cmplog_fsrv.trace_bits = afl->fsrv.trace_bits;
afl->unusual_fsrv.trace_bits = afl->fsrv.trace_bits;
afl_fsrv_start(&afl->fsrv, afl->argv, &afl->stop_soon,
afl->afl_env.afl_debug_child);
if (afl->cmplog_binary) {
afl_fsrv_start(&afl->cmplog_fsrv, afl->argv, &afl->stop_soon,
afl->afl_env.afl_debug_child);
}
afl_fsrv_start(&afl->unusual_fsrv, afl->argv, &afl->stop_soon,
afl->afl_env.afl_debug_child);
}
OKF("Unusual forkserver successfully started");
// afl->shm.unusual->learning = 1;
}
load_auto(afl);
if (extras_dir_cnt) {
@ -1866,8 +1969,12 @@ int main(int argc, char **argv_orig, char **envp) {
memset(afl->virgin_tmout, 255, map_size);
memset(afl->virgin_crash, 255, map_size);
//if (afl->shm.unusual_mode) afl->shm.unusual->learning = 1;
perform_dry_run(afl);
//if (afl->shm.unusual_mode) afl->shm.unusual->learning = 0;
if (afl->q_testcase_max_cache_entries) {
@ -1956,6 +2063,14 @@ int main(int argc, char **argv_orig, char **envp) {
OKF("Writing mutation introspection to '%s'", ifn);
#endif
/*if (getenv("AFL_SKIP_START_LEARNING") && afl->shm.unusual_mode) {
afl->shm.unusual->learning = 0;
}*/
afl->clear_screen = 1;
show_stats(afl);
while (likely(!afl->stop_soon)) {
cull_queue(afl);
@ -1972,6 +2087,23 @@ int main(int argc, char **argv_orig, char **envp) {
}
// Set learning with a given probability
// TODO find a better policy
/*if (afl->queue_cycle && afl->shm.unusual_mode) {
afl->shm.unusual->learning = rand_below(afl, 4) == 0;
afl->clear_screen = 1;
}*/
/*if (afl->shm.unusual_mode && afl->queue_cycle) {
u8 prev_learning = afl->shm.unusual->learning;
afl->shm.unusual->learning = !prev_learning;
afl->clear_screen = 1;
}*/
++afl->queue_cycle;
runs_in_current_cycle = (u32)-1;
afl->cur_skipped_paths = 0;
@ -2022,6 +2154,20 @@ int main(int argc, char **argv_orig, char **envp) {
3600 */
)) {
/*if (afl->shm.unusual_mode) {
afl->shm.unusual->learning = !afl->shm.unusual->learning;
afl->clear_screen = 1;
}*/
/*if (afl->shm.unusual_mode && !prev_learning) {
afl->shm.unusual->learning = 1;
afl->clear_screen = 1;
}*/
if (afl->use_splicing) {
++afl->cycles_wo_finds;
@ -2265,8 +2411,7 @@ stop_fuzzing:
#ifdef PROFILING
SAYF(cYEL "[!] " cRST
"Profiling information: %llu ms total work, %llu ns/run\n",
time_spent_working / 1000000,
time_spent_working / afl->fsrv.total_execs);
time_spent_working / 1000000, time_spent_working / total_execs_all(afl));
#endif
if (afl->is_main_node) {
@ -2293,6 +2438,8 @@ stop_fuzzing:
}
afl_fsrv_deinit(&afl->fsrv);
if (afl->cmplog_binary) afl_fsrv_deinit(&afl->cmplog_fsrv);
if (afl->unusual_binary) afl_fsrv_deinit(&afl->unusual_fsrv);
/* remove tmpfile */
if (afl->tmp_dir != NULL && !afl->in_place_resume && afl->fsrv.out_file) {

View File

@ -36,6 +36,7 @@
#include "hash.h"
#include "sharedmem.h"
#include "cmplog.h"
#include "unusual.h"
#include "list.h"
#include <stdio.h>
@ -130,6 +131,7 @@ void afl_shm_deinit(sharedmem_t *shm) {
#else
shmctl(shm->shm_id, IPC_RMID, NULL);
if (shm->cmplog_mode) { shmctl(shm->cmplog_shm_id, IPC_RMID, NULL); }
shmctl(shm->unusual_shm_id, IPC_RMID, NULL);
#endif
shm->map = NULL;
@ -260,6 +262,28 @@ u8 *afl_shm_init(sharedmem_t *shm, size_t map_size,
}
if (shm->unusual_mode) {
shm->unusual_shm_id =
shmget(IPC_PRIVATE, sizeof(struct unusual_values_state),
IPC_CREAT | IPC_EXCL | DEFAULT_PERMISSION);
if (shm->unusual_shm_id < 0) {
shmctl(shm->shm_id, IPC_RMID, NULL); // do not leak shmem
if (shm->cmplog_mode) {
shmctl(shm->cmplog_shm_id, IPC_RMID, NULL); // do not leak shmem
}
PFATAL("shmget() failed");
}
}
if (!non_instrumented_mode) {
shm_str = alloc_printf("%d", shm->shm_id);
@ -285,6 +309,16 @@ u8 *afl_shm_init(sharedmem_t *shm, size_t map_size,
}
if (shm->unusual_mode && !non_instrumented_mode) {
shm_str = alloc_printf("%d", shm->unusual_shm_id);
setenv(UNUSUAL_SHM_ENV_VAR, shm_str, 1);
ck_free(shm_str);
}
shm->map = shmat(shm->shm_id, NULL, 0);
if (shm->map == (void *)-1 || !shm->map) {
@ -297,6 +331,12 @@ u8 *afl_shm_init(sharedmem_t *shm, size_t map_size,
}
if (shm->unusual_mode) {
shmctl(shm->unusual_shm_id, IPC_RMID, NULL); // do not leak shmem
}
PFATAL("shmat() failed");
}
@ -311,12 +351,42 @@ u8 *afl_shm_init(sharedmem_t *shm, size_t map_size,
shmctl(shm->cmplog_shm_id, IPC_RMID, NULL); // do not leak shmem
if (shm->unusual_mode) {
shmctl(shm->unusual_shm_id, IPC_RMID, NULL); // do not leak shmem
}
PFATAL("shmat() failed");
}
}
if (shm->unusual_mode) {
shm->unusual = shmat(shm->unusual_shm_id, NULL, 0);
if (shm->unusual == (void *)-1 || !shm->unusual) {
shmctl(shm->shm_id, IPC_RMID, NULL); // do not leak shmem
if (shm->cmplog_mode) {
shmctl(shm->cmplog_shm_id, IPC_RMID, NULL); // do not leak shmem
}
shmctl(shm->unusual_shm_id, IPC_RMID, NULL); // do not leak shmem
PFATAL("shmat() failed");
}
unusual_values_state_init(shm->unusual);
}
#endif
shm->map_size = map_size;