Merge branch 'master' of github.com:vanhauser-thc/AFLplusplus

This commit is contained in:
Andrea Fioraldi 2019-12-19 14:35:37 +01:00
commit d8fb4a8e19
16 changed files with 48 additions and 85 deletions

3
.gitmodules vendored
View File

@ -1,3 +0,0 @@
[submodule "unicorn_mode/unicorn"]
path = unicorn_mode/unicorn
url = https://github.com/vanhauser-thc/unicorn.git

View File

@ -310,7 +310,7 @@ all_done: test_build
.NOTPARALLEL: clean .NOTPARALLEL: clean
clean: clean:
rm -f $(PROGS) libradamsa.so afl-as as afl-g++ afl-clang afl-clang++ *.o src/*.o *~ a.out core core.[1-9][0-9]* *.stackdump .test .test1 .test2 test-instr .test-instr0 .test-instr1 qemu_mode/qemu-3.1.1.tar.xz afl-qemu-trace afl-gcc-fast afl-gcc-pass.so afl-gcc-rt.o afl-g++-fast *.so *.8 rm -f $(PROGS) libradamsa.so afl-fuzz-document afl-as as afl-g++ afl-clang afl-clang++ *.o src/*.o *~ a.out core core.[1-9][0-9]* *.stackdump .test .test1 .test2 test-instr .test-instr0 .test-instr1 qemu_mode/qemu-3.1.1.tar.xz afl-qemu-trace afl-gcc-fast afl-gcc-pass.so afl-gcc-rt.o afl-g++-fast *.so *.8
rm -rf out_dir qemu_mode/qemu-3.1.1 *.dSYM */*.dSYM rm -rf out_dir qemu_mode/qemu-3.1.1 *.dSYM */*.dSYM
-$(MAKE) -C llvm_mode clean -$(MAKE) -C llvm_mode clean
-$(MAKE) -C gcc_plugin clean -$(MAKE) -C gcc_plugin clean
@ -319,7 +319,7 @@ clean:
$(MAKE) -C qemu_mode/unsigaction clean $(MAKE) -C qemu_mode/unsigaction clean
$(MAKE) -C qemu_mode/libcompcov clean $(MAKE) -C qemu_mode/libcompcov clean
$(MAKE) -C src/third_party/libradamsa/ clean $(MAKE) -C src/third_party/libradamsa/ clean
$(MAKE) -C unicorn_mode/unicorn clean -$(MAKE) -C unicorn_mode/unicorn clean
distrib: all radamsa distrib: all radamsa
-$(MAKE) -C llvm_mode -$(MAKE) -C llvm_mode

View File

@ -2,9 +2,9 @@
![Travis State](https://api.travis-ci.com/vanhauser-thc/AFLplusplus.svg?branch=master) ![Travis State](https://api.travis-ci.com/vanhauser-thc/AFLplusplus.svg?branch=master)
Release Version: 2.58c Release Version: 2.59c
Github Version: 2.58d Github Version: 2.59d
includes all necessary/interesting changes from Google's afl 2.56b includes all necessary/interesting changes from Google's afl 2.56b

View File

@ -13,9 +13,17 @@ Want to stay in the loop on major new features? Join our mailing list by
sending a mail to <afl-users+subscribe@googlegroups.com>. sending a mail to <afl-users+subscribe@googlegroups.com>.
---------------------- --------------------------
Version ++2.58d (dev): Version ++2.59d (develop):
---------------------- --------------------------
- your patch? :-)
--------------------------
Version ++2.59c (release):
--------------------------
- qbdi_mode: fuzz android native libraries via QBDI framework - qbdi_mode: fuzz android native libraries via QBDI framework
- unicorn_mode: switched to the new unicornafl, thanks domenukk - unicorn_mode: switched to the new unicornafl, thanks domenukk

View File

@ -26,7 +26,7 @@
/* Version string: */ /* Version string: */
#define VERSION "++2.58d" // c = release, d = volatile github dev #define VERSION "++2.59d" // c = release, d = volatile github dev
/****************************************************** /******************************************************
* * * *

View File

@ -130,7 +130,7 @@ static u8 alloc_verbose, /* Additional debug messages */
static __thread size_t total_mem; /* Currently allocated mem */ static __thread size_t total_mem; /* Currently allocated mem */
static __thread u32 call_depth; /* To avoid recursion via fprintf() */ static __thread u32 call_depth; /* To avoid recursion via fprintf() */
static u32 alloc_canary; static u32 alloc_canary;
/* This is the main alloc function. It allocates one page more than necessary, /* This is the main alloc function. It allocates one page more than necessary,
sets that tailing page to PROT_NONE, and then increments the return address sets that tailing page to PROT_NONE, and then increments the return address

View File

@ -358,7 +358,7 @@ static void edit_params(u32 argc, char** argv) {
} }
//#ifndef __ANDROID__ // not sure, we might need these ifdefs for Android //#ifndef __ANDROID__ // not sure, we might need these ifdefs for Android
switch (bit_mode) { switch (bit_mode) {
case 0: case 0:
@ -382,7 +382,8 @@ static void edit_params(u32 argc, char** argv) {
break; break;
} }
//#endif
//#endif
} }
@ -443,9 +444,9 @@ int main(int argc, char** argv) {
} }
//#ifndef __ANDROID__ // not sure this is needed for Android, so at the moment we rather keep this out #ifndef __ANDROID__
find_obj(argv[0]); find_obj(argv[0]);
//#endif #endif
edit_params(argc, argv); edit_params(argc, argv);

View File

@ -243,10 +243,9 @@ else
fi fi
echo "[+] Building libcompcov ..." echo "[+] Building libcompcov ..."
make -C libcompcov make -C libcompcov && echo "[+] libcompcov ready"
echo "[+] Building unsigaction ..." echo "[+] Building unsigaction ..."
make -C unsigaction make -C unsigaction && echo "[+] unsigaction ready"
echo "[+] libcompcov ready"
echo "[+] All done for qemu_mode, enjoy!" echo "[+] All done for qemu_mode, enjoy!"
exit 0 exit 0

View File

@ -79,8 +79,8 @@ void afl_debug_dump_saved_regs();
void afl_persistent_loop(); void afl_persistent_loop();
void tcg_gen_afl_call0(void *func); void tcg_gen_afl_call0(void *func);
void tcg_gen_afl_compcov_log_call(void *func, target_ulong cur_loc, void tcg_gen_afl_compcov_log_call(void *func, target_ulong cur_loc, TCGv arg1,
TCGv arg1, TCGv arg2); TCGv arg2);
void tcg_gen_afl_maybe_log_call(target_ulong cur_loc); void tcg_gen_afl_maybe_log_call(target_ulong cur_loc);

View File

@ -376,8 +376,8 @@ void tcg_gen_afl_call0(void *func) {
} }
void tcg_gen_afl_compcov_log_call(void *func, target_ulong cur_loc, void tcg_gen_afl_compcov_log_call(void *func, target_ulong cur_loc, TCGv arg1,
TCGv arg1, TCGv arg2) { TCGv arg2) {
int i, real_args, nb_rets, pi; int i, real_args, nb_rets, pi;
unsigned sizemask, flags; unsigned sizemask, flags;

View File

@ -685,13 +685,14 @@ u8 save_if_interesting(char** argv, void* mem, u32 len, u8 fault) {
++unique_crashes; ++unique_crashes;
if (infoexec) { // if the user wants to be informed on new crashes - do if (infoexec) { // if the user wants to be informed on new crashes - do
#if !TARGET_OS_IPHONE #if !TARGET_OS_IPHONE
// that // that
if (system(infoexec) == -1) if (system(infoexec) == -1)
hnb += 0; // we dont care if system errors, but we dont want a hnb += 0; // we dont care if system errors, but we dont want a
// compiler warning either // compiler warning either
#else #else
WARNF("command execution unsupported"); WARNF("command execution unsupported");
#endif #endif
} }
last_crash_time = get_cur_time(); last_crash_time = get_cur_time();

View File

@ -1905,9 +1905,10 @@ void check_binary(u8* fname) {
#else #else
#if !defined(__arm__) && !defined(__arm64__) #if !defined(__arm__) && !defined(__arm64__)
if ((f_data[0] != 0xCF || f_data[1] != 0xFA || f_data[2] != 0xED) if ((f_data[0] != 0xCF || f_data[1] != 0xFA || f_data[2] != 0xED) &&
&& (f_data[0] != 0xCA || f_data[1] != 0xFE || f_data[2] != 0xBA)) (f_data[0] != 0xCA || f_data[1] != 0xFE || f_data[2] != 0xBA))
FATAL("Program '%s' is not a 64-bit or universal Mach-O binary", target_path); FATAL("Program '%s' is not a 64-bit or universal Mach-O binary",
target_path);
#endif #endif
#endif /* ^!__APPLE__ */ #endif /* ^!__APPLE__ */

