mirror of
https://github.com/AFLplusplus/AFLplusplus.git
synced 2025-06-13 02:28:09 +00:00
133
.gitignore
vendored
133
.gitignore
vendored
@ -1,104 +1,107 @@
|
|||||||
.test
|
!coresight_mode
|
||||||
.test2
|
!coresight_mode/coresight-trace
|
||||||
.sync_tmp
|
*.dSYM
|
||||||
.vscode
|
|
||||||
*.o
|
*.o
|
||||||
|
*.o.tmp
|
||||||
|
*.pyc
|
||||||
*.so
|
*.so
|
||||||
*.swp
|
*.swp
|
||||||
*.pyc
|
.sync_tmp
|
||||||
*.dSYM
|
.test
|
||||||
as
|
.test2
|
||||||
a.out
|
.vscode
|
||||||
ld
|
|
||||||
in
|
|
||||||
out
|
|
||||||
core*
|
|
||||||
compile_commands.json
|
|
||||||
afl-analyze
|
afl-analyze
|
||||||
|
afl-analyze.8
|
||||||
afl-as
|
afl-as
|
||||||
|
afl-as.8
|
||||||
|
afl-c++
|
||||||
|
afl-c++.8
|
||||||
|
afl-cc
|
||||||
|
afl-cc.8
|
||||||
afl-clang
|
afl-clang
|
||||||
afl-clang++
|
afl-clang++
|
||||||
afl-clang-fast
|
afl-clang-fast
|
||||||
afl-clang-fast++
|
afl-clang-fast++
|
||||||
afl-clang-lto
|
|
||||||
afl-clang-lto++
|
|
||||||
afl-fuzz
|
|
||||||
afl-g++
|
|
||||||
afl-gcc
|
|
||||||
afl-gcc-fast
|
|
||||||
afl-g++-fast
|
|
||||||
afl-gotcpu
|
|
||||||
afl-ld
|
|
||||||
afl-ld-lto
|
|
||||||
afl-cs-proxy
|
|
||||||
afl-qemu-trace
|
|
||||||
afl-showmap
|
|
||||||
afl-tmin
|
|
||||||
afl-analyze.8
|
|
||||||
afl-as.8
|
|
||||||
afl-clang-fast++.8
|
afl-clang-fast++.8
|
||||||
afl-clang-fast.8
|
afl-clang-fast.8
|
||||||
afl-clang-lto.8
|
afl-clang-lto
|
||||||
|
afl-clang-lto++
|
||||||
afl-clang-lto++.8
|
afl-clang-lto++.8
|
||||||
|
afl-clang-lto.8
|
||||||
afl-cmin.8
|
afl-cmin.8
|
||||||
afl-cmin.bash.8
|
afl-cmin.bash.8
|
||||||
|
afl-cs-proxy
|
||||||
|
afl-frida-trace.so
|
||||||
|
afl-fuzz
|
||||||
afl-fuzz.8
|
afl-fuzz.8
|
||||||
afl-c++.8
|
afl-g++
|
||||||
afl-cc.8
|
|
||||||
afl-gcc.8
|
|
||||||
afl-g++.8
|
afl-g++.8
|
||||||
|
afl-gcc
|
||||||
|
afl-gcc.8
|
||||||
|
afl-gcc-fast
|
||||||
afl-gcc-fast.8
|
afl-gcc-fast.8
|
||||||
|
afl-g++-fast
|
||||||
afl-g++-fast.8
|
afl-g++-fast.8
|
||||||
|
afl-gotcpu
|
||||||
afl-gotcpu.8
|
afl-gotcpu.8
|
||||||
afl-plot.8
|
afl-ld
|
||||||
afl-showmap.8
|
afl-ld-lto
|
||||||
afl-system-config.8
|
|
||||||
afl-tmin.8
|
|
||||||
afl-whatsup.8
|
|
||||||
afl-persistent-config.8
|
|
||||||
afl-c++
|
|
||||||
afl-cc
|
|
||||||
afl-lto
|
afl-lto
|
||||||
afl-lto++
|
afl-lto++
|
||||||
afl-lto++.8
|
afl-lto++.8
|
||||||
afl-lto.8
|
afl-lto.8
|
||||||
|
afl-persistent-config.8
|
||||||
|
afl-plot.8
|
||||||
|
afl-qemu-trace
|
||||||
|
afl-showmap
|
||||||
|
afl-showmap.8
|
||||||
|
afl-system-config.8
|
||||||
|
afl-tmin
|
||||||
|
afl-tmin.8
|
||||||
|
afl-whatsup.8
|
||||||
|
a.out
|
||||||
|
as
|
||||||
|
compile_commands.json
|
||||||
|
core*
|
||||||
|
examples/afl_frida/afl-frida
|
||||||
|
examples/afl_frida/frida-gum-example.c
|
||||||
|
examples/afl_frida/frida-gum.h
|
||||||
|
examples/afl_frida/libtestinstr.so
|
||||||
|
examples/afl_network_proxy/afl-network-client
|
||||||
|
examples/afl_network_proxy/afl-network-server
|
||||||
|
examples/aflpp_driver/libAFLDriver.a
|
||||||
|
examples/aflpp_driver/libAFLQemuDriver.a
|
||||||
|
gmon.out
|
||||||
|
in
|
||||||
|
ld
|
||||||
|
libAFLDriver.a
|
||||||
|
libAFLQemuDriver.a
|
||||||
|
out
|
||||||
qemu_mode/libcompcov/compcovtest
|
qemu_mode/libcompcov/compcovtest
|
||||||
qemu_mode/qemu-*
|
qemu_mode/qemu-*
|
||||||
qemu_mode/qemuafl
|
qemu_mode/qemuafl
|
||||||
unicorn_mode/samples/*/\.test-*
|
|
||||||
unicorn_mode/samples/*/output/
|
|
||||||
test/unittests/unit_maybe_alloc
|
|
||||||
test/unittests/unit_preallocable
|
|
||||||
test/unittests/unit_list
|
|
||||||
test/unittests/unit_rand
|
|
||||||
test/unittests/unit_hash
|
|
||||||
examples/afl_network_proxy/afl-network-server
|
|
||||||
examples/afl_network_proxy/afl-network-client
|
|
||||||
examples/afl_frida/afl-frida
|
|
||||||
examples/afl_frida/libtestinstr.so
|
|
||||||
examples/afl_frida/frida-gum-example.c
|
|
||||||
examples/afl_frida/frida-gum.h
|
|
||||||
examples/aflpp_driver/libAFLDriver.a
|
|
||||||
examples/aflpp_driver/libAFLQemuDriver.a
|
|
||||||
libAFLDriver.a
|
|
||||||
libAFLQemuDriver.a
|
|
||||||
test/.afl_performance
|
test/.afl_performance
|
||||||
test-instr
|
test-instr
|
||||||
test/output
|
test/output
|
||||||
|
test/test-c
|
||||||
|
test/test-cmplog
|
||||||
|
test/test-compcov
|
||||||
test/test-instr.ts
|
test/test-instr.ts
|
||||||
test/test-persistent
|
test/test-persistent
|
||||||
gmon.out
|
test/unittests/unit_hash
|
||||||
afl-frida-trace.so
|
test/unittests/unit_list
|
||||||
|
test/unittests/unit_maybe_alloc
|
||||||
|
test/unittests/unit_preallocable
|
||||||
|
test/unittests/unit_rand
|
||||||
|
unicorn_mode/samples/*/output/
|
||||||
|
unicorn_mode/samples/*/\.test-*
|
||||||
utils/afl_network_proxy/afl-network-client
|
utils/afl_network_proxy/afl-network-client
|
||||||
utils/afl_network_proxy/afl-network-server
|
utils/afl_network_proxy/afl-network-server
|
||||||
utils/plot_ui/afl-plot-ui
|
|
||||||
*.o.tmp
|
|
||||||
utils/afl_proxy/afl-proxy
|
utils/afl_proxy/afl-proxy
|
||||||
utils/optimin/build
|
utils/optimin/build
|
||||||
utils/optimin/optimin
|
utils/optimin/optimin
|
||||||
utils/persistent_mode/persistent_demo
|
utils/persistent_mode/persistent_demo
|
||||||
utils/persistent_mode/persistent_demo_new
|
utils/persistent_mode/persistent_demo_new
|
||||||
utils/persistent_mode/test-instr
|
utils/persistent_mode/test-instr
|
||||||
!coresight_mode
|
utils/plot_ui/afl-plot-ui
|
||||||
!coresight_mode/coresight-trace
|
vuln_prog
|
||||||
vuln_prog
|
|
||||||
|
@ -47,7 +47,7 @@ RUN apt-get update && \
|
|||||||
clang-${LLVM_VERSION} clang-tools-${LLVM_VERSION} libc++1-${LLVM_VERSION} \
|
clang-${LLVM_VERSION} clang-tools-${LLVM_VERSION} libc++1-${LLVM_VERSION} \
|
||||||
libc++-${LLVM_VERSION}-dev libc++abi1-${LLVM_VERSION} libc++abi-${LLVM_VERSION}-dev \
|
libc++-${LLVM_VERSION}-dev libc++abi1-${LLVM_VERSION} libc++abi-${LLVM_VERSION}-dev \
|
||||||
libclang1-${LLVM_VERSION} libclang-${LLVM_VERSION}-dev \
|
libclang1-${LLVM_VERSION} libclang-${LLVM_VERSION}-dev \
|
||||||
libclang-common-${LLVM_VERSION}-dev libclang-cpp${LLVM_VERSION} \
|
libclang-common-${LLVM_VERSION}-dev libclang-rt-${LLVM_VERSION}-dev libclang-cpp${LLVM_VERSION} \
|
||||||
libclang-cpp${LLVM_VERSION}-dev liblld-${LLVM_VERSION} \
|
libclang-cpp${LLVM_VERSION}-dev liblld-${LLVM_VERSION} \
|
||||||
liblld-${LLVM_VERSION}-dev liblldb-${LLVM_VERSION} liblldb-${LLVM_VERSION}-dev \
|
liblld-${LLVM_VERSION}-dev liblldb-${LLVM_VERSION} liblldb-${LLVM_VERSION}-dev \
|
||||||
libllvm${LLVM_VERSION} libomp-${LLVM_VERSION}-dev libomp5-${LLVM_VERSION} \
|
libllvm${LLVM_VERSION} libomp-${LLVM_VERSION}-dev libomp5-${LLVM_VERSION} \
|
||||||
|
@ -228,6 +228,7 @@ Thank you! (For people sending pull requests - please add yourself to this list
|
|||||||
Thomas Rooijakkers David Carlier
|
Thomas Rooijakkers David Carlier
|
||||||
Ruben ten Hove Joey Jiao
|
Ruben ten Hove Joey Jiao
|
||||||
fuzzah @intrigus-lgtm
|
fuzzah @intrigus-lgtm
|
||||||
|
Yaakov Saxon
|
||||||
```
|
```
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
3
TODO.md
3
TODO.md
@ -9,13 +9,12 @@
|
|||||||
- afl-plot to support multiple plot_data
|
- afl-plot to support multiple plot_data
|
||||||
- parallel builds for source-only targets
|
- parallel builds for source-only targets
|
||||||
- get rid of check_binary, replace with more forkserver communication
|
- get rid of check_binary, replace with more forkserver communication
|
||||||
- first fuzzer should be a main automatically
|
- first fuzzer should be a main automatically? not sure.
|
||||||
|
|
||||||
## Maybe
|
## Maybe
|
||||||
|
|
||||||
- forkserver tells afl-fuzz if cmplog is supported and if so enable
|
- forkserver tells afl-fuzz if cmplog is supported and if so enable
|
||||||
it by default, with AFL_CMPLOG_NO=1 (?) set to skip?
|
it by default, with AFL_CMPLOG_NO=1 (?) set to skip?
|
||||||
- afl_custom_fuzz_splice_optin()
|
|
||||||
- afl_custom_splice()
|
- afl_custom_splice()
|
||||||
- cmdline option from-to range for mutations
|
- cmdline option from-to range for mutations
|
||||||
|
|
||||||
|
@ -11,6 +11,16 @@ The `./examples` folder contains examples for custom mutators in python and C.
|
|||||||
|
|
||||||
In `./rust`, you will find rust bindings, including a simple example in `./rust/example` and an example for structured fuzzing, based on lain, in`./rust/example_lain`.
|
In `./rust`, you will find rust bindings, including a simple example in `./rust/example` and an example for structured fuzzing, based on lain, in`./rust/example_lain`.
|
||||||
|
|
||||||
|
## The AFL++ grammar agnostic grammar mutator
|
||||||
|
|
||||||
|
In `./autotokens` you find a token-level fuzzer that does not need to know
|
||||||
|
anything about the grammar of an input as long as it is in ascii and allows
|
||||||
|
whitespace.
|
||||||
|
It is very fast and effective.
|
||||||
|
|
||||||
|
If you are looking for an example of how to effectively create a custom
|
||||||
|
mutator take a look at this one.
|
||||||
|
|
||||||
## The AFL++ Grammar Mutator
|
## The AFL++ Grammar Mutator
|
||||||
|
|
||||||
If you use git to clone AFL++, then the following will incorporate our
|
If you use git to clone AFL++, then the following will incorporate our
|
||||||
|
26
custom_mutators/autotokens/Makefile
Normal file
26
custom_mutators/autotokens/Makefile
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
ifdef debug
|
||||||
|
CPPLAGS += -fsanitize=address
|
||||||
|
CXXFLAGS += -Wall
|
||||||
|
CC := clang
|
||||||
|
CXX := clang++
|
||||||
|
endif
|
||||||
|
ifdef DEBUG
|
||||||
|
CPPFLAGS += -fsanitize=address
|
||||||
|
CXXFLAGS += -Wall
|
||||||
|
CC := clang
|
||||||
|
CXX := clang++
|
||||||
|
endif
|
||||||
|
|
||||||
|
all: autotokens.so
|
||||||
|
|
||||||
|
afl-fuzz-queue.o: ../../src/afl-fuzz-queue.c
|
||||||
|
$(CC) -D_STANDALONE_MODULE=1 -I../../include -g -O3 $(CPPFLAGS) -fPIC -c -o ./afl-fuzz-queue.o ../../src/afl-fuzz-queue.c
|
||||||
|
|
||||||
|
afl-common.o: ../../src/afl-common.c
|
||||||
|
$(CC) -I../../include -g -O3 $(CPPFLAGS) -DBIN_PATH=\"dummy\" -Wno-pointer-sign -fPIC -c -o ./afl-common.o ../../src/afl-common.c
|
||||||
|
|
||||||
|
autotokens.so: afl-fuzz-queue.o afl-common.o autotokens.cpp
|
||||||
|
$(CXX) -Wno-deprecated -g -O3 $(CXXFLAGS) $(CPPFLAGS) -shared -fPIC -o autotokens.so -I../../include autotokens.cpp ./afl-fuzz-queue.o ../../src/afl-performance.o ./afl-common.o
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f autotokens.so *.o *~ core
|
34
custom_mutators/autotokens/README
Normal file
34
custom_mutators/autotokens/README
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
# Autotokens
|
||||||
|
|
||||||
|
This implements an improved autotoken grammar fuzzing idea presented in
|
||||||
|
[Token-Level Fuzzing][https://www.usenix.org/system/files/sec21-salls.pdf].
|
||||||
|
It is a grammar fuzzer without actually knowing the grammar, but only works
|
||||||
|
with text based inputs.
|
||||||
|
|
||||||
|
It is recommended to run with together in an instance with `CMPLOG`.
|
||||||
|
|
||||||
|
If you have a dictionary (`-x`) this improves this custom grammar mutator.
|
||||||
|
|
||||||
|
If **not** running with `CMPLOG`, it is possible to set
|
||||||
|
`AFL_CUSTOM_MUTATOR_ONLY` to concentrate on grammar bug classes.
|
||||||
|
|
||||||
|
Do **not** set `AFL_DISABLE_TRIM` with this custom mutator!
|
||||||
|
|
||||||
|
## Configuration via environment variables
|
||||||
|
|
||||||
|
`AUTOTOKENS_ONLY_FAV` - only use this mutator on favorite queue items
|
||||||
|
`AUTOTOKENS_COMMENT` - what character or string starts a comment which will be
|
||||||
|
removed. Default: `/* ... */`
|
||||||
|
`AUTOTOKENS_FUZZ_COUNT_SHIFT` - reduce the number of fuzzing performed, shifting
|
||||||
|
the value by this number, e.g. 1.
|
||||||
|
`AUTOTOKENS_AUTO_DISABLE` - disable this module if the seeds are not ascii
|
||||||
|
(or no input and no (ascii) dictionary)
|
||||||
|
`AUTOTOKENS_LEARN_DICT` - learn from dictionaries?
|
||||||
|
0 = none
|
||||||
|
1 = only -x or autodict
|
||||||
|
2 = -x, autodict and `CMPLOG`
|
||||||
|
`AUTOTOKENS_CHANGE_MIN` - minimum number of mutations (1-256, default 8)
|
||||||
|
`AUTOTOKENS_CHANGE_MAX` - maximum number of mutations (1-4096, default 64)
|
||||||
|
`AUTOTOKENS_CREATE_FROM_THIN_AIR` - if only one small start file is present and
|
||||||
|
a dictionary loaded then create one initial
|
||||||
|
structure based on the dictionary.
|
1101
custom_mutators/autotokens/autotokens.cpp
Normal file
1101
custom_mutators/autotokens/autotokens.cpp
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,7 +1,14 @@
|
|||||||
|
//
|
||||||
|
// This is an example on how to use afl_custom_send
|
||||||
|
// It writes each mutated data set to /tmp/foo
|
||||||
|
// You can modify this to send to IPC, shared memory, etc.
|
||||||
|
//
|
||||||
// cc -O3 -fPIC -shared -g -o custom_send.so -I../../include custom_send.c
|
// cc -O3 -fPIC -shared -g -o custom_send.so -I../../include custom_send.c
|
||||||
// cd ../..
|
// cd ../..
|
||||||
// afl-cc -o test-instr test-instr.c
|
// afl-cc -o test-instr test-instr.c
|
||||||
// afl-fuzz -i in -o out -- ./test-instr -f /tmp/foo
|
// AFL_CUSTOM_MUTATOR_LIBRARY=custom_mutators/examples/custom_send.so \
|
||||||
|
// afl-fuzz -i in -o out -- ./test-instr -f /tmp/foo
|
||||||
|
//
|
||||||
|
|
||||||
#include "custom_mutator_helpers.h"
|
#include "custom_mutator_helpers.h"
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
Dominik Maier <mail@dmnk.co>
|
Dominik Maier <mail@dmnk.co>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// You need to use -I /path/to/AFLplusplus/include
|
// You need to use -I/path/to/AFLplusplus/include -I.
|
||||||
#include "custom_mutator_helpers.h"
|
#include "custom_mutator_helpers.h"
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
@ -118,6 +118,8 @@ size_t afl_custom_fuzz(my_mutator_t *data, uint8_t *buf, size_t buf_size,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (max_size > mutated_size) { mutated_size = max_size; }
|
||||||
|
|
||||||
*out_buf = mutated_out;
|
*out_buf = mutated_out;
|
||||||
return mutated_size;
|
return mutated_size;
|
||||||
|
|
||||||
|
@ -129,8 +129,8 @@ size_t afl_custom_post_process(post_state_t *data, unsigned char *in_buf,
|
|||||||
|
|
||||||
/* Allocate memory for new buffer, reusing previous allocation if
|
/* Allocate memory for new buffer, reusing previous allocation if
|
||||||
possible. Note we have to use afl-fuzz's own realloc!
|
possible. Note we have to use afl-fuzz's own realloc!
|
||||||
Note that you should only do this if you need to grow the buffer,
|
We use afl_realloc because it is effective.
|
||||||
otherwise work with in_buf, and assign it to *out_buf instead. */
|
You can also work within in_buf, and assign it to *out_buf. */
|
||||||
|
|
||||||
*out_buf = afl_realloc(out_buf, len);
|
*out_buf = afl_realloc(out_buf, len);
|
||||||
|
|
||||||
|
@ -6,10 +6,13 @@
|
|||||||
### Version ++4.06a (dev)
|
### Version ++4.06a (dev)
|
||||||
- afl-fuzz:
|
- afl-fuzz:
|
||||||
- ensure temporary file descriptor is closed when not used
|
- ensure temporary file descriptor is closed when not used
|
||||||
|
- added `AFL_NO_WARN_INSTABILITY`
|
||||||
- afl-cc:
|
- afl-cc:
|
||||||
- add CFI sanitizer variant to gcc targets
|
- add CFI sanitizer variant to gcc targets
|
||||||
- llvm 16 support (thanks to @devnexen!)
|
- llvm 16 support (thanks to @devnexen!)
|
||||||
- support llvm 15 native pcguard changes
|
- support llvm 15 native pcguard changes
|
||||||
|
- new custom module: autotoken, grammar free fuzzer for text inputs
|
||||||
|
- LTO autoken and llvm_mode: added AFL_LLVM_DICT2FILE_NO_MAIN support
|
||||||
- better sanitizer default options support for all tools
|
- better sanitizer default options support for all tools
|
||||||
- unicorn_mode: updated and minor issues fixed
|
- unicorn_mode: updated and minor issues fixed
|
||||||
- frida_mode: fix issue on MacOS
|
- frida_mode: fix issue on MacOS
|
||||||
|
@ -48,6 +48,7 @@ C/C++:
|
|||||||
```c
|
```c
|
||||||
void *afl_custom_init(afl_state_t *afl, unsigned int seed);
|
void *afl_custom_init(afl_state_t *afl, unsigned int seed);
|
||||||
unsigned int afl_custom_fuzz_count(void *data, const unsigned char *buf, size_t buf_size);
|
unsigned int afl_custom_fuzz_count(void *data, const unsigned char *buf, size_t buf_size);
|
||||||
|
void afl_custom_splice_optout(void *data);
|
||||||
size_t afl_custom_fuzz(void *data, unsigned char *buf, size_t buf_size, unsigned char **out_buf, unsigned char *add_buf, size_t add_buf_size, size_t max_size);
|
size_t afl_custom_fuzz(void *data, unsigned char *buf, size_t buf_size, unsigned char **out_buf, unsigned char *add_buf, size_t add_buf_size, size_t max_size);
|
||||||
const char *afl_custom_describe(void *data, size_t max_description_len);
|
const char *afl_custom_describe(void *data, size_t max_description_len);
|
||||||
size_t afl_custom_post_process(void *data, unsigned char *buf, size_t buf_size, unsigned char **out_buf);
|
size_t afl_custom_post_process(void *data, unsigned char *buf, size_t buf_size, unsigned char **out_buf);
|
||||||
@ -72,6 +73,9 @@ def init(seed):
|
|||||||
def fuzz_count(buf):
|
def fuzz_count(buf):
|
||||||
return cnt
|
return cnt
|
||||||
|
|
||||||
|
def splice_optout()
|
||||||
|
pass
|
||||||
|
|
||||||
def fuzz(buf, add_buf, max_size):
|
def fuzz(buf, add_buf, max_size):
|
||||||
return mutated_out
|
return mutated_out
|
||||||
|
|
||||||
@ -132,6 +136,13 @@ def deinit(): # optional for Python
|
|||||||
for a specific queue entry, use this function. This function is most useful
|
for a specific queue entry, use this function. This function is most useful
|
||||||
if `AFL_CUSTOM_MUTATOR_ONLY` is **not** used.
|
if `AFL_CUSTOM_MUTATOR_ONLY` is **not** used.
|
||||||
|
|
||||||
|
- `splice_optout` (optional):
|
||||||
|
|
||||||
|
If this function is present, no splicing target is passed to the `fuzz`
|
||||||
|
function. This saves time if splicing data is not needed by the custom
|
||||||
|
fuzzing function.
|
||||||
|
This function is never called, just needs to be present to activate.
|
||||||
|
|
||||||
- `fuzz` (optional):
|
- `fuzz` (optional):
|
||||||
|
|
||||||
This method performs custom mutations on a given input. It also accepts an
|
This method performs custom mutations on a given input. It also accepts an
|
||||||
@ -139,6 +150,7 @@ def deinit(): # optional for Python
|
|||||||
sense to use it. You would only skip this if `post_process` is used to fix
|
sense to use it. You would only skip this if `post_process` is used to fix
|
||||||
checksums etc. so if you are using it, e.g., as a post processing library.
|
checksums etc. so if you are using it, e.g., as a post processing library.
|
||||||
Note that a length > 0 *must* be returned!
|
Note that a length > 0 *must* be returned!
|
||||||
|
The returned output buffer is under **your** memory management!
|
||||||
|
|
||||||
- `describe` (optional):
|
- `describe` (optional):
|
||||||
|
|
||||||
|
@ -129,6 +129,9 @@ subset of the settings discussed in section 1, with the exception of:
|
|||||||
write all constant string comparisons to this file to be used later with
|
write all constant string comparisons to this file to be used later with
|
||||||
afl-fuzz' `-x` option.
|
afl-fuzz' `-x` option.
|
||||||
|
|
||||||
|
- An option to `AFL_LLVM_DICT2FILE` is `AFL_LLVM_DICT2FILE_NO_MAIN=1` which
|
||||||
|
skill not parse `main()`.
|
||||||
|
|
||||||
- `TMPDIR` and `AFL_KEEP_ASSEMBLY`, since no temporary assembly files are
|
- `TMPDIR` and `AFL_KEEP_ASSEMBLY`, since no temporary assembly files are
|
||||||
created.
|
created.
|
||||||
|
|
||||||
@ -354,6 +357,9 @@ checks or alter some of the more exotic semantics of the tool:
|
|||||||
- Setting `AFL_KEEP_TIMEOUTS` will keep longer running inputs if they reach
|
- Setting `AFL_KEEP_TIMEOUTS` will keep longer running inputs if they reach
|
||||||
new coverage
|
new coverage
|
||||||
|
|
||||||
|
- On the contrary, if you are not interested in any timeouts, you can set
|
||||||
|
`AFL_IGNORE_TIMEOUTS` to get a bit of speed instead.
|
||||||
|
|
||||||
- `AFL_EXIT_ON_SEED_ISSUES` will restore the vanilla afl-fuzz behavior which
|
- `AFL_EXIT_ON_SEED_ISSUES` will restore the vanilla afl-fuzz behavior which
|
||||||
does not allow crashes or timeout seeds in the initial -i corpus.
|
does not allow crashes or timeout seeds in the initial -i corpus.
|
||||||
|
|
||||||
@ -474,7 +480,10 @@ checks or alter some of the more exotic semantics of the tool:
|
|||||||
output from afl-fuzz is redirected to a file or to a pipe.
|
output from afl-fuzz is redirected to a file or to a pipe.
|
||||||
|
|
||||||
- Setting `AFL_NO_STARTUP_CALIBRATION` will skip the initial calibration
|
- Setting `AFL_NO_STARTUP_CALIBRATION` will skip the initial calibration
|
||||||
of all starting seeds, and start fuzzing at once.
|
of all starting seeds, and start fuzzing at once. Use with care, this
|
||||||
|
degrades the fuzzing performance!
|
||||||
|
|
||||||
|
- Setting `AFL_NO_WARN_INSTABILITY` will suppress instability warnings.
|
||||||
|
|
||||||
- In QEMU mode (-Q) and FRIDA mode (-O), `AFL_PATH` will be searched for
|
- In QEMU mode (-Q) and FRIDA mode (-O), `AFL_PATH` will be searched for
|
||||||
afl-qemu-trace and afl-frida-trace.so.
|
afl-qemu-trace and afl-frida-trace.so.
|
||||||
|
@ -534,6 +534,8 @@ dictionaries/FORMAT.dict`.
|
|||||||
* With `afl-clang-fast`, you can set
|
* With `afl-clang-fast`, you can set
|
||||||
`AFL_LLVM_DICT2FILE=/full/path/to/new/file.dic` to automatically generate a
|
`AFL_LLVM_DICT2FILE=/full/path/to/new/file.dic` to automatically generate a
|
||||||
dictionary during target compilation.
|
dictionary during target compilation.
|
||||||
|
Adding `AFL_LLVM_DICT2FILE_NO_MAIN=1` to not parse main (usually command line
|
||||||
|
parameter parsing) is often a good idea too.
|
||||||
* You also have the option to generate a dictionary yourself during an
|
* You also have the option to generate a dictionary yourself during an
|
||||||
independent run of the target, see
|
independent run of the target, see
|
||||||
[utils/libtokencap/README.md](../utils/libtokencap/README.md).
|
[utils/libtokencap/README.md](../utils/libtokencap/README.md).
|
||||||
@ -628,7 +630,8 @@ If you have a large corpus, a corpus from a previous run or are fuzzing in a CI,
|
|||||||
then also set `export AFL_CMPLOG_ONLY_NEW=1` and `export AFL_FAST_CAL=1`.
|
then also set `export AFL_CMPLOG_ONLY_NEW=1` and `export AFL_FAST_CAL=1`.
|
||||||
If the queue in the CI is huge and/or the execution time is slow then you can
|
If the queue in the CI is huge and/or the execution time is slow then you can
|
||||||
also add `AFL_NO_STARTUP_CALIBRATION=1` to skip the initial queue calibration
|
also add `AFL_NO_STARTUP_CALIBRATION=1` to skip the initial queue calibration
|
||||||
phase and start fuzzing at once.
|
phase and start fuzzing at once - but only do this if the calibration phase
|
||||||
|
would be too long for your fuzz run time.
|
||||||
|
|
||||||
You can also use different fuzzers. If you are using AFL spinoffs or AFL
|
You can also use different fuzzers. If you are using AFL spinoffs or AFL
|
||||||
conforming fuzzers, then just use the same -o directory and give it a unique
|
conforming fuzzers, then just use the same -o directory and give it a unique
|
||||||
@ -914,7 +917,8 @@ normal fuzzing campaigns as these are much shorter runnings.
|
|||||||
|
|
||||||
If the queue in the CI is huge and/or the execution time is slow then you can
|
If the queue in the CI is huge and/or the execution time is slow then you can
|
||||||
also add `AFL_NO_STARTUP_CALIBRATION=1` to skip the initial queue calibration
|
also add `AFL_NO_STARTUP_CALIBRATION=1` to skip the initial queue calibration
|
||||||
phase and start fuzzing at once.
|
phase and start fuzzing at once. But only do that if the calibration time is
|
||||||
|
too long for your overall available fuzz run time.
|
||||||
|
|
||||||
1. Always:
|
1. Always:
|
||||||
* LTO has a much longer compile time which is diametrical to short fuzzing -
|
* LTO has a much longer compile time which is diametrical to short fuzzing -
|
||||||
@ -935,7 +939,7 @@ phase and start fuzzing at once.
|
|||||||
3. Also randomize the afl-fuzz runtime options, e.g.:
|
3. Also randomize the afl-fuzz runtime options, e.g.:
|
||||||
* 65% for `AFL_DISABLE_TRIM`
|
* 65% for `AFL_DISABLE_TRIM`
|
||||||
* 50% for `AFL_KEEP_TIMEOUTS`
|
* 50% for `AFL_KEEP_TIMEOUTS`
|
||||||
* 50% use a dictionary generated by `AFL_LLVM_DICT2FILE`
|
* 50% use a dictionary generated by `AFL_LLVM_DICT2FILE` + `AFL_LLVM_DICT2FILE_NO_MAIN=1`
|
||||||
* 40% use MOpt (`-L 0`)
|
* 40% use MOpt (`-L 0`)
|
||||||
* 40% for `AFL_EXPAND_HAVOC_NOW`
|
* 40% for `AFL_EXPAND_HAVOC_NOW`
|
||||||
* 20% for old queue processing (`-Z`)
|
* 20% for old queue processing (`-Z`)
|
||||||
|
@ -2,8 +2,9 @@ PWD:=$(shell pwd)/
|
|||||||
ROOT:=$(PWD)../../../
|
ROOT:=$(PWD)../../../
|
||||||
BUILD_DIR:=$(PWD)build/
|
BUILD_DIR:=$(PWD)build/
|
||||||
|
|
||||||
|
TEST_CMPLOG_BASENAME=compcovtest
|
||||||
TEST_CMPLOG_SRC=$(PWD)cmplog.c
|
TEST_CMPLOG_SRC=$(PWD)cmplog.c
|
||||||
TEST_CMPLOG_OBJ=$(BUILD_DIR)compcovtest
|
TEST_CMPLOG_OBJ=$(BUILD_DIR)$(TEST_CMPLOG_BASENAME)
|
||||||
|
|
||||||
TEST_BIN:=$(PWD)../../build/test
|
TEST_BIN:=$(PWD)../../build/test
|
||||||
|
|
||||||
@ -13,7 +14,7 @@ CMP_LOG_INPUT:=$(TEST_DATA_DIR)in
|
|||||||
QEMU_OUT:=$(BUILD_DIR)qemu-out
|
QEMU_OUT:=$(BUILD_DIR)qemu-out
|
||||||
FRIDA_OUT:=$(BUILD_DIR)frida-out
|
FRIDA_OUT:=$(BUILD_DIR)frida-out
|
||||||
|
|
||||||
.PHONY: all 32 clean qemu frida frida-nocmplog format
|
.PHONY: all 32 clean qemu frida frida-nocmplog frida-unprefixedpath format
|
||||||
|
|
||||||
all: $(TEST_CMPLOG_OBJ)
|
all: $(TEST_CMPLOG_OBJ)
|
||||||
make -C $(ROOT)frida_mode/
|
make -C $(ROOT)frida_mode/
|
||||||
@ -64,6 +65,18 @@ frida-nocmplog: $(TEST_CMPLOG_OBJ) $(CMP_LOG_INPUT)
|
|||||||
-- \
|
-- \
|
||||||
$(TEST_CMPLOG_OBJ) @@
|
$(TEST_CMPLOG_OBJ) @@
|
||||||
|
|
||||||
|
|
||||||
|
frida-unprefixedpath: $(TEST_CMPLOG_OBJ) $(CMP_LOG_INPUT)
|
||||||
|
PATH=$(BUILD_DIR) $(ROOT)afl-fuzz \
|
||||||
|
-O \
|
||||||
|
-i $(TEST_DATA_DIR) \
|
||||||
|
-o $(FRIDA_OUT) \
|
||||||
|
-c 0 \
|
||||||
|
-l 3AT \
|
||||||
|
-Z \
|
||||||
|
-- \
|
||||||
|
$(TEST_CMPLOG_BASENAME) @@
|
||||||
|
|
||||||
debug: $(TEST_CMPLOG_OBJ) $(CMP_LOG_INPUT)
|
debug: $(TEST_CMPLOG_OBJ) $(CMP_LOG_INPUT)
|
||||||
gdb \
|
gdb \
|
||||||
--ex 'set environment LD_PRELOAD=$(ROOT)afl-frida-trace.so' \
|
--ex 'set environment LD_PRELOAD=$(ROOT)afl-frida-trace.so' \
|
||||||
|
@ -19,6 +19,9 @@ frida:
|
|||||||
frida-nocmplog:
|
frida-nocmplog:
|
||||||
@gmake frida-nocmplog
|
@gmake frida-nocmplog
|
||||||
|
|
||||||
|
frida-unprefixedpath:
|
||||||
|
@gmake frida-unprefixedpath
|
||||||
|
|
||||||
format:
|
format:
|
||||||
@gmake format
|
@gmake format
|
||||||
|
|
||||||
|
@ -344,6 +344,7 @@ enum {
|
|||||||
/* 12 */ PY_FUNC_INTROSPECTION,
|
/* 12 */ PY_FUNC_INTROSPECTION,
|
||||||
/* 13 */ PY_FUNC_DESCRIBE,
|
/* 13 */ PY_FUNC_DESCRIBE,
|
||||||
/* 14 */ PY_FUNC_FUZZ_SEND,
|
/* 14 */ PY_FUNC_FUZZ_SEND,
|
||||||
|
/* 15 */ PY_FUNC_SPLICE_OPTOUT,
|
||||||
PY_FUNC_COUNT
|
PY_FUNC_COUNT
|
||||||
|
|
||||||
};
|
};
|
||||||
@ -398,7 +399,7 @@ typedef struct afl_env_vars {
|
|||||||
afl_cycle_schedules, afl_expand_havoc, afl_statsd, afl_cmplog_only_new,
|
afl_cycle_schedules, afl_expand_havoc, afl_statsd, afl_cmplog_only_new,
|
||||||
afl_exit_on_seed_issues, afl_try_affinity, afl_ignore_problems,
|
afl_exit_on_seed_issues, afl_try_affinity, afl_ignore_problems,
|
||||||
afl_keep_timeouts, afl_pizza_mode, afl_no_crash_readme,
|
afl_keep_timeouts, afl_pizza_mode, afl_no_crash_readme,
|
||||||
afl_no_startup_calibration;
|
afl_ignore_timeouts, afl_no_startup_calibration, afl_no_warn_instability;
|
||||||
|
|
||||||
u8 *afl_tmpdir, *afl_custom_mutator_library, *afl_python_module, *afl_path,
|
u8 *afl_tmpdir, *afl_custom_mutator_library, *afl_python_module, *afl_path,
|
||||||
*afl_hang_tmout, *afl_forksrv_init_tmout, *afl_preload,
|
*afl_hang_tmout, *afl_forksrv_init_tmout, *afl_preload,
|
||||||
@ -495,6 +496,7 @@ typedef struct afl_state {
|
|||||||
no_unlink, /* do not unlink cur_input */
|
no_unlink, /* do not unlink cur_input */
|
||||||
debug, /* Debug mode */
|
debug, /* Debug mode */
|
||||||
custom_only, /* Custom mutator only mode */
|
custom_only, /* Custom mutator only mode */
|
||||||
|
custom_splice_optout, /* Custom mutator no splice buffer */
|
||||||
is_main_node, /* if this is the main node */
|
is_main_node, /* if this is the main node */
|
||||||
is_secondary_node, /* if this is a secondary instance */
|
is_secondary_node, /* if this is a secondary instance */
|
||||||
pizza_is_served; /* pizza mode */
|
pizza_is_served; /* pizza mode */
|
||||||
@ -829,17 +831,29 @@ struct custom_mutator {
|
|||||||
u32 (*afl_custom_fuzz_count)(void *data, const u8 *buf, size_t buf_size);
|
u32 (*afl_custom_fuzz_count)(void *data, const u8 *buf, size_t buf_size);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Perform custom mutations on a given input
|
* Opt-out of a splicing input for the fuzz mutator
|
||||||
*
|
*
|
||||||
* (Optional for now. Required in the future)
|
* Empty dummy function. It's presence tells afl-fuzz not to pass a
|
||||||
|
* splice data pointer and len.
|
||||||
*
|
*
|
||||||
* @param data pointer returned in afl_custom_init by this custom mutator
|
* @param data pointer returned in afl_custom_init by this custom mutator
|
||||||
|
* @noreturn
|
||||||
|
*/
|
||||||
|
void (*afl_custom_splice_optout)(void *data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Perform custom mutations on a given input
|
||||||
|
*
|
||||||
|
* (Optional)
|
||||||
|
*
|
||||||
|
* Getting an add_buf can be skipped by using afl_custom_splice_optout().
|
||||||
|
*
|
||||||
|
* @param[in] data Pointer returned in afl_custom_init by this custom mutator
|
||||||
* @param[in] buf Pointer to the input data to be mutated and the mutated
|
* @param[in] buf Pointer to the input data to be mutated and the mutated
|
||||||
* output
|
* output
|
||||||
* @param[in] buf_size Size of the input/output data
|
* @param[in] buf_size Size of the input/output data
|
||||||
* @param[out] out_buf the new buffer. We may reuse *buf if large enough.
|
* @param[out] out_buf The new buffer, under your memory mgmt.
|
||||||
* *out_buf = NULL is treated as FATAL.
|
* @param[in] add_buf Buffer containing an additional test case (splicing)
|
||||||
* @param[in] add_buf Buffer containing the additional test case
|
|
||||||
* @param[in] add_buf_size Size of the additional test case
|
* @param[in] add_buf_size Size of the additional test case
|
||||||
* @param[in] max_size Maximum size of the mutated output. The mutation must
|
* @param[in] max_size Maximum size of the mutated output. The mutation must
|
||||||
* not produce data larger than max_size.
|
* not produce data larger than max_size.
|
||||||
@ -1057,6 +1071,7 @@ u8 havoc_mutation_probability_py(void *);
|
|||||||
u8 queue_get_py(void *, const u8 *);
|
u8 queue_get_py(void *, const u8 *);
|
||||||
const char *introspection_py(void *);
|
const char *introspection_py(void *);
|
||||||
u8 queue_new_entry_py(void *, const u8 *, const u8 *);
|
u8 queue_new_entry_py(void *, const u8 *, const u8 *);
|
||||||
|
void splice_optout(void *);
|
||||||
void deinit_py(void *);
|
void deinit_py(void *);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -364,9 +364,9 @@
|
|||||||
* *
|
* *
|
||||||
***********************************************************/
|
***********************************************************/
|
||||||
|
|
||||||
/* Call count interval between reseeding the libc PRNG from /dev/urandom: */
|
/* Call count interval between reseeding the PRNG from /dev/urandom: */
|
||||||
|
|
||||||
#define RESEED_RNG 100000
|
#define RESEED_RNG 2500000
|
||||||
|
|
||||||
/* The default maximum testcase cache size in MB, 0 = disable.
|
/* The default maximum testcase cache size in MB, 0 = disable.
|
||||||
A value between 50 and 250 is a good default value. Note that the
|
A value between 50 and 250 is a good default value. Note that the
|
||||||
@ -491,10 +491,14 @@
|
|||||||
|
|
||||||
#define AFL_TXT_MIN_LEN 12
|
#define AFL_TXT_MIN_LEN 12
|
||||||
|
|
||||||
|
/* Maximum length of a queue input to be evaluated for "is_ascii"? */
|
||||||
|
|
||||||
|
#define AFL_TXT_MAX_LEN 65535
|
||||||
|
|
||||||
/* What is the minimum percentage of ascii characters present to be classifed
|
/* What is the minimum percentage of ascii characters present to be classifed
|
||||||
as "is_ascii"? */
|
as "is_ascii"? */
|
||||||
|
|
||||||
#define AFL_TXT_MIN_PERCENT 94
|
#define AFL_TXT_MIN_PERCENT 99
|
||||||
|
|
||||||
/* How often to perform ASCII mutations 0 = disable, 1-8 are good values */
|
/* How often to perform ASCII mutations 0 = disable, 1-8 are good values */
|
||||||
|
|
||||||
|
@ -104,6 +104,7 @@ static char *afl_environment_variables[] = {
|
|||||||
"AFL_HARDEN",
|
"AFL_HARDEN",
|
||||||
"AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES",
|
"AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES",
|
||||||
"AFL_IGNORE_PROBLEMS",
|
"AFL_IGNORE_PROBLEMS",
|
||||||
|
"AFL_IGNORE_TIMEOUTS",
|
||||||
"AFL_IGNORE_UNKNOWN_ENVS",
|
"AFL_IGNORE_UNKNOWN_ENVS",
|
||||||
"AFL_IMPORT_FIRST",
|
"AFL_IMPORT_FIRST",
|
||||||
"AFL_INPUT_LEN_MIN",
|
"AFL_INPUT_LEN_MIN",
|
||||||
@ -133,6 +134,7 @@ static char *afl_environment_variables[] = {
|
|||||||
"AFL_LLVM_CTX",
|
"AFL_LLVM_CTX",
|
||||||
"AFL_LLVM_CTX_K",
|
"AFL_LLVM_CTX_K",
|
||||||
"AFL_LLVM_DICT2FILE",
|
"AFL_LLVM_DICT2FILE",
|
||||||
|
"AFL_LLVM_DICT2FILE_NO_MAIN",
|
||||||
"AFL_LLVM_DOCUMENT_IDS",
|
"AFL_LLVM_DOCUMENT_IDS",
|
||||||
"AFL_LLVM_INSTRIM_LOOPHEAD",
|
"AFL_LLVM_INSTRIM_LOOPHEAD",
|
||||||
"AFL_LLVM_INSTRUMENT",
|
"AFL_LLVM_INSTRUMENT",
|
||||||
@ -171,6 +173,7 @@ static char *afl_environment_variables[] = {
|
|||||||
"AFL_NO_UI",
|
"AFL_NO_UI",
|
||||||
"AFL_NO_PYTHON",
|
"AFL_NO_PYTHON",
|
||||||
"AFL_NO_STARTUP_CALIBRATION",
|
"AFL_NO_STARTUP_CALIBRATION",
|
||||||
|
"AFL_NO_WARN_INSTABILITY",
|
||||||
"AFL_UNTRACER_FILE",
|
"AFL_UNTRACER_FILE",
|
||||||
"AFL_LLVM_USE_TRACE_PC",
|
"AFL_LLVM_USE_TRACE_PC",
|
||||||
"AFL_MAP_SIZE",
|
"AFL_MAP_SIZE",
|
||||||
|
@ -43,7 +43,7 @@ typedef enum NyxReturnValue {
|
|||||||
Normal,
|
Normal,
|
||||||
Crash,
|
Crash,
|
||||||
Asan,
|
Asan,
|
||||||
Timout,
|
Timeout,
|
||||||
InvalidWriteToPayload,
|
InvalidWriteToPayload,
|
||||||
Error,
|
Error,
|
||||||
IoError,
|
IoError,
|
||||||
|
@ -167,6 +167,10 @@ Just specify `AFL_LLVM_DICT2FILE=/absolute/path/file.txt` and during compilation
|
|||||||
all constant string compare parameters will be written to this file to be used
|
all constant string compare parameters will be written to this file to be used
|
||||||
with afl-fuzz' `-x` option.
|
with afl-fuzz' `-x` option.
|
||||||
|
|
||||||
|
Adding `AFL_LLVM_DICT2FILE_NO_MAIN=1` will skip parsing `main()` which often
|
||||||
|
does command line parsing which has string comparisons that are not helpful
|
||||||
|
for fuzzing.
|
||||||
|
|
||||||
## 6) AFL++ Context Sensitive Branch Coverage
|
## 6) AFL++ Context Sensitive Branch Coverage
|
||||||
|
|
||||||
### What is this?
|
### What is this?
|
||||||
|
@ -236,6 +236,7 @@ class ModuleSanitizerCoverageLTO
|
|||||||
// const SpecialCaseList * Allowlist;
|
// const SpecialCaseList * Allowlist;
|
||||||
// const SpecialCaseList * Blocklist;
|
// const SpecialCaseList * Blocklist;
|
||||||
uint32_t autodictionary = 1;
|
uint32_t autodictionary = 1;
|
||||||
|
uint32_t autodictionary_no_main = 0;
|
||||||
uint32_t inst = 0;
|
uint32_t inst = 0;
|
||||||
uint32_t afl_global_id = 0;
|
uint32_t afl_global_id = 0;
|
||||||
uint32_t unhandled = 0;
|
uint32_t unhandled = 0;
|
||||||
@ -411,7 +412,8 @@ bool ModuleSanitizerCoverageLTO::instrumentModule(
|
|||||||
|
|
||||||
/* Show a banner */
|
/* Show a banner */
|
||||||
setvbuf(stdout, NULL, _IONBF, 0);
|
setvbuf(stdout, NULL, _IONBF, 0);
|
||||||
if (getenv("AFL_DEBUG")) debug = 1;
|
if (getenv("AFL_DEBUG")) { debug = 1; }
|
||||||
|
if (getenv("AFL_LLVM_DICT2FILE_NO_MAIN")) { autodictionary_no_main = 1; }
|
||||||
|
|
||||||
if ((isatty(2) && !getenv("AFL_QUIET")) || debug) {
|
if ((isatty(2) && !getenv("AFL_QUIET")) || debug) {
|
||||||
|
|
||||||
@ -503,6 +505,13 @@ bool ModuleSanitizerCoverageLTO::instrumentModule(
|
|||||||
|
|
||||||
if (!isInInstrumentList(&F, MNAME) || !F.size()) { continue; }
|
if (!isInInstrumentList(&F, MNAME) || !F.size()) { continue; }
|
||||||
|
|
||||||
|
if (autodictionary_no_main &&
|
||||||
|
(!F.getName().compare("main") || !F.getName().compare("_main"))) {
|
||||||
|
|
||||||
|
continue;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
for (auto &BB : F) {
|
for (auto &BB : F) {
|
||||||
|
|
||||||
for (auto &IN : BB) {
|
for (auto &IN : BB) {
|
||||||
|
@ -1518,9 +1518,13 @@ void __sanitizer_cov_trace_pc_guard_init(uint32_t *start, uint32_t *stop) {
|
|||||||
|
|
||||||
_is_sancov = 1;
|
_is_sancov = 1;
|
||||||
|
|
||||||
__afl_auto_first();
|
if (!getenv("AFL_DUMP_MAP_SIZE")) {
|
||||||
__afl_auto_second();
|
|
||||||
__afl_auto_early();
|
__afl_auto_first();
|
||||||
|
__afl_auto_second();
|
||||||
|
__afl_auto_early();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
if (__afl_debug) {
|
if (__afl_debug) {
|
||||||
|
|
||||||
@ -1534,6 +1538,16 @@ void __sanitizer_cov_trace_pc_guard_init(uint32_t *start, uint32_t *stop) {
|
|||||||
|
|
||||||
if (start == stop || *start) return;
|
if (start == stop || *start) return;
|
||||||
|
|
||||||
|
x = getenv("AFL_INST_RATIO");
|
||||||
|
if (x) { inst_ratio = (u32)atoi(x); }
|
||||||
|
|
||||||
|
if (!inst_ratio || inst_ratio > 100) {
|
||||||
|
|
||||||
|
fprintf(stderr, "[-] ERROR: Invalid AFL_INST_RATIO (must be 1-100).\n");
|
||||||
|
abort();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// If a dlopen of an instrumented library happens after the forkserver then
|
// If a dlopen of an instrumented library happens after the forkserver then
|
||||||
// we have a problem as we cannot increase the coverage map anymore.
|
// we have a problem as we cannot increase the coverage map anymore.
|
||||||
if (__afl_already_initialized_forkserver) {
|
if (__afl_already_initialized_forkserver) {
|
||||||
@ -1554,74 +1568,34 @@ void __sanitizer_cov_trace_pc_guard_init(uint32_t *start, uint32_t *stop) {
|
|||||||
|
|
||||||
while (start < stop) {
|
while (start < stop) {
|
||||||
|
|
||||||
*(start++) = offset;
|
if (likely(inst_ratio == 100) || R(100) < inst_ratio)
|
||||||
|
*start = offset;
|
||||||
|
else
|
||||||
|
*start = 0; // write to map[0]
|
||||||
if (unlikely(++offset >= __afl_final_loc)) { offset = 4; }
|
if (unlikely(++offset >= __afl_final_loc)) { offset = 4; }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
return; // we are done for this special case
|
||||||
|
|
||||||
x = getenv("AFL_INST_RATIO");
|
|
||||||
if (x) { inst_ratio = (u32)atoi(x); }
|
|
||||||
|
|
||||||
if (!inst_ratio || inst_ratio > 100) {
|
|
||||||
|
|
||||||
fprintf(stderr, "[-] ERROR: Invalid AFL_INST_RATIO (must be 1-100).\n");
|
|
||||||
abort();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* instrumented code is loaded *after* our forkserver is up. this is a
|
|
||||||
problem. We cannot prevent collisions then :( */
|
|
||||||
/*
|
|
||||||
if (__afl_already_initialized_forkserver &&
|
|
||||||
__afl_final_loc + 1 + stop - start > __afl_map_size) {
|
|
||||||
|
|
||||||
if (__afl_debug) {
|
|
||||||
|
|
||||||
fprintf(stderr, "Warning: new instrumented code after the forkserver!\n");
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
__afl_final_loc = 2;
|
|
||||||
|
|
||||||
if (1 + stop - start > __afl_map_size) {
|
|
||||||
|
|
||||||
*(start++) = ++__afl_final_loc;
|
|
||||||
|
|
||||||
while (start < stop) {
|
|
||||||
|
|
||||||
if (R(100) < inst_ratio)
|
|
||||||
*start = ++__afl_final_loc % __afl_map_size;
|
|
||||||
else
|
|
||||||
*start = 4;
|
|
||||||
|
|
||||||
start++;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Make sure that the first element in the range is always set - we use that
|
/* Make sure that the first element in the range is always set - we use that
|
||||||
to avoid duplicate calls (which can happen as an artifact of the underlying
|
to avoid duplicate calls (which can happen as an artifact of the underlying
|
||||||
implementation in LLVM). */
|
implementation in LLVM). */
|
||||||
|
|
||||||
|
if (__afl_final_loc < 3) __afl_final_loc = 3; // we skip the first 4 entries
|
||||||
|
|
||||||
*(start++) = ++__afl_final_loc;
|
*(start++) = ++__afl_final_loc;
|
||||||
|
|
||||||
while (start < stop) {
|
while (start < stop) {
|
||||||
|
|
||||||
if (R(100) < inst_ratio)
|
if (likely(inst_ratio == 100) || R(100) < inst_ratio)
|
||||||
*start = ++__afl_final_loc;
|
*start = ++__afl_final_loc;
|
||||||
else
|
else
|
||||||
*start = 4;
|
*start = 0; // write to map[0]
|
||||||
|
|
||||||
start++;
|
start++;
|
||||||
|
|
||||||
|
@ -182,7 +182,7 @@ bool AFLdict2filePass::runOnModule(Module &M) {
|
|||||||
|
|
||||||
DenseMap<Value *, std::string *> valueMap;
|
DenseMap<Value *, std::string *> valueMap;
|
||||||
char *ptr;
|
char *ptr;
|
||||||
int found = 0;
|
int found = 0, handle_main = 1;
|
||||||
|
|
||||||
/* Show a banner */
|
/* Show a banner */
|
||||||
setvbuf(stdout, NULL, _IONBF, 0);
|
setvbuf(stdout, NULL, _IONBF, 0);
|
||||||
@ -192,10 +192,14 @@ bool AFLdict2filePass::runOnModule(Module &M) {
|
|||||||
SAYF(cCYA "afl-llvm-dict2file" VERSION cRST
|
SAYF(cCYA "afl-llvm-dict2file" VERSION cRST
|
||||||
" by Marc \"vanHauser\" Heuse <mh@mh-sec.de>\n");
|
" by Marc \"vanHauser\" Heuse <mh@mh-sec.de>\n");
|
||||||
|
|
||||||
} else
|
} else {
|
||||||
|
|
||||||
be_quiet = 1;
|
be_quiet = 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (getenv("AFL_LLVM_DICT2FILE_NO_MAIN")) { handle_main = 0; }
|
||||||
|
|
||||||
scanForDangerousFunctions(&M);
|
scanForDangerousFunctions(&M);
|
||||||
|
|
||||||
ptr = getenv("AFL_LLVM_DICT2FILE");
|
ptr = getenv("AFL_LLVM_DICT2FILE");
|
||||||
@ -210,7 +214,14 @@ bool AFLdict2filePass::runOnModule(Module &M) {
|
|||||||
|
|
||||||
for (auto &F : M) {
|
for (auto &F : M) {
|
||||||
|
|
||||||
if (isIgnoreFunction(&F)) continue;
|
if (!handle_main &&
|
||||||
|
(!F.getName().compare("main") || !F.getName().compare("_main"))) {
|
||||||
|
|
||||||
|
continue;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isIgnoreFunction(&F)) { continue; }
|
||||||
if (!isInInstrumentList(&F, MNAME) || !F.size()) { continue; }
|
if (!isInInstrumentList(&F, MNAME) || !F.size()) { continue; }
|
||||||
|
|
||||||
/* Some implementation notes.
|
/* Some implementation notes.
|
||||||
|
@ -1152,10 +1152,14 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) {
|
|||||||
b_op1 = SelectInst::Create(isMzero_op1, ConstantInt::get(intType, PlusZero),
|
b_op1 = SelectInst::Create(isMzero_op1, ConstantInt::get(intType, PlusZero),
|
||||||
bpre_op1);
|
bpre_op1);
|
||||||
#if LLVM_MAJOR >= 16
|
#if LLVM_MAJOR >= 16
|
||||||
isMzero_op0->insertInto(nonan_bb, BasicBlock::iterator(nonan_bb->getTerminator()));
|
isMzero_op0->insertInto(nonan_bb,
|
||||||
isMzero_op1->insertInto(nonan_bb, BasicBlock::iterator(nonan_bb->getTerminator()));
|
BasicBlock::iterator(nonan_bb->getTerminator()));
|
||||||
b_op0->insertInto(nonan_bb, BasicBlock::iterator(nonan_bb->getTerminator()));
|
isMzero_op1->insertInto(nonan_bb,
|
||||||
b_op1->insertInto(nonan_bb, BasicBlock::iterator(nonan_bb->getTerminator()));
|
BasicBlock::iterator(nonan_bb->getTerminator()));
|
||||||
|
b_op0->insertInto(nonan_bb,
|
||||||
|
BasicBlock::iterator(nonan_bb->getTerminator()));
|
||||||
|
b_op1->insertInto(nonan_bb,
|
||||||
|
BasicBlock::iterator(nonan_bb->getTerminator()));
|
||||||
#else
|
#else
|
||||||
nonan_bb->getInstList().insert(
|
nonan_bb->getInstList().insert(
|
||||||
BasicBlock::iterator(nonan_bb->getTerminator()), isMzero_op0);
|
BasicBlock::iterator(nonan_bb->getTerminator()), isMzero_op0);
|
||||||
@ -1192,7 +1196,8 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) {
|
|||||||
t_s0->insertInto(nonan_bb, BasicBlock::iterator(nonan_bb->getTerminator()));
|
t_s0->insertInto(nonan_bb, BasicBlock::iterator(nonan_bb->getTerminator()));
|
||||||
s_s1->insertInto(nonan_bb, BasicBlock::iterator(nonan_bb->getTerminator()));
|
s_s1->insertInto(nonan_bb, BasicBlock::iterator(nonan_bb->getTerminator()));
|
||||||
t_s1->insertInto(nonan_bb, BasicBlock::iterator(nonan_bb->getTerminator()));
|
t_s1->insertInto(nonan_bb, BasicBlock::iterator(nonan_bb->getTerminator()));
|
||||||
icmp_sign_bit->insertInto(nonan_bb, BasicBlock::iterator(nonan_bb->getTerminator()));
|
icmp_sign_bit->insertInto(nonan_bb,
|
||||||
|
BasicBlock::iterator(nonan_bb->getTerminator()));
|
||||||
#else
|
#else
|
||||||
nonan_bb->getInstList().insert(
|
nonan_bb->getInstList().insert(
|
||||||
BasicBlock::iterator(nonan_bb->getTerminator()), s_s0);
|
BasicBlock::iterator(nonan_bb->getTerminator()), s_s0);
|
||||||
@ -1239,8 +1244,10 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) {
|
|||||||
Instruction::LShr, b_op1,
|
Instruction::LShr, b_op1,
|
||||||
ConstantInt::get(b_op1->getType(), shiftR_exponent));
|
ConstantInt::get(b_op1->getType(), shiftR_exponent));
|
||||||
#if LLVM_MAJOR >= 16
|
#if LLVM_MAJOR >= 16
|
||||||
s_e0->insertInto(signequal_bb, BasicBlock::iterator(signequal_bb->getTerminator()));
|
s_e0->insertInto(signequal_bb,
|
||||||
s_e1->insertInto(signequal_bb, BasicBlock::iterator(signequal_bb->getTerminator()));
|
BasicBlock::iterator(signequal_bb->getTerminator()));
|
||||||
|
s_e1->insertInto(signequal_bb,
|
||||||
|
BasicBlock::iterator(signequal_bb->getTerminator()));
|
||||||
#else
|
#else
|
||||||
signequal_bb->getInstList().insert(
|
signequal_bb->getInstList().insert(
|
||||||
BasicBlock::iterator(signequal_bb->getTerminator()), s_e0);
|
BasicBlock::iterator(signequal_bb->getTerminator()), s_e0);
|
||||||
@ -1251,15 +1258,16 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) {
|
|||||||
t_e0 = new TruncInst(s_e0, IntExponentTy);
|
t_e0 = new TruncInst(s_e0, IntExponentTy);
|
||||||
t_e1 = new TruncInst(s_e1, IntExponentTy);
|
t_e1 = new TruncInst(s_e1, IntExponentTy);
|
||||||
#if LLVM_MAJOR >= 16
|
#if LLVM_MAJOR >= 16
|
||||||
t_e0->insertInto(signequal_bb, BasicBlock::iterator(signequal_bb->getTerminator()));
|
t_e0->insertInto(signequal_bb,
|
||||||
t_e1->insertInto(signequal_bb, BasicBlock::iterator(signequal_bb->getTerminator()));
|
BasicBlock::iterator(signequal_bb->getTerminator()));
|
||||||
|
t_e1->insertInto(signequal_bb,
|
||||||
|
BasicBlock::iterator(signequal_bb->getTerminator()));
|
||||||
#else
|
#else
|
||||||
signequal_bb->getInstList().insert(
|
signequal_bb->getInstList().insert(
|
||||||
BasicBlock::iterator(signequal_bb->getTerminator()), t_e0);
|
BasicBlock::iterator(signequal_bb->getTerminator()), t_e0);
|
||||||
signequal_bb->getInstList().insert(
|
signequal_bb->getInstList().insert(
|
||||||
BasicBlock::iterator(signequal_bb->getTerminator()), t_e1);
|
BasicBlock::iterator(signequal_bb->getTerminator()), t_e1);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
if (sizeInBits - precision < exTySizeBytes * 8) {
|
if (sizeInBits - precision < exTySizeBytes * 8) {
|
||||||
|
|
||||||
@ -1270,8 +1278,10 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) {
|
|||||||
Instruction::And, t_e1,
|
Instruction::And, t_e1,
|
||||||
ConstantInt::get(t_e1->getType(), mask_exponent));
|
ConstantInt::get(t_e1->getType(), mask_exponent));
|
||||||
#if LLVM_MAJOR >= 16
|
#if LLVM_MAJOR >= 16
|
||||||
m_e0->insertInto(signequal_bb, BasicBlock::iterator(signequal_bb->getTerminator()));
|
m_e0->insertInto(signequal_bb,
|
||||||
m_e1->insertInto(signequal_bb, BasicBlock::iterator(signequal_bb->getTerminator()));
|
BasicBlock::iterator(signequal_bb->getTerminator()));
|
||||||
|
m_e1->insertInto(signequal_bb,
|
||||||
|
BasicBlock::iterator(signequal_bb->getTerminator()));
|
||||||
#else
|
#else
|
||||||
signequal_bb->getInstList().insert(
|
signequal_bb->getInstList().insert(
|
||||||
BasicBlock::iterator(signequal_bb->getTerminator()), m_e0);
|
BasicBlock::iterator(signequal_bb->getTerminator()), m_e0);
|
||||||
@ -1312,7 +1322,8 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) {
|
|||||||
icmp_exponents_equal =
|
icmp_exponents_equal =
|
||||||
CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_EQ, m_e0, m_e1);
|
CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_EQ, m_e0, m_e1);
|
||||||
#if LLVM_MAJOR >= 16
|
#if LLVM_MAJOR >= 16
|
||||||
icmp_exponents_equal->insertInto(signequal_bb, BasicBlock::iterator(signequal_bb->getTerminator()));
|
icmp_exponents_equal->insertInto(
|
||||||
|
signequal_bb, BasicBlock::iterator(signequal_bb->getTerminator()));
|
||||||
#else
|
#else
|
||||||
signequal_bb->getInstList().insert(
|
signequal_bb->getInstList().insert(
|
||||||
BasicBlock::iterator(signequal_bb->getTerminator()),
|
BasicBlock::iterator(signequal_bb->getTerminator()),
|
||||||
@ -1332,7 +1343,9 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) {
|
|||||||
icmp_exponent =
|
icmp_exponent =
|
||||||
CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_UGT, m_e0, m_e1);
|
CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_UGT, m_e0, m_e1);
|
||||||
#if LLVM_MAJOR >= 16
|
#if LLVM_MAJOR >= 16
|
||||||
icmp_exponent->insertInto(signequal2_bb, BasicBlock::iterator(signequal2_bb->getTerminator()));
|
icmp_exponent->insertInto(
|
||||||
|
signequal2_bb,
|
||||||
|
BasicBlock::iterator(signequal2_bb->getTerminator()));
|
||||||
#else
|
#else
|
||||||
signequal2_bb->getInstList().insert(
|
signequal2_bb->getInstList().insert(
|
||||||
BasicBlock::iterator(signequal2_bb->getTerminator()),
|
BasicBlock::iterator(signequal2_bb->getTerminator()),
|
||||||
@ -1346,7 +1359,8 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) {
|
|||||||
icmp_exponents_equal =
|
icmp_exponents_equal =
|
||||||
CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_EQ, m_e0, m_e1);
|
CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_EQ, m_e0, m_e1);
|
||||||
#if LLVM_MAJOR >= 16
|
#if LLVM_MAJOR >= 16
|
||||||
icmp_exponents_equal->insertInto(signequal_bb, BasicBlock::iterator(signequal_bb->getTerminator()));
|
icmp_exponents_equal->insertInto(
|
||||||
|
signequal_bb, BasicBlock::iterator(signequal_bb->getTerminator()));
|
||||||
#else
|
#else
|
||||||
signequal_bb->getInstList().insert(
|
signequal_bb->getInstList().insert(
|
||||||
BasicBlock::iterator(signequal_bb->getTerminator()),
|
BasicBlock::iterator(signequal_bb->getTerminator()),
|
||||||
@ -1366,7 +1380,9 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) {
|
|||||||
icmp_exponent =
|
icmp_exponent =
|
||||||
CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_ULT, m_e0, m_e1);
|
CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_ULT, m_e0, m_e1);
|
||||||
#if LLVM_MAJOR >= 16
|
#if LLVM_MAJOR >= 16
|
||||||
icmp_exponent->insertInto(signequal2_bb, BasicBlock::iterator(signequal2_bb->getTerminator()));
|
icmp_exponent->insertInto(
|
||||||
|
signequal2_bb,
|
||||||
|
BasicBlock::iterator(signequal2_bb->getTerminator()));
|
||||||
#else
|
#else
|
||||||
signequal2_bb->getInstList().insert(
|
signequal2_bb->getInstList().insert(
|
||||||
BasicBlock::iterator(signequal2_bb->getTerminator()),
|
BasicBlock::iterator(signequal2_bb->getTerminator()),
|
||||||
@ -1381,7 +1397,8 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if LLVM_MAJOR >= 16
|
#if LLVM_MAJOR >= 16
|
||||||
icmp_exponent_result->insertInto(signequal2_bb, BasicBlock::iterator(signequal2_bb->getTerminator()));
|
icmp_exponent_result->insertInto(
|
||||||
|
signequal2_bb, BasicBlock::iterator(signequal2_bb->getTerminator()));
|
||||||
#else
|
#else
|
||||||
signequal2_bb->getInstList().insert(
|
signequal2_bb->getInstList().insert(
|
||||||
BasicBlock::iterator(signequal2_bb->getTerminator()),
|
BasicBlock::iterator(signequal2_bb->getTerminator()),
|
||||||
@ -1437,8 +1454,10 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) {
|
|||||||
Instruction::And, b_op1,
|
Instruction::And, b_op1,
|
||||||
ConstantInt::get(b_op1->getType(), mask_fraction));
|
ConstantInt::get(b_op1->getType(), mask_fraction));
|
||||||
#if LLVM_MAJOR >= 16
|
#if LLVM_MAJOR >= 16
|
||||||
m_f0->insertInto(middle_bb, BasicBlock::iterator(middle_bb->getTerminator()));
|
m_f0->insertInto(middle_bb,
|
||||||
m_f1->insertInto(middle_bb, BasicBlock::iterator(middle_bb->getTerminator()));
|
BasicBlock::iterator(middle_bb->getTerminator()));
|
||||||
|
m_f1->insertInto(middle_bb,
|
||||||
|
BasicBlock::iterator(middle_bb->getTerminator()));
|
||||||
#else
|
#else
|
||||||
middle_bb->getInstList().insert(
|
middle_bb->getInstList().insert(
|
||||||
BasicBlock::iterator(middle_bb->getTerminator()), m_f0);
|
BasicBlock::iterator(middle_bb->getTerminator()), m_f0);
|
||||||
@ -1451,8 +1470,10 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) {
|
|||||||
t_f0 = new TruncInst(m_f0, IntFractionTy);
|
t_f0 = new TruncInst(m_f0, IntFractionTy);
|
||||||
t_f1 = new TruncInst(m_f1, IntFractionTy);
|
t_f1 = new TruncInst(m_f1, IntFractionTy);
|
||||||
#if LLVM_MAJOR >= 16
|
#if LLVM_MAJOR >= 16
|
||||||
t_f0->insertInto(middle_bb, BasicBlock::iterator(middle_bb->getTerminator()));
|
t_f0->insertInto(middle_bb,
|
||||||
t_f1->insertInto(middle_bb, BasicBlock::iterator(middle_bb->getTerminator()));
|
BasicBlock::iterator(middle_bb->getTerminator()));
|
||||||
|
t_f1->insertInto(middle_bb,
|
||||||
|
BasicBlock::iterator(middle_bb->getTerminator()));
|
||||||
#else
|
#else
|
||||||
middle_bb->getInstList().insert(
|
middle_bb->getInstList().insert(
|
||||||
BasicBlock::iterator(middle_bb->getTerminator()), t_f0);
|
BasicBlock::iterator(middle_bb->getTerminator()), t_f0);
|
||||||
@ -1474,8 +1495,10 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) {
|
|||||||
t_f0 = new TruncInst(b_op0, IntFractionTy);
|
t_f0 = new TruncInst(b_op0, IntFractionTy);
|
||||||
t_f1 = new TruncInst(b_op1, IntFractionTy);
|
t_f1 = new TruncInst(b_op1, IntFractionTy);
|
||||||
#if LLVM_MAJOR >= 16
|
#if LLVM_MAJOR >= 16
|
||||||
t_f0->insertInto(middle_bb, BasicBlock::iterator(middle_bb->getTerminator()));
|
t_f0->insertInto(middle_bb,
|
||||||
t_f1->insertInto(middle_bb, BasicBlock::iterator(middle_bb->getTerminator()));
|
BasicBlock::iterator(middle_bb->getTerminator()));
|
||||||
|
t_f1->insertInto(middle_bb,
|
||||||
|
BasicBlock::iterator(middle_bb->getTerminator()));
|
||||||
#else
|
#else
|
||||||
middle_bb->getInstList().insert(
|
middle_bb->getInstList().insert(
|
||||||
BasicBlock::iterator(middle_bb->getTerminator()), t_f0);
|
BasicBlock::iterator(middle_bb->getTerminator()), t_f0);
|
||||||
@ -1503,7 +1526,8 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) {
|
|||||||
icmp_fraction_result =
|
icmp_fraction_result =
|
||||||
CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_EQ, t_f0, t_f1);
|
CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_EQ, t_f0, t_f1);
|
||||||
#if LLVM_MAJOR >= 16
|
#if LLVM_MAJOR >= 16
|
||||||
icmp_fraction_result->insertInto(middle2_bb, BasicBlock::iterator(middle2_bb->getTerminator()));
|
icmp_fraction_result->insertInto(
|
||||||
|
middle2_bb, BasicBlock::iterator(middle2_bb->getTerminator()));
|
||||||
#else
|
#else
|
||||||
middle2_bb->getInstList().insert(
|
middle2_bb->getInstList().insert(
|
||||||
BasicBlock::iterator(middle2_bb->getTerminator()),
|
BasicBlock::iterator(middle2_bb->getTerminator()),
|
||||||
@ -1516,7 +1540,8 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) {
|
|||||||
icmp_fraction_result =
|
icmp_fraction_result =
|
||||||
CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_NE, t_f0, t_f1);
|
CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_NE, t_f0, t_f1);
|
||||||
#if LLVM_MAJOR >= 16
|
#if LLVM_MAJOR >= 16
|
||||||
icmp_fraction_result->insertInto(middle2_bb, BasicBlock::iterator(middle2_bb->getTerminator()));
|
icmp_fraction_result->insertInto(
|
||||||
|
middle2_bb, BasicBlock::iterator(middle2_bb->getTerminator()));
|
||||||
#else
|
#else
|
||||||
middle2_bb->getInstList().insert(
|
middle2_bb->getInstList().insert(
|
||||||
BasicBlock::iterator(middle2_bb->getTerminator()),
|
BasicBlock::iterator(middle2_bb->getTerminator()),
|
||||||
@ -1542,13 +1567,13 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) {
|
|||||||
if (FcmpInst->getPredicate() == CmpInst::FCMP_OGT ||
|
if (FcmpInst->getPredicate() == CmpInst::FCMP_OGT ||
|
||||||
FcmpInst->getPredicate() == CmpInst::FCMP_UGT) {
|
FcmpInst->getPredicate() == CmpInst::FCMP_UGT) {
|
||||||
|
|
||||||
icmp_fraction_result = CmpInst::Create(
|
icmp_fraction_result =
|
||||||
Instruction::ICmp, CmpInst::ICMP_ULT, t_f0, t_f1);
|
CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_ULT, t_f0, t_f1);
|
||||||
icmp_fraction_result2 = CmpInst::Create(
|
icmp_fraction_result2 =
|
||||||
Instruction::ICmp, CmpInst::ICMP_UGT, t_f0, t_f1);
|
CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_UGT, t_f0, t_f1);
|
||||||
#if LLVM_MAJOR >= 16
|
#if LLVM_MAJOR >= 16
|
||||||
icmp_fraction_result->insertInto(negative_bb, negative_bb->end());
|
icmp_fraction_result->insertInto(negative_bb, negative_bb->end());
|
||||||
icmp_fraction_result2->insertInto(positive_bb, negative_bb->end());
|
icmp_fraction_result2->insertInto(positive_bb, negative_bb->end());
|
||||||
#else
|
#else
|
||||||
negative_bb->getInstList().push_back(icmp_fraction_result);
|
negative_bb->getInstList().push_back(icmp_fraction_result);
|
||||||
positive_bb->getInstList().push_back(icmp_fraction_result2);
|
positive_bb->getInstList().push_back(icmp_fraction_result2);
|
||||||
@ -1556,13 +1581,13 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) {
|
|||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
icmp_fraction_result = CmpInst::Create(
|
icmp_fraction_result =
|
||||||
Instruction::ICmp, CmpInst::ICMP_UGT, t_f0, t_f1);
|
CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_UGT, t_f0, t_f1);
|
||||||
icmp_fraction_result2 = CmpInst::Create(
|
icmp_fraction_result2 =
|
||||||
Instruction::ICmp, CmpInst::ICMP_ULT, t_f0, t_f1);
|
CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_ULT, t_f0, t_f1);
|
||||||
#if LLVM_MAJOR >= 16
|
#if LLVM_MAJOR >= 16
|
||||||
icmp_fraction_result->insertInto(negative_bb, negative_bb->end());
|
icmp_fraction_result->insertInto(negative_bb, negative_bb->end());
|
||||||
icmp_fraction_result2->insertInto(positive_bb, negative_bb->end());
|
icmp_fraction_result2->insertInto(positive_bb, negative_bb->end());
|
||||||
#else
|
#else
|
||||||
negative_bb->getInstList().push_back(icmp_fraction_result);
|
negative_bb->getInstList().push_back(icmp_fraction_result);
|
||||||
positive_bb->getInstList().push_back(icmp_fraction_result2);
|
positive_bb->getInstList().push_back(icmp_fraction_result2);
|
||||||
@ -1581,7 +1606,8 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) {
|
|||||||
PN2->addIncoming(icmp_fraction_result, negative_bb);
|
PN2->addIncoming(icmp_fraction_result, negative_bb);
|
||||||
PN2->addIncoming(icmp_fraction_result2, positive_bb);
|
PN2->addIncoming(icmp_fraction_result2, positive_bb);
|
||||||
#if LLVM_MAJOR >= 16
|
#if LLVM_MAJOR >= 16
|
||||||
PN2->insertInto(middle2_bb, BasicBlock::iterator(middle2_bb->getTerminator()));
|
PN2->insertInto(middle2_bb,
|
||||||
|
BasicBlock::iterator(middle2_bb->getTerminator()));
|
||||||
#else
|
#else
|
||||||
middle2_bb->getInstList().insert(
|
middle2_bb->getInstList().insert(
|
||||||
BasicBlock::iterator(middle2_bb->getTerminator()), PN2);
|
BasicBlock::iterator(middle2_bb->getTerminator()), PN2);
|
||||||
|
201
qemu_mode/README.deferred_initialization_example.md
Normal file
201
qemu_mode/README.deferred_initialization_example.md
Normal file
@ -0,0 +1,201 @@
|
|||||||
|
# Fuzz ARM32 Python Native Extensions in Binary-only Mode (LLVM fork-based)
|
||||||
|
|
||||||
|
This is an example on how to fuzz Python native extensions in LLVM mode with deferred initialization on ARM32.
|
||||||
|
|
||||||
|
We use Ubuntu x86_64 to run AFL++ and an Alpine ARMv7 Chroot to build the fuzzing target.
|
||||||
|
|
||||||
|
Check [Resources](#resources) for the code used in this example.
|
||||||
|
|
||||||
|
## Setup Alpine ARM Chroot on your x86_64 Linux Host
|
||||||
|
|
||||||
|
### Use systemd-nspawn
|
||||||
|
|
||||||
|
1. Install `qemu-user-binfmt`, `qemu-user-static` and `systemd-container` dependencies.
|
||||||
|
2. Restart the systemd-binfmt service: `systemctl restart systemd-binfmt.service`
|
||||||
|
3. Download an Alpine ARM RootFS from https://alpinelinux.org/downloads/
|
||||||
|
4. Create a new `alpine_sysroot` folder and extract: `tar xfz alpine-minirootfs-3.17.1-armv7.tar.gz -C alpine_sysroot/`
|
||||||
|
5. Copy `qemu-arm-static` to Alpine's RootFS: `cp $(which qemu-arm-static) ./alpine/usr/bin/`
|
||||||
|
6. Chroot into the container: `sudo systemd-nspawn -D alpine/ --bind-ro=/etc/resolv.conf`
|
||||||
|
7. Install dependencies: `apk update && apk add build-base musl-dev clang15 python3 python3-dev py3-pip`
|
||||||
|
8. Exit the container with `exit`
|
||||||
|
|
||||||
|
### Alternatively use Docker
|
||||||
|
|
||||||
|
1. Install `qemu-user-binfmt` and `qemu-user-static`
|
||||||
|
2. Run Qemu container: ```$ docker run --rm --privileged multiarch/qemu-user-static --reset -p yes```
|
||||||
|
3. Run Alpine container: ```$ docker run -it --rm arm32v7/alpine sh```
|
||||||
|
|
||||||
|
## Build AFL++ Qemu Mode with ARM Support
|
||||||
|
|
||||||
|
First, build AFL++ as described [here](https://github.com/AFLplusplus/AFLplusplus/blob/dev/docs/INSTALL.md). Then, run the Qemu build script:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd qemu_mode && CPU_TARGET=arm ./build_qemu_support.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
## Compile and Build the Fuzzing Project
|
||||||
|
Build the native extension and the fuzzing harness for ARM using the Alpine container (check [Resources](#resources) for the code):
|
||||||
|
```bash
|
||||||
|
ALPINE_ROOT=<your-alpine-sysroot-directory>
|
||||||
|
FUZZ=<your-path-to-the-code>
|
||||||
|
sudo systemd-nspawn -D $ALPINE_ROOT --bind=$FUZZ:/fuzz
|
||||||
|
CC=$(which clang) CFLAGS="-g" LDSHARED="clang -shared" python3 -m pip install /fuzz
|
||||||
|
clang $(python3-config --embed --cflags) $(python3-config --embed --ldflags) -o /fuzz/fuzz_harness /fuzz/fuzz_harness.c
|
||||||
|
exit
|
||||||
|
```
|
||||||
|
|
||||||
|
Manually trigger bug:
|
||||||
|
```bash
|
||||||
|
echo -n "FUZZ" | qemu-arm-static -L $ALPINE_ROOT $FUZZ/fuzz_harness
|
||||||
|
```
|
||||||
|
|
||||||
|
## Run AFL++
|
||||||
|
Make sure to start the forkserver *after* loading all the shared objects by setting the `AFL_ENTRYPOINT` environment variable (see [here](https://aflplus.plus/docs/env_variables/#5-settings-for-afl-qemu-trace) for details):
|
||||||
|
|
||||||
|
Choose an address just before the `while()` loop, for example:
|
||||||
|
```bash
|
||||||
|
qemu-arm-static -L $ALPINE_ROOT $ALPINE_ROOT/usr/bin/objdump -d $FUZZ/fuzz_harness | grep -A 1 "PyObject_GetAttrString"
|
||||||
|
|
||||||
|
00000584 <PyObject_GetAttrString@plt>:
|
||||||
|
584: e28fc600 add ip, pc, #0, 12
|
||||||
|
--
|
||||||
|
7c8: ebffff6d bl 584 <PyObject_GetAttrString@plt>
|
||||||
|
7cc: e58d0008 str r0, [sp, #8]
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
|
Check Qemu memory maps using the instructions from [here](https://aflplus.plus/docs/tutorials/libxml2_tutorial/):
|
||||||
|
>The binary is position independent and QEMU persistent needs the real addresses, not the offsets. Fortunately, QEMU loads PIE executables at a fixed address, 0x4000000000 for x86_64.
|
||||||
|
>
|
||||||
|
> We can check it using `AFL_QEMU_DEBUG_MAPS`. You don’t need this step if your binary is not PIE.
|
||||||
|
|
||||||
|
Setup Python environment variables and run `afl-qemu-trace`:
|
||||||
|
```bash
|
||||||
|
PYTHONPATH=$ALPINE_ROOT/usr/lib/python3.10/ PYTHONHOME=$ALPINE_ROOT/usr/bin/ QEMU_LD_PREFIX=$ALPINE_ROOT AFL_QEMU_DEBUG_MAPS=1 afl-qemu-trace $FUZZ/fuzz_harness
|
||||||
|
|
||||||
|
...
|
||||||
|
40000000-40001000 r-xp 00000000 103:03 8002276 fuzz_harness
|
||||||
|
40001000-4001f000 ---p 00000000 00:00 0
|
||||||
|
4001f000-40020000 r--p 0000f000 103:03 8002276 fuzz_harness
|
||||||
|
40020000-40021000 rw-p 00010000 103:03 8002276 fuzz_harness
|
||||||
|
40021000-40022000 ---p 00000000 00:00 0
|
||||||
|
40022000-40023000 rw-p 00000000 00:00 0
|
||||||
|
```
|
||||||
|
|
||||||
|
Finally, setup Qemu environment variables...
|
||||||
|
```bash
|
||||||
|
export QEMU_SET_ENV=PYTHONPATH=$ALPINE_ROOT/usr/lib/python310.zip:$ALPINE_ROOT/usr/lib/python3.10:$ALPINE_ROOT/usr/lib/python3.10/lib-dynload:$ALPINE_ROOT/usr/lib/python3.10/site-packages,PYTHONHOME=$ALPINE_ROOT/usr/bin/
|
||||||
|
export QEMU_LD_PREFIX=$ALPINE_ROOT
|
||||||
|
```
|
||||||
|
|
||||||
|
... and run AFL++:
|
||||||
|
```bash
|
||||||
|
mkdir -p $FUZZ/in && echo -n "FU" > $FUZZ/in/seed
|
||||||
|
AFL_ENTRYPOINT=0x400007cc afl-fuzz -i $FUZZ/in -o $FUZZ/out -Q -- $FUZZ/fuzz_harness
|
||||||
|
```
|
||||||
|
|
||||||
|
## Resources
|
||||||
|
|
||||||
|
### setup.py
|
||||||
|
|
||||||
|
```python
|
||||||
|
from distutils.core import setup, Extension
|
||||||
|
|
||||||
|
module = Extension("memory", sources=["fuzz_target.c"])
|
||||||
|
|
||||||
|
setup(
|
||||||
|
name="memory",
|
||||||
|
version="1.0",
|
||||||
|
description='A simple "BOOM!" extension',
|
||||||
|
ext_modules=[module],
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
### fuzz_target.c
|
||||||
|
|
||||||
|
```c
|
||||||
|
#define PY_SSIZE_T_CLEAN
|
||||||
|
#include <Python.h>
|
||||||
|
|
||||||
|
#pragma clang optimize off
|
||||||
|
|
||||||
|
static PyObject *corruption(PyObject* self, PyObject* args) {
|
||||||
|
char arr[3];
|
||||||
|
Py_buffer name;
|
||||||
|
|
||||||
|
if (!PyArg_ParseTuple(args, "y*", &name))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (name.buf != NULL) {
|
||||||
|
if (strcmp(name.buf, "FUZZ") == 0) {
|
||||||
|
arr[0] = 'B';
|
||||||
|
arr[1] = 'O';
|
||||||
|
arr[2] = 'O';
|
||||||
|
arr[3] = 'M';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PyBuffer_Release(&name);
|
||||||
|
Py_RETURN_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyMethodDef MemoryMethods[] = {
|
||||||
|
{"corruption", corruption, METH_VARARGS, "BOOM!"},
|
||||||
|
{NULL, NULL, 0, NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct PyModuleDef memory_module = {
|
||||||
|
PyModuleDef_HEAD_INIT,
|
||||||
|
"memory",
|
||||||
|
"BOOM!",
|
||||||
|
-1,
|
||||||
|
MemoryMethods
|
||||||
|
};
|
||||||
|
|
||||||
|
PyMODINIT_FUNC PyInit_memory(void) {
|
||||||
|
return PyModule_Create(&memory_module);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### fuzz_harness.c
|
||||||
|
|
||||||
|
```c
|
||||||
|
#include <Python.h>
|
||||||
|
|
||||||
|
#pragma clang optimize off
|
||||||
|
|
||||||
|
int main(int argc, char **argv) {
|
||||||
|
unsigned char buf[1024000];
|
||||||
|
ssize_t size;
|
||||||
|
|
||||||
|
Py_Initialize();
|
||||||
|
PyObject* name = PyUnicode_DecodeFSDefault("memory");
|
||||||
|
PyObject* module = PyImport_Import(name);
|
||||||
|
Py_DECREF(name);
|
||||||
|
|
||||||
|
if (module != NULL) {
|
||||||
|
PyObject* corruption_func = PyObject_GetAttrString(module, "corruption");
|
||||||
|
|
||||||
|
while ((size = read(0, buf, sizeof(buf))) > 0 ? 1 : 0) {
|
||||||
|
PyObject* arg = PyBytes_FromStringAndSize((char *)buf, size);
|
||||||
|
|
||||||
|
if (arg != NULL) {
|
||||||
|
PyObject* res = PyObject_CallFunctionObjArgs(corruption_func, arg, NULL);
|
||||||
|
|
||||||
|
if (res != NULL) {
|
||||||
|
Py_XDECREF(res);
|
||||||
|
}
|
||||||
|
|
||||||
|
Py_DECREF(arg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Py_DECREF(corruption_func);
|
||||||
|
Py_DECREF(module);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Py_Finalize() leaks memory on certain Python versions (see https://bugs.python.org/issue1635741)
|
||||||
|
// Py_Finalize();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
```
|
@ -66,6 +66,8 @@ allows to move the forkserver to a different part, e.g., just before the file is
|
|||||||
opened (e.g., way after command line parsing and config file loading, etc.)
|
opened (e.g., way after command line parsing and config file loading, etc.)
|
||||||
which can be a huge speed improvement.
|
which can be a huge speed improvement.
|
||||||
|
|
||||||
|
For an example, see [README.deferred_initialization_example.md](README.deferred_initialization_example.md).
|
||||||
|
|
||||||
## 4) Persistent mode
|
## 4) Persistent mode
|
||||||
|
|
||||||
AFL++'s QEMU mode now supports also persistent mode for x86, x86_64, arm, and
|
AFL++'s QEMU mode now supports also persistent mode for x86, x86_64, arm, and
|
||||||
|
@ -2041,6 +2041,8 @@ int main(int argc, char **argv, char **envp) {
|
|||||||
|
|
||||||
" AFL_LLVM_DICT2FILE: generate an afl dictionary based on found "
|
" AFL_LLVM_DICT2FILE: generate an afl dictionary based on found "
|
||||||
"comparisons\n"
|
"comparisons\n"
|
||||||
|
" AFL_LLVM_DICT2FILE_NO_MAIN: skip parsing main() for the "
|
||||||
|
"dictionary\n"
|
||||||
" AFL_LLVM_LAF_ALL: enables all LAF splits/transforms\n"
|
" AFL_LLVM_LAF_ALL: enables all LAF splits/transforms\n"
|
||||||
" AFL_LLVM_LAF_SPLIT_COMPARES: enable cascaded comparisons\n"
|
" AFL_LLVM_LAF_SPLIT_COMPARES: enable cascaded comparisons\n"
|
||||||
" AFL_LLVM_LAF_SPLIT_COMPARES_BITW: size limit (default 8)\n"
|
" AFL_LLVM_LAF_SPLIT_COMPARES_BITW: size limit (default 8)\n"
|
||||||
@ -2128,7 +2130,8 @@ int main(int argc, char **argv, char **envp) {
|
|||||||
"defaults.\n"
|
"defaults.\n"
|
||||||
"Recommended is afl-clang-lto with AFL_LLVM_CMPLOG or afl-clang-fast "
|
"Recommended is afl-clang-lto with AFL_LLVM_CMPLOG or afl-clang-fast "
|
||||||
"with\n"
|
"with\n"
|
||||||
"AFL_LLVM_CMPLOG and AFL_LLVM_DICT2FILE.\n\n");
|
"AFL_LLVM_CMPLOG and "
|
||||||
|
"AFL_LLVM_DICT2FILE+AFL_LLVM_DICT2FILE_NO_MAIN.\n\n");
|
||||||
|
|
||||||
exit(1);
|
exit(1);
|
||||||
|
|
||||||
|
@ -59,7 +59,7 @@ static list_t fsrv_list = {.element_prealloc_count = 0};
|
|||||||
|
|
||||||
static void fsrv_exec_child(afl_forkserver_t *fsrv, char **argv) {
|
static void fsrv_exec_child(afl_forkserver_t *fsrv, char **argv) {
|
||||||
|
|
||||||
if (fsrv->qemu_mode || fsrv->cs_mode) {
|
if (fsrv->qemu_mode || fsrv->frida_mode || fsrv->cs_mode) {
|
||||||
|
|
||||||
setenv("AFL_DISABLE_LLVM_INSTRUMENTATION", "1", 0);
|
setenv("AFL_DISABLE_LLVM_INSTRUMENTATION", "1", 0);
|
||||||
|
|
||||||
@ -1370,7 +1370,7 @@ afl_fsrv_run_target(afl_forkserver_t *fsrv, u32 timeout,
|
|||||||
case Crash:
|
case Crash:
|
||||||
case Asan:
|
case Asan:
|
||||||
return FSRV_RUN_CRASH;
|
return FSRV_RUN_CRASH;
|
||||||
case Timout:
|
case Timeout:
|
||||||
return FSRV_RUN_TMOUT;
|
return FSRV_RUN_TMOUT;
|
||||||
case InvalidWriteToPayload:
|
case InvalidWriteToPayload:
|
||||||
/* ??? */
|
/* ??? */
|
||||||
|
@ -457,6 +457,12 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) {
|
|||||||
|
|
||||||
if (unlikely(len == 0)) { return 0; }
|
if (unlikely(len == 0)) { return 0; }
|
||||||
|
|
||||||
|
if (unlikely(fault == FSRV_RUN_TMOUT && afl->afl_env.afl_ignore_timeouts)) {
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
u8 fn[PATH_MAX];
|
u8 fn[PATH_MAX];
|
||||||
u8 *queue_fn = "";
|
u8 *queue_fn = "";
|
||||||
u8 new_bits = 0, keeping = 0, res, classified = 0, is_timeout = 0;
|
u8 new_bits = 0, keeping = 0, res, classified = 0, is_timeout = 0;
|
||||||
|
@ -33,15 +33,19 @@ void cmplog_exec_child(afl_forkserver_t *fsrv, char **argv) {
|
|||||||
|
|
||||||
setenv("___AFL_EINS_ZWEI_POLIZEI___", "1", 1);
|
setenv("___AFL_EINS_ZWEI_POLIZEI___", "1", 1);
|
||||||
|
|
||||||
if (fsrv->qemu_mode) { setenv("AFL_DISABLE_LLVM_INSTRUMENTATION", "1", 0); }
|
if (fsrv->qemu_mode || fsrv->frida_mode || fsrv->cs_mode) {
|
||||||
|
|
||||||
if (!fsrv->qemu_mode && !fsrv->frida_mode && argv[0] != fsrv->cmplog_binary) {
|
setenv("AFL_DISABLE_LLVM_INSTRUMENTATION", "1", 0);
|
||||||
|
|
||||||
argv[0] = fsrv->cmplog_binary;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
execv(argv[0], argv);
|
if (!fsrv->qemu_mode && !fsrv->frida_mode && argv[0] != fsrv->cmplog_binary) {
|
||||||
|
|
||||||
|
fsrv->target_path = argv[0] = fsrv->cmplog_binary;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
execv(fsrv->target_path, argv);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1120,7 +1120,7 @@ void perform_dry_run(afl_state_t *afl) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (q->var_behavior) {
|
if (unlikely(q->var_behavior && !afl->afl_env.afl_no_warn_instability)) {
|
||||||
|
|
||||||
WARNF("Instrumentation output varies across runs.");
|
WARNF("Instrumentation output varies across runs.");
|
||||||
|
|
||||||
|
@ -312,12 +312,18 @@ struct custom_mutator *load_custom_mutator(afl_state_t *afl, const char *fn) {
|
|||||||
|
|
||||||
if (notrim) {
|
if (notrim) {
|
||||||
|
|
||||||
|
if (mutator->afl_custom_init_trim || mutator->afl_custom_trim ||
|
||||||
|
mutator->afl_custom_post_trim) {
|
||||||
|
|
||||||
|
WARNF(
|
||||||
|
"Custom mutator does not implement all three trim APIs, standard "
|
||||||
|
"trimming will be used.");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
mutator->afl_custom_init_trim = NULL;
|
mutator->afl_custom_init_trim = NULL;
|
||||||
mutator->afl_custom_trim = NULL;
|
mutator->afl_custom_trim = NULL;
|
||||||
mutator->afl_custom_post_trim = NULL;
|
mutator->afl_custom_post_trim = NULL;
|
||||||
ACTF(
|
|
||||||
"Custom mutator does not implement all three trim APIs, standard "
|
|
||||||
"trimming will be used.");
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -358,6 +364,19 @@ struct custom_mutator *load_custom_mutator(afl_state_t *afl, const char *fn) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* "afl_custom_splice_optout", optional, never called */
|
||||||
|
mutator->afl_custom_splice_optout = dlsym(dh, "afl_custom_splice_optout");
|
||||||
|
if (!mutator->afl_custom_splice_optout) {
|
||||||
|
|
||||||
|
ACTF("optional symbol 'afl_custom_splice_optout' not found.");
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
OKF("Found 'afl_custom_splice_optout'.");
|
||||||
|
afl->custom_splice_optout = 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/* "afl_custom_fuzz_send", optional */
|
/* "afl_custom_fuzz_send", optional */
|
||||||
mutator->afl_custom_fuzz_send = dlsym(dh, "afl_custom_fuzz_send");
|
mutator->afl_custom_fuzz_send = dlsym(dh, "afl_custom_fuzz_send");
|
||||||
if (!mutator->afl_custom_fuzz_send) {
|
if (!mutator->afl_custom_fuzz_send) {
|
||||||
|
@ -446,9 +446,12 @@ u8 fuzz_one_original(afl_state_t *afl) {
|
|||||||
|
|
||||||
ACTF(
|
ACTF(
|
||||||
"Fuzzing test case #%u (%u total, %llu crashes saved, "
|
"Fuzzing test case #%u (%u total, %llu crashes saved, "
|
||||||
"perf_score=%0.0f, exec_us=%llu, hits=%u, map=%u, ascii=%u)...",
|
"perf_score=%0.0f, weight=%0.0f, favorite=%u, was_fuzzed=%u, "
|
||||||
|
"exec_us=%llu, hits=%u, map=%u, ascii=%u)...",
|
||||||
afl->current_entry, afl->queued_items, afl->saved_crashes,
|
afl->current_entry, afl->queued_items, afl->saved_crashes,
|
||||||
afl->queue_cur->perf_score, afl->queue_cur->exec_us,
|
afl->queue_cur->perf_score, afl->queue_cur->weight,
|
||||||
|
afl->queue_cur->favored, afl->queue_cur->was_fuzzed,
|
||||||
|
afl->queue_cur->exec_us,
|
||||||
likely(afl->n_fuzz) ? afl->n_fuzz[afl->queue_cur->n_fuzz_entry] : 0,
|
likely(afl->n_fuzz) ? afl->n_fuzz[afl->queue_cur->n_fuzz_entry] : 0,
|
||||||
afl->queue_cur->bitmap_size, afl->queue_cur->is_ascii);
|
afl->queue_cur->bitmap_size, afl->queue_cur->is_ascii);
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
@ -561,11 +564,11 @@ u8 fuzz_one_original(afl_state_t *afl) {
|
|||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
if (afl->cmplog_lvl == 3 ||
|
if (afl->queue_cur->favored || afl->cmplog_lvl == 3 ||
|
||||||
(afl->cmplog_lvl == 2 && afl->queue_cur->tc_ref) ||
|
(afl->cmplog_lvl == 2 &&
|
||||||
afl->queue_cur->favored ||
|
(afl->queue_cur->tc_ref ||
|
||||||
!(afl->fsrv.total_execs % afl->queued_items) ||
|
afl->fsrv.total_execs % afl->queued_items <= 10)) ||
|
||||||
get_cur_time() - afl->last_find_time > 300000) { // 300 seconds
|
get_cur_time() - afl->last_find_time > 250000) { // 250 seconds
|
||||||
|
|
||||||
if (input_to_state_stage(afl, in_buf, out_buf, len)) {
|
if (input_to_state_stage(afl, in_buf, out_buf, len)) {
|
||||||
|
|
||||||
@ -584,7 +587,7 @@ u8 fuzz_one_original(afl_state_t *afl) {
|
|||||||
if it has gone through deterministic testing in earlier, resumed runs
|
if it has gone through deterministic testing in earlier, resumed runs
|
||||||
(passed_det). */
|
(passed_det). */
|
||||||
|
|
||||||
if (likely(afl->queue_cur->passed_det) || likely(afl->skip_deterministic) ||
|
if (likely(afl->skip_deterministic) || likely(afl->queue_cur->passed_det) ||
|
||||||
likely(perf_score <
|
likely(perf_score <
|
||||||
(afl->queue_cur->depth * 30 <= afl->havoc_max_mult * 100
|
(afl->queue_cur->depth * 30 <= afl->havoc_max_mult * 100
|
||||||
? afl->queue_cur->depth * 30
|
? afl->queue_cur->depth * 30
|
||||||
@ -1908,9 +1911,10 @@ custom_mutator_stage:
|
|||||||
|
|
||||||
afl->stage_name = "custom mutator";
|
afl->stage_name = "custom mutator";
|
||||||
afl->stage_short = "custom";
|
afl->stage_short = "custom";
|
||||||
afl->stage_max = HAVOC_CYCLES * perf_score / afl->havoc_div / 100;
|
|
||||||
afl->stage_val_type = STAGE_VAL_NONE;
|
afl->stage_val_type = STAGE_VAL_NONE;
|
||||||
bool has_custom_fuzz = false;
|
bool has_custom_fuzz = false;
|
||||||
|
u32 shift = unlikely(afl->custom_only) ? 7 : 8;
|
||||||
|
afl->stage_max = (HAVOC_CYCLES * perf_score / afl->havoc_div) >> shift;
|
||||||
|
|
||||||
if (afl->stage_max < HAVOC_MIN) { afl->stage_max = HAVOC_MIN; }
|
if (afl->stage_max < HAVOC_MIN) { afl->stage_max = HAVOC_MIN; }
|
||||||
|
|
||||||
@ -1953,7 +1957,8 @@ custom_mutator_stage:
|
|||||||
u32 target_len = 0;
|
u32 target_len = 0;
|
||||||
|
|
||||||
/* check if splicing makes sense yet (enough entries) */
|
/* check if splicing makes sense yet (enough entries) */
|
||||||
if (likely(afl->ready_for_splicing_count > 1)) {
|
if (likely(!afl->custom_splice_optout &&
|
||||||
|
afl->ready_for_splicing_count > 1)) {
|
||||||
|
|
||||||
/* Pick a random other queue entry for passing to external API
|
/* Pick a random other queue entry for passing to external API
|
||||||
that has the necessary length */
|
that has the necessary length */
|
||||||
@ -1983,7 +1988,8 @@ custom_mutator_stage:
|
|||||||
|
|
||||||
if (unlikely(!mutated_buf)) {
|
if (unlikely(!mutated_buf)) {
|
||||||
|
|
||||||
FATAL("Error in custom_fuzz. Size returned: %zu", mutated_size);
|
// FATAL("Error in custom_fuzz. Size returned: %zu", mutated_size);
|
||||||
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2035,7 +2041,7 @@ custom_mutator_stage:
|
|||||||
new_hit_cnt = afl->queued_items + afl->saved_crashes;
|
new_hit_cnt = afl->queued_items + afl->saved_crashes;
|
||||||
|
|
||||||
afl->stage_finds[STAGE_CUSTOM_MUTATOR] += new_hit_cnt - orig_hit_cnt;
|
afl->stage_finds[STAGE_CUSTOM_MUTATOR] += new_hit_cnt - orig_hit_cnt;
|
||||||
afl->stage_cycles[STAGE_CUSTOM_MUTATOR] += afl->stage_max;
|
afl->stage_cycles[STAGE_CUSTOM_MUTATOR] += afl->stage_cur;
|
||||||
#ifdef INTROSPECTION
|
#ifdef INTROSPECTION
|
||||||
afl->queue_cur->stats_mutated += afl->stage_max;
|
afl->queue_cur->stats_mutated += afl->stage_max;
|
||||||
#endif
|
#endif
|
||||||
@ -2063,8 +2069,9 @@ havoc_stage:
|
|||||||
|
|
||||||
afl->stage_name = "havoc";
|
afl->stage_name = "havoc";
|
||||||
afl->stage_short = "havoc";
|
afl->stage_short = "havoc";
|
||||||
afl->stage_max = (doing_det ? HAVOC_CYCLES_INIT : HAVOC_CYCLES) *
|
afl->stage_max = ((doing_det ? HAVOC_CYCLES_INIT : HAVOC_CYCLES) *
|
||||||
perf_score / afl->havoc_div / 100;
|
perf_score / afl->havoc_div) >>
|
||||||
|
7;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
@ -2073,7 +2080,7 @@ havoc_stage:
|
|||||||
snprintf(afl->stage_name_buf, STAGE_BUF_SIZE, "splice %u", splice_cycle);
|
snprintf(afl->stage_name_buf, STAGE_BUF_SIZE, "splice %u", splice_cycle);
|
||||||
afl->stage_name = afl->stage_name_buf;
|
afl->stage_name = afl->stage_name_buf;
|
||||||
afl->stage_short = "splice";
|
afl->stage_short = "splice";
|
||||||
afl->stage_max = SPLICE_HAVOC * perf_score / afl->havoc_div / 100;
|
afl->stage_max = (SPLICE_HAVOC * perf_score / afl->havoc_div) >> 7;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4621,8 +4628,9 @@ pacemaker_fuzzing:
|
|||||||
|
|
||||||
afl->stage_name = MOpt_globals.havoc_stagename;
|
afl->stage_name = MOpt_globals.havoc_stagename;
|
||||||
afl->stage_short = MOpt_globals.havoc_stagenameshort;
|
afl->stage_short = MOpt_globals.havoc_stagenameshort;
|
||||||
afl->stage_max = (doing_det ? HAVOC_CYCLES_INIT : HAVOC_CYCLES) *
|
afl->stage_max = ((doing_det ? HAVOC_CYCLES_INIT : HAVOC_CYCLES) *
|
||||||
perf_score / afl->havoc_div / 100;
|
perf_score / afl->havoc_div) >>
|
||||||
|
7;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
@ -4632,7 +4640,7 @@ pacemaker_fuzzing:
|
|||||||
MOpt_globals.splice_stageformat, splice_cycle);
|
MOpt_globals.splice_stageformat, splice_cycle);
|
||||||
afl->stage_name = afl->stage_name_buf;
|
afl->stage_name = afl->stage_name_buf;
|
||||||
afl->stage_short = MOpt_globals.splice_stagenameshort;
|
afl->stage_short = MOpt_globals.splice_stagenameshort;
|
||||||
afl->stage_max = SPLICE_HAVOC * perf_score / afl->havoc_div / 100;
|
afl->stage_max = (SPLICE_HAVOC * perf_score / afl->havoc_div) >> 7;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5683,6 +5691,7 @@ pacemaker_fuzzing:
|
|||||||
|
|
||||||
} /* block */
|
} /* block */
|
||||||
|
|
||||||
|
++afl->queue_cur->fuzz_level;
|
||||||
return ret_val;
|
return ret_val;
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -5792,13 +5801,11 @@ void pso_updating(afl_state_t *afl) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* larger change for MOpt implementation: the original fuzz_one was renamed
|
/* The entry point for the mutator, choosing the default mutator, and/or MOpt
|
||||||
to fuzz_one_original. All documentation references to fuzz_one therefore
|
depending on the configuration. */
|
||||||
mean fuzz_one_original */
|
|
||||||
|
|
||||||
u8 fuzz_one(afl_state_t *afl) {
|
u8 fuzz_one(afl_state_t *afl) {
|
||||||
|
|
||||||
int key_val_lv_1 = 0, key_val_lv_2 = 0;
|
int key_val_lv_1 = -1, key_val_lv_2 = -1;
|
||||||
|
|
||||||
#ifdef _AFL_DOCUMENT_MUTATIONS
|
#ifdef _AFL_DOCUMENT_MUTATIONS
|
||||||
|
|
||||||
@ -5818,7 +5825,12 @@ u8 fuzz_one(afl_state_t *afl) {
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// if limit_time_sig == -1 then both are run after each other
|
/*
|
||||||
|
-L command line paramter => limit_time_sig value
|
||||||
|
limit_time_sig == 0 then run the default mutator
|
||||||
|
limit_time_sig > 0 then run MOpt
|
||||||
|
limit_time_sig < 0 both are run
|
||||||
|
*/
|
||||||
|
|
||||||
if (afl->limit_time_sig <= 0) { key_val_lv_1 = fuzz_one_original(afl); }
|
if (afl->limit_time_sig <= 0) { key_val_lv_1 = fuzz_one_original(afl); }
|
||||||
|
|
||||||
@ -5840,6 +5852,9 @@ u8 fuzz_one(afl_state_t *afl) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (unlikely(key_val_lv_1 == -1)) { key_val_lv_1 = 0; }
|
||||||
|
if (likely(key_val_lv_2 == -1)) { key_val_lv_2 = 0; }
|
||||||
|
|
||||||
return (key_val_lv_1 | key_val_lv_2);
|
return (key_val_lv_1 | key_val_lv_2);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -231,8 +231,12 @@ static py_mutator_t *init_py_module(afl_state_t *afl, u8 *module_name) {
|
|||||||
PyObject_GetAttrString(py_module, "describe");
|
PyObject_GetAttrString(py_module, "describe");
|
||||||
py_functions[PY_FUNC_FUZZ_COUNT] =
|
py_functions[PY_FUNC_FUZZ_COUNT] =
|
||||||
PyObject_GetAttrString(py_module, "fuzz_count");
|
PyObject_GetAttrString(py_module, "fuzz_count");
|
||||||
if (!py_functions[PY_FUNC_FUZZ])
|
if (!py_functions[PY_FUNC_FUZZ]) {
|
||||||
|
|
||||||
WARNF("fuzz function not found in python module");
|
WARNF("fuzz function not found in python module");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
py_functions[PY_FUNC_POST_PROCESS] =
|
py_functions[PY_FUNC_POST_PROCESS] =
|
||||||
PyObject_GetAttrString(py_module, "post_process");
|
PyObject_GetAttrString(py_module, "post_process");
|
||||||
py_functions[PY_FUNC_INIT_TRIM] =
|
py_functions[PY_FUNC_INIT_TRIM] =
|
||||||
@ -248,6 +252,9 @@ static py_mutator_t *init_py_module(afl_state_t *afl, u8 *module_name) {
|
|||||||
PyObject_GetAttrString(py_module, "queue_get");
|
PyObject_GetAttrString(py_module, "queue_get");
|
||||||
py_functions[PY_FUNC_FUZZ_SEND] =
|
py_functions[PY_FUNC_FUZZ_SEND] =
|
||||||
PyObject_GetAttrString(py_module, "fuzz_send");
|
PyObject_GetAttrString(py_module, "fuzz_send");
|
||||||
|
py_functions[PY_FUNC_SPLICE_OPTOUT] =
|
||||||
|
PyObject_GetAttrString(py_module, "splice_optout");
|
||||||
|
if (py_functions[PY_FUNC_SPLICE_OPTOUT]) { afl->custom_splice_optout = 1; }
|
||||||
py_functions[PY_FUNC_QUEUE_NEW_ENTRY] =
|
py_functions[PY_FUNC_QUEUE_NEW_ENTRY] =
|
||||||
PyObject_GetAttrString(py_module, "queue_new_entry");
|
PyObject_GetAttrString(py_module, "queue_new_entry");
|
||||||
py_functions[PY_FUNC_INTROSPECTION] =
|
py_functions[PY_FUNC_INTROSPECTION] =
|
||||||
@ -394,6 +401,13 @@ void deinit_py(void *py_mutator) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void splice_optout_py(void *py_mutator) {
|
||||||
|
|
||||||
|
// this is never called
|
||||||
|
(void)(py_mutator);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
struct custom_mutator *load_custom_mutator_py(afl_state_t *afl,
|
struct custom_mutator *load_custom_mutator_py(afl_state_t *afl,
|
||||||
char *module_name) {
|
char *module_name) {
|
||||||
|
|
||||||
@ -474,6 +488,13 @@ struct custom_mutator *load_custom_mutator_py(afl_state_t *afl,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (py_functions[PY_FUNC_SPLICE_OPTOUT]) {
|
||||||
|
|
||||||
|
mutator->afl_custom_splice_optout = splice_optout_py;
|
||||||
|
afl->custom_splice_optout = 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
if (py_functions[PY_FUNC_QUEUE_NEW_ENTRY]) {
|
if (py_functions[PY_FUNC_QUEUE_NEW_ENTRY]) {
|
||||||
|
|
||||||
mutator->afl_custom_queue_new_entry = queue_new_entry_py;
|
mutator->afl_custom_queue_new_entry = queue_new_entry_py;
|
||||||
|
@ -27,6 +27,22 @@
|
|||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
|
#ifdef _STANDALONE_MODULE
|
||||||
|
void minimize_bits(afl_state_t *afl, u8 *dst, u8 *src) {
|
||||||
|
|
||||||
|
return;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void run_afl_custom_queue_new_entry(afl_state_t *afl, struct queue_entry *q,
|
||||||
|
u8 *a, u8 *b) {
|
||||||
|
|
||||||
|
return;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
/* select next queue entry based on alias algo - fast! */
|
/* select next queue entry based on alias algo - fast! */
|
||||||
|
|
||||||
inline u32 select_next_queue_entry(afl_state_t *afl) {
|
inline u32 select_next_queue_entry(afl_state_t *afl) {
|
||||||
@ -78,8 +94,8 @@ void create_alias_table(afl_state_t *afl) {
|
|||||||
afl->alias_probability = (double *)afl_realloc(
|
afl->alias_probability = (double *)afl_realloc(
|
||||||
(void **)&afl->alias_probability, n * sizeof(double));
|
(void **)&afl->alias_probability, n * sizeof(double));
|
||||||
double *P = (double *)afl_realloc(AFL_BUF_PARAM(out), n * sizeof(double));
|
double *P = (double *)afl_realloc(AFL_BUF_PARAM(out), n * sizeof(double));
|
||||||
int *S = (u32 *)afl_realloc(AFL_BUF_PARAM(out_scratch), n * sizeof(u32));
|
int *S = (int *)afl_realloc(AFL_BUF_PARAM(out_scratch), n * sizeof(u32));
|
||||||
int *L = (u32 *)afl_realloc(AFL_BUF_PARAM(in_scratch), n * sizeof(u32));
|
int *L = (int *)afl_realloc(AFL_BUF_PARAM(in_scratch), n * sizeof(u32));
|
||||||
|
|
||||||
if (!P || !S || !L || !afl->alias_table || !afl->alias_probability) {
|
if (!P || !S || !L || !afl->alias_table || !afl->alias_probability) {
|
||||||
|
|
||||||
@ -247,11 +263,11 @@ void create_alias_table(afl_state_t *afl) {
|
|||||||
|
|
||||||
void mark_as_det_done(afl_state_t *afl, struct queue_entry *q) {
|
void mark_as_det_done(afl_state_t *afl, struct queue_entry *q) {
|
||||||
|
|
||||||
u8 fn[PATH_MAX];
|
char fn[PATH_MAX];
|
||||||
s32 fd;
|
s32 fd;
|
||||||
|
|
||||||
snprintf(fn, PATH_MAX, "%s/queue/.state/deterministic_done/%s", afl->out_dir,
|
snprintf(fn, PATH_MAX, "%s/queue/.state/deterministic_done/%s", afl->out_dir,
|
||||||
strrchr(q->fname, '/') + 1);
|
strrchr((char *)q->fname, '/') + 1);
|
||||||
|
|
||||||
fd = open(fn, O_WRONLY | O_CREAT | O_EXCL, DEFAULT_PERMISSION);
|
fd = open(fn, O_WRONLY | O_CREAT | O_EXCL, DEFAULT_PERMISSION);
|
||||||
if (fd < 0) { PFATAL("Unable to create '%s'", fn); }
|
if (fd < 0) { PFATAL("Unable to create '%s'", fn); }
|
||||||
@ -266,10 +282,10 @@ void mark_as_det_done(afl_state_t *afl, struct queue_entry *q) {
|
|||||||
|
|
||||||
void mark_as_variable(afl_state_t *afl, struct queue_entry *q) {
|
void mark_as_variable(afl_state_t *afl, struct queue_entry *q) {
|
||||||
|
|
||||||
u8 fn[PATH_MAX];
|
char fn[PATH_MAX];
|
||||||
u8 ldest[PATH_MAX];
|
char ldest[PATH_MAX];
|
||||||
|
|
||||||
u8 *fn_name = strrchr(q->fname, '/') + 1;
|
char *fn_name = strrchr((char *)q->fname, '/') + 1;
|
||||||
|
|
||||||
sprintf(ldest, "../../%s", fn_name);
|
sprintf(ldest, "../../%s", fn_name);
|
||||||
sprintf(fn, "%s/queue/.state/variable_behavior/%s", afl->out_dir, fn_name);
|
sprintf(fn, "%s/queue/.state/variable_behavior/%s", afl->out_dir, fn_name);
|
||||||
@ -293,12 +309,12 @@ void mark_as_redundant(afl_state_t *afl, struct queue_entry *q, u8 state) {
|
|||||||
|
|
||||||
if (likely(state == q->fs_redundant)) { return; }
|
if (likely(state == q->fs_redundant)) { return; }
|
||||||
|
|
||||||
u8 fn[PATH_MAX];
|
char fn[PATH_MAX];
|
||||||
|
|
||||||
q->fs_redundant = state;
|
q->fs_redundant = state;
|
||||||
|
|
||||||
sprintf(fn, "%s/queue/.state/redundant_edges/%s", afl->out_dir,
|
sprintf(fn, "%s/queue/.state/redundant_edges/%s", afl->out_dir,
|
||||||
strrchr(q->fname, '/') + 1);
|
strrchr((char *)q->fname, '/') + 1);
|
||||||
|
|
||||||
if (state) {
|
if (state) {
|
||||||
|
|
||||||
@ -409,7 +425,7 @@ u8 check_if_text_buf(u8 *buf, u32 len) {
|
|||||||
|
|
||||||
static u8 check_if_text(afl_state_t *afl, struct queue_entry *q) {
|
static u8 check_if_text(afl_state_t *afl, struct queue_entry *q) {
|
||||||
|
|
||||||
if (q->len < AFL_TXT_MIN_LEN) return 0;
|
if (q->len < AFL_TXT_MIN_LEN || q->len < AFL_TXT_MAX_LEN) return 0;
|
||||||
|
|
||||||
u8 *buf;
|
u8 *buf;
|
||||||
int fd;
|
int fd;
|
||||||
@ -417,8 +433,8 @@ static u8 check_if_text(afl_state_t *afl, struct queue_entry *q) {
|
|||||||
ssize_t comp;
|
ssize_t comp;
|
||||||
|
|
||||||
if (len >= MAX_FILE) len = MAX_FILE - 1;
|
if (len >= MAX_FILE) len = MAX_FILE - 1;
|
||||||
if ((fd = open(q->fname, O_RDONLY)) < 0) return 0;
|
if ((fd = open((char *)q->fname, O_RDONLY)) < 0) return 0;
|
||||||
buf = afl_realloc(AFL_BUF_PARAM(in_scratch), len + 1);
|
buf = (u8 *)afl_realloc(AFL_BUF_PARAM(in_scratch), len + 1);
|
||||||
comp = read(fd, buf, len);
|
comp = read(fd, buf, len);
|
||||||
close(fd);
|
close(fd);
|
||||||
if (comp != (ssize_t)len) return 0;
|
if (comp != (ssize_t)len) return 0;
|
||||||
@ -520,7 +536,8 @@ static u8 check_if_text(afl_state_t *afl, struct queue_entry *q) {
|
|||||||
|
|
||||||
void add_to_queue(afl_state_t *afl, u8 *fname, u32 len, u8 passed_det) {
|
void add_to_queue(afl_state_t *afl, u8 *fname, u32 len, u8 passed_det) {
|
||||||
|
|
||||||
struct queue_entry *q = ck_alloc(sizeof(struct queue_entry));
|
struct queue_entry *q =
|
||||||
|
(struct queue_entry *)ck_alloc(sizeof(struct queue_entry));
|
||||||
|
|
||||||
q->fname = fname;
|
q->fname = fname;
|
||||||
q->len = len;
|
q->len = len;
|
||||||
@ -554,7 +571,7 @@ void add_to_queue(afl_state_t *afl, u8 *fname, u32 len, u8 passed_det) {
|
|||||||
|
|
||||||
afl->cycles_wo_finds = 0;
|
afl->cycles_wo_finds = 0;
|
||||||
|
|
||||||
struct queue_entry **queue_buf = afl_realloc(
|
struct queue_entry **queue_buf = (struct queue_entry **)afl_realloc(
|
||||||
AFL_BUF_PARAM(queue), afl->queued_items * sizeof(struct queue_entry *));
|
AFL_BUF_PARAM(queue), afl->queued_items * sizeof(struct queue_entry *));
|
||||||
if (unlikely(!queue_buf)) { PFATAL("alloc"); }
|
if (unlikely(!queue_buf)) { PFATAL("alloc"); }
|
||||||
queue_buf[afl->queued_items - 1] = q;
|
queue_buf[afl->queued_items - 1] = q;
|
||||||
@ -574,7 +591,11 @@ void add_to_queue(afl_state_t *afl, u8 *fname, u32 len, u8 passed_det) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* only redqueen currently uses is_ascii */
|
/* only redqueen currently uses is_ascii */
|
||||||
if (afl->shm.cmplog_mode) q->is_ascii = check_if_text(afl, q);
|
if (unlikely(afl->shm.cmplog_mode && !q->is_ascii)) {
|
||||||
|
|
||||||
|
q->is_ascii = check_if_text(afl, q);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -704,7 +725,7 @@ void update_bitmap_score(afl_state_t *afl, struct queue_entry *q) {
|
|||||||
if (!q->trace_mini) {
|
if (!q->trace_mini) {
|
||||||
|
|
||||||
u32 len = (afl->fsrv.map_size >> 3);
|
u32 len = (afl->fsrv.map_size >> 3);
|
||||||
q->trace_mini = ck_alloc(len);
|
q->trace_mini = (u8 *)ck_alloc(len);
|
||||||
minimize_bits(afl, q->trace_mini, afl->fsrv.trace_bits);
|
minimize_bits(afl, q->trace_mini, afl->fsrv.trace_bits);
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -1007,10 +1028,16 @@ u32 calculate_score(afl_state_t *afl, struct queue_entry *q) {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case LIN:
|
case LIN:
|
||||||
|
// Don't modify perf_score for unfuzzed seeds
|
||||||
|
if (!q->fuzz_level) break;
|
||||||
|
|
||||||
factor = q->fuzz_level / (afl->n_fuzz[q->n_fuzz_entry] + 1);
|
factor = q->fuzz_level / (afl->n_fuzz[q->n_fuzz_entry] + 1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case QUAD:
|
case QUAD:
|
||||||
|
// Don't modify perf_score for unfuzzed seeds
|
||||||
|
if (!q->fuzz_level) break;
|
||||||
|
|
||||||
factor =
|
factor =
|
||||||
q->fuzz_level * q->fuzz_level / (afl->n_fuzz[q->n_fuzz_entry] + 1);
|
q->fuzz_level * q->fuzz_level / (afl->n_fuzz[q->n_fuzz_entry] + 1);
|
||||||
break;
|
break;
|
||||||
@ -1090,19 +1117,19 @@ inline void queue_testcase_retake(afl_state_t *afl, struct queue_entry *q,
|
|||||||
if (len != old_len) {
|
if (len != old_len) {
|
||||||
|
|
||||||
afl->q_testcase_cache_size = afl->q_testcase_cache_size + len - old_len;
|
afl->q_testcase_cache_size = afl->q_testcase_cache_size + len - old_len;
|
||||||
q->testcase_buf = realloc(q->testcase_buf, len);
|
q->testcase_buf = (u8 *)realloc(q->testcase_buf, len);
|
||||||
|
|
||||||
if (unlikely(!q->testcase_buf)) {
|
if (unlikely(!q->testcase_buf)) {
|
||||||
|
|
||||||
PFATAL("Unable to malloc '%s' with len %u", q->fname, len);
|
PFATAL("Unable to malloc '%s' with len %u", (char *)q->fname, len);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int fd = open(q->fname, O_RDONLY);
|
int fd = open((char *)q->fname, O_RDONLY);
|
||||||
|
|
||||||
if (unlikely(fd < 0)) { PFATAL("Unable to open '%s'", q->fname); }
|
if (unlikely(fd < 0)) { PFATAL("Unable to open '%s'", (char *)q->fname); }
|
||||||
|
|
||||||
ck_read(fd, q->testcase_buf, len, q->fname);
|
ck_read(fd, q->testcase_buf, len, q->fname);
|
||||||
close(fd);
|
close(fd);
|
||||||
@ -1122,7 +1149,7 @@ inline void queue_testcase_retake_mem(afl_state_t *afl, struct queue_entry *q,
|
|||||||
|
|
||||||
if (likely(len != old_len)) {
|
if (likely(len != old_len)) {
|
||||||
|
|
||||||
u8 *ptr = realloc(q->testcase_buf, len);
|
u8 *ptr = (u8 *)realloc(q->testcase_buf, len);
|
||||||
|
|
||||||
if (likely(ptr)) {
|
if (likely(ptr)) {
|
||||||
|
|
||||||
@ -1154,23 +1181,23 @@ inline u8 *queue_testcase_get(afl_state_t *afl, struct queue_entry *q) {
|
|||||||
|
|
||||||
if (unlikely(q == afl->queue_cur)) {
|
if (unlikely(q == afl->queue_cur)) {
|
||||||
|
|
||||||
buf = afl_realloc((void **)&afl->testcase_buf, len);
|
buf = (u8 *)afl_realloc((void **)&afl->testcase_buf, len);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
buf = afl_realloc((void **)&afl->splicecase_buf, len);
|
buf = (u8 *)afl_realloc((void **)&afl->splicecase_buf, len);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (unlikely(!buf)) {
|
if (unlikely(!buf)) {
|
||||||
|
|
||||||
PFATAL("Unable to malloc '%s' with len %u", q->fname, len);
|
PFATAL("Unable to malloc '%s' with len %u", (char *)q->fname, len);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int fd = open(q->fname, O_RDONLY);
|
int fd = open((char *)q->fname, O_RDONLY);
|
||||||
|
|
||||||
if (unlikely(fd < 0)) { PFATAL("Unable to open '%s'", q->fname); }
|
if (unlikely(fd < 0)) { PFATAL("Unable to open '%s'", (char *)q->fname); }
|
||||||
|
|
||||||
ck_read(fd, buf, len, q->fname);
|
ck_read(fd, buf, len, q->fname);
|
||||||
close(fd);
|
close(fd);
|
||||||
@ -1214,7 +1241,7 @@ inline u8 *queue_testcase_get(afl_state_t *afl, struct queue_entry *q) {
|
|||||||
|
|
||||||
do_once = 1;
|
do_once = 1;
|
||||||
// release unneeded memory
|
// release unneeded memory
|
||||||
afl->q_testcase_cache = ck_realloc(
|
afl->q_testcase_cache = (struct queue_entry **)ck_realloc(
|
||||||
afl->q_testcase_cache,
|
afl->q_testcase_cache,
|
||||||
(afl->q_testcase_max_cache_entries + 1) * sizeof(size_t));
|
(afl->q_testcase_max_cache_entries + 1) * sizeof(size_t));
|
||||||
|
|
||||||
@ -1261,15 +1288,15 @@ inline u8 *queue_testcase_get(afl_state_t *afl, struct queue_entry *q) {
|
|||||||
|
|
||||||
/* Map the test case into memory. */
|
/* Map the test case into memory. */
|
||||||
|
|
||||||
int fd = open(q->fname, O_RDONLY);
|
int fd = open((char *)q->fname, O_RDONLY);
|
||||||
|
|
||||||
if (unlikely(fd < 0)) { PFATAL("Unable to open '%s'", q->fname); }
|
if (unlikely(fd < 0)) { PFATAL("Unable to open '%s'", (char *)q->fname); }
|
||||||
|
|
||||||
q->testcase_buf = malloc(len);
|
q->testcase_buf = (u8 *)malloc(len);
|
||||||
|
|
||||||
if (unlikely(!q->testcase_buf)) {
|
if (unlikely(!q->testcase_buf)) {
|
||||||
|
|
||||||
PFATAL("Unable to malloc '%s' with len %u", q->fname, len);
|
PFATAL("Unable to malloc '%s' with len %u", (char *)q->fname, len);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1332,11 +1359,11 @@ inline void queue_testcase_store_mem(afl_state_t *afl, struct queue_entry *q,
|
|||||||
|
|
||||||
/* Map the test case into memory. */
|
/* Map the test case into memory. */
|
||||||
|
|
||||||
q->testcase_buf = malloc(len);
|
q->testcase_buf = (u8 *)malloc(len);
|
||||||
|
|
||||||
if (unlikely(!q->testcase_buf)) {
|
if (unlikely(!q->testcase_buf)) {
|
||||||
|
|
||||||
PFATAL("Unable to malloc '%s' with len %u", q->fname, len);
|
PFATAL("Unable to malloc '%s' with len %u", (char *)q->fname, len);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1035,7 +1035,7 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h,
|
|||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
diff = 0;
|
o_diff = 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1624,6 +1624,8 @@ static void try_to_add_to_dictN(afl_state_t *afl, u128 v, u8 size) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cons_0 > 1 || cons_ff > 1) { return; }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
maybe_add_auto(afl, (u8 *)&v + off, size);
|
maybe_add_auto(afl, (u8 *)&v + off, size);
|
||||||
|
@ -523,7 +523,7 @@ u8 calibrate_case(afl_state_t *afl, struct queue_entry *q, u8 *use_mem,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (unlikely(!var_detected)) {
|
if (unlikely(!var_detected && !afl->afl_env.afl_no_warn_instability)) {
|
||||||
|
|
||||||
// note: from_queue seems to only be set during initialization
|
// note: from_queue seems to only be set during initialization
|
||||||
if (afl->afl_env.afl_no_ui || from_queue) {
|
if (afl->afl_env.afl_no_ui || from_queue) {
|
||||||
|
@ -204,6 +204,13 @@ void read_afl_environment(afl_state_t *afl, char **envp) {
|
|||||||
afl->afl_env.afl_no_affinity =
|
afl->afl_env.afl_no_affinity =
|
||||||
get_afl_env(afl_environment_variables[i]) ? 1 : 0;
|
get_afl_env(afl_environment_variables[i]) ? 1 : 0;
|
||||||
|
|
||||||
|
} else if (!strncmp(env, "AFL_NO_WARN_INSTABILITY",
|
||||||
|
|
||||||
|
afl_environment_variable_len)) {
|
||||||
|
|
||||||
|
afl->afl_env.afl_no_warn_instability =
|
||||||
|
get_afl_env(afl_environment_variables[i]) ? 1 : 0;
|
||||||
|
|
||||||
} else if (!strncmp(env, "AFL_TRY_AFFINITY",
|
} else if (!strncmp(env, "AFL_TRY_AFFINITY",
|
||||||
|
|
||||||
afl_environment_variable_len)) {
|
afl_environment_variable_len)) {
|
||||||
@ -292,6 +299,13 @@ void read_afl_environment(afl_state_t *afl, char **envp) {
|
|||||||
afl->afl_env.afl_ignore_problems =
|
afl->afl_env.afl_ignore_problems =
|
||||||
get_afl_env(afl_environment_variables[i]) ? 1 : 0;
|
get_afl_env(afl_environment_variables[i]) ? 1 : 0;
|
||||||
|
|
||||||
|
} else if (!strncmp(env, "AFL_IGNORE_TIMEOUTS",
|
||||||
|
|
||||||
|
afl_environment_variable_len)) {
|
||||||
|
|
||||||
|
afl->afl_env.afl_ignore_timeouts =
|
||||||
|
get_afl_env(afl_environment_variables[i]) ? 1 : 0;
|
||||||
|
|
||||||
} else if (!strncmp(env, "AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES",
|
} else if (!strncmp(env, "AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES",
|
||||||
|
|
||||||
afl_environment_variable_len)) {
|
afl_environment_variable_len)) {
|
||||||
|
@ -258,8 +258,9 @@ static void usage(u8 *argv0, int more_help) {
|
|||||||
"AFL_FORKSRV_INIT_TMOUT: time spent waiting for forkserver during startup (in ms)\n"
|
"AFL_FORKSRV_INIT_TMOUT: time spent waiting for forkserver during startup (in ms)\n"
|
||||||
"AFL_HANG_TMOUT: override timeout value (in milliseconds)\n"
|
"AFL_HANG_TMOUT: override timeout value (in milliseconds)\n"
|
||||||
"AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES: don't warn about core dump handlers\n"
|
"AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES: don't warn about core dump handlers\n"
|
||||||
"AFL_IGNORE_UNKNOWN_ENVS: don't warn on unknown env vars\n"
|
|
||||||
"AFL_IGNORE_PROBLEMS: do not abort fuzzing if an incorrect setup is detected\n"
|
"AFL_IGNORE_PROBLEMS: do not abort fuzzing if an incorrect setup is detected\n"
|
||||||
|
"AFL_IGNORE_TIMEOUTS: do not process or save any timeouts\n"
|
||||||
|
"AFL_IGNORE_UNKNOWN_ENVS: don't warn on unknown env vars\n"
|
||||||
"AFL_IMPORT_FIRST: sync and import test cases from other fuzzer instances first\n"
|
"AFL_IMPORT_FIRST: sync and import test cases from other fuzzer instances first\n"
|
||||||
"AFL_INPUT_LEN_MIN/AFL_INPUT_LEN_MAX: like -g/-G set min/max fuzz length produced\n"
|
"AFL_INPUT_LEN_MIN/AFL_INPUT_LEN_MAX: like -g/-G set min/max fuzz length produced\n"
|
||||||
"AFL_PIZZA_MODE: 1 - enforce pizza mode, 0 - disable for April 1st\n"
|
"AFL_PIZZA_MODE: 1 - enforce pizza mode, 0 - disable for April 1st\n"
|
||||||
@ -1297,6 +1298,13 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (afl->is_main_node == 1 && afl->schedule != FAST &&
|
||||||
|
afl->schedule != EXPLORE) {
|
||||||
|
|
||||||
|
FATAL("-M is compatible only with fast and explore -p power schedules");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
if (optind == argc || !afl->in_dir || !afl->out_dir || show_help) {
|
if (optind == argc || !afl->in_dir || !afl->out_dir || show_help) {
|
||||||
|
|
||||||
usage(argv[0], show_help);
|
usage(argv[0], show_help);
|
||||||
@ -1579,6 +1587,29 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (afl->limit_time_sig > 0 && afl->custom_mutators_count) {
|
||||||
|
|
||||||
|
if (afl->custom_only) {
|
||||||
|
|
||||||
|
FATAL("Custom mutators are incompatible with MOpt (-L)");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 custom_fuzz = 0;
|
||||||
|
LIST_FOREACH(&afl->custom_mutator_list, struct custom_mutator, {
|
||||||
|
|
||||||
|
if (el->afl_custom_fuzz) { custom_fuzz = 1; }
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
if (custom_fuzz) {
|
||||||
|
|
||||||
|
WARNF("afl_custom_fuzz is incompatible with MOpt (-L)");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
if (afl->afl_env.afl_max_det_extras) {
|
if (afl->afl_env.afl_max_det_extras) {
|
||||||
|
|
||||||
s32 max_det_extras = atoi(afl->afl_env.afl_max_det_extras);
|
s32 max_det_extras = atoi(afl->afl_env.afl_max_det_extras);
|
||||||
@ -2081,6 +2112,7 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
afl->cmplog_fsrv.qemu_mode = afl->fsrv.qemu_mode;
|
afl->cmplog_fsrv.qemu_mode = afl->fsrv.qemu_mode;
|
||||||
afl->cmplog_fsrv.frida_mode = afl->fsrv.frida_mode;
|
afl->cmplog_fsrv.frida_mode = afl->fsrv.frida_mode;
|
||||||
afl->cmplog_fsrv.cmplog_binary = afl->cmplog_binary;
|
afl->cmplog_fsrv.cmplog_binary = afl->cmplog_binary;
|
||||||
|
afl->cmplog_fsrv.target_path = afl->fsrv.target_path;
|
||||||
afl->cmplog_fsrv.init_child_func = cmplog_exec_child;
|
afl->cmplog_fsrv.init_child_func = cmplog_exec_child;
|
||||||
|
|
||||||
if ((map_size <= DEFAULT_SHMEM_SIZE ||
|
if ((map_size <= DEFAULT_SHMEM_SIZE ||
|
||||||
@ -2549,6 +2581,7 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
skipped_fuzz = fuzz_one(afl);
|
skipped_fuzz = fuzz_one(afl);
|
||||||
#ifdef INTROSPECTION
|
#ifdef INTROSPECTION
|
||||||
++afl->queue_cur->stats_selected;
|
++afl->queue_cur->stats_selected;
|
||||||
|
|
||||||
if (unlikely(skipped_fuzz)) {
|
if (unlikely(skipped_fuzz)) {
|
||||||
|
|
||||||
++afl->queue_cur->stats_skipped;
|
++afl->queue_cur->stats_skipped;
|
||||||
|
@ -92,7 +92,7 @@ static u32 measure_preemption(u32 target_ms) {
|
|||||||
volatile u32 v1, v2 = 0;
|
volatile u32 v1, v2 = 0;
|
||||||
|
|
||||||
u64 st_t, en_t, st_c, en_c, real_delta, slice_delta;
|
u64 st_t, en_t, st_c, en_c, real_delta, slice_delta;
|
||||||
s32 loop_repeats = 0;
|
// s32 loop_repeats = 0;
|
||||||
|
|
||||||
st_t = get_cur_time_us();
|
st_t = get_cur_time_us();
|
||||||
st_c = get_cpu_usage_us();
|
st_c = get_cpu_usage_us();
|
||||||
@ -113,7 +113,7 @@ repeat_loop:
|
|||||||
|
|
||||||
if (en_t - st_t < target_ms * 1000) {
|
if (en_t - st_t < target_ms * 1000) {
|
||||||
|
|
||||||
loop_repeats++;
|
// loop_repeats++;
|
||||||
goto repeat_loop;
|
goto repeat_loop;
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -214,7 +214,13 @@ int main(int argc, char **argv) {
|
|||||||
#if defined(__linux__)
|
#if defined(__linux__)
|
||||||
if (sched_setaffinity(0, sizeof(c), &c)) {
|
if (sched_setaffinity(0, sizeof(c), &c)) {
|
||||||
|
|
||||||
PFATAL("sched_setaffinity failed for cpu %d", i);
|
const char *error_code = "Unkown error code";
|
||||||
|
if (errno == EFAULT) error_code = "EFAULT";
|
||||||
|
if (errno == EINVAL) error_code = "EINVAL";
|
||||||
|
if (errno == EPERM) error_code = "EPERM";
|
||||||
|
if (errno == ESRCH) error_code = "ESRCH";
|
||||||
|
|
||||||
|
PFATAL("sched_setaffinity failed for cpu %d, error: %s", i, error_code);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -257,12 +257,13 @@ test -e ../afl-clang-fast -a -e ../split-switches-pass.so && {
|
|||||||
}
|
}
|
||||||
rm -f test-compcov test.out instrumentlist.txt
|
rm -f test-compcov test.out instrumentlist.txt
|
||||||
AFL_LLVM_CMPLOG=1 ../afl-clang-fast -o test-cmplog test-cmplog.c > /dev/null 2>&1
|
AFL_LLVM_CMPLOG=1 ../afl-clang-fast -o test-cmplog test-cmplog.c > /dev/null 2>&1
|
||||||
|
../afl-clang-fast -o test-c test-cmplog.c > /dev/null 2>&1
|
||||||
test -e test-cmplog && {
|
test -e test-cmplog && {
|
||||||
$ECHO "$GREY[*] running afl-fuzz for llvm_mode cmplog, this will take approx 10 seconds"
|
$ECHO "$GREY[*] running afl-fuzz for llvm_mode cmplog, this will take approx 10 seconds"
|
||||||
{
|
{
|
||||||
mkdir -p in
|
mkdir -p in
|
||||||
echo 00000000000000000000000000000000 > in/in
|
echo 00000000000000000000000000000000 > in/in
|
||||||
AFL_BENCH_UNTIL_CRASH=1 ../afl-fuzz -m none -V60 -i in -o out -c./test-cmplog -- ./test-cmplog >>errors 2>&1
|
AFL_BENCH_UNTIL_CRASH=1 ../afl-fuzz -m none -V60 -i in -o out -c./test-cmplog -- ./test-c >>errors 2>&1
|
||||||
} >>errors 2>&1
|
} >>errors 2>&1
|
||||||
test -n "$( ls out/default/crashes/id:000000* out/default/hangs/id:000000* 2>/dev/null )" & {
|
test -n "$( ls out/default/crashes/id:000000* out/default/hangs/id:000000* 2>/dev/null )" & {
|
||||||
$ECHO "$GREEN[+] afl-fuzz is working correctly with llvm_mode cmplog"
|
$ECHO "$GREEN[+] afl-fuzz is working correctly with llvm_mode cmplog"
|
||||||
@ -277,7 +278,7 @@ test -e ../afl-clang-fast -a -e ../split-switches-pass.so && {
|
|||||||
$ECHO "$YELLOW[-] we cannot test llvm_mode cmplog because it is not present"
|
$ECHO "$YELLOW[-] we cannot test llvm_mode cmplog because it is not present"
|
||||||
INCOMPLETE=1
|
INCOMPLETE=1
|
||||||
}
|
}
|
||||||
rm -rf errors test-cmplog in core.*
|
rm -rf errors test-cmplog test-c in core.*
|
||||||
../afl-clang-fast -o test-persistent ../utils/persistent_mode/persistent_demo.c > /dev/null 2>&1
|
../afl-clang-fast -o test-persistent ../utils/persistent_mode/persistent_demo.c > /dev/null 2>&1
|
||||||
test -e test-persistent && {
|
test -e test-persistent && {
|
||||||
echo foo | AFL_QUIET=1 ../afl-showmap -m ${MEM_LIMIT} -o /dev/null -q -r ./test-persistent && {
|
echo foo | AFL_QUIET=1 ../afl-showmap -m ${MEM_LIMIT} -o /dev/null -q -r ./test-persistent && {
|
||||||
|
Reference in New Issue
Block a user