Compare commits

...

76 Commits

Author SHA1 Message Date
1d17210d9f Merge pull request #2052 from AFLplusplus/dev
4.20 release pre-PR
2024-04-13 11:50:49 +02:00
1582aa9da2 Merge pull request #2027 from choller/nyx-handler-fix
Add optional handling of Nyx InvalidWriteToPayload event
2024-04-13 11:40:28 +02:00
e01307a993 v4.20c 2024-04-13 11:39:26 +02:00
beb9f95359 Merge pull request #2051 from Phasip/patch-1
Clarify that oss-fuzz doesn't randomize builds anymore
2024-04-12 11:07:33 +02:00
c49a4c7027 Clarify that oss-fuzz doesn't randomize builds anymore 2024-04-12 09:28:38 +02:00
b08df87f5c fix syncing with custom mutator 2024-04-11 09:40:28 +02:00
72226d6f89 fix shared memory test cases 2024-04-09 16:20:42 +02:00
40adc34413 fix -V, code format 2024-04-09 09:24:19 +02:00
eeae114b76 Merge pull request #2034 from fbeqv/add_effective_fuzzing_time_tracker
Adds stats tracking for time spend actually mutating & running test i…
2024-04-09 09:04:53 +02:00
48a862c503 :Adds stats tracking time spend in calibration/trim/sync
This currently does not affect statsd nor the UI. Only the fuzzer_stats file is updated
2024-04-08 11:54:19 -07:00
29544e4d2b fix time 2024-04-07 18:44:21 +02:00
420a90ff75 code format 2024-04-07 12:53:41 +02:00
45603367bf fix llvm modules 2024-04-07 09:44:33 +02:00
f7ea0f569f fix aflpp custom mutator + standalone tool 2024-04-05 14:53:02 +02:00
2bf92848ff Fixed unicorn_dumper_gdb.py for updated version of gef (#2045)
Updated unicorn_dumper_gdb.py to support new gef api and replaced deprecated functions . The functions that are not in the new gef api are read_memory(), and current_arch(). Also replaced some deprecated functions with the updated versions of them.

    replaced read_memory() with GefMemoryManager.read() as read_memory(). read_memory() is in legacy-gef-api
    replaced current_arch with gef.arch.registers
    replaced get_process_maps() with gef.memory.maps (just depreacated)
    replaced get_register() with gef.arch.register()
2024-04-03 11:57:09 +02:00
ad65cfb400 Merge pull request #2043 from ligurio/ligurio/fix-clock_gettime
src: fix calculation of fuzzing time in statistics
2024-03-31 18:41:26 +07:00
5ffc8c7076 src: fix calculation of fuzzing time in statistics
When the computer is suspended during a fuzzing session,
the time spent in suspended state is counted as a "run time"
on a statistics screen.

The time returned by `gettimeofday(2)` is affected by discontinuous
jumps in the system time. It is better using `clock_gettime(2)`.

The patch replace `gettimeofday` with `clock_gettime` [1].
`clock_gettime` uses a CLOCK_MONOTONIC_COARSE clock type,
it is faster than CLOCK_MONOTONIC, but still has resolution (~1ms)
that is adequate for our purposes. However, CLOCK_MONOTONIC_COARSE
is a Linux-specific clock variant, so on macOS it is replaced
with CLOCK_MONOTONIC, and with CLOCK_MONOTONIC_FAST on FreeBSD [2].

Closes #1241

1. https://pubs.opengroup.org/onlinepubs/9699919799/functions/clock_gettime.html
2. https://man.freebsd.org/cgi/man.cgi?query=clock_gettime
2024-03-31 11:11:29 +03:00
8943ba0249 Merge pull request #2042 from ligurio/patch-1
citation: fix typo
2024-03-28 18:58:02 +07:00
b02adf6b3f citation: fix typo 2024-03-28 12:46:49 +03:00
6ef5d7c135 Merge pull request #2038 from SonicStark/dev-makefile-0322
bugfix: override directive and recipe echoing in GNUmakefile
2024-03-23 16:19:49 +07:00
9ece2e3f2c Merge pull request #2040 from flk0/stable
Fix build_qemu_support.sh static builds
2024-03-23 15:17:42 +07:00
4b2cdaf47c Fix build_qemu_support.sh static builds
The recently added config option 'enable-plugins' breaks static builds of qemuafl. Override the enable for static builds.
2024-03-23 15:39:54 +10:00
9b5b71b61b fix override directive and recipe echoing 2024-03-22 03:24:53 +00:00
59465bd249 Merge pull request #2035 from Resery/patch-6
bugfix: update_firda_version can't get the newest version of frida
2024-03-15 12:57:50 +07:00
ed50f37c79 bugfix: update_firda_version can't get the newest version of frida
The method of getting the newest version of Frida is invalid. Need update.
2024-03-15 12:03:01 +08:00
a96bda82f9 Merge pull request #2033 from gnbon/stable
Add -l option for adjustable block deletion performance in tmin
2024-03-15 08:39:39 +07:00
1860f6e594 Fix invalid range for del_len_limit 2024-03-14 11:00:59 +09:00
c9ad3acc9b Add -l option for adjustable block deletion
- Introduce the -l option to set min block deletion length using
powers of 2 (e.g., 1, 2, 4, 8, 16, ...).
- This enables a trade-off between minimization thoroughness and speed.
- Adjusting del_len_limit allows for faster processing, as doubling it
roughly halves the minimization time.
2024-03-13 12:10:38 +09:00
93c7a42453 Merge pull request #2029 from ocean1/minor_ver_fix
support parsing of llvm rc minor version
2024-03-12 15:30:27 +07:00
=
ee07fc9f6d fix rc minor version parsing 2024-03-12 08:20:08 +00:00
443edcd771 nits 2024-03-12 07:42:16 +01:00
6650ef4274 Merge pull request #2030 from ocean1/replay_loop_fix
Replay record loop fix
2024-03-12 10:08:29 +07:00
b85174fc8d nit 2024-03-12 04:00:19 +01:00
=
08f6d59f50 correct fix 2024-03-11 12:01:06 +00:00
=
2ed2ac80bc fix record compat loop to replay correct number of inputs, and at least one input 2024-03-11 10:30:35 +00:00
=
2300088446 support parsing of llvm rc minor version 2024-03-11 10:12:53 +00:00
306a917956 UI fix 2024-03-07 12:09:22 +01:00
0ea53ea5b5 likely 2024-03-06 12:41:00 +01:00
092260e9f9 Merge pull request #2026 from choller/pcmap_fix2
Fix delayed pcmap writing for code coverage with pc-table
2024-03-06 17:56:24 +07:00
52e19d35fa Add optional handling of Nyx InvalidWriteToPayload event 2024-03-06 10:55:53 +01:00
bf17953353 Code formating 2024-03-06 10:50:29 +01:00
e46fac6063 Fix delayed pcmap writing for code coverage with pc-table 2024-03-06 10:19:52 +01:00
6062668679 fix not using autodict 2024-02-29 14:31:47 +01:00
acc178e5dd log 2024-02-29 14:16:56 +01:00
31adb57fd7 Merge pull request #2014 from seanm/issue2007
Issue #2007: add filename extension to /crashes files
2024-02-29 14:16:07 +01:00
7652406c12 nit 2024-02-29 13:34:04 +01:00
a607adb7a3 Merge pull request #2019 from zidel/fork_server_fix
Load autodictionary when using new forkserver
2024-02-29 09:14:38 +01:00
036a79268b gcc cmplog fix 2024-02-29 09:10:29 +01:00
335b2d4542 Load autodictionary when using new forkserver
Fixes a bug where the new fork server would decrement dict_size until
zero then try to use it as the upper bound for the number of bytes to
pass to add_extra_func, causing it to never store any of the tokens.
2024-02-28 22:29:55 +01:00
603136efa0 unicornafl: Fix dump_regs() type errors in pwndbg dumper (#2005)
* push to stable (#1983)

* Output afl-clang-fast stuffs only if necessary (#1912)

* afl-cc header

* afl-cc common declarations

 - Add afl-cc-state.c
 - Strip includes, find_object, debug/be_quiet/have_*/callname setting from afl-cc.c
 - Use debugf_args in main
 - Modify execvp stuffs to fit new aflcc struct

* afl-cc show usage

* afl-cc mode selecting

1. compiler_mode by callname in argv[0]
2. compiler_mode by env "AFL_CC_COMPILER"
3. compiler_mode/instrument_mode by command line options "--afl-..."
4. instrument_mode/compiler_mode by various env vars including "AFL_LLVM_INSTRUMENT"
5. final checking steps
6. print "... - mode: %s-%s\n"
7. determine real argv[0] according to compiler_mode

* afl-cc macro defs

* afl-cc linking behaviors

* afl-cc fsanitize behaviors

* afl-cc misc

* afl-cc body update

* afl-cc all-in-one

formated with custom-format.py

* nits

---------

Co-authored-by: vanhauser-thc <vh@thc.org>

* changelog

* update grammar mutator

* lto llvm 12+

* docs(custom_mutators): fix missing ':' (#1953)

* Fix broken LTO mode and response file support (#1948)

* Strip `-Wl,-no-undefined` during compilation (#1952)

Make the compiler wrapper stripping `-Wl,-no-undefined` in addition to `-Wl,--no-undefined`.
Both versions of the flag are accepted by clang and, therefore, used by building systems in the wild (e.g., samba will not build without this fix).

* Remove dead code in write_to_testcase (#1955)

The custom_mutators_count check in if case is duplicate with if condition.
The else case is custom_mutators_count == 0, neither custom_mutator_list iteration nor sent check needed.

Signed-off-by: Xeonacid <h.dwwwwww@gmail.com>

* update qemuafl

* WIP: Add ability to generate drcov trace using QEMU backend (#1956)

* Document new drcov QEMU plugin

* Add link to lightkeeper for QEMU drcov file loading

---------

Co-authored-by: Jean-Romain Garnier <jean-romain.garnier@airbus.com>

* code format

* changelog

* sleep on uid != 0 afl-system-config

* fix segv about skip_next, warn on unsupported cases of linking options (#1958)

* todos

* ensure afl-cc only allows available compiler modes

* update grammar mutator

* disable aslr on apple

* fix for arm64

* help selective instrumentation

* typos

* macos

* add compiler test script

* apple fixes

* bump nyx submodules (#1963)

* fix docs

* update changelog

* update grammar mutator

* improve compiler test script

* gcc asan workaround (#1966)

* fix github merge fuckup

* fix

* Fix afl-cc (#1968)

- Check if too many cmdline params here, each time before insert a new param.
 - Check if it is "-fsanitize=..." before we do sth.
 - Remove improper param_st transfer.

* Avoid adding llvmnative instrumentation when linking rust sanitizer runtime (#1969)

* Dynamic instrumentation filtering for LLVM native (#1971)

* Add two dynamic instrumentation filter methods to runtime

* Always use pc-table with native pcguard

* Add make_symbol_list.py and README

* changelog

* todos

* new forkserver check

* fix

* nyx test for CI

* improve nyx docs

* Fixes to afl-cc and documentation (#1974)

* Always compile with -ldl when building for CODE_COVERAGE

When building with CODE_COVERAGE, the afl runtime contains code that
calls `dladdr` which requires -ldl. Under most circumstances, clang
already adds this (e.g. when building with pc-table), but there are some
circumstances where it isn't added automatically.

* Add visibility declaration to __afl_connected

When building with hidden visibility, the use of __AFL_LOOP inside such
code can cause linker errors due to __afl_connected being declared
"hidden".

* Update docs to clarify that CODE_COVERAGE=1 is required for dynamic_covfilter

* nits

* nyx build script updates

* test error output

* debug ci

* debug ci

* Improve afl-cc (#1975)

* update response file support

 - full support of rsp file
 - fix some segv issues

* Improve afl-cc

 - remove dead code about allow/denylist options of sancov
 - missing `if (!aflcc->have_msan)`
 - add docs for each function
 - typo

* enable nyx

* debug ci

* debug ci

* debug ci

* debug ci

* debug ci

* debug ci

* debug ci

* debug ci

* fix ci

* clean test script

* NO_NYX

* NO_NYX

* fix ci

* debug ci

* fix ci

* finalize ci fix

* Enhancement on Deterministic stage (#1972)

* fuzzer: init commit based on aflpp 60dc37a8cf

* fuzzers: adding the skip variables and initialize

* log: profile the det/havoc finding

* log: add profile log output

* fuzzers: sperate log/skipdet module

* fuzzers: add quick eff_map calc

* fuzzers: add skip_eff_map in fuzz_one

* fuzzers: mark whole input space in eff_map

* fuzzers: add undet bit threshold to skip some seeds

* fuzzers: fix one byte overflow

* fuzzers: fix overflow

* fix code format

* add havoc only again

* code format

* remove log to INTROSPECTION, rename skipdet module

* rename skipdet module

* remove log to stats

* clean redundant code

* code format

* remove redundant code format check

* remove redundant doc

* remove redundant objects

* clean files

* change -d to default skipdet

* disable deterministic when using CUSTOM_MUTATOR

* revert fix

* final touches for skipdet

* remove unused var

* remove redundant eff struct (#1977)

* update QEMU-Nyx submodule (#1978)

* update QEMU-Nyx submodule (#1980)

* Fix type in AFL_NOOPT env variable in afl-cc help message (#1982)

* nits

* 2024 v4.10c release

* fixes

---------

Signed-off-by: Xeonacid <h.dwwwwww@gmail.com>
Co-authored-by: Sonic <50692172+SonicStark@users.noreply.github.com>
Co-authored-by: Xeonacid <h.dwwwwww@gmail.com>
Co-authored-by: Nils Bars <nils.bars@rub.de>
Co-authored-by: Jean-Romain Garnier <7504819+JRomainG@users.noreply.github.com>
Co-authored-by: Jean-Romain Garnier <jean-romain.garnier@airbus.com>
Co-authored-by: Sergej Schumilo <sergej@schumilo.de>
Co-authored-by: Christian Holler (:decoder) <choller@mozilla.com>
Co-authored-by: Han Zheng <35988108+kdsjZh@users.noreply.github.com>
Co-authored-by: Khaled Yakdan <yakdan@code-intelligence.com>

* Fix dump_regs() type errors in Python

TypeError will occur as gdb api return some strange type of values that json can't serialize, this would fix this issue

* Update reg_val is None condition

---------

Signed-off-by: Xeonacid <h.dwwwwww@gmail.com>
Co-authored-by: van Hauser <vh@thc.org>
Co-authored-by: Sonic <50692172+SonicStark@users.noreply.github.com>
Co-authored-by: Xeonacid <h.dwwwwww@gmail.com>
Co-authored-by: Nils Bars <nils.bars@rub.de>
Co-authored-by: Jean-Romain Garnier <7504819+JRomainG@users.noreply.github.com>
Co-authored-by: Jean-Romain Garnier <jean-romain.garnier@airbus.com>
Co-authored-by: Sergej Schumilo <sergej@schumilo.de>
Co-authored-by: Christian Holler (:decoder) <choller@mozilla.com>
Co-authored-by: Han Zheng <35988108+kdsjZh@users.noreply.github.com>
Co-authored-by: Khaled Yakdan <yakdan@code-intelligence.com>
2024-02-27 09:46:07 +01:00
1e01ccc8fd unicornafl: Add UAF chcker to loader (#2009)
* impl uaf chcker

By adding a list of freed chunks, add the chunk to the list during free, check whether the allocated block is in the freed chunk list during malloc, and if so, remove the chunk from the freed chunk list, in __check_mem_access check whether the address is in the freed chunk list. This enables the detection of uaf.

* make uaf_check be configruable
2024-02-27 09:43:50 +01:00
9f6d27ddce Merge pull request #2018 from hyrathon/patch-2
Add -ldl flag
2024-02-27 08:57:23 +01:00
8fcd404352 Update GNUmakefile
The linker flags lacks a -ldl so the dlopen series of func symbols can't be found
2024-02-27 15:34:42 +08:00
b2b887d04d Issue #2007: add filename extension to /crashes files
This is very helpful for code that inpects a file name extension when determining what code to run.

It's also useful for applications that constrain the user to choose files by extension.
2024-02-26 14:07:49 -05:00
849994dedd update changelog 2024-02-23 14:09:22 +01:00
1286d1906f Merge pull request #2012 from clesmian/dev
Fix bug where `-t 1000+` may result in enormous timeouts
2024-02-23 13:53:15 +01:00
fae760fc9e Add upper and lower safety margins 2024-02-23 13:39:46 +01:00
01f442d810 Be specific about the unit of time 2024-02-23 12:53:20 +01:00
eaedf2e62f Adhere to documented behavior 2024-02-23 12:52:11 +01:00
07e0b39126 Do not circumvent sanity checks from arg parsing 2024-02-22 15:55:18 +01:00
98238ed763 Convert from microseconds (us) to milliseconds (ms) 2024-02-22 15:28:55 +01:00
340d6aa97c unicornafl: fix malloc of size 0 (#2010)
* bugfix: free a chunk with a size of 0, it will cause 1 byte oob.

Malloc does not check the size. Generally, malloc(0) should return 0 but there will return two pages. Free will use is_buffer_in_chunk to check whether the address is in the chunk. At that time, the chunk.data_addr == total_size . Free pass address and "1" to is_buffer_in_chunk. So cause 1 byte out-of-bound.

* typo
2024-02-21 12:42:55 +01:00
5ae4a7ae02 afl-whatsup current speed 2024-02-20 15:48:48 +01:00
80158de3e8 Catch invalid frees (#2008)
1. There isn't a need to check all chunks when address == 0
2. If the address is not in chunks, the program may want to free an object that doesn't exist. There may be a "double-free" or "invalid-free" vulnerability. (This patch is from the repo named "Battelle/afl-unicorn")
2024-02-20 14:01:37 +01:00
730713193a replaced unicornafl with unicorn (#2003)
* push to stable (#1983)

* Output afl-clang-fast stuffs only if necessary (#1912)

* afl-cc header

* afl-cc common declarations

 - Add afl-cc-state.c
 - Strip includes, find_object, debug/be_quiet/have_*/callname setting from afl-cc.c
 - Use debugf_args in main
 - Modify execvp stuffs to fit new aflcc struct

* afl-cc show usage

* afl-cc mode selecting

1. compiler_mode by callname in argv[0]
2. compiler_mode by env "AFL_CC_COMPILER"
3. compiler_mode/instrument_mode by command line options "--afl-..."
4. instrument_mode/compiler_mode by various env vars including "AFL_LLVM_INSTRUMENT"
5. final checking steps
6. print "... - mode: %s-%s\n"
7. determine real argv[0] according to compiler_mode

* afl-cc macro defs

* afl-cc linking behaviors

* afl-cc fsanitize behaviors

* afl-cc misc

* afl-cc body update

* afl-cc all-in-one

formated with custom-format.py

* nits

---------

Co-authored-by: vanhauser-thc <vh@thc.org>

* changelog

* update grammar mutator

* lto llvm 12+

* docs(custom_mutators): fix missing ':' (#1953)

* Fix broken LTO mode and response file support (#1948)

* Strip `-Wl,-no-undefined` during compilation (#1952)

Make the compiler wrapper stripping `-Wl,-no-undefined` in addition to `-Wl,--no-undefined`.
Both versions of the flag are accepted by clang and, therefore, used by building systems in the wild (e.g., samba will not build without this fix).

* Remove dead code in write_to_testcase (#1955)

The custom_mutators_count check in if case is duplicate with if condition.
The else case is custom_mutators_count == 0, neither custom_mutator_list iteration nor sent check needed.

Signed-off-by: Xeonacid <h.dwwwwww@gmail.com>

* update qemuafl

* WIP: Add ability to generate drcov trace using QEMU backend (#1956)

* Document new drcov QEMU plugin

* Add link to lightkeeper for QEMU drcov file loading

---------

Co-authored-by: Jean-Romain Garnier <jean-romain.garnier@airbus.com>

* code format

* changelog

* sleep on uid != 0 afl-system-config

* fix segv about skip_next, warn on unsupported cases of linking options (#1958)

* todos

* ensure afl-cc only allows available compiler modes

* update grammar mutator

* disable aslr on apple

* fix for arm64

* help selective instrumentation

* typos

* macos

* add compiler test script

* apple fixes

* bump nyx submodules (#1963)

* fix docs

* update changelog

* update grammar mutator

* improve compiler test script

* gcc asan workaround (#1966)

* fix github merge fuckup

* fix

* Fix afl-cc (#1968)

- Check if too many cmdline params here, each time before insert a new param.
 - Check if it is "-fsanitize=..." before we do sth.
 - Remove improper param_st transfer.

* Avoid adding llvmnative instrumentation when linking rust sanitizer runtime (#1969)

* Dynamic instrumentation filtering for LLVM native (#1971)

* Add two dynamic instrumentation filter methods to runtime

* Always use pc-table with native pcguard

* Add make_symbol_list.py and README

* changelog

* todos

* new forkserver check

* fix

* nyx test for CI

* improve nyx docs

* Fixes to afl-cc and documentation (#1974)

* Always compile with -ldl when building for CODE_COVERAGE

When building with CODE_COVERAGE, the afl runtime contains code that
calls `dladdr` which requires -ldl. Under most circumstances, clang
already adds this (e.g. when building with pc-table), but there are some
circumstances where it isn't added automatically.

* Add visibility declaration to __afl_connected

When building with hidden visibility, the use of __AFL_LOOP inside such
code can cause linker errors due to __afl_connected being declared
"hidden".

* Update docs to clarify that CODE_COVERAGE=1 is required for dynamic_covfilter

* nits

* nyx build script updates

* test error output

* debug ci

* debug ci

* Improve afl-cc (#1975)

* update response file support

 - full support of rsp file
 - fix some segv issues

* Improve afl-cc

 - remove dead code about allow/denylist options of sancov
 - missing `if (!aflcc->have_msan)`
 - add docs for each function
 - typo

* enable nyx

* debug ci

* debug ci

* debug ci

* debug ci

* debug ci

* debug ci

* debug ci

* debug ci

* fix ci

* clean test script

* NO_NYX

* NO_NYX

* fix ci

* debug ci

* fix ci

* finalize ci fix

* Enhancement on Deterministic stage (#1972)

* fuzzer: init commit based on aflpp 60dc37a8cf

* fuzzers: adding the skip variables and initialize

* log: profile the det/havoc finding

* log: add profile log output

* fuzzers: sperate log/skipdet module

* fuzzers: add quick eff_map calc

* fuzzers: add skip_eff_map in fuzz_one

* fuzzers: mark whole input space in eff_map

* fuzzers: add undet bit threshold to skip some seeds

* fuzzers: fix one byte overflow

* fuzzers: fix overflow

* fix code format

* add havoc only again

* code format

* remove log to INTROSPECTION, rename skipdet module

* rename skipdet module

* remove log to stats

* clean redundant code

* code format

* remove redundant code format check

* remove redundant doc

* remove redundant objects

* clean files

* change -d to default skipdet

* disable deterministic when using CUSTOM_MUTATOR

* revert fix

* final touches for skipdet

* remove unused var

* remove redundant eff struct (#1977)

* update QEMU-Nyx submodule (#1978)

* update QEMU-Nyx submodule (#1980)

* Fix type in AFL_NOOPT env variable in afl-cc help message (#1982)

* nits

* 2024 v4.10c release

* fixes

---------

Signed-off-by: Xeonacid <h.dwwwwww@gmail.com>
Co-authored-by: Sonic <50692172+SonicStark@users.noreply.github.com>
Co-authored-by: Xeonacid <h.dwwwwww@gmail.com>
Co-authored-by: Nils Bars <nils.bars@rub.de>
Co-authored-by: Jean-Romain Garnier <7504819+JRomainG@users.noreply.github.com>
Co-authored-by: Jean-Romain Garnier <jean-romain.garnier@airbus.com>
Co-authored-by: Sergej Schumilo <sergej@schumilo.de>
Co-authored-by: Christian Holler (:decoder) <choller@mozilla.com>
Co-authored-by: Han Zheng <35988108+kdsjZh@users.noreply.github.com>
Co-authored-by: Khaled Yakdan <yakdan@code-intelligence.com>

* replaced unicornafl with unicorn

The submodule of unicorn cannot be imported through unicornafl.*_const here. If we want to use the *_const module, we should reference `from unicorn.*_const import *` like this instead of importing the entire contents of the *_const module via unicornafl。

---------

Signed-off-by: Xeonacid <h.dwwwwww@gmail.com>
Co-authored-by: van Hauser <vh@thc.org>
Co-authored-by: Sonic <50692172+SonicStark@users.noreply.github.com>
Co-authored-by: Xeonacid <h.dwwwwww@gmail.com>
Co-authored-by: Nils Bars <nils.bars@rub.de>
Co-authored-by: Jean-Romain Garnier <7504819+JRomainG@users.noreply.github.com>
Co-authored-by: Jean-Romain Garnier <jean-romain.garnier@airbus.com>
Co-authored-by: Sergej Schumilo <sergej@schumilo.de>
Co-authored-by: Christian Holler (:decoder) <choller@mozilla.com>
Co-authored-by: Han Zheng <35988108+kdsjZh@users.noreply.github.com>
Co-authored-by: Khaled Yakdan <yakdan@code-intelligence.com>
2024-02-19 22:44:05 +01:00
fea76dff23 Merge pull request #1999 from seanm/issue1865
Fixed #1865: create symlinks for afl-clang-fast
2024-02-19 19:07:30 +01:00
808022d3e0 Fixed #1865: many updates to INSTALL.md for macOS
- moved shared mem instructions to before building so that tests during build don't fail
- corrected path to README.llvm.md
- updated some macOS spelling
- added missing sudo
- misc other changes from reading the document carefully
2024-02-19 12:06:11 -05:00
eee78077e2 Merge pull request #1998 from trail-of-forks/grub-cmdline
afl-persistent-config: Use GRUB_CMDLINE_LINUX instead of GRUB_CMDLINE_LINUX_DEFAULT
2024-02-16 18:22:30 +01:00
ca91d3fbc0 Revert other changes 2024-02-16 13:54:05 +00:00
ad4a776fc6 Change both 2024-02-16 12:01:50 +00:00
ebdb71aeb0 Merge pull request #2002 from seanm/issue2001
issue #2001: fix passing rpath to linker on macOS
2024-02-16 10:14:56 +01:00
6dc58750cf issue #2001: fix passing rpath to linker on macOS
Seems on macOS, `ld` does not want an `=` when specifying `-rpath`.
2024-02-15 19:19:51 -05:00
1b84448be3 afl-persistent-config: Use GRUB_CMDLINE_LINUX instead of GRUB_CMDLINE_LINUX_DEFAULT.
The latter is often overwritten in images used in cloud setups. For example DigitalOcean sets GRUB_CMDLINE_LINUX_DEFAULT="console=tty1 console=ttyS0" in /etc/default/grub.d/
2024-02-14 15:55:32 +00:00
61ceef64b1 valid comparison.md 2024-02-13 20:14:35 +01:00
775861ea94 Merge pull request #1985 from AFLplusplus/dev
push to stable
2024-02-03 11:57:27 +01:00
602eceed8b push to stable (#1983)
* Output afl-clang-fast stuffs only if necessary (#1912)

* afl-cc header

* afl-cc common declarations

 - Add afl-cc-state.c
 - Strip includes, find_object, debug/be_quiet/have_*/callname setting from afl-cc.c
 - Use debugf_args in main
 - Modify execvp stuffs to fit new aflcc struct

* afl-cc show usage

* afl-cc mode selecting

1. compiler_mode by callname in argv[0]
2. compiler_mode by env "AFL_CC_COMPILER"
3. compiler_mode/instrument_mode by command line options "--afl-..."
4. instrument_mode/compiler_mode by various env vars including "AFL_LLVM_INSTRUMENT"
5. final checking steps
6. print "... - mode: %s-%s\n"
7. determine real argv[0] according to compiler_mode

* afl-cc macro defs

* afl-cc linking behaviors

* afl-cc fsanitize behaviors

* afl-cc misc

* afl-cc body update

* afl-cc all-in-one

formated with custom-format.py

* nits

---------

Co-authored-by: vanhauser-thc <vh@thc.org>

* changelog

* update grammar mutator

* lto llvm 12+

* docs(custom_mutators): fix missing ':' (#1953)

* Fix broken LTO mode and response file support (#1948)

* Strip `-Wl,-no-undefined` during compilation (#1952)

Make the compiler wrapper stripping `-Wl,-no-undefined` in addition to `-Wl,--no-undefined`.
Both versions of the flag are accepted by clang and, therefore, used by building systems in the wild (e.g., samba will not build without this fix).

* Remove dead code in write_to_testcase (#1955)

The custom_mutators_count check in if case is duplicate with if condition.
The else case is custom_mutators_count == 0, neither custom_mutator_list iteration nor sent check needed.

Signed-off-by: Xeonacid <h.dwwwwww@gmail.com>

* update qemuafl

* WIP: Add ability to generate drcov trace using QEMU backend (#1956)

* Document new drcov QEMU plugin

* Add link to lightkeeper for QEMU drcov file loading

---------

Co-authored-by: Jean-Romain Garnier <jean-romain.garnier@airbus.com>

* code format

* changelog

* sleep on uid != 0 afl-system-config

* fix segv about skip_next, warn on unsupported cases of linking options (#1958)

* todos

* ensure afl-cc only allows available compiler modes

* update grammar mutator

* disable aslr on apple

* fix for arm64

* help selective instrumentation

* typos

* macos

* add compiler test script

* apple fixes

* bump nyx submodules (#1963)

* fix docs

* update changelog

* update grammar mutator

* improve compiler test script

* gcc asan workaround (#1966)

* fix github merge fuckup

* fix

* Fix afl-cc (#1968)

- Check if too many cmdline params here, each time before insert a new param.
 - Check if it is "-fsanitize=..." before we do sth.
 - Remove improper param_st transfer.

* Avoid adding llvmnative instrumentation when linking rust sanitizer runtime (#1969)

* Dynamic instrumentation filtering for LLVM native (#1971)

* Add two dynamic instrumentation filter methods to runtime

* Always use pc-table with native pcguard

* Add make_symbol_list.py and README

* changelog

* todos

* new forkserver check

* fix

* nyx test for CI

* improve nyx docs

* Fixes to afl-cc and documentation (#1974)

* Always compile with -ldl when building for CODE_COVERAGE

When building with CODE_COVERAGE, the afl runtime contains code that
calls `dladdr` which requires -ldl. Under most circumstances, clang
already adds this (e.g. when building with pc-table), but there are some
circumstances where it isn't added automatically.

* Add visibility declaration to __afl_connected

When building with hidden visibility, the use of __AFL_LOOP inside such
code can cause linker errors due to __afl_connected being declared
"hidden".

* Update docs to clarify that CODE_COVERAGE=1 is required for dynamic_covfilter

* nits

* nyx build script updates

* test error output

* debug ci

* debug ci

* Improve afl-cc (#1975)

* update response file support

 - full support of rsp file
 - fix some segv issues

* Improve afl-cc

 - remove dead code about allow/denylist options of sancov
 - missing `if (!aflcc->have_msan)`
 - add docs for each function
 - typo

* enable nyx

* debug ci

* debug ci

* debug ci

* debug ci

* debug ci

* debug ci

* debug ci

* debug ci

* fix ci

* clean test script

* NO_NYX

* NO_NYX

* fix ci

* debug ci

* fix ci

* finalize ci fix

* Enhancement on Deterministic stage (#1972)

* fuzzer: init commit based on aflpp 60dc37a8cf

* fuzzers: adding the skip variables and initialize

* log: profile the det/havoc finding

* log: add profile log output

* fuzzers: sperate log/skipdet module

* fuzzers: add quick eff_map calc

* fuzzers: add skip_eff_map in fuzz_one

* fuzzers: mark whole input space in eff_map

* fuzzers: add undet bit threshold to skip some seeds

* fuzzers: fix one byte overflow

* fuzzers: fix overflow

* fix code format

* add havoc only again

* code format

* remove log to INTROSPECTION, rename skipdet module

* rename skipdet module

* remove log to stats

* clean redundant code

* code format

* remove redundant code format check

* remove redundant doc

* remove redundant objects

* clean files

* change -d to default skipdet

* disable deterministic when using CUSTOM_MUTATOR

* revert fix

* final touches for skipdet

* remove unused var

* remove redundant eff struct (#1977)

* update QEMU-Nyx submodule (#1978)

* update QEMU-Nyx submodule (#1980)

* Fix type in AFL_NOOPT env variable in afl-cc help message (#1982)

* nits

* 2024 v4.10c release

* fixes

---------

Signed-off-by: Xeonacid <h.dwwwwww@gmail.com>
Co-authored-by: Sonic <50692172+SonicStark@users.noreply.github.com>
Co-authored-by: Xeonacid <h.dwwwwww@gmail.com>
Co-authored-by: Nils Bars <nils.bars@rub.de>
Co-authored-by: Jean-Romain Garnier <7504819+JRomainG@users.noreply.github.com>
Co-authored-by: Jean-Romain Garnier <jean-romain.garnier@airbus.com>
Co-authored-by: Sergej Schumilo <sergej@schumilo.de>
Co-authored-by: Christian Holler (:decoder) <choller@mozilla.com>
Co-authored-by: Han Zheng <35988108+kdsjZh@users.noreply.github.com>
Co-authored-by: Khaled Yakdan <yakdan@code-intelligence.com>
2024-02-03 10:55:51 +00:00
50 changed files with 688 additions and 392 deletions

View File

@ -27,5 +27,5 @@ keywords:
- qemu
- llvm
- unicorn-emulator
- securiy
- security
license: AGPL-3.0-or-later

View File

@ -52,7 +52,7 @@ endif
ifdef ASAN_BUILD
$(info Compiling ASAN version of binaries)
override CFLAGS += $(ASAN_CFLAGS)
LDFLAGS += $(ASAN_LDFLAGS)
override LDFLAGS += $(ASAN_LDFLAGS)
endif
ifdef UBSAN_BUILD
$(info Compiling UBSAN version of binaries)
@ -106,22 +106,22 @@ ifneq "$(SYS)" "Darwin"
# SPECIAL_PERFORMANCE += -march=native
#endif
#ifndef DEBUG
# CFLAGS_OPT += -D_FORTIFY_SOURCE=1
# override CFLAGS_OPT += -D_FORTIFY_SOURCE=1
#endif
else
# On some odd MacOS system configurations, the Xcode sdk path is not set correctly
SDK_LD = -L$(shell xcrun --show-sdk-path)/usr/lib
LDFLAGS += $(SDK_LD)
override LDFLAGS += $(SDK_LD)
endif
COMPILER_TYPE=$(shell $(CC) --version|grep "Free Software Foundation")
ifneq "$(COMPILER_TYPE)" ""
#$(info gcc is being used)
CFLAGS_OPT += -Wno-error=format-truncation -Wno-format-truncation
override CFLAGS_OPT += -Wno-error=format-truncation -Wno-format-truncation
endif
ifeq "$(SYS)" "SunOS"
LDFLAGS = -lkstat -lrt -lsocket -lnsl
override LDFLAGS = -lkstat -lrt -lsocket -lnsl
endif
ifdef STATIC
@ -131,8 +131,8 @@ ifdef STATIC
PYFLAGS=
PYTHON_INCLUDE = /
CFLAGS_OPT += -static
LDFLAGS += -lm -lpthread -lz -lutil
override CFLAGS_OPT += -static
override LDFLAGS += -lm -lpthread -lz -lutil
endif
ifdef PROFILING
@ -759,7 +759,7 @@ endif
@test -e SanitizerCoveragePCGUARD.so && echo "[+] LLVM mode successfully built" || echo "[-] LLVM mode could not be built, please install at least llvm-13 and clang-13 or newer, see docs/INSTALL.md"
@test -e SanitizerCoverageLTO.so && echo "[+] LLVM LTO mode successfully built" || echo "[-] LLVM LTO mode could not be built, it is optional, if you want it, please install LLVM 11-14. More information at instrumentation/README.lto.md on how to build it"
ifneq "$(SYS)" "Darwin"
test -e afl-gcc-pass.so && echo "[+] gcc_mode successfully built" || echo "[-] gcc_mode could not be built, it is optional, install gcc-VERSION-plugin-dev to enable this"
@test -e afl-gcc-pass.so && echo "[+] gcc_mode successfully built" || echo "[-] gcc_mode could not be built, it is optional, install gcc-VERSION-plugin-dev to enable this"
endif
ifeq "$(SYS)" "Linux"
ifndef NO_NYX

View File

@ -44,7 +44,7 @@ endif
LLVMVER = $(shell $(LLVM_CONFIG) --version 2>/dev/null | sed 's/git//' | sed 's/svn//' )
LLVM_MAJOR = $(shell $(LLVM_CONFIG) --version 2>/dev/null | sed 's/\..*//' )
LLVM_MINOR = $(shell $(LLVM_CONFIG) --version 2>/dev/null | sed 's/.*\.//' | sed 's/git//' | sed 's/svn//' | sed 's/ .*//' )
LLVM_MINOR = $(shell $(LLVM_CONFIG) --version 2>/dev/null | sed 's/.*\.//' | sed 's/git//' | sed 's/svn//' | sed 's/ .*//' | sed 's/rc.*//' )
LLVM_UNSUPPORTED = $(shell $(LLVM_CONFIG) --version 2>/dev/null | grep -E -q '^[0-2]\.|^3.[0-8]\.' && echo 1 || echo 0 )
LLVM_TOO_NEW = $(shell $(LLVM_CONFIG) --version 2>/dev/null | grep -E -q '^1[8-9]|^2[0-9]' && echo 1 || echo 0 )
LLVM_TOO_OLD = $(shell $(LLVM_CONFIG) --version 2>/dev/null | grep -E -q '^[1-9]\.|^1[012]\.' && echo 1 || echo 0 )

View File

@ -2,9 +2,9 @@
<img align="right" src="https://raw.githubusercontent.com/AFLplusplus/Website/main/static/aflpp_bg.svg" alt="AFL++ logo" width="250" heigh="250">
Release version: [4.10c](https://github.com/AFLplusplus/AFLplusplus/releases)
Release version: [4.20c](https://github.com/AFLplusplus/AFLplusplus/releases)
GitHub version: 4.20a
GitHub version: 4.20c
Repository:
[https://github.com/AFLplusplus/AFLplusplus](https://github.com/AFLplusplus/AFLplusplus)

View File

@ -108,7 +108,7 @@ function usage() {
"\n" \
"Execution control settings:\n" \
" -T tasks - how many parallel tasks to run (default: 1, all=nproc)\n" \
" -f file - location read by the fuzzed program (stdin)\n" \
" -f file - location read by the fuzzed program (default: stdin)\n" \
" -m megs - memory limit for child process ("mem_limit" MB)\n" \
" -t msec - run time limit for child process (default: 5000)\n" \
" -O - use binary-only instrumentation (FRIDA mode)\n" \

View File

@ -124,17 +124,26 @@ kernel.sched_latency_ns=250000000
EOF
}
grep -E -q '^GRUB_CMDLINE_LINUX_DEFAULT=' /etc/default/grub 2>/dev/null || echo Error: /etc/default/grub with GRUB_CMDLINE_LINUX_DEFAULT is not present, cannot set boot options
grep -E -q '^GRUB_CMDLINE_LINUX_DEFAULT=' /etc/default/grub 2>/dev/null && {
grep -E '^GRUB_CMDLINE_LINUX_DEFAULT=' /etc/default/grub | grep -E -q 'noibrs pcid nopti' || {
grub_try_disable_mitigation () {
KEY="$1"
if ! grep -E "^$KEY=" /etc/default/grub | grep -E -q 'noibrs pcid nopti'; then
echo "Configuring performance boot options"
LINE=`grep -E '^GRUB_CMDLINE_LINUX_DEFAULT=' /etc/default/grub | sed 's/^GRUB_CMDLINE_LINUX_DEFAULT=//' | tr -d '"'`
LINE=`grep -E "^$KEY=" /etc/default/grub | sed "s/^$KEY=//" | tr -d '"'`
OPTIONS="$LINE ibpb=off ibrs=off kpti=off l1tf=off spec_rstack_overflow=off mds=off no_stf_barrier noibpb noibrs pcid nopti nospec_store_bypass_disable nospectre_v1 nospectre_v2 pcid=on pti=off spec_store_bypass_disable=off spectre_v2=off stf_barrier=off srbds=off noexec=off noexec32=off tsx=on tsx=on tsx_async_abort=off mitigations=off audit=0 hardened_usercopy=off ssbd=force-off"
echo Setting boot options in /etc/default/grub to GRUB_CMDLINE_LINUX_DEFAULT=\"$OPTIONS\"
sed -i "s|^GRUB_CMDLINE_LINUX_DEFAULT=.*|GRUB_CMDLINE_LINUX_DEFAULT=\"$OPTIONS\"|" /etc/default/grub
}
echo Setting boot options in /etc/default/grub to $KEY=\"$OPTIONS\"
sed -i "s|^$KEY=.*|$KEY=\"$OPTIONS\"|" /etc/default/grub
fi
}
if grep -E -q '^GRUB_CMDLINE_LINUX=' /etc/default/grub || grep -E -q '^GRUB_CMDLINE_LINUX_DEFAULT=' /etc/default/grub; then
grub_try_disable_mitigation "GRUB_CMDLINE_LINUX_DEFAULT"
# We also overwrite GRUB_CMDLINE_LINUX because some distributions already overwrite GRUB_CMDLINE_LINUX_DEFAULT
grub_try_disable_mitigation "GRUB_CMDLINE_LINUX"
else
echo "Error: /etc/default/grub with GRUB_CMDLINE_LINUX is not present, cannot set boot options"
fi
echo
echo "Reboot and enjoy your fuzzing"
exit 0

View File

@ -123,6 +123,7 @@ START_CNT=0
TOTAL_TIME=0
TOTAL_EXECS=0
TOTAL_EPS=0
TOTAL_EPLM=0
TOTAL_CRASHES=0
TOTAL_HANGS=0
TOTAL_PFAV=0
@ -182,6 +183,8 @@ for j in `find . -maxdepth 2 -iname fuzzer_setup | sort`; do
if [ -f "$i" ]; then
IS_STARTING=
IS_DEAD=
sed 's/^command_line.*$/_skip:1/;s/[ ]*:[ ]*/="/;s/$/"/' "$i" >"$TMP"
. "$TMP"
DIRECTORY=$DIR
@ -212,9 +215,6 @@ for j in `find . -maxdepth 2 -iname fuzzer_setup | sort`; do
if ! kill -0 "$fuzzer_pid" 2>/dev/null; then
IS_STARTING=
IS_DEAD=
if [ -e "$i" ] && [ -e "$j" ] && [ -n "$FUSER" ]; then
if [ "$i" -ot "$j" ]; then
@ -273,11 +273,15 @@ for j in `find . -maxdepth 2 -iname fuzzer_setup | sort`; do
ALIVE_CNT=$((ALIVE_CNT + 1))
EXEC_SEC=0
EXEC_MIN=0
test -z "$RUN_UNIX" -o "$RUN_UNIX" = 0 || EXEC_SEC=$((execs_done / RUN_UNIX))
PATH_PERC=$((cur_item * 100 / corpus_count))
test "$IS_DEAD" = 1 || EXEC_MIN=$(echo $execs_ps_last_min|sed 's/\..*//')
TOTAL_TIME=$((TOTAL_TIME + RUN_UNIX))
TOTAL_EPS=$((TOTAL_EPS + EXEC_SEC))
TOTAL_EPLM=$((TOTAL_EPLM + EXEC_MIN))
TOTAL_EXECS=$((TOTAL_EXECS + execs_done))
TOTAL_CRASHES=$((TOTAL_CRASHES + saved_crashes))
TOTAL_HANGS=$((TOTAL_HANGS + saved_hangs))
@ -399,41 +403,44 @@ if [ -z "$SUMMARY_ONLY" -o -z "$MINIMAL_ONLY" ]; then
echo
fi
echo " Fuzzers alive : $ALIVE_CNT"
echo " Fuzzers alive : $ALIVE_CNT"
if [ ! "$START_CNT" = "0" ]; then
echo " Starting up : $START_CNT ($TXT)"
echo " Starting up : $START_CNT ($TXT)"
fi
if [ ! "$DEAD_CNT" = "0" ]; then
echo " Dead or remote : $DEAD_CNT ($TXT)"
echo " Dead or remote : $DEAD_CNT ($TXT)"
fi
echo " Total run time : $FMT_TIME"
echo " Total run time : $FMT_TIME"
if [ -z "$MINIMAL_ONLY" ]; then
echo " Total execs : $FMT_EXECS"
echo " Cumulative speed : $TOTAL_EPS execs/sec"
echo " Total execs : $FMT_EXECS"
echo " Cumulative speed : $TOTAL_EPS execs/sec"
if [ "$ALIVE_CNT" -gt "0" ]; then
echo " Total average speed : $((TOTAL_EPS / ALIVE_CNT)) execs/sec"
fi
fi
if [ "$ALIVE_CNT" -gt "0" ]; then
echo " Average speed : $((TOTAL_EPS / ALIVE_CNT)) execs/sec"
echo "Current average speed : $TOTAL_EPLM execs/sec"
fi
if [ -z "$MINIMAL_ONLY" ]; then
echo " Pending items : $TOTAL_PFAV faves, $TOTAL_PENDING total"
echo " Pending items : $TOTAL_PFAV faves, $TOTAL_PENDING total"
fi
if [ "$ALIVE_CNT" -gt "1" -o -n "$MINIMAL_ONLY" ]; then
if [ "$ALIVE_CNT" -gt "0" ]; then
echo " Pending per fuzzer : $((TOTAL_PFAV/ALIVE_CNT)) faves, $((TOTAL_PENDING/ALIVE_CNT)) total (on average)"
echo " Pending per fuzzer : $((TOTAL_PFAV/ALIVE_CNT)) faves, $((TOTAL_PENDING/ALIVE_CNT)) total (on average)"
fi
fi
echo " Coverage reached : ${TOTAL_COVERAGE}%"
echo " Crashes saved : $TOTAL_CRASHES"
echo " Coverage reached : ${TOTAL_COVERAGE}%"
echo " Crashes saved : $TOTAL_CRASHES"
if [ -z "$MINIMAL_ONLY" ]; then
echo " Hangs saved : $TOTAL_HANGS"
echo "Cycles without finds : $TOTAL_WCOP"
echo " Hangs saved : $TOTAL_HANGS"
echo " Cycles without finds : $TOTAL_WCOP"
fi
echo " Time without finds : $TOTAL_LAST_FIND"
echo " Time without finds : $TOTAL_LAST_FIND"
echo
exit 0

View File

@ -1,13 +1,13 @@
CPU | MHz | threads | singlecore | multicore | afl-*-config |
====================================================|=======|=========|============|===========|==============|
Raspberry Pi 5 | 2400 | 4 | 25786 | 101114 | both |
AMD EPYC 7282 16-Core Processor | 3194 | 32 | 87199 | 769001 | both |
AMD Ryzen 5 PRO 4650G with Radeon Graphics | 3700 | 12 | 95356 | 704840 | both |
Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz | 4995 | 16 | 120064 | 1168943 | both |
12th Gen Intel(R) Core(TM) i7-1270P | 4761 | 16 | 149778 | 641219 | both |
AMD Ryzen 9 5950X 16-Core Processor | 4792 | 32 | 161690 | 2339763 | both |
Apple Mac Studio M2 Ultra 2023, Linux VM guest | 3500 | 16 | 163570 | 1157465 | both |
AMD Ryzen 9 6900HS with Radeon Graphics | 4676 | 16 | 62860 | 614404 | system |
AMD Ryzen 9 6900HS with Radeon Graphics | 4745 | 16 | 135501 | 991133 | both |
AMD Ryzen 9 7950X3D 16-Core Processor | 5400 | 32 | 71566 | 1566279 | system |
AMD Ryzen 9 7950X3D 16-Core Processor | 5478 | 32 | 161960 | 2173959 | both |
|CPU | MHz | threads | singlecore | multicore | afl-*-config |
|----------------------------------------------------|-------|---------|------------|-----------|--------------|
|Raspberry Pi 5 | 2400 | 4 | 25786 | 101114 | both |
|AMD EPYC 7282 16-Core Processor | 3194 | 32 | 87199 | 769001 | both |
|AMD Ryzen 5 PRO 4650G with Radeon Graphics | 3700 | 12 | 95356 | 704840 | both |
|Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz | 4995 | 16 | 120064 | 1168943 | both |
|12th Gen Intel(R) Core(TM) i7-1270P | 4761 | 16 | 149778 | 641219 | both |
|AMD Ryzen 9 5950X 16-Core Processor | 4792 | 32 | 161690 | 2339763 | both |
|Apple Mac Studio M2 Ultra 2023, Linux VM guest | 3500 | 16 | 163570 | 1157465 | both |
|AMD Ryzen 9 6900HS with Radeon Graphics | 4676 | 16 | 62860 | 614404 | system |
|AMD Ryzen 9 6900HS with Radeon Graphics | 4745 | 16 | 135501 | 991133 | both |
|AMD Ryzen 9 7950X3D 16-Core Processor | 5400 | 32 | 71566 | 1566279 | system |
|AMD Ryzen 9 7950X3D 16-Core Processor | 5478 | 32 | 161960 | 2173959 | both |

View File

@ -205,7 +205,7 @@ async def save_benchmark_results() -> None:
single = str(round(results.targets["test-instr-persist-shmem"]["singlecore"].execs_per_sec)).ljust(10)
multi = str(round(results.targets["test-instr-persist-shmem"]["multicore"].execs_per_sec)).ljust(9)
cores = str(args.fuzzers).ljust(7)
comparisonfile.write(f"{cpu_model} | {cpu_mhz} | {cores} | {single} | {multi} | {aflconfig} |\n")
comparisonfile.write(f"|{cpu_model} | {cpu_mhz} | {cores} | {single} | {multi} | {aflconfig} |\n")
print(blue(f" [*] Results have been written to the COMPARISON.md file."))
with open("COMPARISON.md", "r") as comparisonfile:
print(comparisonfile.read())

View File

@ -1,3 +1,4 @@
#include "afl-fuzz.h"
#include "afl-mutations.h"
typedef struct my_mutator {

View File

@ -1,9 +1,6 @@
#include "afl-fuzz.h"
#include "afl-mutations.h"
s8 interesting_8[] = {INTERESTING_8};
s16 interesting_16[] = {INTERESTING_8, INTERESTING_16};
s32 interesting_32[] = {INTERESTING_8, INTERESTING_16, INTERESTING_32};
typedef struct my_mutator {
afl_state_t *afl;
@ -155,7 +152,7 @@ int main(int argc, char *argv[]) {
return -1;
}
if (verbose) fprintf(stderr, "Mutation output length: %zu\n", outlen);
if (verbose) fprintf(stderr, "Mutation output length: %u\n", outlen);
if (fwrite(outbuf, 1, outlen, out) != outlen) {
fprintf(stderr, "Warning: incomplete write.\n");

View File

@ -3,12 +3,12 @@
This is the list of all noteworthy changes made in every public
release of the tool. See README.md for the general instruction manual.
### Version ++4.20a (dev)
### Version ++4.20c (release)
! A new forkserver communication model is now introduced. afl-fuzz is
backward compatible to old compiled targets if they are not built
for CMPLOG/Redqueen, but new compiled targets will not work with
old afl-fuzz versions!
! Recompiled all targets that are instrumented for CMPLOG/Redqueen!
! Recompile all targets that are instrumented for CMPLOG/Redqueen!
- AFL++ now supports up to 4 billion coverage edges, up from 6 million.
- New compile option: `make PERFORMANCE=1` - this will enable special
CPU dependent optimizations that make everything more performant - but
@ -22,10 +22,21 @@
- small improvements to CMPLOG/redqueen
- workround for a bug with MOpt -L when used with -M - in the future
we will either remove or rewrite MOpt.
- fix for `-t xxx+` feature
- -e extension option now saves the queue items, crashes, etc. with the
extension too
- fixes for trimmming, correct -V time and reading stats on resume by eqv
thanks a lot!
- afl-cc:
- added collision free caller instrumentation to LTO mode. activate with
`AFL_LLVM_LTO_CALLER=1`. You can set a max depth to go through single
block functions with `AFL_LLVM_LTO_CALLER_DEPTH` (default 0)
- fixes for COMPCOV/LAF and most other modules
- fix for GCC_PLUGIN cmplog that broke on std::strings
- afl-whatsup:
- now also displays current average speed
- small bugfixes
- Fixes for aflpp custom mutator and standalone tool
- Minor edits to afl-persistent-config
- Prevent temporary files being left behind on aborted afl-whatsup
- More CPU benchmarks added to benchmark/

View File

@ -21,7 +21,7 @@ If you want to build AFL++ yourself, you have many options. The easiest choice
is to build and install everything:
NOTE: depending on your Debian/Ubuntu/Kali/... release, replace `-14` with
whatever llvm version is available. We recommend llvm 13, 14, 15 or 16.
whatever llvm version is available. We recommend llvm 13 or newer.
```shell
sudo apt-get update
@ -67,7 +67,7 @@ These build targets exist:
* unit: perform unit tests (based on cmocka)
* help: shows these build options
[Unless you are on Mac OS X](https://developer.apple.com/library/archive/qa/qa1118/_index.html),
[Unless you are on macOS](https://developer.apple.com/library/archive/qa/qa1118/_index.html),
you can also build statically linked versions of the AFL++ binaries by passing
the `PERFORMANCE=1` argument to make:
@ -77,10 +77,10 @@ make PERFORMANCE=1
These build options exist:
* PERFORMANCE - compile with performance options that make the binary not transferable to other systems. Recommended!
* STATIC - compile AFL++ static
* CODE_COVERAGE - compile the target for code coverage (see docs/instrumentation/README.llvm.md)
* ASAN_BUILD - compiles AFL++ with memory sanitizer for debug purposes
* PERFORMANCE - compile with performance options that make the binary not transferable to other systems. Recommended (except on macOS)!
* STATIC - compile AFL++ static (does not work on macOS)
* CODE_COVERAGE - compile the target for code coverage (see [README.llvm.md](../instrumentation/README.llvm.md))
* ASAN_BUILD - compiles AFL++ with address sanitizer for debug purposes
* UBSAN_BUILD - compiles AFL++ tools with undefined behaviour sanitizer for debug purposes
* DEBUG - no optimization, -ggdb3, all warnings and -Werror
* LLVM_DEBUG - shows llvm deprecation warnings
@ -92,7 +92,7 @@ These build options exist:
* NO_NYX - disable building nyx mode dependencies
* NO_CORESIGHT - disable building coresight (arm64 only)
* NO_UNICORN_ARM64 - disable building unicorn on arm64
* AFL_NO_X86 - if compiling on non-intel/amd platforms
* AFL_NO_X86 - if compiling on non-Intel/AMD platforms
* LLVM_CONFIG - if your distro doesn't use the standard name for llvm-config (e.g., Debian)
e.g.: `make LLVM_CONFIG=llvm-config-14`
@ -101,8 +101,19 @@ e.g.: `make LLVM_CONFIG=llvm-config-14`
macOS has some gotchas due to the idiosyncrasies of the platform.
To build AFL, install llvm (and perhaps gcc) from brew and follow the general
instructions for Linux. If possible, avoid Xcode at all cost.
macOS supports SYSV shared memory used by AFL++'s instrumentation, but the
default settings aren't sufficient. Before even building, increase
them by running the provided script:
```shell
sudo afl-system-config
```
See
[https://www.spy-hill.com/help/apple/SharedMemory.html](https://www.spy-hill.com/help/apple/SharedMemory.html)
for documentation for the shared memory settings and how to make them permanent.
Next, to build AFL++, install the following packages from brew:
```shell
brew install wget git make cmake llvm gdb coreutils
@ -113,38 +124,37 @@ You can check with `brew info llvm` to know where, then create a variable for it
```shell
export HOMEBREW_BASE="/opt/homebrew/opt"
# or
```
or
```shell
export HOMEBREW_BASE="/usr/local/opt"
```
Be sure to setup `PATH` to point to the correct clang binaries and use the
freshly installed clang, clang++, llvm-config, gmake and coreutils, e.g.:
Set `PATH` to point to the brew clang, clang++, llvm-config, gmake and coreutils.
Also use the brew clang compiler; the Xcode clang compiler must not be used.
```shell
export PATH="$HOMEBREW_BASE/coreutils/libexec/gnubin:/usr/local/bin:$HOMEBREW_BASE/llvm/bin:$PATH"
export CC=clang
export CXX=clang++
gmake
cd frida_mode
gmake
cd ..
sudo gmake install
```
`afl-gcc` will fail unless you have GCC installed, but that is using outdated
instrumentation anyway. `afl-clang` might fail too depending on your PATH setup.
But you don't want neither, you want `afl-clang-fast` anyway :) Note that
`afl-clang-lto`, `afl-gcc-fast` and `qemu_mode` are not working on macOS.
Then build following the general Linux instructions.
If everything worked, you should then have `afl-clang-fast` installed, which you can check with:
```shell
which afl-clang-fast
```
Note that `afl-clang-lto`, `afl-gcc-fast` and `qemu_mode` are not working on macOS.
The crash reporting daemon that comes by default with macOS will cause
problems with fuzzing. You need to turn it off:
problems with fuzzing. You need to turn it off, which you can do with `afl-system-config`.
```
launchctl unload -w /System/Library/LaunchAgents/com.apple.ReportCrash.plist
sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.ReportCrash.Root.plist
```
The `fork()` semantics on OS X are a bit unusual compared to other unix systems
The `fork()` semantics on macOS are a bit unusual compared to other unix systems
and definitely don't look POSIX-compliant. This means two things:
- Fuzzing will be probably slower than on Linux. In fact, some folks report
@ -157,39 +167,3 @@ and definitely don't look POSIX-compliant. This means two things:
User emulation mode of QEMU does not appear to be supported on macOS, so
black-box instrumentation mode (`-Q`) will not work. However, FRIDA mode (`-O`)
works on both x86 and arm64 macOS boxes.
macOS supports SYSV shared memory used by AFL's instrumentation, but the
default settings aren't usable with AFL++. The default settings on 10.14 seem to
be:
```bash
$ ipcs -M
IPC status from <running system> as of XXX
shminfo:
shmmax: 4194304 (max shared memory segment size)
shmmin: 1 (min shared memory segment size)
shmmni: 32 (max number of shared memory identifiers)
shmseg: 8 (max shared memory segments per process)
shmall: 1024 (max amount of shared memory in pages)
```
To temporarily change your settings to something minimally usable with AFL++,
run these commands as root:
```bash
sysctl kern.sysv.shmmax=8388608
sysctl kern.sysv.shmall=4096
```
If you're running more than one instance of AFL, you likely want to make
`shmall` bigger and increase `shmseg` as well:
```bash
sysctl kern.sysv.shmmax=8388608
sysctl kern.sysv.shmseg=48
sysctl kern.sysv.shmall=98304
```
See
[http://www.spy-hill.com/help/apple/SharedMemory.html](http://www.spy-hill.com/help/apple/SharedMemory.html)
for documentation for these settings and how to make them permanent.

View File

@ -958,7 +958,7 @@ too long for your overall available fuzz run time.
campaign but not good for short CI runs.
How this can look like can, e.g., be seen at AFL++'s setup in Google's
[oss-fuzz](https://github.com/google/oss-fuzz/blob/master/infra/base-images/base-builder/compile_afl)
[previous oss-fuzz version](https://github.com/google/oss-fuzz/blob/3e2c5312417d1a6f9564472f3df1fd27759b289d/infra/base-images/base-builder/compile_afl)
and
[clusterfuzz](https://github.com/google/clusterfuzz/blob/master/src/clusterfuzz/_internal/bot/fuzzers/afl/launcher.py).

View File

@ -2,7 +2,7 @@
test -n "$1" && { echo This script has no options. It updates the referenced Frida version in GNUmakefile to the most current one. ; exit 1 ; }
OLD=$(grep -E '^GUM_DEVKIT_VERSION=' GNUmakefile 2>/dev/null|awk -F= '{print$2}')
NEW=$(curl https://github.com/frida/frida/releases/ 2>/dev/null|grep -E 'frida-gum-devkit-[0-9.]*-linux-x86_64'|head -n 1|sed 's/.*frida-gum-devkit-//'|sed 's/-linux.*//')
NEW=$(curl https://github.com/frida/frida/releases/ 2>/dev/null|grep 'Frida\ [0-9.]*'|head -n 1|sed 's/.*Frida\ //'| sed 's/<\/h2>//')
echo Current set version: $OLD
echo Newest available version: $NEW

View File

@ -5,9 +5,9 @@
Originally written by Michal Zalewski
Now maintained by Marc Heuse <mh@mh-sec.de>,
Heiko Eißfeldt <heiko.eissfeldt@hexco.de>,
Andrea Fioraldi <andreafioraldi@gmail.com>,
Dominik Maier <mail@dmnk.co>
Dominik Maier <mail@dmnk.co>,
Andrea Fioraldi <andreafioraldi@gmail.com>, and
Heiko Eissfeldt <heiko.eissfeldt@hexco.de>
Copyright 2016, 2017 Google Inc. All rights reserved.
Copyright 2019-2024 AFLplusplus Project. All rights reserved.
@ -648,7 +648,10 @@ typedef struct afl_state {
longest_find_time, /* Longest time taken for a find */
exit_on_time, /* Delay to exit if no new paths */
sync_time, /* Sync time (ms) */
switch_fuzz_mode; /* auto or fixed fuzz mode */
switch_fuzz_mode, /* auto or fixed fuzz mode */
calibration_time_us, /* Time spend on calibration */
sync_time_us, /* Time spend on sync */
trim_time_us; /* Time spend on trimming */
u32 slowest_exec_ms, /* Slowest testcase non hang in ms */
subseq_tmouts; /* Number of timeouts in a row */
@ -1215,6 +1218,10 @@ void show_stats_normal(afl_state_t *);
void show_stats_pizza(afl_state_t *);
void show_init_stats(afl_state_t *);
void update_calibration_time(afl_state_t *afl, u64 *time);
void update_trim_time(afl_state_t *afl, u64 *time);
void update_sync_time(afl_state_t *afl, u64 *time);
/* StatsD */
void statsd_setup_format(afl_state_t *afl);

View File

@ -30,10 +30,13 @@
#include <stdbool.h>
#include <inttypes.h>
#include "afl-fuzz.h"
#define MUT_STRATEGY_ARRAY_SIZE 256
s8 interesting_8[] = {INTERESTING_8};
s16 interesting_16[] = {INTERESTING_8, INTERESTING_16};
s32 interesting_32[] = {INTERESTING_8, INTERESTING_16, INTERESTING_32};
enum {
/* 00 */ MUT_FLIPBIT,

View File

@ -28,7 +28,7 @@ int __afl_persistent_loop(unsigned int max_cnt) {
static unsigned short int inited = 0;
char tcase[PATH_MAX];
if (is_replay_record) {
if (is_replay_record && cycle_cnt) {
if (!inited) {
@ -59,7 +59,7 @@ int __afl_persistent_loop(unsigned int max_cnt) {
}
return --cycle_cnt;
return cycle_cnt--;
}

View File

@ -26,7 +26,7 @@
/* Version string: */
// c = release, a = volatile github dev, e = experimental branch
#define VERSION "++4.20a"
#define VERSION "++4.20c"
/******************************************************
* *

View File

@ -95,26 +95,26 @@ static char *afl_environment_variables[] = {
"AFL_MAX_DET_EXTRAS",
"AFL_NO_X86", // not really an env but we dont want to warn on it
"AFL_NOOPT", "AFL_NYX_AUX_SIZE", "AFL_NYX_DISABLE_SNAPSHOT_MODE",
"AFL_NYX_LOG", "AFL_NYX_REUSE_SNAPSHOT", "AFL_PASSTHROUGH", "AFL_PATH",
"AFL_PERFORMANCE_FILE", "AFL_PERSISTENT_RECORD",
"AFL_POST_PROCESS_KEEP_ORIGINAL", "AFL_PRELOAD", "AFL_TARGET_ENV",
"AFL_PYTHON_MODULE", "AFL_QEMU_CUSTOM_BIN", "AFL_QEMU_COMPCOV",
"AFL_QEMU_COMPCOV_DEBUG", "AFL_QEMU_DEBUG_MAPS", "AFL_QEMU_DISABLE_CACHE",
"AFL_QEMU_DRIVER_NO_HOOK", "AFL_QEMU_FORCE_DFL", "AFL_QEMU_PERSISTENT_ADDR",
"AFL_QEMU_PERSISTENT_CNT", "AFL_QEMU_PERSISTENT_GPR",
"AFL_QEMU_PERSISTENT_HOOK", "AFL_QEMU_PERSISTENT_MEM",
"AFL_QEMU_PERSISTENT_RET", "AFL_QEMU_PERSISTENT_RETADDR_OFFSET",
"AFL_QEMU_PERSISTENT_EXITS", "AFL_QEMU_INST_RANGES",
"AFL_QEMU_EXCLUDE_RANGES", "AFL_QEMU_SNAPSHOT", "AFL_QEMU_TRACK_UNSTABLE",
"AFL_QUIET", "AFL_RANDOM_ALLOC_CANARY", "AFL_REAL_PATH",
"AFL_SHUFFLE_QUEUE", "AFL_SKIP_BIN_CHECK", "AFL_SKIP_CPUFREQ",
"AFL_SKIP_CRASHES", "AFL_SKIP_OSSFUZZ", "AFL_STATSD", "AFL_STATSD_HOST",
"AFL_STATSD_PORT", "AFL_STATSD_TAGS_FLAVOR", "AFL_SYNC_TIME",
"AFL_TESTCACHE_SIZE", "AFL_TESTCACHE_ENTRIES", "AFL_TMIN_EXACT",
"AFL_TMPDIR", "AFL_TOKEN_FILE", "AFL_TRACE_PC", "AFL_USE_ASAN",
"AFL_USE_MSAN", "AFL_USE_TRACE_PC", "AFL_USE_UBSAN", "AFL_USE_TSAN",
"AFL_USE_CFISAN", "AFL_USE_LSAN", "AFL_WINE_PATH", "AFL_NO_SNAPSHOT",
"AFL_EXPAND_HAVOC_NOW", "AFL_USE_FASAN", "AFL_USE_QASAN",
"AFL_NYX_HANDLE_INVALID_WRITE", "AFL_NYX_LOG", "AFL_NYX_REUSE_SNAPSHOT",
"AFL_PASSTHROUGH", "AFL_PATH", "AFL_PERFORMANCE_FILE",
"AFL_PERSISTENT_RECORD", "AFL_POST_PROCESS_KEEP_ORIGINAL", "AFL_PRELOAD",
"AFL_TARGET_ENV", "AFL_PYTHON_MODULE", "AFL_QEMU_CUSTOM_BIN",
"AFL_QEMU_COMPCOV", "AFL_QEMU_COMPCOV_DEBUG", "AFL_QEMU_DEBUG_MAPS",
"AFL_QEMU_DISABLE_CACHE", "AFL_QEMU_DRIVER_NO_HOOK", "AFL_QEMU_FORCE_DFL",
"AFL_QEMU_PERSISTENT_ADDR", "AFL_QEMU_PERSISTENT_CNT",
"AFL_QEMU_PERSISTENT_GPR", "AFL_QEMU_PERSISTENT_HOOK",
"AFL_QEMU_PERSISTENT_MEM", "AFL_QEMU_PERSISTENT_RET",
"AFL_QEMU_PERSISTENT_RETADDR_OFFSET", "AFL_QEMU_PERSISTENT_EXITS",
"AFL_QEMU_INST_RANGES", "AFL_QEMU_EXCLUDE_RANGES", "AFL_QEMU_SNAPSHOT",
"AFL_QEMU_TRACK_UNSTABLE", "AFL_QUIET", "AFL_RANDOM_ALLOC_CANARY",
"AFL_REAL_PATH", "AFL_SHUFFLE_QUEUE", "AFL_SKIP_BIN_CHECK",
"AFL_SKIP_CPUFREQ", "AFL_SKIP_CRASHES", "AFL_SKIP_OSSFUZZ", "AFL_STATSD",
"AFL_STATSD_HOST", "AFL_STATSD_PORT", "AFL_STATSD_TAGS_FLAVOR",
"AFL_SYNC_TIME", "AFL_TESTCACHE_SIZE", "AFL_TESTCACHE_ENTRIES",
"AFL_TMIN_EXACT", "AFL_TMPDIR", "AFL_TOKEN_FILE", "AFL_TRACE_PC",
"AFL_USE_ASAN", "AFL_USE_MSAN", "AFL_USE_TRACE_PC", "AFL_USE_UBSAN",
"AFL_USE_TSAN", "AFL_USE_CFISAN", "AFL_USE_LSAN", "AFL_WINE_PATH",
"AFL_NO_SNAPSHOT", "AFL_EXPAND_HAVOC_NOW", "AFL_USE_FASAN", "AFL_USE_QASAN",
"AFL_PRINT_FILENAMES", "AFL_PIZZA_MODE", NULL
};

View File

@ -207,7 +207,7 @@ static __maybe_unused __always_inline unsigned e2k_add64carry_first(
return (unsigned)__builtin_e2k_addcd_c(base, addend, 0);
}
\
#define add64carry_first(base, addend, sum) \
e2k_add64carry_first(base, addend, sum)
@ -218,7 +218,7 @@ static __maybe_unused __always_inline unsigned e2k_add64carry_next(
return (unsigned)__builtin_e2k_addcd_c(base, addend, carry);
}
\
#define add64carry_next(carry, base, addend, sum) \
e2k_add64carry_next(carry, base, addend, sum)
@ -230,7 +230,7 @@ static __maybe_unused __always_inline void e2k_add64carry_last(unsigned carry,
*sum = __builtin_e2k_addcd(base, addend, carry);
}
\
#define add64carry_last(carry, base, addend, sum) \
e2k_add64carry_last(carry, base, addend, sum)
#endif /* __iset__ >= 5 */
@ -311,7 +311,7 @@ static __forceinline char msvc32_add64carry_first(uint64_t base,
base_32h, addend_32h, sum32 + 1);
}
\
#define add64carry_first(base, addend, sum) \
msvc32_add64carry_first(base, addend, sum)
@ -328,7 +328,7 @@ static __forceinline char msvc32_add64carry_next(char carry, uint64_t base,
base_32h, addend_32h, sum32 + 1);
}
\
#define add64carry_next(carry, base, addend, sum) \
msvc32_add64carry_next(carry, base, addend, sum)
@ -345,7 +345,7 @@ static __forceinline void msvc32_add64carry_last(char carry, uint64_t base,
addend_32h, sum32 + 1);
}
\
#define add64carry_last(carry, base, addend, sum) \
msvc32_add64carry_last(carry, base, addend, sum)
#endif /* _MSC_FULL_VER >= 190024231 */
@ -454,7 +454,7 @@ typedef struct {
uint64_t unaligned_64;
} __attribute__((__packed__)) t1ha_unaligned_proxy;
\
#define read_unaligned(ptr, bits) \
(((const t1ha_unaligned_proxy *)((const uint8_t *)(ptr)-offsetof( \
t1ha_unaligned_proxy, unaligned_##bits))) \
@ -539,6 +539,7 @@ static __always_inline const uint64_t *__attribute__((
(void)(ptr); \
\
} while (0)
#endif
#endif /* prefetch */

View File

@ -1734,7 +1734,7 @@ XXH128_hashFromCanonical(XXH_NOESCAPE const XXH128_canonical_t *src);
* These declarations should only be used with static linking.
* Never use them in association with dynamic linking!
*****************************************************************************
*/
*/
/*
* These definitions are only present to allow static allocation
@ -2399,9 +2399,9 @@ XXH_PUBLIC_API XXH_errorcode XXH3_128bits_reset_withSecretandSeed(
#define XXH_NO_STREAM
#undef XXH_NO_STREAM /* don't actually */
#endif /* XXH_DOXYGEN */
/*!
* @}
*/
/*!
* @}
*/
#ifndef XXH_FORCE_MEMORY_ACCESS /* can be defined externally, on command \
line for example */
@ -2614,6 +2614,7 @@ static void *XXH_memcpy(void *dest, const void *src, size_t size) {
_Static_assert((c), m); \
\
} while (0)
#elif defined(__cplusplus) && (__cplusplus >= 201103L) /* C++11 */
#define XXH_STATIC_ASSERT_WITH_MESSAGE(c, m) \
do { \
@ -2621,6 +2622,7 @@ static void *XXH_memcpy(void *dest, const void *src, size_t size) {
static_assert((c), m); \
\
} while (0)
#else
#define XXH_STATIC_ASSERT_WITH_MESSAGE(c, m) \
do { \
@ -2632,6 +2634,7 @@ static void *XXH_memcpy(void *dest, const void *src, size_t size) {
}; \
\
} while (0)
#endif
#define XXH_STATIC_ASSERT(c) XXH_STATIC_ASSERT_WITH_MESSAGE((c), #c)
#endif
@ -2850,7 +2853,7 @@ static int XXH_isLittleEndian(void) {
return one.c[0];
}
\
#define XXH_CPU_LITTLE_ENDIAN XXH_isLittleEndian()
#endif
#endif
@ -4679,6 +4682,7 @@ XXH_FORCE_INLINE xxh_u64x2 XXH_vec_mule(xxh_u32x4 a, xxh_u32x4 b) {
acc = svadd_u64_x(mask, acc, mul); \
\
} while (0)
#endif /* XXH_VECTOR == XXH_SVE */
/* prefetch
@ -4737,12 +4741,14 @@ static const xxh_u8 XXH3_kSecret[XXH_SECRET_DEFAULT_SIZE] = {
};
static const xxh_u64 PRIME_MX1 = 0x165667919E3779F9ULL; /*!<
0b0001011001010110011001111001000110011110001101110111100111111001
*/
static const xxh_u64 PRIME_MX2 = 0x9FB21C651E98DF25ULL; /*!<
0b1001111110110010000111000110010100011110100110001101111100100101
*/
static const xxh_u64 PRIME_MX1 =
0x165667919E3779F9ULL; /*!<
0b0001011001010110011001111001000110011110001101110111100111111001
*/
static const xxh_u64 PRIME_MX2 =
0x9FB21C651E98DF25ULL; /*!<
0b1001111110110010000111000110010100011110100110001101111100100101
*/
#ifdef XXH_OLD_NAMES
#define kSecret XXH3_kSecret
@ -7854,7 +7860,7 @@ XXH3_128bits_digest(XXH_NOESCAPE const XXH3_state_t *state) {
}
#endif /* !XXH_NO_STREAM */
/* 128-bit utility functions */
/* 128-bit utility functions */
#include <string.h> /* memcmp, memcpy */

View File

@ -341,7 +341,7 @@ llvmGetPassPluginInfo() {
using OptimizationLevel = typename PassBuilder::OptimizationLevel;
#endif
#if LLVM_VERSION_MAJOR >= 15
PB.registerFullLinkTimeOptimizationLastEPCallback(
PB.registerFullLinkTimeOptimizationEarlyEPCallback(
#else
PB.registerOptimizerLastEPCallback(
#endif
@ -1304,7 +1304,12 @@ u32 countCallers(Function *F) {
for (auto *U : F->users()) {
if (auto *CI = dyn_cast<CallInst>(U)) { ++callers; }
if (auto *CI = dyn_cast<CallInst>(U)) {
++callers;
(void)(CI);
}
}

View File

@ -1617,7 +1617,7 @@ void __sanitizer_cov_pcs_init(const uintptr_t *pcs_beg,
}
if (pc_filter) {
if (pc_filter && !mod_info->next) {
char PcDescr[1024];
// This function is a part of the sanitizer run-time.
@ -1644,7 +1644,8 @@ void __sanitizer_cov_pcs_init(const uintptr_t *pcs_beg,
}
if (__afl_filter_pcs && strstr(mod_info->name, __afl_filter_pcs_module)) {
if (__afl_filter_pcs && !mod_info->next &&
strstr(mod_info->name, __afl_filter_pcs_module)) {
u32 result_index;
if (locate_in_pcs(PC, &result_index)) {
@ -1669,7 +1670,7 @@ void __sanitizer_cov_pcs_init(const uintptr_t *pcs_beg,
}
mod_info->mapped = 1;
if (__afl_pcmap_ptr) { mod_info->mapped = 1; }
if (__afl_debug) {

View File

@ -180,19 +180,19 @@ struct afl_cmptrs_pass : afl_base_pass {
c = DECL_CONTEXT(c);
if (c && TREE_CODE(c) != TRANSLATION_UNIT_DECL) return false;
/* Check that the first nonstatic data member of the record type
/* Check that the first nonstatic named data member of the record type
is named _M_dataplus. */
for (c = TYPE_FIELDS(t); c; c = DECL_CHAIN(c))
if (TREE_CODE(c) == FIELD_DECL) break;
if (TREE_CODE(c) == FIELD_DECL && DECL_NAME(c)) break;
if (!c || !integer_zerop(DECL_FIELD_BIT_OFFSET(c)) ||
strcmp(IDENTIFIER_POINTER(DECL_NAME(c)), "_M_dataplus") != 0)
return false;
/* Check that the second nonstatic data member of the record type
/* Check that the second nonstatic named data member of the record type
is named _M_string_length. */
tree f2;
for (f2 = DECL_CHAIN(c); f2; f2 = DECL_CHAIN(f2))
if (TREE_CODE(f2) == FIELD_DECL) break;
if (TREE_CODE(f2) == FIELD_DECL && DECL_NAME(f2)) break;
if (!f2 /* No need to check this field's offset. */
|| strcmp(IDENTIFIER_POINTER(DECL_NAME(f2)), "_M_string_length") != 0)
return false;
@ -208,9 +208,12 @@ struct afl_cmptrs_pass : afl_base_pass {
strcmp(IDENTIFIER_POINTER(TYPE_IDENTIFIER(c)), "_Alloc_hider") != 0)
return false;
/* And its first data member is named _M_p. */
/* And its first nonstatic named data member should be named _M_p.
There may be (unnamed) subobjects from empty base classes. We
skip the subobjects, then check the offset of the first data
member. */
for (c = TYPE_FIELDS(c); c; c = DECL_CHAIN(c))
if (TREE_CODE(c) == FIELD_DECL) break;
if (TREE_CODE(c) == FIELD_DECL && DECL_NAME(c)) break;
if (!c || !integer_zerop(DECL_FIELD_BIT_OFFSET(c)) ||
strcmp(IDENTIFIER_POINTER(DECL_NAME(c)), "_M_p") != 0)
return false;

View File

@ -746,7 +746,7 @@ bool AFLdict2filePass::runOnModule(Module &M) {
auto PA = PreservedAnalyses::all();
return PA;
#else
return true;
return false;
#endif
}

View File

@ -128,7 +128,11 @@ llvmGetPassPluginInfo() {
#if LLVM_VERSION_MAJOR <= 13
using OptimizationLevel = typename PassBuilder::OptimizationLevel;
#endif
#if LLVM_VERSION_MAJOR >= 16
PB.registerOptimizerEarlyEPCallback(
#else
PB.registerOptimizerLastEPCallback(
#endif
[](ModulePassManager &MPM, OptimizationLevel OL) {
MPM.addPass(AFLCoverage());
@ -212,10 +216,6 @@ bool AFLCoverage::runOnModule(Module &M) {
u32 rand_seed;
unsigned int cur_loc = 0;
#if LLVM_VERSION_MAJOR >= 11 /* use new pass manager */
auto PA = PreservedAnalyses::all();
#endif
/* Setup random() so we get Actually Random(TM) outputs from AFL_R() */
gettimeofday(&tv, &tz);
rand_seed = tv.tv_sec ^ tv.tv_usec ^ getpid();
@ -1081,7 +1081,7 @@ bool AFLCoverage::runOnModule(Module &M) {
}
#if LLVM_VERSION_MAJOR >= 11 /* use new pass manager */
return PA;
return PreservedAnalyses();
#else
return true;
#endif

View File

@ -680,13 +680,16 @@ bool CmpLogInstructions::runOnModule(Module &M) {
printf("Running cmplog-instructions-pass by andreafioraldi@gmail.com\n");
else
be_quiet = 1;
hookInstrs(M);
bool ret = hookInstrs(M);
verifyModule(M);
#if LLVM_MAJOR >= 11 /* use new pass manager */
return PreservedAnalyses::all();
if (ret == false)
return PreservedAnalyses::all();
else
return PreservedAnalyses();
#else
return true;
return ret;
#endif
}

View File

@ -758,16 +758,16 @@ bool CmpLogRoutines::runOnModule(Module &M) {
printf("Running cmplog-routines-pass by andreafioraldi@gmail.com\n");
else
be_quiet = 1;
hookRtns(M);
#if LLVM_VERSION_MAJOR >= 11 /* use new pass manager */
auto PA = PreservedAnalyses::all();
#endif
bool ret = hookRtns(M);
verifyModule(M);
#if LLVM_VERSION_MAJOR >= 11 /* use new pass manager */
return PA;
if (ret == false)
return PreservedAnalyses::all();
else
return PreservedAnalyses();
#else
return true;
return ret;
#endif
}

View File

@ -442,16 +442,16 @@ bool CmplogSwitches::runOnModule(Module &M) {
printf("Running cmplog-switches-pass by andreafioraldi@gmail.com\n");
else
be_quiet = 1;
hookInstrs(M);
#if LLVM_VERSION_MAJOR >= 11 /* use new pass manager */
auto PA = PreservedAnalyses::all();
#endif
bool ret = hookInstrs(M);
verifyModule(M);
#if LLVM_VERSION_MAJOR >= 11 /* use new pass manager */
return PA;
if (ret == false)
return PreservedAnalyses::all();
else
return PreservedAnalyses();
#else
return true;
return ret;
#endif
}

View File

@ -89,7 +89,7 @@ class CompareTransform : public ModulePass {
#endif
return "cmplog transform";
return "compcov transform";
}
@ -123,7 +123,11 @@ llvmGetPassPluginInfo() {
#if LLVM_VERSION_MAJOR <= 13
using OptimizationLevel = typename PassBuilder::OptimizationLevel;
#endif
#if LLVM_VERSION_MAJOR >= 16
PB.registerOptimizerEarlyEPCallback(
#else
PB.registerOptimizerLastEPCallback(
#endif
[](ModulePassManager &MPM, OptimizationLevel OL) {
MPM.addPass(CompareTransform());
@ -746,6 +750,8 @@ bool CompareTransform::runOnModule(Module &M) {
#endif
bool ret = false;
if ((isatty(2) && getenv("AFL_QUIET") == NULL) || getenv("AFL_DEBUG") != NULL)
printf(
"Running compare-transform-pass by laf.intel@gmail.com, extended by "
@ -753,11 +759,7 @@ bool CompareTransform::runOnModule(Module &M) {
else
be_quiet = 1;
#if LLVM_MAJOR >= 11 /* use new pass manager */
auto PA = PreservedAnalyses::all();
#endif
transformCmps(M, true, true, true, true, true);
if (transformCmps(M, true, true, true, true, true) == true) ret = true;
verifyModule(M);
#if LLVM_MAJOR >= 11 /* use new pass manager */
@ -767,9 +769,18 @@ bool CompareTransform::runOnModule(Module &M) {
}*/
return PA;
if (ret == true) {
return PreservedAnalyses();
} else {
return PreservedAnalyses::all();
}
#else
return true;
return ret;
#endif
}

View File

@ -204,6 +204,8 @@ bool InjectionRoutines::hookRtns(Module &M) {
Function *FuncPtr;
#endif
bool ret = false;
/* iterate over all functions, bbs and instruction and add suitable calls */
for (auto &F : M) {
@ -281,6 +283,7 @@ bool InjectionRoutines::hookRtns(Module &M) {
IRBuilder<> IRB(callInst->getParent());
IRB.SetInsertPoint(callInst);
ret = true;
Value *parameter = callInst->getArgOperand(param);
@ -299,7 +302,7 @@ bool InjectionRoutines::hookRtns(Module &M) {
}
return true;
return ret;
}
@ -328,16 +331,16 @@ bool InjectionRoutines::runOnModule(Module &M) {
if (getenv("AFL_LLVM_INJECTIONS_LDAP")) { doLDAP = true; }
if (getenv("AFL_LLVM_INJECTIONS_XSS")) { doXSS = true; }
hookRtns(M);
#if LLVM_VERSION_MAJOR >= 11 /* use new pass manager */
auto PA = PreservedAnalyses::all();
#endif
bool ret = hookRtns(M);
verifyModule(M);
#if LLVM_VERSION_MAJOR >= 11 /* use new pass manager */
return PA;
if (ret == false)
return PreservedAnalyses::all();
else
return PreservedAnalyses();
#else
return true;
return ret;
#endif
}

View File

@ -189,7 +189,11 @@ llvmGetPassPluginInfo() {
#if LLVM_VERSION_MAJOR <= 13
using OptimizationLevel = typename PassBuilder::OptimizationLevel;
#endif
#if LLVM_VERSION_MAJOR >= 16
PB.registerOptimizerEarlyEPCallback(
#else
PB.registerOptimizerLastEPCallback(
#endif
[](ModulePassManager &MPM, OptimizationLevel OL) {
MPM.addPass(SplitComparesTransform());
@ -935,7 +939,7 @@ size_t SplitComparesTransform::nextPowerOfTwo(size_t in) {
/* splits fcmps into two nested fcmps with sign compare and the rest */
size_t SplitComparesTransform::splitFPCompares(Module &M) {
size_t count = 0;
size_t counts = 0;
LLVMContext &C = M.getContext();
@ -951,7 +955,7 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) {
} else {
return count;
return counts;
}
@ -1004,7 +1008,7 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) {
}
if (!fcomps.size()) { return count; }
if (!fcomps.size()) { return counts; }
IntegerType *Int1Ty = IntegerType::getInt1Ty(C);
@ -1690,11 +1694,11 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) {
#else
ReplaceInstWithInst(FcmpInst->getParent()->getInstList(), ii, PN);
#endif
++count;
++counts;
}
return count;
return counts;
}
@ -1743,10 +1747,6 @@ bool SplitComparesTransform::runOnModule(Module &M) {
}
#if LLVM_MAJOR >= 11
auto PA = PreservedAnalyses::all();
#endif
if (enableFPSplit) {
simplifyFPCompares(M);
@ -1778,15 +1778,7 @@ bool SplitComparesTransform::runOnModule(Module &M) {
auto op0 = CI->getOperand(0);
auto op1 = CI->getOperand(1);
if (!op0 || !op1) {
#if LLVM_MAJOR >= 11
return PA;
#else
return false;
#endif
}
if (!op0 || !op1) { continue; }
auto iTy1 = dyn_cast<IntegerType>(op0->getType());
if (iTy1 && isa<IntegerType>(op1->getType())) {
@ -1814,6 +1806,8 @@ bool SplitComparesTransform::runOnModule(Module &M) {
}
bool ret = count == 0 ? false : true;
bool brokenDebug = false;
if (verifyModule(M, &errs()
#if LLVM_VERSION_MAJOR >= 4 || \
@ -1852,9 +1846,12 @@ bool SplitComparesTransform::runOnModule(Module &M) {
}*/
return PA;
if (ret == false)
return PreservedAnalyses::all();
else
return PreservedAnalyses();
#else
return true;
return ret;
#endif
}

View File

@ -137,7 +137,11 @@ llvmGetPassPluginInfo() {
#if LLVM_VERSION_MAJOR <= 13
using OptimizationLevel = typename PassBuilder::OptimizationLevel;
#endif
#if LLVM_VERSION_MAJOR >= 16
PB.registerOptimizerEarlyEPCallback(
#else
PB.registerOptimizerLastEPCallback(
#endif
[](ModulePassManager &MPM, OptimizationLevel OL) {
MPM.addPass(SplitSwitchesTransform());
@ -516,11 +520,7 @@ bool SplitSwitchesTransform::runOnModule(Module &M) {
else
be_quiet = 1;
#if LLVM_VERSION_MAJOR >= 11 /* use new pass manager */
auto PA = PreservedAnalyses::all();
#endif
splitSwitches(M);
bool ret = splitSwitches(M);
verifyModule(M);
#if LLVM_VERSION_MAJOR >= 11 /* use new pass manager */
@ -530,9 +530,12 @@ bool SplitSwitchesTransform::runOnModule(Module &M) {
}*/
return PA;
if (ret == false)
return PreservedAnalyses::all();
else
return PreservedAnalyses();
#else
return true;
return ret;
#endif
}

View File

@ -215,8 +215,10 @@ if [ "$STATIC" = "1" ]; then
echo Building STATIC binary
# static PIE causes https://github.com/AFLplusplus/AFLplusplus/issues/892
# plugin support requires dynamic linking
QEMU_CONF_FLAGS="$QEMU_CONF_FLAGS \
--static --disable-pie \
--disable-plugins \
--extra-cflags=-DAFL_QEMU_STATIC_BUILD=1 \
"

View File

@ -828,7 +828,8 @@ static void instrument_mode_old_environ(aflcc_state_t *aflcc) {
}
if (getenv("AFL_LLVM_CTX")) aflcc->instrument_opt_mode |= INSTRUMENT_OPT_CTX;
if (getenv("AFL_LLVM_CALLER") || getenv("AFL_LLVM_LTO_CALLER") || getenv("AFL_LLVM_LTO_CTX"))
if (getenv("AFL_LLVM_CALLER") || getenv("AFL_LLVM_LTO_CALLER") ||
getenv("AFL_LLVM_LTO_CTX"))
aflcc->instrument_opt_mode |= INSTRUMENT_OPT_CALLER;
if (getenv("AFL_LLVM_NGRAM_SIZE")) {
@ -1368,6 +1369,13 @@ void mode_final_checkout(aflcc_state_t *aflcc, int argc, char **argv) {
}
if (getenv("AFL_LLVM_DICT2FILE") &&
(getenv("AFL_LLVM_LAF_SPLIT_SWITCHES") ||
getenv("AFL_LLVM_LAF_SPLIT_COMPARES") ||
getenv("AFL_LLVM_LAF_SPLIT_FLOATS") ||
getenv("AFL_LLVM_LAF_TRANSFORM_COMPARES")))
FATAL("AFL_LLVM_DICT2FILE is incompatible with AFL_LLVM_LAF_*");
aflcc->cmplog_mode = getenv("AFL_CMPLOG") || getenv("AFL_LLVM_CMPLOG") ||
getenv("AFL_GCC_CMPLOG");
@ -2379,7 +2387,11 @@ void add_runtime(aflcc_state_t *aflcc) {
if (aflcc->plusplus_mode && strlen(libdir) && strncmp(libdir, "/usr", 4) &&
strncmp(libdir, "/lib", 4)) {
#ifdef __APPLE__
u8 *libdir_opt = strdup("-Wl,-rpath," LLVM_LIBDIR);
#else
u8 *libdir_opt = strdup("-Wl,-rpath=" LLVM_LIBDIR);
#endif
insert_param(aflcc, libdir_opt);
}

View File

@ -34,6 +34,7 @@
#endif
#include <string.h>
#include <strings.h>
#include <time.h>
#include <math.h>
#include <sys/mman.h>
@ -58,6 +59,27 @@ u8 last_intr = 0;
#define AFL_PATH "/usr/local/lib/afl/"
#endif
/* - Some BSD (i.e.: FreeBSD) offer the FAST clock source as
* equivalent to Linux COARSE clock source. Aliasing COARSE to
* FAST on such systems when COARSE is not already defined.
* - macOS has no support of CLOCK_MONOTONIC_COARSE clock type.
*/
#if defined(OS_DARWIN) || defined(OS_SUNOS) || defined(__APPLE__) || \
defined(__sun) || defined(__NetBSD__)
#define CLOCK_MONOTONIC_COARSE CLOCK_MONOTONIC
#elif defined(OS_FREEBSD)
#define CLOCK_MONOTONIC_COARSE CLOCK_MONOTONIC_FAST
#endif
/* Convert seconds to milliseconds. */
#define SEC_TO_MS(sec) ((sec) * 1000)
/* Convert seconds to microseconds. */
#define SEC_TO_US(sec) ((sec) * 1000000)
/* Convert nanoseconds to milliseconds. */
#define NS_TO_MS(ns) ((ns) / 1000000)
/* Convert nanoseconds to microseconds. */
#define NS_TO_US(ns) ((ns) / 1000)
void *afl_memmem(const void *haystack, size_t haystacklen, const void *needle,
size_t needlelen) {
@ -974,12 +996,16 @@ void read_bitmap(u8 *fname, u8 *map, size_t len) {
inline u64 get_cur_time(void) {
struct timeval tv;
struct timezone tz;
struct timespec ts;
int rc = clock_gettime(CLOCK_MONOTONIC_COARSE, &ts);
if (rc == -1) {
gettimeofday(&tv, &tz);
PFATAL("Failed to obtain timestamp (errno = %i: %s)\n", errno,
strerror(errno));
return (tv.tv_sec * 1000ULL) + (tv.tv_usec / 1000);
}
return SEC_TO_MS((uint64_t)ts.tv_sec) + NS_TO_MS((uint64_t)ts.tv_nsec);
}
@ -987,12 +1013,16 @@ inline u64 get_cur_time(void) {
u64 get_cur_time_us(void) {
struct timeval tv;
struct timezone tz;
struct timespec ts;
int rc = clock_gettime(CLOCK_MONOTONIC_COARSE, &ts);
if (rc == -1) {
gettimeofday(&tv, &tz);
PFATAL("Failed to obtain timestamp (errno = %i: %s)\n", errno,
strerror(errno));
return (tv.tv_sec * 1000000ULL) + tv.tv_usec;
}
return SEC_TO_US((uint64_t)ts.tv_sec) + NS_TO_US((uint64_t)ts.tv_nsec);
}

View File

@ -724,7 +724,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
}
/* autodict in Nyx mode */
if (!ignore_autodict) {
if (!ignore_autodict && fsrv->add_extra_func) {
char *x =
alloc_printf("%s/workdir/dump/afl_autodict.txt", fsrv->out_dir_path);
@ -1111,7 +1111,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
}
if ((status & FS_NEW_OPT_SHDMEM_FUZZ)) {
if (status & FS_NEW_OPT_SHDMEM_FUZZ) {
if (fsrv->support_shmem_fuzz) {
@ -1128,7 +1128,9 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
}
if ((status & FS_NEW_OPT_AUTODICT)) {
if (status & FS_NEW_OPT_AUTODICT) {
// even if we do not need the dictionary we have to read it
u32 dict_size;
if (read(fsrv->fsrv_st_fd, &dict_size, 4) != 4) {
@ -1152,12 +1154,11 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
}
while (dict_size != 0) {
while (offset < dict_size) {
rlen = read(fsrv->fsrv_st_fd, dict + offset, dict_size);
rlen = read(fsrv->fsrv_st_fd, dict + offset, dict_size - offset);
if (rlen > 0) {
dict_size -= rlen;
offset += rlen;
} else {
@ -1165,7 +1166,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
FATAL(
"Reading autodictionary fail at position %u with %u bytes "
"left.",
offset, dict_size);
offset, dict_size - offset);
}
@ -1174,14 +1175,24 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
offset = 0;
while (offset < dict_size && (u8)dict[offset] + offset < dict_size) {
fsrv->add_extra_func(fsrv->afl_ptr, dict + offset + 1,
(u8)dict[offset]);
if (!ignore_autodict && fsrv->add_extra_func) {
fsrv->add_extra_func(fsrv->afl_ptr, dict + offset + 1,
(u8)dict[offset]);
count++;
}
offset += (1 + dict[offset]);
count++;
}
if (!be_quiet) { ACTF("Loaded %u autodictionary entries", count); }
if (!be_quiet && count) {
ACTF("Loaded %u autodictionary entries", count);
}
ck_free(dict);
}
@ -1828,6 +1839,8 @@ afl_fsrv_run_target(afl_forkserver_t *fsrv, u32 timeout,
case Timeout:
return FSRV_RUN_TMOUT;
case InvalidWriteToPayload:
if (!!getenv("AFL_NYX_HANDLE_INVALID_WRITE")) { return FSRV_RUN_CRASH; }
/* ??? */
FATAL("FixMe: Nyx InvalidWriteToPayload handler is missing");
break;
@ -1861,7 +1874,7 @@ afl_fsrv_run_target(afl_forkserver_t *fsrv, u32 timeout,
territory. */
#ifdef __linux__
if (!fsrv->nyx_mode) {
if (likely(!fsrv->nyx_mode)) {
memset(fsrv->trace_bits, 0, fsrv->map_size);
MEM_BARRIER();
@ -1931,7 +1944,7 @@ afl_fsrv_run_target(afl_forkserver_t *fsrv, u32 timeout,
if (exec_ms > timeout) {
/* If there was no response from forkserver after timeout seconds,
/* If there was no response from forkserver after timeout milliseconds,
we kill the child. The forkserver should inform us afterwards */
s32 tmp_pid = fsrv->child_pid;
@ -2003,7 +2016,7 @@ afl_fsrv_run_target(afl_forkserver_t *fsrv, u32 timeout,
if (unlikely(fsrv->persistent_record)) {
retval = FSRV_RUN_TMOUT;
persistent_out_fmt = "%s/hangs/RECORD:%06u,cnt:%06u";
persistent_out_fmt = "%s/hangs/RECORD:%06u,cnt:%06u%s%s";
goto store_persistent_record;
}
@ -2039,7 +2052,7 @@ afl_fsrv_run_target(afl_forkserver_t *fsrv, u32 timeout,
if (unlikely(fsrv->persistent_record)) {
retval = FSRV_RUN_CRASH;
persistent_out_fmt = "%s/crashes/RECORD:%06u,cnt:%06u";
persistent_out_fmt = "%s/crashes/RECORD:%06u,cnt:%06u%s%s";
goto store_persistent_record;
}
@ -2066,7 +2079,9 @@ store_persistent_record: {
if (likely(len && data)) {
snprintf(fn, sizeof(fn), persistent_out_fmt, fsrv->persistent_record_dir,
fsrv->persistent_record_cnt, writecnt++);
fsrv->persistent_record_cnt, writecnt++,
afl->file_extension ? "." : "",
afl->file_extension ? (const char *)afl->file_extension : "");
int fd = open(fn, O_CREAT | O_TRUNC | O_WRONLY, 0644);
if (fd >= 0) {

View File

@ -527,15 +527,19 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) {
#ifndef SIMPLE_FILES
queue_fn =
alloc_printf("%s/queue/id:%06u,%s", afl->out_dir, afl->queued_items,
describe_op(afl, new_bits + is_timeout,
NAME_MAX - strlen("id:000000,")));
queue_fn = alloc_printf(
"%s/queue/id:%06u,%s%s%s", afl->out_dir, afl->queued_items,
describe_op(afl, new_bits + is_timeout,
NAME_MAX - strlen("id:000000,")),
afl->file_extension ? "." : "",
afl->file_extension ? (const char *)afl->file_extension : "");
#else
queue_fn =
alloc_printf("%s/queue/id_%06u", afl->out_dir, afl->queued_items);
queue_fn = alloc_printf(
"%s/queue/id_%06u", afl->out_dir, afl->queued_items,
afl->file_extension ? "." : "",
afl->file_extension ? (const char *)afl->file_extension : "");
#endif /* ^!SIMPLE_FILES */
fd = open(queue_fn, O_WRONLY | O_CREAT | O_EXCL, DEFAULT_PERMISSION);
@ -739,14 +743,17 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) {
#ifndef SIMPLE_FILES
snprintf(fn, PATH_MAX, "%s/hangs/id:%06llu,%s", afl->out_dir,
snprintf(fn, PATH_MAX, "%s/hangs/id:%06llu,%s%s%s", afl->out_dir,
afl->saved_hangs,
describe_op(afl, 0, NAME_MAX - strlen("id:000000,")));
describe_op(afl, 0, NAME_MAX - strlen("id:000000,")),
afl->file_extension ? "." : "",
afl->file_extension ? (const char *)afl->file_extension : "");
#else
snprintf(fn, PATH_MAX, "%s/hangs/id_%06llu", afl->out_dir,
afl->saved_hangs);
snprintf(fn, PATH_MAX, "%s/hangs/id_%06llu%s%s", afl->out_dir,
afl->saved_hangs, afl->file_extension ? "." : "",
afl->file_extension ? (const char *)afl->file_extension : "");
#endif /* ^!SIMPLE_FILES */
@ -792,14 +799,18 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) {
#ifndef SIMPLE_FILES
snprintf(fn, PATH_MAX, "%s/crashes/id:%06llu,sig:%02u,%s", afl->out_dir,
afl->saved_crashes, afl->fsrv.last_kill_signal,
describe_op(afl, 0, NAME_MAX - strlen("id:000000,sig:00,")));
snprintf(fn, PATH_MAX, "%s/crashes/id:%06llu,sig:%02u,%s%s%s",
afl->out_dir, afl->saved_crashes, afl->fsrv.last_kill_signal,
describe_op(afl, 0, NAME_MAX - strlen("id:000000,sig:00,")),
afl->file_extension ? "." : "",
afl->file_extension ? (const char *)afl->file_extension : "");
#else
snprintf(fn, PATH_MAX, "%s/crashes/id_%06llu_%02u", afl->out_dir,
afl->saved_crashes, afl->fsrv.last_kill_signal);
snprintf(fn, PATH_MAX, "%s/crashes/id_%06llu_%02u%s%s", afl->out_dir,
afl->saved_crashes, afl->fsrv.last_kill_signal,
afl->file_extension ? "." : "",
afl->file_extension ? (const char *)afl->file_extension : "");
#endif /* ^!SIMPLE_FILES */

View File

@ -742,8 +742,11 @@ void save_auto(afl_state_t *afl) {
for (i = 0; i < MIN((u32)USE_AUTO_EXTRAS, afl->a_extras_cnt); ++i) {
u8 *fn =
alloc_printf("%s/queue/.state/auto_extras/auto_%06u", afl->out_dir, i);
u8 *fn = alloc_printf(
"%s/queue/.state/auto_extras/auto_%06u%s%s", afl->out_dir, i,
afl->file_extension ? "." : "",
afl->file_extension ? (const char *)afl->file_extension : "");
s32 fd;
fd = open(fn, O_WRONLY | O_CREAT | O_TRUNC, DEFAULT_PERMISSION);

View File

@ -1157,18 +1157,22 @@ void perform_dry_run(afl_state_t *afl) {
#ifndef SIMPLE_FILES
snprintf(crash_fn, PATH_MAX, "%s/crashes/id:%06llu,sig:%02u,%s%s",
afl->out_dir, afl->saved_crashes, afl->fsrv.last_kill_signal,
describe_op(afl, 0,
NAME_MAX - strlen("id:000000,sig:00,") -
strlen(use_name)),
use_name);
snprintf(
crash_fn, PATH_MAX, "%s/crashes/id:%06llu,sig:%02u,%s%s%s%s",
afl->out_dir, afl->saved_crashes, afl->fsrv.last_kill_signal,
describe_op(
afl, 0,
NAME_MAX - strlen("id:000000,sig:00,") - strlen(use_name)),
use_name, afl->file_extension ? "." : "",
afl->file_extension ? (const char *)afl->file_extension : "");
#else
snprintf(crash_fn, PATH_MAX, "%s/crashes/id_%06llu_%02u",
afl->out_dir, afl->saved_crashes,
afl->fsrv.last_kill_signal);
snprintf(
crash_fn, PATH_MAX, "%s/crashes/id_%06llu_%02u%s%s", afl->out_dir,
afl->saved_crashes, afl->fsrv.last_kill_signal,
afl->file_extension ? "." : "",
afl->file_extension ? (const char *)afl->file_extension : "");
#endif
@ -1439,7 +1443,9 @@ void pivot_inputs(afl_state_t *afl) {
u32 src_id;
afl->resuming_fuzz = 1;
nfn = alloc_printf("%s/queue/%s", afl->out_dir, rsl);
nfn = alloc_printf(
"%s/queue/%s%s%s", afl->out_dir, rsl, afl->file_extension ? "." : "",
afl->file_extension ? (const char *)afl->file_extension : "");
/* Since we're at it, let's also get the parent and figure out the
appropriate depth for this entry. */
@ -1479,12 +1485,17 @@ void pivot_inputs(afl_state_t *afl) {
}
nfn = alloc_printf("%s/queue/id:%06u,time:0,execs:%llu,orig:%s",
afl->out_dir, id, afl->fsrv.total_execs, use_name);
nfn = alloc_printf(
"%s/queue/id:%06u,time:0,execs:%llu,orig:%s%s%s", afl->out_dir, id,
afl->fsrv.total_execs, use_name, afl->file_extension ? "." : "",
afl->file_extension ? (const char *)afl->file_extension : "");
#else
nfn = alloc_printf("%s/queue/id_%06u", afl->out_dir, id);
nfn = alloc_printf(
"%s/queue/id_%06u%s%s", afl->out_dir, id,
afl->file_extension ? "." : "",
afl->file_extension ? (const char *)afl->file_extension : "");
#endif /* ^!SIMPLE_FILES */

View File

@ -409,6 +409,7 @@ u8 calibrate_case(afl_state_t *afl, struct queue_entry *q, u8 *use_mem,
u32 use_tmout = afl->fsrv.exec_tmout;
u8 *old_sn = afl->stage_name;
u64 calibration_start_us = get_cur_time_us();
if (unlikely(afl->shm.cmplog_mode)) { q->exec_cksum = 0; }
/* Be a bit more generous about timeouts when resuming sessions, or when
@ -504,6 +505,10 @@ u8 calibrate_case(afl_state_t *afl, struct queue_entry *q, u8 *use_mem,
fault = fuzz_run_target(afl, &afl->fsrv, use_tmout);
// update the time spend in calibration after each execution, as those may
// be slow
update_calibration_time(afl, &calibration_start_us);
/* afl->stop_soon is set by the handler for Ctrl+C. When it's pressed,
we want to bail out quickly. */
@ -650,6 +655,7 @@ abort_calibration:
if (!first_run) { show_stats(afl); }
update_calibration_time(afl, &calibration_start_us);
return fault;
}
@ -669,11 +675,16 @@ void sync_fuzzers(afl_state_t *afl) {
afl->stage_max = afl->stage_cur = 0;
afl->cur_depth = 0;
u64 sync_start_us = get_cur_time_us();
/* Look at the entries created for every other fuzzer in the sync directory.
*/
while ((sd_ent = readdir(sd))) {
// since sync can take substantial amounts of time, update time spend every
// iteration
update_sync_time(afl, &sync_start_us);
u8 qd_synced_path[PATH_MAX], qd_path[PATH_MAX];
u32 min_accept = 0, next_min_accept = 0;
@ -811,7 +822,7 @@ void sync_fuzzers(afl_state_t *afl) {
/* See what happens. We rely on save_if_interesting() to catch major
errors and save the test case. */
(void)write_to_testcase(afl, (void **)&mem, st.st_size, 1);
u32 new_len = write_to_testcase(afl, (void **)&mem, st.st_size, 1);
fault = fuzz_run_target(afl, &afl->fsrv, afl->fsrv.exec_tmout);
@ -819,7 +830,7 @@ void sync_fuzzers(afl_state_t *afl) {
afl->syncing_party = sd_ent->d_name;
afl->queued_imported +=
save_if_interesting(afl, mem, st.st_size, fault);
save_if_interesting(afl, mem, new_len, fault);
afl->syncing_party = 0;
munmap(mem, st.st_size);
@ -861,6 +872,9 @@ void sync_fuzzers(afl_state_t *afl) {
if (afl->foreign_sync_cnt) read_foreign_testcases(afl, 0);
// add time in sync one last time
update_sync_time(afl, &sync_start_us);
afl->last_sync_time = get_cur_time();
afl->last_sync_cycle = afl->queue_cycle;
@ -872,8 +886,9 @@ void sync_fuzzers(afl_state_t *afl) {
u8 trim_case(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) {
u8 needs_write = 0, fault = 0;
u32 orig_len = q->len;
u64 trim_start_us = get_cur_time_us();
/* Custom mutator trimmer */
if (afl->custom_mutators_count) {
@ -897,11 +912,15 @@ u8 trim_case(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) {
}
if (custom_trimmed) return trimmed_case;
if (custom_trimmed) {
fault = trimmed_case;
goto abort_trimming;
}
}
u8 needs_write = 0, fault = 0;
u32 trim_exec = 0;
u32 remove_len;
u32 len_p2;
@ -912,7 +931,12 @@ u8 trim_case(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) {
detected, it will still work to some extent, so we don't check for
this. */
if (unlikely(q->len < 5)) { return 0; }
if (unlikely(q->len < 5)) {
fault = 0;
goto abort_trimming;
}
afl->stage_name = afl->stage_name_buf;
afl->bytes_trim_in += q->len;
@ -946,6 +970,8 @@ u8 trim_case(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) {
fault = fuzz_run_target(afl, &afl->fsrv, afl->fsrv.exec_tmout);
update_trim_time(afl, &trim_start_us);
if (afl->stop_soon || fault == FSRV_RUN_ERROR) { goto abort_trimming; }
/* Note that we don't keep track of crashes or hangs here; maybe TODO?
@ -972,7 +998,6 @@ u8 trim_case(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) {
/* Let's save a clean trace, which will be needed by
update_bitmap_score once we're done with the trimming stuff. */
if (!needs_write) {
needs_write = 1;
@ -987,7 +1012,6 @@ u8 trim_case(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) {
}
/* Since this can be slow, update the screen every now and then. */
if (!(trim_exec++ % afl->stats_update_freq)) { show_stats(afl); }
++afl->stage_cur;
@ -1039,8 +1063,9 @@ u8 trim_case(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) {
}
abort_trimming:
afl->bytes_trim_out += q->len;
update_trim_time(afl, &trim_start_us);
return fault;
}

View File

@ -28,10 +28,6 @@
#include "afl-fuzz.h"
#include "envs.h"
s8 interesting_8[] = {INTERESTING_8};
s16 interesting_16[] = {INTERESTING_8, INTERESTING_16};
s32 interesting_32[] = {INTERESTING_8, INTERESTING_16, INTERESTING_32};
char *power_names[POWER_SCHEDULES_NUM] = {"explore", "mmopt", "exploit",
"fast", "coe", "lin",
"quad", "rare", "seek"};

View File

@ -133,6 +133,12 @@ void write_setup_file(afl_state_t *afl, u32 argc, char **argv) {
}
static bool starts_with(char *key, char *line) {
return strncmp(key, line, strlen(key)) == 0;
}
/* load some of the existing stats file when resuming.*/
void load_stats_file(afl_state_t *afl) {
@ -175,58 +181,84 @@ void load_stats_file(afl_state_t *afl) {
strcpy(keystring, lstartptr);
lptr++;
char *nptr;
switch (lineno) {
if (starts_with("run_time", keystring)) {
case 3:
if (!strcmp(keystring, "run_time "))
afl->prev_run_time = 1000 * strtoull(lptr, &nptr, 10);
break;
case 5:
if (!strcmp(keystring, "cycles_done "))
afl->queue_cycle =
strtoull(lptr, &nptr, 10) ? strtoull(lptr, &nptr, 10) + 1 : 0;
break;
case 7:
if (!strcmp(keystring, "execs_done "))
afl->fsrv.total_execs = strtoull(lptr, &nptr, 10);
break;
case 10:
if (!strcmp(keystring, "corpus_count ")) {
afl->prev_run_time = 1000 * strtoull(lptr, &nptr, 10);
u32 corpus_count = strtoul(lptr, &nptr, 10);
if (corpus_count != afl->queued_items) {
}
WARNF(
"queue/ has been modified -- things might not work, you're "
"on your own!");
if (starts_with("cycles_done", keystring)) {
}
afl->queue_cycle =
strtoull(lptr, &nptr, 10) ? strtoull(lptr, &nptr, 10) + 1 : 0;
}
}
break;
case 12:
if (!strcmp(keystring, "corpus_found "))
afl->queued_discovered = strtoul(lptr, &nptr, 10);
break;
case 13:
if (!strcmp(keystring, "corpus_imported "))
afl->queued_imported = strtoul(lptr, &nptr, 10);
break;
case 14:
if (!strcmp(keystring, "max_depth "))
afl->max_depth = strtoul(lptr, &nptr, 10);
break;
case 21:
if (!strcmp(keystring, "saved_crashes "))
afl->saved_crashes = strtoull(lptr, &nptr, 10);
break;
case 22:
if (!strcmp(keystring, "saved_hangs "))
afl->saved_hangs = strtoull(lptr, &nptr, 10);
break;
default:
break;
if (starts_with("calibration_time", keystring)) {
afl->calibration_time_us = strtoull(lptr, &nptr, 10) * 1000000;
}
if (starts_with("sync_time", keystring)) {
afl->sync_time_us = strtoull(lptr, &nptr, 10) * 1000000;
}
if (starts_with("trim_time", keystring)) {
afl->trim_time_us = strtoull(lptr, &nptr, 10) * 1000000;
}
if (starts_with("execs_done", keystring)) {
afl->fsrv.total_execs = strtoull(lptr, &nptr, 10);
}
if (starts_with("corpus_count", keystring)) {
u32 corpus_count = strtoul(lptr, &nptr, 10);
if (corpus_count != afl->queued_items) {
WARNF(
"queue/ has been modified -- things might not work, you're "
"on your own!");
sleep(3);
}
}
if (starts_with("corpus_found", keystring)) {
afl->queued_discovered = strtoul(lptr, &nptr, 10);
}
if (starts_with("corpus_imported", keystring)) {
afl->queued_imported = strtoul(lptr, &nptr, 10);
}
if (starts_with("max_depth", keystring)) {
afl->max_depth = strtoul(lptr, &nptr, 10);
}
if (starts_with("saved_crashes", keystring)) {
afl->saved_crashes = strtoull(lptr, &nptr, 10);
}
if (starts_with("saved_hangs", keystring)) {
afl->saved_hangs = strtoull(lptr, &nptr, 10);
}
@ -300,6 +332,10 @@ void write_stats_file(afl_state_t *afl, u32 t_bytes, double bitmap_cvg,
"cycles_done : %llu\n"
"cycles_wo_finds : %llu\n"
"time_wo_finds : %llu\n"
"fuzz_time : %llu\n"
"calibration_time : %llu\n"
"sync_time : %llu\n"
"trim_time : %llu\n"
"execs_done : %llu\n"
"execs_per_sec : %0.02f\n"
"execs_ps_last_min : %0.02f\n"
@ -337,7 +373,7 @@ void write_stats_file(afl_state_t *afl, u32 t_bytes, double bitmap_cvg,
"\n"
"target_mode : %s%s%s%s%s%s%s%s%s%s\n"
"command_line : %s\n",
(afl->start_time - afl->prev_run_time) / 1000, cur_time / 1000,
(afl->start_time /*- afl->prev_run_time*/) / 1000, cur_time / 1000,
runtime / 1000, (u32)getpid(),
afl->queue_cycle ? (afl->queue_cycle - 1) : 0, afl->cycles_wo_finds,
afl->longest_find_time > cur_time - afl->last_find_time
@ -345,7 +381,13 @@ void write_stats_file(afl_state_t *afl, u32 t_bytes, double bitmap_cvg,
: ((afl->start_time == 0 || afl->last_find_time == 0)
? 0
: (cur_time - afl->last_find_time) / 1000),
afl->fsrv.total_execs, afl->fsrv.total_execs / ((double)(runtime) / 1000),
(runtime -
(afl->calibration_time_us + afl->sync_time_us + afl->trim_time_us) /
1000) /
1000,
afl->calibration_time_us / 1000000, afl->sync_time_us / 1000000,
afl->trim_time_us / 1000000, afl->fsrv.total_execs,
afl->fsrv.total_execs / ((double)(runtime) / 1000),
afl->last_avg_execs_saved, afl->queued_items, afl->queued_favored,
afl->queued_discovered, afl->queued_imported, afl->queued_variable,
afl->max_depth, afl->current_entry, afl->pending_favored,
@ -876,6 +918,10 @@ void show_stats_normal(afl_state_t *afl) {
#endif
if (banner_pad)
for (u32 i = 0; i < banner_pad; ++i)
strcat(banner, " ");
}
SAYF("\n%s\n", banner);
@ -2435,3 +2481,27 @@ void show_init_stats(afl_state_t *afl) {
}
void update_calibration_time(afl_state_t *afl, u64 *time) {
u64 cur = get_cur_time_us();
afl->calibration_time_us += cur - *time;
*time = cur;
}
void update_trim_time(afl_state_t *afl, u64 *time) {
u64 cur = get_cur_time_us();
afl->trim_time_us += cur - *time;
*time = cur;
}
void update_sync_time(afl_state_t *afl, u64 *time) {
u64 cur = get_cur_time_us();
afl->sync_time_us += cur - *time;
*time = cur;
}

View File

@ -5,8 +5,9 @@
Originally written by Michal Zalewski
Now maintained by Marc Heuse <mh@mh-sec.de>,
Heiko Eißfeldt <heiko.eissfeldt@hexco.de> and
Andrea Fioraldi <andreafioraldi@gmail.com>
Dominik Meier <mail@dmnk.co>,
Andrea Fioraldi <andreafioraldi@gmail.com>, and
Heiko Eissfeldt <heiko.eissfeldt@hexco.de>
Copyright 2016, 2017 Google Inc. All rights reserved.
Copyright 2019-2024 AFLplusplus Project. All rights reserved.
@ -199,7 +200,8 @@ static void usage(u8 *argv0, int more_help) {
"Test settings:\n"
" -s seed - use a fixed seed for the RNG\n"
" -V seconds - fuzz for a specified time then terminate\n"
" -V seconds - fuzz for a specified time then terminate (fuzz time "
"only!)\n"
" -E execs - fuzz for an approx. no. of total executions then "
"terminate\n"
" Note: not precise and can have several more "
@ -2073,6 +2075,17 @@ int main(int argc, char **argv_orig, char **envp) {
}
/* Simply code if AFL_TMPDIR is used or not */
if (!afl->afl_env.afl_tmpdir) {
afl->tmp_dir = afl->out_dir;
} else {
afl->tmp_dir = afl->afl_env.afl_tmpdir;
}
write_setup_file(afl, argc, argv);
setup_cmdline_file(afl, argv + optind);
@ -2085,8 +2098,7 @@ int main(int argc, char **argv_orig, char **envp) {
if (!afl->timeout_given) { find_timeout(afl); } // only for resumes!
if ((afl->tmp_dir = afl->afl_env.afl_tmpdir) != NULL &&
!afl->in_place_resume) {
if (afl->afl_env.afl_tmpdir && !afl->in_place_resume) {
char tmpfile[PATH_MAX];
@ -2111,10 +2123,6 @@ int main(int argc, char **argv_orig, char **envp) {
}
} else {
afl->tmp_dir = afl->out_dir;
}
/* If we don't have a file name chosen yet, use a safe default. */
@ -2493,8 +2501,15 @@ int main(int argc, char **argv_orig, char **envp) {
for (entry = 0; entry < afl->queued_items; ++entry)
if (!afl->queue_buf[entry]->disabled)
if (afl->queue_buf[entry]->exec_us > max_ms)
max_ms = afl->queue_buf[entry]->exec_us;
if ((afl->queue_buf[entry]->exec_us / 1000) > max_ms)
max_ms = afl->queue_buf[entry]->exec_us / 1000;
// Add 20% as a safety margin, capped to exec_tmout given in -t option
max_ms *= 1.2;
if (max_ms > afl->fsrv.exec_tmout) max_ms = afl->fsrv.exec_tmout;
// Ensure that there is a sensible timeout even for very fast binaries
if (max_ms < 5) max_ms = 5;
afl->fsrv.exec_tmout = max_ms;
afl->timeout_given = 1;
@ -2530,8 +2545,6 @@ int main(int argc, char **argv_orig, char **envp) {
}
// (void)nice(-20); // does not improve the speed
// real start time, we reset, so this works correctly with -V
afl->start_time = get_cur_time();
#ifdef INTROSPECTION
u32 prev_saved_crashes = 0, prev_saved_tmouts = 0;
@ -2552,6 +2565,9 @@ int main(int argc, char **argv_orig, char **envp) {
OKF("Writing mutation introspection to '%s'", ifn);
#endif
// real start time, we reset, so this works correctly with -V
afl->start_time = get_cur_time();
while (likely(!afl->stop_soon)) {
cull_queue(afl);
@ -2572,6 +2588,13 @@ int main(int argc, char **argv_orig, char **envp) {
sync_fuzzers(afl);
if (!afl->queue_cycle && afl->afl_env.afl_import_first) {
// real start time, we reset, so this works correctly with -V
afl->start_time = get_cur_time();
}
}
++afl->queue_cycle;
@ -3061,7 +3084,7 @@ stop_fuzzing:
afl_fsrv_deinit(&afl->fsrv);
/* remove tmpfile */
if (afl->tmp_dir != NULL && !afl->in_place_resume && afl->fsrv.out_file) {
if (!afl->in_place_resume && afl->fsrv.out_file) {
(void)unlink(afl->fsrv.out_file);

View File

@ -82,6 +82,8 @@ static u8 crash_mode, /* Crash-centric mode? */
remove_shm = 1, /* remove shmem on exit? */
debug; /* debug mode */
static u32 del_len_limit = 1; /* Minimum block deletion length */
static volatile u8 stop_soon; /* Ctrl-C pressed? */
static afl_forkserver_t *fsrv;
@ -480,7 +482,7 @@ next_del_blksize:
}
if (del_len > 1 && in_len >= 1) {
if (del_len > del_len_limit && in_len >= 1) {
del_len /= 2;
goto next_del_blksize;
@ -796,8 +798,9 @@ static void usage(u8 *argv0) {
"Minimization settings:\n"
" -e - solve for edge coverage only, ignore hit counts\n"
" -x - treat non-zero exit codes as crashes\n\n"
" -H - minimize a hang (hang mode)\n"
" -l bytes - set minimum block deletion length to speed up minimization\n"
" -x - treat non-zero exit codes as crashes\n"
" -H - minimize a hang (hang mode)\n\n"
"For additional tips, please consult %s/README.md.\n\n"
@ -829,8 +832,9 @@ static void usage(u8 *argv0) {
int main(int argc, char **argv_orig, char **envp) {
s32 opt;
u8 mem_limit_given = 0, timeout_given = 0, unicorn_mode = 0, use_wine = 0;
s32 opt;
u8 mem_limit_given = 0, timeout_given = 0, unicorn_mode = 0, use_wine = 0,
del_limit_given = 0;
char **use_argv;
char **argv = argv_cpy_dup(argc, argv_orig);
@ -846,7 +850,7 @@ int main(int argc, char **argv_orig, char **envp) {
SAYF(cCYA "afl-tmin" VERSION cRST " by Michal Zalewski\n");
while ((opt = getopt(argc, argv, "+i:o:f:m:t:B:xeAOQUWXYHh")) > 0) {
while ((opt = getopt(argc, argv, "+i:o:f:m:t:l:B:xeAOQUWXYHh")) > 0) {
switch (opt) {
@ -1055,6 +1059,24 @@ int main(int argc, char **argv_orig, char **envp) {
read_bitmap(optarg, mask_bitmap, map_size);
break;
case 'l':
if (del_limit_given) { FATAL("Multiple -l options not supported"); }
del_limit_given = 1;
if (!optarg) { FATAL("Wrong usage of -l"); }
if (optarg[0] == '-') { FATAL("Dangerously low value of -l"); }
del_len_limit = atoi(optarg);
if (del_len_limit < 1 || del_len_limit > TMIN_MAX_FILE) {
FATAL("Value of -l out of range between 1 and TMIN_MAX_FILE");
}
break;
case 'h':
usage(argv[0]);
return -1;

View File

@ -89,8 +89,8 @@ def dump_arch_info():
def dump_regs():
reg_state = {}
for reg in current_arch.all_registers:
reg_val = get_register(reg)
for reg in gef.arch.registers:
reg_val = gef.arch.register(reg)
reg_state[reg.strip().strip("$")] = reg_val
return reg_state
@ -101,7 +101,9 @@ def dump_process_memory(output_dir):
final_segment_list = []
# GEF:
vmmap = get_process_maps()
vmmap = gef.memory.maps
memory = GefMemoryManager()
if not vmmap:
print("No address mapping information found")
return final_segment_list
@ -126,7 +128,7 @@ def dump_process_memory(output_dir):
if entry.is_readable() and not "(deleted)" in entry.path:
try:
# Compress and dump the content to a file
seg_content = read_memory(entry.page_start, entry.size)
seg_content = memory.read(entry.page_start, entry.size)
if seg_content == None:
print(
"Segment empty: @0x{0:016x} (size:UNKNOWN) {1}".format(

View File

@ -111,12 +111,14 @@ def dump_regs():
reg_state = {}
for reg in pwndbg.gdblib.regs.all:
reg_val = pwndbg.gdblib.regs[reg]
if reg_val is None:
continue
# current dumper script looks for register values to be hex strings
# reg_str = "0x{:08x}".format(reg_val)
# if "64" in get_arch():
# reg_str = "0x{:016x}".format(reg_val)
# reg_state[reg.strip().strip('$')] = reg_str
reg_state[reg.strip().strip("$")] = reg_val
reg_state[reg.strip().strip("$")] = int(reg_val)
return reg_state

View File

@ -21,10 +21,10 @@ import zlib
# Unicorn imports
from unicornafl import *
from unicornafl.arm_const import *
from unicornafl.arm64_const import *
from unicornafl.x86_const import *
from unicornafl.mips_const import *
from unicorn.arm_const import *
from unicorn.arm64_const import *
from unicorn.x86_const import *
from unicorn.mips_const import *
# If Capstone libraries are availible (only check once)
try:
@ -87,9 +87,10 @@ class UnicornSimpleHeap(object):
_uc = None # Unicorn engine instance to interact with
_chunks = [] # List of all known chunks
_chunks_freed = [] # List of all freed chunks
_debug_print = False # True to print debug information
def __init__(self, uc, debug_print=False):
def __init__(self, uc, debug_print=False uaf_check=False):
self._uc = uc
self._debug_print = debug_print
@ -101,12 +102,23 @@ class UnicornSimpleHeap(object):
# - Allocate at least 1 4k page of memory to make Unicorn happy
# - Add guard pages at the start and end of the region
total_chunk_size = UNICORN_PAGE_SIZE + ALIGN_PAGE_UP(size) + UNICORN_PAGE_SIZE
if size == 0:
return 0
# Gross but efficient way to find space for the chunk:
chunk = None
for addr in range(self.HEAP_MIN_ADDR, self.HEAP_MAX_ADDR, UNICORN_PAGE_SIZE):
try:
self._uc.mem_map(addr, total_chunk_size, UC_PROT_READ | UC_PROT_WRITE)
chunk = self.HeapChunk(addr, total_chunk_size, size)
if self.uaf_check:
for chunk_freed in self._chunks_freed:
if chunk_freed.is_buffer_in_chunk(chunk.data_addr, 1):
self._chunks_freed.remove(chunk_freed)
break
if self._debug_print:
print(
"Allocating 0x{0:x}-byte chunk @ 0x{1:016x}".format(
@ -148,6 +160,9 @@ class UnicornSimpleHeap(object):
return new_chunk_addr
def free(self, addr):
if addr == 0:
return False
for chunk in self._chunks:
if chunk.is_buffer_in_chunk(addr, 1):
if self._debug_print:
@ -157,9 +172,14 @@ class UnicornSimpleHeap(object):
)
)
self._uc.mem_unmap(chunk.actual_addr, chunk.total_size)
if self.uaf_check:
self._chunks_freed.append(chunk)
self._chunks.remove(chunk)
return True
return False
# Freed an object that doesn't exist. Maybe 'dobule-free' or 'invalid free' vulnerability here.
self._uc.force_crash(UcError(UC_ERR_FETCH_UNMAPPED))
# Implements basic guard-page functionality
def __check_mem_access(self, uc, access, address, size, value, user_data):
@ -179,6 +199,15 @@ class UnicornSimpleHeap(object):
# Force a memory-based crash
uc.force_crash(UcError(UC_ERR_READ_PROT))
if self.uaf_check:
for chunk in self._chunks_freed:
if address >= chunk.actual_addr and (
(address + size) <= (chunk.actual_addr + chunk.total_size)
):
if chunk.is_buffer_in_chunk(address, size):
print("Use-after-free @ 0x{0:016x}".format(address))
uc.force_crash(UcError(UC_ERR_FETCH_UNMAPPED))
# ---------------------------
# ---- Loading function

View File

@ -10,6 +10,7 @@ PROGRAMS = afl-network-client afl-network-server
HASH=\#
CFLAGS += -Wno-pointer-sign
LDFLAGS += -ldl
ifdef STATIC
CFLAGS += -static