View File

@ -89,7 +89,7 @@ if [ "$PLT" = "NetBSD" ] || [ "$PLT" = "OpenBSD" ]; then
TARCMD=gtar TARCMD=gtar
fi fi
for i in wget $PYTHONBIN automake autoconf $MAKECMD $TARCMD; do for i in wget $PYTHONBIN automake autoconf git $MAKECMD $TARCMD; do
T=`which "$i" 2>/dev/null` T=`which "$i" 2>/dev/null`
@ -124,8 +124,10 @@ fi
echo "[+] All checks passed!" echo "[+] All checks passed!"
echo "[*] Making sure unicornafl is checked out" echo "[*] Making sure unicornafl is checked out"
git submodule init || exit 1 rm -rf unicorn # workaround for travis ... sadly ...
git submodule update || exit 1 #test -d unicorn && { cd unicorn && { git stash ; git pull ; cd .. ; } }
test -d unicorn || git clone https://github.com/vanhauser-thc/unicorn
test -d unicorn || { echo "[-] not checked out, please install git or check your internet connection." ; exit 1 ; }
echo "[+] Got unicornafl." echo "[+] Got unicornafl."
echo "[*] making sure config.h matches" echo "[*] making sure config.h matches"

View File

@ -59,35 +59,17 @@ def unicorn_debug_mem_invalid_access(uc, access, address, size, value, user_data
else: else:
print(" >>> INVALID Read: addr=0x{0:016x} size={1}".format(address, size)) print(" >>> INVALID Read: addr=0x{0:016x} size={1}".format(address, size))
def force_crash(uc_error):
# This function should be called to indicate to AFL that a crash occurred during emulation.
# Pass in the exception received from Uc.emu_start()
mem_errors = [
UC_ERR_READ_UNMAPPED, UC_ERR_READ_PROT, UC_ERR_READ_UNALIGNED,
UC_ERR_WRITE_UNMAPPED, UC_ERR_WRITE_PROT, UC_ERR_WRITE_UNALIGNED,
UC_ERR_FETCH_UNMAPPED, UC_ERR_FETCH_PROT, UC_ERR_FETCH_UNALIGNED,
]
if uc_error.errno in mem_errors:
# Memory error - throw SIGSEGV
os.kill(os.getpid(), signal.SIGSEGV)
elif uc_error.errno == UC_ERR_INSN_INVALID:
# Invalid instruction - throw SIGILL
os.kill(os.getpid(), signal.SIGILL)
else:
# Not sure what happened - throw SIGABRT
os.kill(os.getpid(), signal.SIGABRT)
def main(): def main():
parser = argparse.ArgumentParser(description="Test harness for compcov_target.bin") parser = argparse.ArgumentParser(description="Test harness for compcov_target.bin")
parser.add_argument('input_file', type=str, help="Path to the file containing the mutated input to load") parser.add_argument('input_file', type=str, help="Path to the file containing the mutated input to load")
parser.add_argument('-d', '--debug', default=False, action="store_true", help="Enables debug tracing") parser.add_argument('-t', '--trace', default=False, action="store_true", help="Enables debug tracing")
args = parser.parse_args() args = parser.parse_args()
# Instantiate a MIPS32 big endian Unicorn Engine instance # Instantiate a MIPS32 big endian Unicorn Engine instance
uc = Uc(UC_ARCH_X86, UC_MODE_64) uc = Uc(UC_ARCH_X86, UC_MODE_64)
if args.debug: if args.trace:
uc.hook_add(UC_HOOK_BLOCK, unicorn_debug_block) uc.hook_add(UC_HOOK_BLOCK, unicorn_debug_block)
uc.hook_add(UC_HOOK_CODE, unicorn_debug_instruction) uc.hook_add(UC_HOOK_CODE, unicorn_debug_instruction)
uc.hook_add(UC_HOOK_MEM_WRITE | UC_HOOK_MEM_READ, unicorn_debug_mem_access) uc.hook_add(UC_HOOK_MEM_WRITE | UC_HOOK_MEM_READ, unicorn_debug_mem_access)
@ -132,11 +114,6 @@ def main():
""" """
Callback that loads the mutated input into memory. Callback that loads the mutated input into memory.
""" """
# Load the mutated input from disk
input_file = open(args.input_file, 'rb')
input = input_file.read()
input_file.close()
# Apply constraints to the mutated input # Apply constraints to the mutated input
if len(input) > DATA_SIZE_MAX: if len(input) > DATA_SIZE_MAX:
return return

View File

@ -5,8 +5,8 @@
This loads the simple_target.bin binary (precompiled as MIPS code) into This loads the simple_target.bin binary (precompiled as MIPS code) into
Unicorn's memory map for emulation, places the specified input into Unicorn's memory map for emulation, places the specified input into
simple_target's buffer (hardcoded to be at 0x300000), and executes 'main()'. simple_target's buffer (hardcoded to be at 0x300000), and executes 'main()'.
If any crashes occur during emulation, this script throws a matching signal If any crashes occur during emulation, unicornafl will
to tell AFL that a crash occurred. tell AFL that a crash occurred.
Run under AFL as follows: Run under AFL as follows:
@ -59,35 +59,17 @@ def unicorn_debug_mem_invalid_access(uc, access, address, size, value, user_data
else: else:
print(" >>> INVALID Read: addr=0x{0:016x} size={1}".format(address, size)) print(" >>> INVALID Read: addr=0x{0:016x} size={1}".format(address, size))
def force_crash(uc_error):
# This function should be called to indicate to AFL that a crash occurred during emulation.
# Pass in the exception received from Uc.emu_start()
mem_errors = [
UC_ERR_READ_UNMAPPED, UC_ERR_READ_PROT, UC_ERR_READ_UNALIGNED,
UC_ERR_WRITE_UNMAPPED, UC_ERR_WRITE_PROT, UC_ERR_WRITE_UNALIGNED,
UC_ERR_FETCH_UNMAPPED, UC_ERR_FETCH_PROT, UC_ERR_FETCH_UNALIGNED,
]
if uc_error.errno in mem_errors:
# Memory error - throw SIGSEGV
os.kill(os.getpid(), signal.SIGSEGV)
elif uc_error.errno == UC_ERR_INSN_INVALID:
# Invalid instruction - throw SIGILL
os.kill(os.getpid(), signal.SIGILL)
else:
# Not sure what happened - throw SIGABRT
os.kill(os.getpid(), signal.SIGABRT)
def main(): def main():
parser = argparse.ArgumentParser(description="Test harness for simple_target.bin") parser = argparse.ArgumentParser(description="Test harness for simple_target.bin")
parser.add_argument('input_file', type=str, help="Path to the file containing the mutated input to load") parser.add_argument('input_file', type=str, help="Path to the file containing the mutated input to load")
parser.add_argument('-d', '--debug', default=False, action="store_true", help="Enables debug tracing") parser.add_argument('-t', '--trace', default=False, action="store_true", help="Enables debug tracing")
args = parser.parse_args() args = parser.parse_args()
# Instantiate a MIPS32 big endian Unicorn Engine instance # Instantiate a MIPS32 big endian Unicorn Engine instance
uc = Uc(UC_ARCH_MIPS, UC_MODE_MIPS32 + UC_MODE_BIG_ENDIAN) uc = Uc(UC_ARCH_MIPS, UC_MODE_MIPS32 + UC_MODE_BIG_ENDIAN)
if args.debug: if args.trace:
uc.hook_add(UC_HOOK_BLOCK, unicorn_debug_block) uc.hook_add(UC_HOOK_BLOCK, unicorn_debug_block)
uc.hook_add(UC_HOOK_CODE, unicorn_debug_instruction) uc.hook_add(UC_HOOK_CODE, unicorn_debug_instruction)
uc.hook_add(UC_HOOK_MEM_WRITE | UC_HOOK_MEM_READ, unicorn_debug_mem_access) uc.hook_add(UC_HOOK_MEM_WRITE | UC_HOOK_MEM_READ, unicorn_debug_mem_access)
@ -129,11 +111,6 @@ def main():
# We did not pass in any data and don't use persistent mode, so we can ignore these params. # We did not pass in any data and don't use persistent mode, so we can ignore these params.
# Be sure to check out the docstrings for the uc.afl_* functions. # Be sure to check out the docstrings for the uc.afl_* functions.
def place_input_callback(uc, input, persistent_round, data): def place_input_callback(uc, input, persistent_round, data):
# Load the mutated input from disk
input_file = open(args.input_file, 'rb')
input = input_file.read()
input_file.close()
# Apply constraints to the mutated input # Apply constraints to the mutated input
if len(input) > DATA_SIZE_MAX: if len(input) > DATA_SIZE_MAX:
#print("Test input is too long (> {} bytes)") #print("Test input is too long (> {} bytes)")

@ -1 +1 @@
Subproject commit aa5ebf5e16f4f5781cfe94229b41eee7ff93b357 Subproject commit db248c8d8167e47ee07943961d1ce6244d57602b