From 95f47ac3a4d23b28a573a0614893d7aac5f5d4b4 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Mon, 24 May 2021 14:06:46 +0200 Subject: Final push to stable (#936) * sync (#886) * Create FUNDING.yml * Update FUNDING.yml * moved custom_mutator examples * unicorn speedtest makefile cleanup * fixed example location * fix qdbi * update util readme * Frida persistent (#880) * Added x64 support for persistent mode (function call only), in-memory teest cases and complog * Review changes, fix NeverZero and code to parse the .text section of the main executable. Excluded ranges TBC * Various minor fixes and finished support for AFL_INST_LIBS * Review changes Co-authored-by: Your Name * nits * fix frida mode * Integer overflow/underflow fixes in libdislocator (#889) * libdislocator: fixing integer overflow in 'max_mem' variable and setting 'max_mem' type to 'size_t' * libdislocator: fixing potential integer underflow in 'total_mem' variable due to its different values in different threads * Bumped warnings up to the max and fixed remaining issues (#890) Co-authored-by: Your Name * nits * frida mode - support non-pie * nits * nit * update grammar mutator * Fixes for aarch64, OSX and other minor issues (#891) Co-authored-by: Your Name * nits * nits * fix PCGUARD, build aflpp_driver with fPIC * Added representative fuzzbench test and test for libxml (#893) * Added representative fuzzbench test and test for libxml * Added support for building FRIDA from source with FRIDA_SOURCE=1 Co-authored-by: Your Name * nits * update changelog * typos * fixed potential double free in custom trim (#881) * error handling, freeing mem * frida: complog -> cmplog * fix statsd writing * let aflpp_qemu_driver_hook.so build fail gracefully * fix stdin trimming * Support for AFL_ENTRYPOINT (#898) Co-authored-by: Your Name * remove the input file .cur_input at the end of the fuzzing, if AFL_TMPDIR is used * reverse push (#901) * Create FUNDING.yml * Update FUNDING.yml * disable QEMU static pie Co-authored-by: Andrea Fioraldi * clarify that no modifications are required. * add new test for frida_mode (please review) * typos * fix persistent mode (64-bit) * set ARCH for linux intel 32-bit for frida-gum-devkit * prepare for 32-bit support (later) * not on qemu 3 anymore * unicorn mips fixes * instrumentation further move to C++11 (#900) * unicorn fixes * more unicorn fixes * Fix memory errors when trim causes testcase growth (#881) (#903) * Revert "fixed potential double free in custom trim (#881)" This reverts commit e9d2f72382cab75832721d859c3e731da071435d. * Revert "fix custom trim for increasing data" This reverts commit 86a8ef168dda766d2f25f15c15c4d3ecf21d0667. * Fix memory errors when trim causes testcase growth Modify trim_case_custom to avoid writing into in_buf because some custom mutators can cause the testcase to grow rather than shrink. Instead of modifying in_buf directly, we write the update out to the disk when trimming is complete, and then the caller is responsible for refreshing the in-memory buffer from the file. This is still a bit sketchy because it does need to modify q->len in order to notify the upper layers that something changed, and it could end up telling upper layer code that the q->len is *bigger* than the buffer (q->testcase_buf) that contains it, which is asking for trouble down the line somewhere... * Fix an unlikely situation Put back some `unlikely()` calls that were in the e9d2f72382cab75832721d859c3e731da071435d commit that was reverted. * typo * Exit on time (#904) * Variable AFL_EXIT_ON_TIME description has been added. Variables AFL_EXIT_ON_TIME and afl_exit_on_time has been added. afl->exit_on_time variable initialization has been added. The asignment of a value to the afl->afl_env.afl_exit_on_time variable from environment variables has been added. Code to exit on timeout if new path not found has been added. * Type of afl_exit_on_time variable has been changed. Variable exit_on_time has been added to the afl_state_t structure. * Command `export AFL_EXIT_WHEN_DONE=1` has been added. * Millisecond to second conversion has been added. Call get_cur_time() has been added. * Revert to using the saved current time value. * Useless check has been removed. * fix new path to custom-mutators * ensure crashes/README.txt exists * fix * Changes to bump FRIDA version and to clone FRIDA repo in to build directory rather than use a submodule as the FRIDA build scripts don't like it (#906) Co-authored-by: Your Name * Fix numeric overflow in cmplog implementation (#907) Co-authored-by: Your Name * testcase fixes for unicorn * remove merge conflict artifacts * fix afl-plot * Changes to remove binaries from frida_mode (#913) Co-authored-by: Your Name * Frida cmplog fail fast (#914) * Changes to remove binaries from frida_mode * Changes to make cmplog fail fast Co-authored-by: Your Name * afl-plot: relative time * arch linux and mac os support for afl-system-config * typo * code-format * update documentation * github workflow for qemu * OSX-specific improvements (#912) * Fix afl-cc to work correctly by default on OSX using xcode - CLANG_ENV_VAR must be set for afl-as to work - Use clang mode by default if no specific compiler selected * Add OSX-specific documentation for configuring shared memory * Fixes to memory operands for complog (#916) Co-authored-by: Your Name * fix a few cur_time uses * added bounds check to pivot_inputs (fixes #921) * additional safety checks for restarts * restrict afl-showmap in_file size * fix seed crash disable * add warning for afl-showmap partial read * no core dumps * AFL_PRINT_FILENAMES added * more documentation for AFL_EXIT_ON_TIME * Flushing for AFL_PRINT_FILENAMES * FASAN Support (#918) * FASAN Support * Fix handling of Address Sanitizer DSO * Changes to identification of Address Sanitizer DSO Co-authored-by: Your Name * Support for x86 (#920) Co-authored-by: Your Name * Update frida_mode readme (#925) * libqasan: use syscalls for read and write * update readme * Minor integration tweaks (#926) Co-authored-by: Your Name * merge * fix afl-fuzz.c frida preload * cleaned up AFL_PRINT_FILENAMES env * Changes to have persistent mode exit at the end of the loop (#928) Co-authored-by: Your Name * fix llvm-dict2file * push to stable (#931) (#932) * sync (#886) * Create FUNDING.yml * Update FUNDING.yml * moved custom_mutator examples * unicorn speedtest makefile cleanup * fixed example location * fix qdbi * update util readme * Frida persistent (#880) * Added x64 support for persistent mode (function call only), in-memory teest cases and complog * Review changes, fix NeverZero and code to parse the .text section of the main executable. Excluded ranges TBC * Various minor fixes and finished support for AFL_INST_LIBS * Review changes Co-authored-by: Your Name * nits * fix frida mode * Integer overflow/underflow fixes in libdislocator (#889) * libdislocator: fixing integer overflow in 'max_mem' variable and setting 'max_mem' type to 'size_t' * libdislocator: fixing potential integer underflow in 'total_mem' variable due to its different values in different threads * Bumped warnings up to the max and fixed remaining issues (#890) Co-authored-by: Your Name * nits * frida mode - support non-pie * nits * nit * update grammar mutator * Fixes for aarch64, OSX and other minor issues (#891) Co-authored-by: Your Name * nits * nits * fix PCGUARD, build aflpp_driver with fPIC * Added representative fuzzbench test and test for libxml (#893) * Added representative fuzzbench test and test for libxml * Added support for building FRIDA from source with FRIDA_SOURCE=1 Co-authored-by: Your Name * nits * update changelog * typos * fixed potential double free in custom trim (#881) * error handling, freeing mem * frida: complog -> cmplog * fix statsd writing * let aflpp_qemu_driver_hook.so build fail gracefully * fix stdin trimming * Support for AFL_ENTRYPOINT (#898) Co-authored-by: Your Name * remove the input file .cur_input at the end of the fuzzing, if AFL_TMPDIR is used * reverse push (#901) * Create FUNDING.yml * Update FUNDING.yml * disable QEMU static pie Co-authored-by: Andrea Fioraldi * clarify that no modifications are required. * add new test for frida_mode (please review) * typos * fix persistent mode (64-bit) * set ARCH for linux intel 32-bit for frida-gum-devkit * prepare for 32-bit support (later) * not on qemu 3 anymore * unicorn mips fixes * instrumentation further move to C++11 (#900) * unicorn fixes * more unicorn fixes * Fix memory errors when trim causes testcase growth (#881) (#903) * Revert "fixed potential double free in custom trim (#881)" This reverts commit e9d2f72382cab75832721d859c3e731da071435d. * Revert "fix custom trim for increasing data" This reverts commit 86a8ef168dda766d2f25f15c15c4d3ecf21d0667. * Fix memory errors when trim causes testcase growth Modify trim_case_custom to avoid writing into in_buf because some custom mutators can cause the testcase to grow rather than shrink. Instead of modifying in_buf directly, we write the update out to the disk when trimming is complete, and then the caller is responsible for refreshing the in-memory buffer from the file. This is still a bit sketchy because it does need to modify q->len in order to notify the upper layers that something changed, and it could end up telling upper layer code that the q->len is *bigger* than the buffer (q->testcase_buf) that contains it, which is asking for trouble down the line somewhere... * Fix an unlikely situation Put back some `unlikely()` calls that were in the e9d2f72382cab75832721d859c3e731da071435d commit that was reverted. * typo * Exit on time (#904) * Variable AFL_EXIT_ON_TIME description has been added. Variables AFL_EXIT_ON_TIME and afl_exit_on_time has been added. afl->exit_on_time variable initialization has been added. The asignment of a value to the afl->afl_env.afl_exit_on_time variable from environment variables has been added. Code to exit on timeout if new path not found has been added. * Type of afl_exit_on_time variable has been changed. Variable exit_on_time has been added to the afl_state_t structure. * Command `export AFL_EXIT_WHEN_DONE=1` has been added. * Millisecond to second conversion has been added. Call get_cur_time() has been added. * Revert to using the saved current time value. * Useless check has been removed. * fix new path to custom-mutators * ensure crashes/README.txt exists * fix * Changes to bump FRIDA version and to clone FRIDA repo in to build directory rather than use a submodule as the FRIDA build scripts don't like it (#906) Co-authored-by: Your Name * Fix numeric overflow in cmplog implementation (#907) Co-authored-by: Your Name * testcase fixes for unicorn * remove merge conflict artifacts * fix afl-plot * Changes to remove binaries from frida_mode (#913) Co-authored-by: Your Name * Frida cmplog fail fast (#914) * Changes to remove binaries from frida_mode * Changes to make cmplog fail fast Co-authored-by: Your Name * afl-plot: relative time * arch linux and mac os support for afl-system-config * typo * code-format * update documentation * github workflow for qemu * OSX-specific improvements (#912) * Fix afl-cc to work correctly by default on OSX using xcode - CLANG_ENV_VAR must be set for afl-as to work - Use clang mode by default if no specific compiler selected * Add OSX-specific documentation for configuring shared memory * Fixes to memory operands for complog (#916) Co-authored-by: Your Name * fix a few cur_time uses * added bounds check to pivot_inputs (fixes #921) * additional safety checks for restarts * restrict afl-showmap in_file size * fix seed crash disable * add warning for afl-showmap partial read * no core dumps * AFL_PRINT_FILENAMES added * more documentation for AFL_EXIT_ON_TIME * Flushing for AFL_PRINT_FILENAMES * FASAN Support (#918) * FASAN Support * Fix handling of Address Sanitizer DSO * Changes to identification of Address Sanitizer DSO Co-authored-by: Your Name * Support for x86 (#920) Co-authored-by: Your Name * Update frida_mode readme (#925) * libqasan: use syscalls for read and write * update readme * Minor integration tweaks (#926) Co-authored-by: Your Name * merge * fix afl-fuzz.c frida preload * cleaned up AFL_PRINT_FILENAMES env * Changes to have persistent mode exit at the end of the loop (#928) Co-authored-by: Your Name * fix llvm-dict2file Co-authored-by: Dominik Maier Co-authored-by: WorksButNotTested <62701594+WorksButNotTested@users.noreply.github.com> Co-authored-by: Your Name Co-authored-by: Dmitry Zheregelya Co-authored-by: hexcoder Co-authored-by: hexcoder- Co-authored-by: Andrea Fioraldi Co-authored-by: David CARLIER Co-authored-by: realmadsci <71108352+realmadsci@users.noreply.github.com> Co-authored-by: Roman M. Iudichev Co-authored-by: Dustin Spicuzza Co-authored-by: Dominik Maier Co-authored-by: WorksButNotTested <62701594+WorksButNotTested@users.noreply.github.com> Co-authored-by: Your Name Co-authored-by: Dmitry Zheregelya Co-authored-by: hexcoder Co-authored-by: hexcoder- Co-authored-by: Andrea Fioraldi Co-authored-by: David CARLIER Co-authored-by: realmadsci <71108352+realmadsci@users.noreply.github.com> Co-authored-by: Roman M. Iudichev Co-authored-by: Dustin Spicuzza * improve error msg * Added documentation for wine LoadLibrary workaround (#933) * Fix cmake target compilation command example (#934) - Fix typo DCMAKE_C_COMPILERC -> DCMAKE_C_COMPILER. - Add `cd build` after `mkdir build`. * showmap passes queue items in alphabetical order * added tmp files to gitignore * lenient dict parsing, no map size enum for binary fuzzing * added info about showmap queue directions * update binary-only doc * turn off map size detection if skip_bin_check is set * Typo * update docs * update afl-system-config * Set kill signal before using it in afl-showmap (#935) * fix afl-cc help output * add libafl to binary-only doc Co-authored-by: Dominik Maier Co-authored-by: WorksButNotTested <62701594+WorksButNotTested@users.noreply.github.com> Co-authored-by: Your Name Co-authored-by: Dmitry Zheregelya Co-authored-by: hexcoder Co-authored-by: hexcoder- Co-authored-by: Andrea Fioraldi Co-authored-by: David CARLIER Co-authored-by: realmadsci <71108352+realmadsci@users.noreply.github.com> Co-authored-by: Roman M. Iudichev Co-authored-by: Dustin Spicuzza Co-authored-by: 0x4d5a-ctf <51098072+0x4d5a-ctf@users.noreply.github.com> Co-authored-by: Tommy Chiang Co-authored-by: buherator --- docs/binaryonly_fuzzing.md | 50 +++++++++++++++++++++++++++------------------- 1 file changed, 29 insertions(+), 21 deletions(-) (limited to 'docs/binaryonly_fuzzing.md') diff --git a/docs/binaryonly_fuzzing.md b/docs/binaryonly_fuzzing.md index 787d970d..bab64a30 100644 --- a/docs/binaryonly_fuzzing.md +++ b/docs/binaryonly_fuzzing.md @@ -41,6 +41,33 @@ As it is included in afl++ this needs no URL. + If you like to code a customized fuzzer without much work, we highly + recommend to check out our sister project libafl which will support QEMU + very too: + [https://github.com/AFLplusplus/LibAFL](https://github.com/AFLplusplus/LibAFL) + + +## AFL FRIDA + + In frida_mode you can fuzz binary-only targets easily like with QEMU, + with the advantage that frida_mode also works on MacOS (both intel and M1). + + If you want to fuzz a binary-only library then you can fuzz it with + frida-gum via utils/afl_frida/, you will have to write a harness to + call the target function in the library, use afl-frida.c as a template. + + Both come with afl++ so this needs no URL. + + You can also perform remote fuzzing with frida, e.g. if you want to fuzz + on iPhone or Android devices, for this you can use + [https://github.com/ttdennis/fpicker/](https://github.com/ttdennis/fpicker/) + as an intermediate that uses afl++ for fuzzing. + + If you like to code a customized fuzzer without much work, we highly + recommend to check out our sister project libafl which supports Frida too: + [https://github.com/AFLplusplus/LibAFL](https://github.com/AFLplusplus/LibAFL) + Working examples already exist :-) + ## WINE+QEMU @@ -62,13 +89,6 @@ As it is included in afl++ this needs no URL. -## AFL FRIDA - - If you want to fuzz a binary-only shared library then you can fuzz it with - frida-gum via utils/afl_frida/, you will have to write a harness to - call the target function in the library, use afl-frida.c as a template. - - ## AFL UNTRACER If you want to fuzz a binary-only shared library then you can fuzz it with @@ -157,19 +177,6 @@ If anyone finds any coresight implementation for afl please ping me: vh@thc.org -## FRIDA - - Frida is a dynamic instrumentation engine like Pintool, Dyninst and Dynamorio. - What is special is that it is written Python, and scripted with Javascript. - It is mostly used to reverse binaries on mobile phones however can be used - everywhere. - - There is a WIP fuzzer available at [https://github.com/andreafioraldi/frida-fuzzer](https://github.com/andreafioraldi/frida-fuzzer) - - There is also an early implementation in an AFL++ test branch: - [https://github.com/AFLplusplus/AFLplusplus/tree/frida](https://github.com/AFLplusplus/AFLplusplus/tree/frida) - - ## PIN & DYNAMORIO Pintool and Dynamorio are dynamic instrumentation engines, and they can be @@ -205,7 +212,8 @@ * QSYM: [https://github.com/sslab-gatech/qsym](https://github.com/sslab-gatech/qsym) * Manticore: [https://github.com/trailofbits/manticore](https://github.com/trailofbits/manticore) * S2E: [https://github.com/S2E](https://github.com/S2E) - * Tinyinst [https://github.com/googleprojectzero/TinyInst](https://github.com/googleprojectzero/TinyInst) (Mac/Windows only) + * Tinyinst: [https://github.com/googleprojectzero/TinyInst](https://github.com/googleprojectzero/TinyInst) (Mac/Windows only) + * Jackalope: [https://github.com/googleprojectzero/Jackalope](https://github.com/googleprojectzero/Jackalope) * ... please send me any missing that are good -- cgit 1.4.1 From 67293b298d2f6146022ac7adebdf17aebf27bea7 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Sun, 30 May 2021 02:06:05 +0200 Subject: final push to stable (really?) (#939) * sync (#886) * Create FUNDING.yml * Update FUNDING.yml * moved custom_mutator examples * unicorn speedtest makefile cleanup * fixed example location * fix qdbi * update util readme * Frida persistent (#880) * Added x64 support for persistent mode (function call only), in-memory teest cases and complog * Review changes, fix NeverZero and code to parse the .text section of the main executable. Excluded ranges TBC * Various minor fixes and finished support for AFL_INST_LIBS * Review changes Co-authored-by: Your Name * nits * fix frida mode * Integer overflow/underflow fixes in libdislocator (#889) * libdislocator: fixing integer overflow in 'max_mem' variable and setting 'max_mem' type to 'size_t' * libdislocator: fixing potential integer underflow in 'total_mem' variable due to its different values in different threads * Bumped warnings up to the max and fixed remaining issues (#890) Co-authored-by: Your Name * nits * frida mode - support non-pie * nits * nit * update grammar mutator * Fixes for aarch64, OSX and other minor issues (#891) Co-authored-by: Your Name * nits * nits * fix PCGUARD, build aflpp_driver with fPIC * Added representative fuzzbench test and test for libxml (#893) * Added representative fuzzbench test and test for libxml * Added support for building FRIDA from source with FRIDA_SOURCE=1 Co-authored-by: Your Name * nits * update changelog * typos * fixed potential double free in custom trim (#881) * error handling, freeing mem * frida: complog -> cmplog * fix statsd writing * let aflpp_qemu_driver_hook.so build fail gracefully * fix stdin trimming * Support for AFL_ENTRYPOINT (#898) Co-authored-by: Your Name * remove the input file .cur_input at the end of the fuzzing, if AFL_TMPDIR is used * reverse push (#901) * Create FUNDING.yml * Update FUNDING.yml * disable QEMU static pie Co-authored-by: Andrea Fioraldi * clarify that no modifications are required. * add new test for frida_mode (please review) * typos * fix persistent mode (64-bit) * set ARCH for linux intel 32-bit for frida-gum-devkit * prepare for 32-bit support (later) * not on qemu 3 anymore * unicorn mips fixes * instrumentation further move to C++11 (#900) * unicorn fixes * more unicorn fixes * Fix memory errors when trim causes testcase growth (#881) (#903) * Revert "fixed potential double free in custom trim (#881)" This reverts commit e9d2f72382cab75832721d859c3e731da071435d. * Revert "fix custom trim for increasing data" This reverts commit 86a8ef168dda766d2f25f15c15c4d3ecf21d0667. * Fix memory errors when trim causes testcase growth Modify trim_case_custom to avoid writing into in_buf because some custom mutators can cause the testcase to grow rather than shrink. Instead of modifying in_buf directly, we write the update out to the disk when trimming is complete, and then the caller is responsible for refreshing the in-memory buffer from the file. This is still a bit sketchy because it does need to modify q->len in order to notify the upper layers that something changed, and it could end up telling upper layer code that the q->len is *bigger* than the buffer (q->testcase_buf) that contains it, which is asking for trouble down the line somewhere... * Fix an unlikely situation Put back some `unlikely()` calls that were in the e9d2f72382cab75832721d859c3e731da071435d commit that was reverted. * typo * Exit on time (#904) * Variable AFL_EXIT_ON_TIME description has been added. Variables AFL_EXIT_ON_TIME and afl_exit_on_time has been added. afl->exit_on_time variable initialization has been added. The asignment of a value to the afl->afl_env.afl_exit_on_time variable from environment variables has been added. Code to exit on timeout if new path not found has been added. * Type of afl_exit_on_time variable has been changed. Variable exit_on_time has been added to the afl_state_t structure. * Command `export AFL_EXIT_WHEN_DONE=1` has been added. * Millisecond to second conversion has been added. Call get_cur_time() has been added. * Revert to using the saved current time value. * Useless check has been removed. * fix new path to custom-mutators * ensure crashes/README.txt exists * fix * Changes to bump FRIDA version and to clone FRIDA repo in to build directory rather than use a submodule as the FRIDA build scripts don't like it (#906) Co-authored-by: Your Name * Fix numeric overflow in cmplog implementation (#907) Co-authored-by: Your Name * testcase fixes for unicorn * remove merge conflict artifacts * fix afl-plot * Changes to remove binaries from frida_mode (#913) Co-authored-by: Your Name * Frida cmplog fail fast (#914) * Changes to remove binaries from frida_mode * Changes to make cmplog fail fast Co-authored-by: Your Name * afl-plot: relative time * arch linux and mac os support for afl-system-config * typo * code-format * update documentation * github workflow for qemu * OSX-specific improvements (#912) * Fix afl-cc to work correctly by default on OSX using xcode - CLANG_ENV_VAR must be set for afl-as to work - Use clang mode by default if no specific compiler selected * Add OSX-specific documentation for configuring shared memory * Fixes to memory operands for complog (#916) Co-authored-by: Your Name * fix a few cur_time uses * added bounds check to pivot_inputs (fixes #921) * additional safety checks for restarts * restrict afl-showmap in_file size * fix seed crash disable * add warning for afl-showmap partial read * no core dumps * AFL_PRINT_FILENAMES added * more documentation for AFL_EXIT_ON_TIME * Flushing for AFL_PRINT_FILENAMES * FASAN Support (#918) * FASAN Support * Fix handling of Address Sanitizer DSO * Changes to identification of Address Sanitizer DSO Co-authored-by: Your Name * Support for x86 (#920) Co-authored-by: Your Name * Update frida_mode readme (#925) * libqasan: use syscalls for read and write * update readme * Minor integration tweaks (#926) Co-authored-by: Your Name * merge * fix afl-fuzz.c frida preload * cleaned up AFL_PRINT_FILENAMES env * Changes to have persistent mode exit at the end of the loop (#928) Co-authored-by: Your Name * fix llvm-dict2file * push to stable (#931) (#932) * sync (#886) * Create FUNDING.yml * Update FUNDING.yml * moved custom_mutator examples * unicorn speedtest makefile cleanup * fixed example location * fix qdbi * update util readme * Frida persistent (#880) * Added x64 support for persistent mode (function call only), in-memory teest cases and complog * Review changes, fix NeverZero and code to parse the .text section of the main executable. Excluded ranges TBC * Various minor fixes and finished support for AFL_INST_LIBS * Review changes Co-authored-by: Your Name * nits * fix frida mode * Integer overflow/underflow fixes in libdislocator (#889) * libdislocator: fixing integer overflow in 'max_mem' variable and setting 'max_mem' type to 'size_t' * libdislocator: fixing potential integer underflow in 'total_mem' variable due to its different values in different threads * Bumped warnings up to the max and fixed remaining issues (#890) Co-authored-by: Your Name * nits * frida mode - support non-pie * nits * nit * update grammar mutator * Fixes for aarch64, OSX and other minor issues (#891) Co-authored-by: Your Name * nits * nits * fix PCGUARD, build aflpp_driver with fPIC * Added representative fuzzbench test and test for libxml (#893) * Added representative fuzzbench test and test for libxml * Added support for building FRIDA from source with FRIDA_SOURCE=1 Co-authored-by: Your Name * nits * update changelog * typos * fixed potential double free in custom trim (#881) * error handling, freeing mem * frida: complog -> cmplog * fix statsd writing * let aflpp_qemu_driver_hook.so build fail gracefully * fix stdin trimming * Support for AFL_ENTRYPOINT (#898) Co-authored-by: Your Name * remove the input file .cur_input at the end of the fuzzing, if AFL_TMPDIR is used * reverse push (#901) * Create FUNDING.yml * Update FUNDING.yml * disable QEMU static pie Co-authored-by: Andrea Fioraldi * clarify that no modifications are required. * add new test for frida_mode (please review) * typos * fix persistent mode (64-bit) * set ARCH for linux intel 32-bit for frida-gum-devkit * prepare for 32-bit support (later) * not on qemu 3 anymore * unicorn mips fixes * instrumentation further move to C++11 (#900) * unicorn fixes * more unicorn fixes * Fix memory errors when trim causes testcase growth (#881) (#903) * Revert "fixed potential double free in custom trim (#881)" This reverts commit e9d2f72382cab75832721d859c3e731da071435d. * Revert "fix custom trim for increasing data" This reverts commit 86a8ef168dda766d2f25f15c15c4d3ecf21d0667. * Fix memory errors when trim causes testcase growth Modify trim_case_custom to avoid writing into in_buf because some custom mutators can cause the testcase to grow rather than shrink. Instead of modifying in_buf directly, we write the update out to the disk when trimming is complete, and then the caller is responsible for refreshing the in-memory buffer from the file. This is still a bit sketchy because it does need to modify q->len in order to notify the upper layers that something changed, and it could end up telling upper layer code that the q->len is *bigger* than the buffer (q->testcase_buf) that contains it, which is asking for trouble down the line somewhere... * Fix an unlikely situation Put back some `unlikely()` calls that were in the e9d2f72382cab75832721d859c3e731da071435d commit that was reverted. * typo * Exit on time (#904) * Variable AFL_EXIT_ON_TIME description has been added. Variables AFL_EXIT_ON_TIME and afl_exit_on_time has been added. afl->exit_on_time variable initialization has been added. The asignment of a value to the afl->afl_env.afl_exit_on_time variable from environment variables has been added. Code to exit on timeout if new path not found has been added. * Type of afl_exit_on_time variable has been changed. Variable exit_on_time has been added to the afl_state_t structure. * Command `export AFL_EXIT_WHEN_DONE=1` has been added. * Millisecond to second conversion has been added. Call get_cur_time() has been added. * Revert to using the saved current time value. * Useless check has been removed. * fix new path to custom-mutators * ensure crashes/README.txt exists * fix * Changes to bump FRIDA version and to clone FRIDA repo in to build directory rather than use a submodule as the FRIDA build scripts don't like it (#906) Co-authored-by: Your Name * Fix numeric overflow in cmplog implementation (#907) Co-authored-by: Your Name * testcase fixes for unicorn * remove merge conflict artifacts * fix afl-plot * Changes to remove binaries from frida_mode (#913) Co-authored-by: Your Name * Frida cmplog fail fast (#914) * Changes to remove binaries from frida_mode * Changes to make cmplog fail fast Co-authored-by: Your Name * afl-plot: relative time * arch linux and mac os support for afl-system-config * typo * code-format * update documentation * github workflow for qemu * OSX-specific improvements (#912) * Fix afl-cc to work correctly by default on OSX using xcode - CLANG_ENV_VAR must be set for afl-as to work - Use clang mode by default if no specific compiler selected * Add OSX-specific documentation for configuring shared memory * Fixes to memory operands for complog (#916) Co-authored-by: Your Name * fix a few cur_time uses * added bounds check to pivot_inputs (fixes #921) * additional safety checks for restarts * restrict afl-showmap in_file size * fix seed crash disable * add warning for afl-showmap partial read * no core dumps * AFL_PRINT_FILENAMES added * more documentation for AFL_EXIT_ON_TIME * Flushing for AFL_PRINT_FILENAMES * FASAN Support (#918) * FASAN Support * Fix handling of Address Sanitizer DSO * Changes to identification of Address Sanitizer DSO Co-authored-by: Your Name * Support for x86 (#920) Co-authored-by: Your Name * Update frida_mode readme (#925) * libqasan: use syscalls for read and write * update readme * Minor integration tweaks (#926) Co-authored-by: Your Name * merge * fix afl-fuzz.c frida preload * cleaned up AFL_PRINT_FILENAMES env * Changes to have persistent mode exit at the end of the loop (#928) Co-authored-by: Your Name * fix llvm-dict2file Co-authored-by: Dominik Maier Co-authored-by: WorksButNotTested <62701594+WorksButNotTested@users.noreply.github.com> Co-authored-by: Your Name Co-authored-by: Dmitry Zheregelya Co-authored-by: hexcoder Co-authored-by: hexcoder- Co-authored-by: Andrea Fioraldi Co-authored-by: David CARLIER Co-authored-by: realmadsci <71108352+realmadsci@users.noreply.github.com> Co-authored-by: Roman M. Iudichev Co-authored-by: Dustin Spicuzza Co-authored-by: Dominik Maier Co-authored-by: WorksButNotTested <62701594+WorksButNotTested@users.noreply.github.com> Co-authored-by: Your Name Co-authored-by: Dmitry Zheregelya Co-authored-by: hexcoder Co-authored-by: hexcoder- Co-authored-by: Andrea Fioraldi Co-authored-by: David CARLIER Co-authored-by: realmadsci <71108352+realmadsci@users.noreply.github.com> Co-authored-by: Roman M. Iudichev Co-authored-by: Dustin Spicuzza * improve error msg * Added documentation for wine LoadLibrary workaround (#933) * Fix cmake target compilation command example (#934) - Fix typo DCMAKE_C_COMPILERC -> DCMAKE_C_COMPILER. - Add `cd build` after `mkdir build`. * showmap passes queue items in alphabetical order * added tmp files to gitignore * lenient dict parsing, no map size enum for binary fuzzing * added info about showmap queue directions * update binary-only doc * turn off map size detection if skip_bin_check is set * Typo * update docs * update afl-system-config * Set kill signal before using it in afl-showmap (#935) * fix afl-cc help output * add libafl to binary-only doc * update docs * less executions on variable paths * AFL_SKIP_CRASHES is obsolete since 3.0 * add AFL_TRY_AFFINITY * Typo * Typo * Typo/wording * tweaks * typos * fix afl-whatsup help output * fix afl-plot output * fix for MacOS * fix cmpcov doc for qemu * fix tmpfile removal * update dockerfile * Frida (#940) * Added re2 test * Added libpcap test * Fix validation of setting of ADDR_NO_RANDOMIZE * Added support for printing original and instrumented code Co-authored-by: Your Name * Support for AFL_FRIDA_PERSISTENT_RET (#941) Co-authored-by: Your Name * Changes to add missing exclusion of ranges (#943) Co-authored-by: Your Name * add --afl-noopt to afl-cc * docs: fix link to README in QuickStartGuide (#946) * Support writing Stalker stats (#945) * Support writing Stalker stats * Fixed string handling in print functions Co-authored-by: Your Name * afl-cmin help fix, aflpp_driver - + @@ support * fix for afl-showmap Co-authored-by: Dominik Maier Co-authored-by: WorksButNotTested <62701594+WorksButNotTested@users.noreply.github.com> Co-authored-by: Your Name Co-authored-by: Dmitry Zheregelya Co-authored-by: hexcoder Co-authored-by: hexcoder- Co-authored-by: Andrea Fioraldi Co-authored-by: David CARLIER Co-authored-by: realmadsci <71108352+realmadsci@users.noreply.github.com> Co-authored-by: Roman M. Iudichev Co-authored-by: Dustin Spicuzza Co-authored-by: 0x4d5a-ctf <51098072+0x4d5a-ctf@users.noreply.github.com> Co-authored-by: Tommy Chiang Co-authored-by: buherator Co-authored-by: Dag Heyman Kajevic --- Dockerfile | 7 +- README.md | 12 +- afl-cmin | 8 +- afl-plot | 2 +- afl-whatsup | 13 +- docs/Changelog.md | 12 +- docs/QuickStartGuide.md | 2 +- docs/binaryonly_fuzzing.md | 2 +- docs/custom_mutators.md | 3 + docs/env_variables.md | 8 +- frida_mode/GNUmakefile | 3 - frida_mode/README.md | 148 +- frida_mode/include/instrument.h | 4 + frida_mode/include/output.h | 9 + frida_mode/include/persistent.h | 4 + frida_mode/include/ranges.h | 2 + frida_mode/include/stats.h | 28 + frida_mode/include/util.h | 2 +- frida_mode/src/instrument/instrument.c | 53 +- frida_mode/src/instrument/instrument_debug.c | 129 + frida_mode/src/main.c | 7 +- frida_mode/src/output.c | 45 + frida_mode/src/persistent/persistent.c | 34 +- frida_mode/src/persistent/persistent_arm32.c | 7 + frida_mode/src/persistent/persistent_arm64.c | 7 + frida_mode/src/persistent/persistent_x64.c | 19 +- frida_mode/src/persistent/persistent_x86.c | 15 + frida_mode/src/ranges.c | 69 +- frida_mode/src/stats/stats.c | 208 ++ frida_mode/src/stats/stats_arm.c | 36 + frida_mode/src/stats/stats_arm64.c | 36 + frida_mode/src/stats/stats_x64.c | 307 +++ frida_mode/src/stats/stats_x86.c | 36 + frida_mode/src/util.c | 13 +- frida_mode/test/deferred/GNUmakefile | 71 + frida_mode/test/deferred/Makefile | 13 + frida_mode/test/deferred/testinstr.c | 125 + frida_mode/test/libpcap/GNUmakefile | 188 ++ frida_mode/test/libpcap/Makefile | 1143 +++++++++ frida_mode/test/libpcap/aflpp_qemu_driver_hook.c | 97 + frida_mode/test/libpcap/get_symbol_addr.py | 36 + frida_mode/test/output/GNUmakefile | 47 + frida_mode/test/output/Makefile | 13 + frida_mode/test/output/frida_stderr.txt | 2824 +++++++++++++++++++++ frida_mode/test/output/frida_stdout.txt | 349 +++ frida_mode/test/output/testinstr.c | 112 + frida_mode/test/persistent_ret/GNUmakefile | 105 + frida_mode/test/persistent_ret/Makefile | 22 + frida_mode/test/persistent_ret/get_symbol_addr.py | 36 + frida_mode/test/persistent_ret/testinstr.c | 120 + frida_mode/test/re2/GNUmakefile | 170 ++ frida_mode/test/re2/Makefile | 22 + frida_mode/test/re2/aflpp_qemu_driver_hook.c | 97 + frida_mode/test/re2/get_symbol_addr.py | 36 + include/afl-fuzz.h | 4 +- include/config.h | 4 +- include/envs.h | 11 +- qemu_mode/README.md | 21 +- src/afl-cc.c | 14 + src/afl-fuzz-init.c | 64 +- src/afl-fuzz-python.c | 2 +- src/afl-fuzz-run.c | 2 +- src/afl-fuzz-state.c | 10 +- src/afl-fuzz.c | 28 +- src/afl-showmap.c | 3 + utils/aflpp_driver/README.md | 6 + utils/aflpp_driver/aflpp_driver.c | 44 +- 67 files changed, 6961 insertions(+), 168 deletions(-) create mode 100644 frida_mode/include/output.h create mode 100644 frida_mode/include/stats.h create mode 100644 frida_mode/src/instrument/instrument_debug.c create mode 100644 frida_mode/src/output.c create mode 100644 frida_mode/src/stats/stats.c create mode 100644 frida_mode/src/stats/stats_arm.c create mode 100644 frida_mode/src/stats/stats_arm64.c create mode 100644 frida_mode/src/stats/stats_x64.c create mode 100644 frida_mode/src/stats/stats_x86.c create mode 100644 frida_mode/test/deferred/GNUmakefile create mode 100644 frida_mode/test/deferred/Makefile create mode 100644 frida_mode/test/deferred/testinstr.c create mode 100644 frida_mode/test/libpcap/GNUmakefile create mode 100644 frida_mode/test/libpcap/Makefile create mode 100644 frida_mode/test/libpcap/aflpp_qemu_driver_hook.c create mode 100755 frida_mode/test/libpcap/get_symbol_addr.py create mode 100644 frida_mode/test/output/GNUmakefile create mode 100644 frida_mode/test/output/Makefile create mode 100644 frida_mode/test/output/frida_stderr.txt create mode 100644 frida_mode/test/output/frida_stdout.txt create mode 100644 frida_mode/test/output/testinstr.c create mode 100644 frida_mode/test/persistent_ret/GNUmakefile create mode 100644 frida_mode/test/persistent_ret/Makefile create mode 100755 frida_mode/test/persistent_ret/get_symbol_addr.py create mode 100644 frida_mode/test/persistent_ret/testinstr.c create mode 100644 frida_mode/test/re2/GNUmakefile create mode 100644 frida_mode/test/re2/Makefile create mode 100644 frida_mode/test/re2/aflpp_qemu_driver_hook.c create mode 100755 frida_mode/test/re2/get_symbol_addr.py (limited to 'docs/binaryonly_fuzzing.md') diff --git a/Dockerfile b/Dockerfile index 8f89b9aa..18fb6367 100644 --- a/Dockerfile +++ b/Dockerfile @@ -50,6 +50,7 @@ RUN update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-10 0 ENV LLVM_CONFIG=llvm-config-12 ENV AFL_SKIP_CPUFREQ=1 +ENV AFL_TRY_AFFINITY=1 ENV AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES=1 RUN git clone --depth=1 https://github.com/vanhauser-thc/afl-cov /afl-cov @@ -61,8 +62,10 @@ WORKDIR /AFLplusplus RUN export CC=gcc-10 && export CXX=g++-10 && make clean && \ make distrib && make install && make clean -RUN echo 'alias joe="jupp --wordwrap"' >> ~/.bashrc -RUN echo 'export PS1="[afl++]$PS1"' >> ~/.bashrc +RUN sh -c 'echo set encoding=utf-8 > /root/.vimrc' +RUN echo '. /etc/bash_completion' >> ~/.bashrc +RUN echo 'alias joe="joe --wordwrap --joe_state -nobackup"' >> ~/.bashrc +RUN echo "export PS1='"'[afl++ \h] \w$(__git_ps1) \$ '"'" >> ~/.bashrc ENV IS_DOCKER="1" # Disabled until we have the container ready diff --git a/README.md b/README.md index 501f0591..69e2d14a 100644 --- a/README.md +++ b/README.md @@ -679,8 +679,8 @@ If you see that an important area or a feature has not been covered so far then try to find an input that is able to reach that and start a new secondary in that fuzzing campaign with that seed as input, let it run for a few minutes, then terminate it. The main node will pick it up and make it available to the -other secondary nodes over time. Set `export AFL_NO_AFFINITY=1` if you have no -free core. +other secondary nodes over time. Set `export AFL_NO_AFFINITY=1` or +`export AFL_TRY_AFFINITY=1` if you have no free core. Note that you in nearly all cases can never reach full coverage. A lot of functionality is usually behind options that were not activated or fuzz e.g. @@ -800,10 +800,10 @@ Alternatively you can use frida_mode, just switch `-Q` with `-O` and remove the LAF instance. Then run as many instances as you have cores left with either -Q mode or - better - -use a binary rewriter like afl-dyninst, retrowrite, zaflr, fibre, etc. +use a binary rewriter like afl-dyninst, retrowrite, zaflr, etc. -For Qemu and Frida mode, check out the persistent mode and snapshot features, -they give a huge speed improvement! +For Qemu and Frida mode, check out the persistent mode, it gives a huge speed +improvement if it is possible to use. ### QEMU @@ -822,7 +822,7 @@ less conducive to parallelization. If [afl-dyninst](https://github.com/vanhauser-thc/afl-dyninst) works for your binary, then you can use afl-fuzz normally and it will have twice -the speed compared to qemu_mode (but slower than persistent mode). +the speed compared to qemu_mode (but slower than qemu persistent mode). Note that several other binary rewriters exist, all with their advantages and caveats. diff --git a/afl-cmin b/afl-cmin index adcbb221..9fa63ec6 100755 --- a/afl-cmin +++ b/afl-cmin @@ -119,13 +119,13 @@ function usage() { "Environment variables used:\n" \ "AFL_ALLOW_TMP: allow unsafe use of input/output directories under {/var}/tmp\n" \ "AFL_CRASH_EXITCODE: optional child exit code to be interpreted as crash\n" \ -"AFL_FORKSRV_INIT_TMOUT: time the fuzzer waits for the target to come up, initially\n" \ +"AFL_FORKSRV_INIT_TMOUT: time the fuzzer waits for the forkserver to come up\n" \ "AFL_KEEP_TRACES: leave the temporary /.traces directory\n" \ -"AFL_KILL_SIGNAL: Signal ID delivered to child processes on timeout, etc. (default: SIGKILL)\n" -"AFL_PATH: path for the afl-showmap binary if not found anywhere else\n" \ +"AFL_KILL_SIGNAL: Signal delivered to child processes on timeout (default: SIGKILL)\n" \ +"AFL_PATH: path for the afl-showmap binary if not found anywhere in PATH\n" \ "AFL_PRINT_FILENAMES: If set, the filename currently processed will be " \ "printed to stdout\n" \ -"AFL_SKIP_BIN_CHECK: skip check for target binary\n" +"AFL_SKIP_BIN_CHECK: skip afl instrumentation checks for target binary\n" exit 1 } diff --git a/afl-plot b/afl-plot index 26c8d1b7..60a351ab 100755 --- a/afl-plot +++ b/afl-plot @@ -127,7 +127,7 @@ set key outside set autoscale xfixmin set autoscale xfixmax -set xlabel "all times in UTC" font "small" +#set xlabel "all times in UTC" font "small" plot '$inputdir/plot_data' using 1:4 with filledcurve x1 title 'total paths' linecolor rgb '#000000' fillstyle transparent solid 0.2 noborder, \\ '' using 1:3 with filledcurve x1 title 'current path' linecolor rgb '#f0f0f0' fillstyle transparent solid 0.5 noborder, \\ diff --git a/afl-whatsup b/afl-whatsup index be259829..9c2564c6 100755 --- a/afl-whatsup +++ b/afl-whatsup @@ -21,11 +21,11 @@ echo "$0 status check tool for afl-fuzz by Michal Zalewski" echo test "$1" = "-h" -o "$1" = "-hh" && { - echo "$0 [-s] [-d] output_directory" + echo "Usage: $0 [-s] [-d] afl_output_directory" echo echo Options: - echo -s - skip details and output summary results only - echo -d - include dead fuzzer stats + echo " -s - skip details and output summary results only" + echo " -d - include dead fuzzer stats" echo exit 1 } @@ -51,10 +51,11 @@ DIR="$1" if [ "$DIR" = "" ]; then - echo "Usage: $0 [-s] [-d] afl_sync_dir" 1>&2 + echo "Usage: $0 [-s] [-d] afl_output_directory" 1>&2 echo 1>&2 - echo "The -s option causes the tool to skip all the per-fuzzer trivia and show" 1>&2 - echo "just the summary results. See docs/parallel_fuzzing.md for additional tips." 1>&2 + echo Options: 1>&2 + echo " -s - skip details and output summary results only" 1>&2 + echo " -d - include dead fuzzer stats" 1>&2 echo 1>&2 exit 1 diff --git a/docs/Changelog.md b/docs/Changelog.md index dfd5c393..298a3998 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -33,8 +33,12 @@ sending a mail to . - added AFL_EXIT_ON_SEED_ISSUES env that will exit if a seed in -i dir crashes the target or results in a timeout. By default afl++ ignores these and uses them for splicing instead. - - added AFL_EXIT_ON_TIME env that will make afl-fuzz exit fuzzing after - no new paths have been found for n seconds + - added AFL_EXIT_ON_TIME env that will make afl-fuzz exit fuzzing + after no new paths have been found for n seconds + - when AFL_FAST_CAL is set a variable path will now be calibrated + 8 times instead of originally 40. Long calibration is now 20. + - added AFL_TRY_AFFINITY to try to bind to CPUs but don't error if + it fails - afl-cc: - We do not support llvm versions prior 6.0 anymore - Fix for -pie compiled binaries with default afl-clang-fast PCGUARD @@ -42,6 +46,7 @@ sending a mail to . - Removed InsTrim instrumentation as it is not as good as PCGUARD - Removed automatic linking with -lc++ for LTO mode - Fixed a crash in llvm dict2file when a strncmp length was -1 + - added --afl-noopt support - utils/aflpp_driver: - aflpp_qemu_driver_hook fixed to work with qemu_mode - aflpp_driver now compiled with -fPIC @@ -53,7 +58,8 @@ sending a mail to . MacOS shared memory - updated the grammar custom mutator to the newest version - add -d (add dead fuzzer stats) to afl-whatsup - - added AFL_PRINT_FILENAMES to afl-showmap/cmin to print the current filename + - added AFL_PRINT_FILENAMES to afl-showmap/cmin to print the + current filename - afl-showmap/cmin will now process queue items in alphabetical order ### Version ++3.12c (release) diff --git a/docs/QuickStartGuide.md b/docs/QuickStartGuide.md index 10be409a..d1966170 100644 --- a/docs/QuickStartGuide.md +++ b/docs/QuickStartGuide.md @@ -1,6 +1,6 @@ # AFL quick start guide -You should read [README.md](README.md) - it's pretty short. If you really can't, here's +You should read [README.md](../README.md) - it's pretty short. If you really can't, here's how to hit the ground running: 1) Compile AFL with 'make'. If build fails, see [INSTALL.md](INSTALL.md) for tips. diff --git a/docs/binaryonly_fuzzing.md b/docs/binaryonly_fuzzing.md index bab64a30..11e1dbeb 100644 --- a/docs/binaryonly_fuzzing.md +++ b/docs/binaryonly_fuzzing.md @@ -43,7 +43,7 @@ If you like to code a customized fuzzer without much work, we highly recommend to check out our sister project libafl which will support QEMU - very too: + too: [https://github.com/AFLplusplus/LibAFL](https://github.com/AFLplusplus/LibAFL) diff --git a/docs/custom_mutators.md b/docs/custom_mutators.md index 9d5381e8..3e3ae01d 100644 --- a/docs/custom_mutators.md +++ b/docs/custom_mutators.md @@ -92,6 +92,9 @@ def queue_new_entry(filename_new_queue, filename_orig_queue): def introspection(): return string + +def deinit(): # optional for Python + pass ``` ### Custom Mutation diff --git a/docs/env_variables.md b/docs/env_variables.md index def1e297..7bbc0fdd 100644 --- a/docs/env_variables.md +++ b/docs/env_variables.md @@ -312,14 +312,12 @@ checks or alter some of the more exotic semantics of the tool: on Linux systems. This slows things down, but lets you run more instances of afl-fuzz than would be prudent (if you really want to). + - Setting `AFL_TRY_AFFINITY` tries to attempt binding to a specific CPU core + on Linux systems, but will not terminate if that fails. + - Setting `AFL_NO_AUTODICT` will not load an LTO generated auto dictionary that is compiled into the target. - - `AFL_SKIP_CRASHES` causes AFL++ to tolerate crashing files in the input - queue. This can help with rare situations where a program crashes only - intermittently, but it's not really recommended under normal operating - conditions. - - Setting `AFL_HANG_TMOUT` allows you to specify a different timeout for deciding if a particular test case is a "hang". The default is 1 second or the value of the `-t` parameter, whichever is larger. Dialing the value diff --git a/frida_mode/GNUmakefile b/frida_mode/GNUmakefile index 20fbb544..a0387cac 100644 --- a/frida_mode/GNUmakefile +++ b/frida_mode/GNUmakefile @@ -94,9 +94,6 @@ AFL_COMPILER_RT_OBJ:=$(OBJ_DIR)afl-compiler-rt.o all: $(FRIDA_TRACE) -32: - CFLAGS="-m32" LDFLAGS="-m32" ARCH="x86" make all - 32: CFLAGS="-m32" LDFLAGS="-m32" ARCH="x86" make all diff --git a/frida_mode/README.md b/frida_mode/README.md index ecce0bfd..0103a395 100644 --- a/frida_mode/README.md +++ b/frida_mode/README.md @@ -21,7 +21,7 @@ perhaps leverage some of its design and implementation. | Feature/Instrumentation | frida-mode | Notes | | -------------------------|:----------:|:--------------------------------------------:| | NeverZero | x | | - | Persistent Mode | x | (x86/x64 only)(Only on function boundaries) | + | Persistent Mode | x | (x86/x64 only)(Only on function boundaries) | | LAF-Intel / CompCov | - | (CMPLOG is better 90% of the time) | | CMPLOG | x | (x86/x64 only) | | Selective Instrumentation| x | | @@ -43,16 +43,16 @@ system does not support cross compilation. ## Getting Started -To build everything run `make`. To build for x86 run `make 32`. Note that in +To build everything run `make`. To build for x86 run `make 32`. Note that in x86 bit mode, it is not necessary for afl-fuzz to be built for 32-bit. However, the shared library for frida_mode must be since it is injected into the target process. Various tests can be found in subfolders within the `test/` directory. To use these, first run `make` to build any dependencies. Then run `make qemu` or -`make frida` to run on either QEMU of FRIDA mode respectively. To run frida -tests in 32-bit mode, run `make ARCH=x86 frida`. When switching between -architectures it may be necessary to run `make clean` first for a given build +`make frida` to run on either QEMU of FRIDA mode respectively. To run frida +tests in 32-bit mode, run `make ARCH=x86 frida`. When switching between +architectures it may be necessary to run `make clean` first for a given build target to remove previously generated binaries for a different architecture. ## Usage @@ -74,6 +74,8 @@ following options are currently supported: * `AFL_FRIDA_PERSISTENT_ADDR` - See `AFL_QEMU_PERSISTENT_ADDR` * `AFL_FRIDA_PERSISTENT_CNT` - See `AFL_QEMU_PERSISTENT_CNT` * `AFL_FRIDA_PERSISTENT_HOOK` - See `AFL_QEMU_PERSISTENT_HOOK` +* `AFL_FRIDA_PERSISTENT_RET` - See `AFL_QEMU_PERSISTENT_RET` +* `AFL_FRIDA_PERSISTENT_RETADDR_OFFSET` - See `AFL_QEMU_PERSISTENT_RETADDR_OFFSET` To enable the powerful CMPLOG mechanism, set `-c 0` for `afl-fuzz`. @@ -127,34 +129,144 @@ instances run CMPLOG mode and instrumentation of the binary is less frequent ## Advanced configuration options +* `AFL_FRIDA_INST_DEBUG_FILE` - File to write raw assembly of original blocks +and their instrumented counterparts during block compilation. +``` +*** + +Creating block for 0x7ffff7953313: + 0x7ffff7953313 mov qword ptr [rax], 0 + 0x7ffff795331a add rsp, 8 + 0x7ffff795331e ret + +Generated block 0x7ffff75e98e2 + 0x7ffff75e98e2 mov qword ptr [rax], 0 + 0x7ffff75e98e9 add rsp, 8 + 0x7ffff75e98ed lea rsp, [rsp - 0x80] + 0x7ffff75e98f5 push rcx + 0x7ffff75e98f6 movabs rcx, 0x7ffff795331e + 0x7ffff75e9900 jmp 0x7ffff75e9384 + + +*** +``` * `AFL_FRIDA_INST_NO_OPTIMIZE` - Don't use optimized inline assembly coverage instrumentation (the default where available). Required to use `AFL_FRIDA_INST_TRACE`. * `AFL_FRIDA_INST_NO_PREFETCH` - Disable prefetching. By default the child will report instrumented blocks back to the parent so that it can also instrument them and they be inherited by the next child on fork. -* `AFL_FRIDA_INST_TRACE` - Generate some logging when running instrumented code. -Requires `AFL_FRIDA_INST_NO_OPTIMIZE`. - +* `AFL_FRIDA_INST_TRACE` - Log to stdout the address of executed blocks +`AFL_FRIDA_INST_NO_OPTIMIZE`. +* `AFL_FRIDA_OUTPUT_STDOUT` - Redirect the standard output of the target +application to the named file (supersedes the setting of `AFL_DEBUG_CHILD`) +* `AFL_FRIDA_OUTPUT_STDERR` - Redirect the standard error of the target +application to the named file (supersedes the setting of `AFL_DEBUG_CHILD`) +* `AFL_FRIDA_PERSISTENT_DEBUG` - Insert a Breakpoint into the instrumented code +at `AFL_FRIDA_PERSISTENT_HOOK` and `AFL_FRIDA_PERSISTENT_RET` to allow the user +to determine the value of `AFL_FRIDA_PERSISTENT_RETADDR_OFFSET` using a +debugger. + +``` + +gdb \ + --ex 'set environment AFL_FRIDA_PERSISTENT_ADDR=XXXXXXXXXX' \ + --ex 'set environment AFL_FRIDA_PERSISTENT_RET=XXXXXXXXXX' \ + --ex 'set environment AFL_FRIDA_PERSISTENT_DEBUG=1' \ + --ex 'set environment AFL_DEBUG_CHILD=1' \ + --ex 'set environment LD_PRELOAD=afl-frida-trace.so' \ + --args [my arguments] + +``` +* `AFL_FRIDA_STATS_FILE` - Write statistics information about the code being +instrumented to the given file name. The statistics are written only for the +child process when new block is instrumented (when the +`AFL_FRIDA_STATS_INTERVAL` has expired). Note that simply because a new path is +found does not mean a new block needs to be compiled. It could simply be that +the existing blocks instrumented have been executed in a different order. +``` +stats +----- +Index: 2 +Pid: 1815944 +Time: 2021-05-28 15:26:41 +Blocks: 1985 +Instructions: 9192 +Avg Instructions / Block: 4 + +Call Immediates: 391 (4.25%) +Call Immediates Excluded: 65 (0.71%) +Call Register: 0 (0.00%) +Call Memory: 0 (0.00%) + +Jump Immediates: 202 (2.20%) +Jump Register: 10 (0.11%) +Jump Memory: 12 (0.13%) + +Conditional Jump Immediates: 1210 (13.16%) +Conditional Jump CX Immediate: 0 (0.00%) +Conditional Jump Register: 0 (0.00%) +Conditional Jump Memory: 0 (0.00%) + +Returns: 159 (0.00%) + +Rip Relative: 247 (0.00%) + +``` +* `AFL_FRIDA_STATS_INTERVAL` - The maximum frequency to output statistics +information. Stats will be written whenever they are updated if the given +interval has elapsed since last time they were written. +* `AFL_FRIDA_STATS_TRANSITIONS` - Also dump the internal stalker counters to +stderr when the regular stats are written. Note that these stats are reset in +the child each time a new fork occurs since they are not stored in shared +memory. Unfortunately, these stats are internal to stalker, so this is the best +we can do for now. +``` +stats +----- +Index: 2 +Pid: 1816794 +Time: 2021-05-28 15:26:41 + + +total_transitions: 786 + call_imms: 97 + call_regs: 0 + call_mems: 0 + post_call_invokes: 86 + excluded_call_imms: 29 + ret_slow_paths: 23 + + jmp_imms: 58 + jmp_mems: 7 + jmp_regs: 26 + + jmp_cond_imms: 460 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 +``` ## FASAN - Frida Address Sanitizer Mode Frida mode also supports FASAN. The design of this is actually quite simple and very similar to that used when instrumenting applications compiled from source. ### Address Sanitizer Basics -When Address Sanitizer is used to instrument programs built from source, the +When Address Sanitizer is used to instrument programs built from source, the compiler first adds a dependency (`DT_NEEDED` entry) for the Address Sanitizer dynamic shared object (DSO). This shared object contains the main logic for Address Sanitizer, including setting and managing up the shadow memory. It also provides -replacement implementations for a number of functions in standard libraries. +replacement implementations for a number of functions in standard libraries. These replacements include things like `malloc` and `free` which allows for those allocations to be marked in the shadow memory, but also a number of other fuctions. -Consider `memcpy` for example, this is instrumented to validate the paramters -(test the source and destination buffers against the shadow memory. This is much -easier than instrumenting those standard libraries since, first it would require +Consider `memcpy` for example, this is instrumented to validate the paramters +(test the source and destination buffers against the shadow memory. This is much +easier than instrumenting those standard libraries since, first it would require you to re-compile them and secondly it would mean that the instrumentation would -be applied at a more expensive granular level. Lastly, load-widening (typically +be applied at a more expensive granular level. Lastly, load-widening (typically found in highy optimized code) can also make this instrumentation more difficult. Since the DSO is loaded before all of the standard libraries (in fact it insists @@ -165,9 +277,9 @@ modules which depend on it. FASAN takes a similar approach. It requires the user to add the Address Sanitizer DSO to the `AFL_PRELOAD` environment variable such that it is loaded into the target. -Again, it must be first in the list. This means that it is not necessary to -instrument the standard libraries to detect when an application has provided an -incorrect argument to `memcpy` for example. This avoids issues with load-widening +Again, it must be first in the list. This means that it is not necessary to +instrument the standard libraries to detect when an application has provided an +incorrect argument to `memcpy` for example. This avoids issues with load-widening and should also mean a huge improvement in performance. FASAN then adds instrumentation for any instrucutions which use memory operands and @@ -176,7 +288,7 @@ to validate memory accesses against the shadow memory. ## TODO -The next features to be added are Aarch64 and Aarch32 support as well as looking at +The next features to be added are Aarch64 and Aarch32 support as well as looking at potential performance improvements. The intention is to achieve feature parity with QEMU mode in due course. Contributions are welcome, but please get in touch to ensure that efforts are deconflicted. diff --git a/frida_mode/include/instrument.h b/frida_mode/include/instrument.h index 03fd33e5..ed92c25a 100644 --- a/frida_mode/include/instrument.h +++ b/frida_mode/include/instrument.h @@ -19,5 +19,9 @@ gboolean instrument_is_coverage_optimize_supported(void); void instrument_coverage_optimize(const cs_insn * instr, GumStalkerOutput *output); +void instrument_debug_init(void); +void instrument_debug_start(uint64_t address, GumStalkerOutput *output); +void instrument_debug_instruction(uint64_t address, uint16_t size); +void instrument_debug_end(GumStalkerOutput *output); #endif diff --git a/frida_mode/include/output.h b/frida_mode/include/output.h new file mode 100644 index 00000000..53a9fdd3 --- /dev/null +++ b/frida_mode/include/output.h @@ -0,0 +1,9 @@ +#ifndef _OUTPUT_H +#define _OUTPUT_H + +#include "frida-gum.h" + +void output_init(void); + +#endif + diff --git a/frida_mode/include/persistent.h b/frida_mode/include/persistent.h index e58c5301..25b44ab0 100644 --- a/frida_mode/include/persistent.h +++ b/frida_mode/include/persistent.h @@ -18,6 +18,9 @@ extern unsigned char *__afl_fuzz_ptr; extern guint64 persistent_start; extern guint64 persistent_count; +extern guint64 persistent_ret; +extern guint64 persistent_ret_offset; +extern gboolean persistent_debug; extern afl_persistent_hook_fn hook; void persistent_init(void); @@ -26,6 +29,7 @@ void persistent_init(void); gboolean persistent_is_supported(void); void persistent_prologue(GumStalkerOutput *output); +void persistent_epilogue(GumStalkerOutput *output); #endif diff --git a/frida_mode/include/ranges.h b/frida_mode/include/ranges.h index f652eb8a..c623f473 100644 --- a/frida_mode/include/ranges.h +++ b/frida_mode/include/ranges.h @@ -7,5 +7,7 @@ void ranges_init(void); gboolean range_is_excluded(gpointer address); +void ranges_exclude(); + #endif diff --git a/frida_mode/include/stats.h b/frida_mode/include/stats.h new file mode 100644 index 00000000..4271132a --- /dev/null +++ b/frida_mode/include/stats.h @@ -0,0 +1,28 @@ +#ifndef _STATS_H +#define _STATS_H + +#include "frida-gum.h" + +typedef struct { + + guint64 num_blocks; + guint64 num_instructions; + guint64 stats_last_time; + guint64 stats_idx; + guint64 transitions_idx; + +} stats_data_header_t; + +extern stats_data_header_t *stats_data; + +void stats_init(void); +void stats_collect(const cs_insn *instr, gboolean begin); +void stats_print(char *format, ...); + +gboolean stats_is_supported_arch(void); +size_t stats_data_size_arch(void); +void stats_collect_arch(const cs_insn *instr); +void stats_write_arch(void); + +#endif + diff --git a/frida_mode/include/util.h b/frida_mode/include/util.h index afd0b9c1..7b443b5e 100644 --- a/frida_mode/include/util.h +++ b/frida_mode/include/util.h @@ -4,7 +4,7 @@ #include "frida-gum.h" #define UNUSED_PARAMETER(x) (void)(x) -#define IGNORED_RERURN(x) (void)!(x) +#define IGNORED_RETURN(x) (void)!(x) guint64 util_read_address(char *key); diff --git a/frida_mode/src/instrument/instrument.c b/frida_mode/src/instrument/instrument.c index 67eadc3f..cd1ac0be 100644 --- a/frida_mode/src/instrument/instrument.c +++ b/frida_mode/src/instrument/instrument.c @@ -13,6 +13,7 @@ #include "prefetch.h" #include "ranges.h" #include "stalker.h" +#include "stats.h" #include "util.h" static gboolean tracing = false; @@ -47,7 +48,7 @@ __attribute__((hot)) static void on_basic_block(GumCpuContext *context, "x, previous_pc: 0x%016" G_GINT64_MODIFIER "x\n", current_pc, previous_pc); - IGNORED_RERURN(write(STDOUT_FILENO, buffer, len + 1)); + IGNORED_RETURN(write(STDOUT_FILENO, buffer, len + 1)); } @@ -79,17 +80,52 @@ static void instr_basic_block(GumStalkerIterator *iterator, const cs_insn *instr; gboolean begin = TRUE; + gboolean excluded; + while (gum_stalker_iterator_next(iterator, &instr)) { if (instr->address == entry_start) { entry_prologue(iterator, output); } if (instr->address == persistent_start) { persistent_prologue(output); } - - if (begin) { + if (instr->address == persistent_ret) { persistent_epilogue(output); } + + /* + * Until we reach AFL_ENTRYPOINT (assumed to be main if not specified) or + * AFL_FRIDA_PERSISTENT_ADDR (if specified), we don't mark our ranges + * excluded as we wish to remain inside stalker at all times so that we can + * instrument our entry point and persistent loop (if present). This allows + * the user to exclude ranges which would be traversed between main and the + * AFL_ENTRYPOINT, but which they don't want included in their coverage + * information when fuzzing. + * + * Since we have no means to discard the instrumented copies of blocks + * (setting the trust threshold simply causes a new copy to be made on each + * execution), we instead ensure that we honour the additional + * instrumentation requested (e.g. coverage, asan and complog) when a block + * is compiled no matter where we are during initialization. We will end up + * re-using these blocks if the code under test calls a block which is also + * used during initialization. + * + * Coverage data generated during initialization isn't a problem since the + * map is zeroed each time the target is forked or each time the persistent + * loop is run. + * + * Lastly, we don't enable pre-fetching back to the parent until we reach + * our AFL_ENTRYPOINT, since it is not until then that we start the + * fork-server and thus start executing in the child. + */ + excluded = range_is_excluded(GSIZE_TO_POINTER(instr->address)); + + stats_collect(instr, begin); + + if (unlikely(begin)) { + + instrument_debug_start(instr->address, output); prefetch_write(GSIZE_TO_POINTER(instr->address)); - if (!range_is_excluded(GSIZE_TO_POINTER(instr->address))) { - if (optimize) { + if (likely(!excluded)) { + + if (likely(optimize)) { instrument_coverage_optimize(instr, output); @@ -106,7 +142,9 @@ static void instr_basic_block(GumStalkerIterator *iterator, } - if (!range_is_excluded(GSIZE_TO_POINTER(instr->address))) { + instrument_debug_instruction(instr->address, instr->size); + + if (likely(!excluded)) { asan_instrument(instr, iterator); cmplog_instrument(instr, iterator); @@ -117,6 +155,8 @@ static void instr_basic_block(GumStalkerIterator *iterator, } + instrument_debug_end(output); + } void instrument_init(void) { @@ -144,6 +184,7 @@ void instrument_init(void) { transformer = gum_stalker_transformer_make_from_callback(instr_basic_block, NULL, NULL); + instrument_debug_init(); asan_init(); cmplog_init(); diff --git a/frida_mode/src/instrument/instrument_debug.c b/frida_mode/src/instrument/instrument_debug.c new file mode 100644 index 00000000..be72ef89 --- /dev/null +++ b/frida_mode/src/instrument/instrument_debug.c @@ -0,0 +1,129 @@ +#include +#include +#include +#include + +#include "frida-gum.h" + +#include "debug.h" + +#include "util.h" + +static int debugging_fd = -1; +static gpointer instrument_gen_start = NULL; + +static void instrument_debug(char *format, ...) { + + va_list ap; + char buffer[4096] = {0}; + int ret; + int len; + + va_start(ap, format); + ret = vsnprintf(buffer, sizeof(buffer) - 1, format, ap); + va_end(ap); + + if (ret < 0) { return; } + + len = strnlen(buffer, sizeof(buffer)); + + IGNORED_RETURN(write(debugging_fd, buffer, len)); + +} + +static void instrument_disasm(guint8 *code, guint size) { + + csh capstone; + cs_err err; + cs_insn *insn; + size_t count, i; + + err = cs_open(GUM_DEFAULT_CS_ARCH, + GUM_DEFAULT_CS_MODE | GUM_DEFAULT_CS_ENDIAN, &capstone); + g_assert(err == CS_ERR_OK); + + count = cs_disasm(capstone, code, size, GPOINTER_TO_SIZE(code), 0, &insn); + g_assert(insn != NULL); + + for (i = 0; i != count; i++) { + + instrument_debug("\t0x%" G_GINT64_MODIFIER "x\t%s %s\n", insn[i].address, + insn[i].mnemonic, insn[i].op_str); + + } + + cs_free(insn, count); + + cs_close(&capstone); + +} + +static gpointer instrument_cur(GumStalkerOutput *output) { + +#if defined(__i386__) || defined(__x86_64__) + return gum_x86_writer_cur(output->writer.x86); +#elif defined(__aarch64__) + return gum_arm64_writer_cur(output->writer.arm64); +#elif defined(__arm__) + return gum_arm_writer_cur(output->writer.arm); +#else + #error "Unsupported architecture" +#endif + +} + +void instrument_debug_init(void) { + + char *filename = getenv("AFL_FRIDA_INST_DEBUG_FILE"); + OKF("Instrumentation debugging - enabled [%c]", filename == NULL ? ' ' : 'X'); + + if (filename == NULL) { return; } + + OKF("Instrumentation debugging - file [%s]", filename); + + if (filename == NULL) { return; } + + char *path = g_canonicalize_filename(filename, g_get_current_dir()); + + OKF("Instrumentation debugging - path [%s]", path); + + debugging_fd = open(path, O_RDWR | O_CREAT | O_TRUNC, + S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); + + if (debugging_fd < 0) { FATAL("Failed to open stats file '%s'", path); } + + g_free(path); + +} + +void instrument_debug_start(uint64_t address, GumStalkerOutput *output) { + + if (likely(debugging_fd < 0)) { return; } + + instrument_gen_start = instrument_cur(output); + + instrument_debug("\n\n***\n\nCreating block for 0x%" G_GINT64_MODIFIER "x:\n", + address); + +} + +void instrument_debug_instruction(uint64_t address, uint16_t size) { + + if (likely(debugging_fd < 0)) { return; } + uint8_t *start = (uint8_t *)GSIZE_TO_POINTER(address); + instrument_disasm(start, size); + +} + +void instrument_debug_end(GumStalkerOutput *output) { + + if (likely(debugging_fd < 0)) { return; } + gpointer instrument_gen_end = instrument_cur(output); + uint16_t size = GPOINTER_TO_SIZE(instrument_gen_end) - + GPOINTER_TO_SIZE(instrument_gen_start); + + instrument_debug("\nGenerated block %p\n", instrument_gen_start); + instrument_disasm(instrument_gen_start, size); + +} + diff --git a/frida_mode/src/main.c b/frida_mode/src/main.c index 21073cbe..1ab9993f 100644 --- a/frida_mode/src/main.c +++ b/frida_mode/src/main.c @@ -1,3 +1,4 @@ +#include #include #include @@ -18,10 +19,12 @@ #include "instrument.h" #include "interceptor.h" #include "lib.h" +#include "output.h" #include "persistent.h" #include "prefetch.h" #include "ranges.h" #include "stalker.h" +#include "stats.h" #include "util.h" #ifdef __APPLE__ @@ -58,10 +61,10 @@ static void on_main_os(int argc, char **argv, char **envp) { static void on_main_os(int argc, char **argv, char **envp) { UNUSED_PARAMETER(argc); - /* Personality doesn't affect the current process, it only takes effect on * evec */ int persona = personality(ADDR_NO_RANDOMIZE); + if (persona == -1) { WARNF("Failed to set ADDR_NO_RANDOMIZE: %d", errno); } if ((persona & ADDR_NO_RANDOMIZE) == 0) { execvpe(argv[0], argv, envp); } GumInterceptor *interceptor = gum_interceptor_obtain(); @@ -94,9 +97,11 @@ void afl_frida_start() { lib_init(); entry_init(); instrument_init(); + output_init(); persistent_init(); prefetch_init(); ranges_init(); + stats_init(); void *fork_addr = GSIZE_TO_POINTER(gum_module_find_export_by_name(NULL, "fork")); diff --git a/frida_mode/src/output.c b/frida_mode/src/output.c new file mode 100644 index 00000000..8a222b25 --- /dev/null +++ b/frida_mode/src/output.c @@ -0,0 +1,45 @@ +#include +#include +#include + +#include "frida-gum.h" + +#include "debug.h" + +#include "output.h" + +static int output_fd = -1; + +static void output_redirect(int fd, char *variable) { + + char *filename = getenv(variable); + char *path = NULL; + + if (filename == NULL) { return; } + + path = g_canonicalize_filename(filename, g_get_current_dir()); + + OKF("Redirect %d -> '%s'", fd, path); + + output_fd = open(path, O_RDWR | O_CREAT | O_TRUNC, + S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); + + g_free(path); + + if (output_fd < 0) { FATAL("Failed to open fd(%d) error %d", fd, errno); } + + if (dup2(output_fd, fd) < 0) { + + FATAL("Failed to set fd(%d) error %d", fd, errno); + + } + +} + +void output_init(void) { + + output_redirect(STDOUT_FILENO, "AFL_FRIDA_OUTPUT_STDOUT"); + output_redirect(STDERR_FILENO, "AFL_FRIDA_OUTPUT_STDERR"); + +} + diff --git a/frida_mode/src/persistent/persistent.c b/frida_mode/src/persistent/persistent.c index 918ff153..2ec5b9cc 100644 --- a/frida_mode/src/persistent/persistent.c +++ b/frida_mode/src/persistent/persistent.c @@ -12,6 +12,9 @@ int __afl_sharedmem_fuzzing = 0; afl_persistent_hook_fn hook = NULL; guint64 persistent_start = 0; guint64 persistent_count = 0; +guint64 persistent_ret = 0; +guint64 persistent_ret_offset = 0; +gboolean persistent_debug = FALSE; void persistent_init(void) { @@ -19,12 +22,36 @@ void persistent_init(void) { persistent_start = util_read_address("AFL_FRIDA_PERSISTENT_ADDR"); persistent_count = util_read_num("AFL_FRIDA_PERSISTENT_CNT"); + persistent_ret = util_read_address("AFL_FRIDA_PERSISTENT_RET"); + persistent_ret_offset = + util_read_address("AFL_FRIDA_PERSISTENT_RETADDR_OFFSET"); + + if (getenv("AFL_FRIDA_PERSISTENT_DEBUG") != NULL) { persistent_debug = TRUE; } + + if (persistent_count != 0 && persistent_start == 0) { - if (persistent_count != 0 && persistent_start == 0) FATAL( "AFL_FRIDA_PERSISTENT_ADDR must be specified if " "AFL_FRIDA_PERSISTENT_CNT is"); + } + + if (persistent_ret != 0 && persistent_start == 0) { + + FATAL( + "AFL_FRIDA_PERSISTENT_ADDR must be specified if " + "AFL_FRIDA_PERSISTENT_RET is"); + + } + + if (persistent_ret_offset != 0 && persistent_ret == 0) { + + FATAL( + "AFL_FRIDA_PERSISTENT_RET must be specified if " + "AFL_FRIDA_PERSISTENT_RETADDR_OFFSET is"); + + } + if (persistent_start != 0 && persistent_count == 0) persistent_count = 1000; if (persistent_count != 0 && persistent_count < 100) @@ -39,6 +66,11 @@ void persistent_init(void) { persistent_start == 0 ? ' ' : 'X', persistent_count); OKF("Instrumentation - hook [%s]", hook_name); + OKF("Instrumentation - persistent ret [%c] (0x%016" G_GINT64_MODIFIER "X)", + persistent_ret == 0 ? ' ' : 'X', persistent_ret); + OKF("Instrumentation - persistent ret offset [%c] (%" G_GINT64_MODIFIER "d)", + persistent_ret_offset == 0 ? ' ' : 'X', persistent_ret_offset); + if (hook_name != NULL) { void *hook_obj = dlopen(hook_name, RTLD_NOW); diff --git a/frida_mode/src/persistent/persistent_arm32.c b/frida_mode/src/persistent/persistent_arm32.c index bc021ff3..6a3c06fa 100644 --- a/frida_mode/src/persistent/persistent_arm32.c +++ b/frida_mode/src/persistent/persistent_arm32.c @@ -68,5 +68,12 @@ void persistent_prologue(GumStalkerOutput *output) { } +void persistent_epilogue(GumStalkerOutput *output) { + + UNUSED_PARAMETER(output); + FATAL("Persistent mode not supported on this architecture"); + +} + #endif diff --git a/frida_mode/src/persistent/persistent_arm64.c b/frida_mode/src/persistent/persistent_arm64.c index c198da69..1215d8da 100644 --- a/frida_mode/src/persistent/persistent_arm64.c +++ b/frida_mode/src/persistent/persistent_arm64.c @@ -111,5 +111,12 @@ void persistent_prologue(GumStalkerOutput *output) { } +void persistent_epilogue(GumStalkerOutput *output) { + + UNUSED_PARAMETER(output); + FATAL("Persistent mode not supported on this architecture"); + +} + #endif diff --git a/frida_mode/src/persistent/persistent_x64.c b/frida_mode/src/persistent/persistent_x64.c index aa772b7f..4c495d47 100644 --- a/frida_mode/src/persistent/persistent_x64.c +++ b/frida_mode/src/persistent/persistent_x64.c @@ -1,9 +1,11 @@ #include "frida-gum.h" #include "config.h" +#include "debug.h" #include "instrument.h" #include "persistent.h" +#include "util.h" #if defined(__x86_64__) @@ -264,7 +266,6 @@ void persistent_prologue(GumStalkerOutput *output) { GumX86Writer *cw = output->writer.x86; gconstpointer loop = cw->code + 1; - // gum_x86_writer_put_breakpoint(cw); /* Stack must be 16-byte aligned per ABI */ instrument_persitent_save_regs(cw, &saved_regs); @@ -288,7 +289,9 @@ void persistent_prologue(GumStalkerOutput *output) { instrument_persitent_restore_regs(cw, &saved_regs); gconstpointer original = cw->code + 1; /* call original */ + gum_x86_writer_put_call_near_label(cw, original); + /* jmp loop */ gum_x86_writer_put_jmp_near_label(cw, loop); @@ -300,9 +303,23 @@ void persistent_prologue(GumStalkerOutput *output) { /* original: */ gum_x86_writer_put_label(cw, original); + if (persistent_debug) { gum_x86_writer_put_breakpoint(cw); } + gum_x86_writer_flush(cw); } +void persistent_epilogue(GumStalkerOutput *output) { + + GumX86Writer *cw = output->writer.x86; + + if (persistent_debug) { gum_x86_writer_put_breakpoint(cw); } + + gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_REG_RSP, GUM_REG_RSP, + persistent_ret_offset); + gum_x86_writer_put_ret(cw); + +} + #endif diff --git a/frida_mode/src/persistent/persistent_x86.c b/frida_mode/src/persistent/persistent_x86.c index 20a3dc42..b30dfadf 100644 --- a/frida_mode/src/persistent/persistent_x86.c +++ b/frida_mode/src/persistent/persistent_x86.c @@ -244,9 +244,24 @@ void persistent_prologue(GumStalkerOutput *output) { /* original: */ gum_x86_writer_put_label(cw, original); + if (persistent_debug) { gum_x86_writer_put_breakpoint(cw); } + gum_x86_writer_flush(cw); } +void persistent_epilogue(GumStalkerOutput *output) { + + GumX86Writer *cw = output->writer.x86; + + if (persistent_debug) { gum_x86_writer_put_breakpoint(cw); } + + gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_REG_ESP, GUM_REG_ESP, + persistent_ret_offset); + + gum_x86_writer_put_ret(cw); + +} + #endif diff --git a/frida_mode/src/ranges.c b/frida_mode/src/ranges.c index e3f09f9e..ef25b371 100644 --- a/frida_mode/src/ranges.c +++ b/frida_mode/src/ranges.c @@ -480,15 +480,40 @@ static GArray *merge_ranges(GArray *a) { } +static gboolean exclude_ranges_callback(const GumRangeDetails *details, + gpointer user_data) { + + UNUSED_PARAMETER(user_data); + gchar * name; + gboolean found; + GumStalker *stalker; + if (details->file == NULL) { return TRUE; } + name = g_path_get_basename(details->file->path); + + found = (g_strcmp0(name, "afl-frida-trace.so") == 0); + g_free(name); + if (!found) { return TRUE; } + + stalker = stalker_get(); + gum_stalker_exclude(stalker, details->range); + + return FALSE; + +} + +static void ranges_exclude_self(void) { + + gum_process_enumerate_ranges(GUM_PAGE_EXECUTE, exclude_ranges_callback, NULL); + +} + void ranges_init(void) { - GumMemoryRange ri; - GArray * step1; - GArray * step2; - GArray * step3; - GArray * step4; - GumMemoryRange *r; - GumStalker * stalker; + GumMemoryRange ri; + GArray * step1; + GArray * step2; + GArray * step3; + GArray * step4; if (getenv("AFL_FRIDA_DEBUG_MAPS") != NULL) { @@ -535,20 +560,16 @@ void ranges_init(void) { ranges = merge_ranges(step4); print_ranges("final", ranges); - stalker = stalker_get(); - - for (guint i = 0; i < ranges->len; i++) { - - r = &g_array_index(ranges, GumMemoryRange, i); - gum_stalker_exclude(stalker, r); - - } - g_array_free(step4, TRUE); g_array_free(step3, TRUE); g_array_free(step2, TRUE); g_array_free(step1, TRUE); + /* *NEVER* stalk the stalker, only bad things will ever come of this! */ + ranges_exclude_self(); + + ranges_exclude(); + } gboolean range_is_excluded(gpointer address) { @@ -572,3 +593,19 @@ gboolean range_is_excluded(gpointer address) { } +void ranges_exclude() { + + GumMemoryRange *r; + GumStalker * stalker = stalker_get(); + + OKF("Excluding ranges"); + + for (guint i = 0; i < ranges->len; i++) { + + r = &g_array_index(ranges, GumMemoryRange, i); + gum_stalker_exclude(stalker, r); + + } + +} + diff --git a/frida_mode/src/stats/stats.c b/frida_mode/src/stats/stats.c new file mode 100644 index 00000000..890a8d6b --- /dev/null +++ b/frida_mode/src/stats/stats.c @@ -0,0 +1,208 @@ +#include +#include +#include +#include +#include +#include + +#include "frida-gum.h" + +#include "config.h" +#include "debug.h" +#include "util.h" + +#include "stats.h" + +#define MICRO_TO_SEC 1000000 + +stats_data_header_t *stats_data = NULL; + +static int stats_parent_pid = -1; +static int stats_fd = -1; +static gboolean stats_transitions = FALSE; +static guint64 stats_interval = 0; + +void stats_init(void) { + + stats_parent_pid = getpid(); + char *filename = getenv("AFL_FRIDA_STATS_FILE"); + stats_interval = util_read_num("AFL_FRIDA_STATS_INTERVAL"); + if (getenv("AFL_FRIDA_STATS_TRANSITIONS") != NULL) { + + stats_transitions = TRUE; + + } + + OKF("Stats - file [%s]", filename); + OKF("Stats - interval [%" G_GINT64_MODIFIER "u]", stats_interval); + + if (stats_interval != 0 && filename == NULL) { + + FATAL( + "AFL_FRIDA_STATS_FILE must be specified if " + "AFL_FRIDA_STATS_INTERVAL is"); + + } + + if (stats_interval == 0) { stats_interval = 10; } + + if (filename == NULL) { return; } + + if (!stats_is_supported_arch()) { + + FATAL("Stats is not supported on this architecture"); + + } + + char *path = NULL; + + if (filename == NULL) { return; } + + if (stats_transitions) { gum_stalker_set_counters_enabled(TRUE); } + + path = g_canonicalize_filename(filename, g_get_current_dir()); + + OKF("Stats - path [%s]", path); + + stats_fd = open(path, O_RDWR | O_CREAT | O_TRUNC, + S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); + + if (stats_fd < 0) { FATAL("Failed to open stats file '%s'", path); } + + g_free(path); + + size_t data_size = stats_data_size_arch(); + + int shm_id = shmget(IPC_PRIVATE, data_size, IPC_CREAT | IPC_EXCL | 0600); + if (shm_id < 0) { FATAL("shm_id < 0 - errno: %d\n", errno); } + + stats_data = shmat(shm_id, NULL, 0); + g_assert(stats_data != MAP_FAILED); + + /* + * Configure the shared memory region to be removed once the process dies. + */ + if (shmctl(shm_id, IPC_RMID, NULL) < 0) { + + FATAL("shmctl (IPC_RMID) < 0 - errno: %d\n", errno); + + } + + /* Clear it, not sure it's necessary, just seems like good practice */ + memset(stats_data, '\0', data_size); + +} + +void stats_vprint(int fd, char *format, va_list ap) { + + char buffer[4096] = {0}; + int ret; + int len; + + if(vsnprintf(buffer, sizeof(buffer) - 1, format, ap) < 0) { return; } + + len = strnlen(buffer, sizeof(buffer)); + IGNORED_RETURN(write(fd, buffer, len)); + +} + +void stats_print_fd(int fd, char *format, ...) { + + va_list ap; + va_start(ap, format); + stats_vprint(fd, format, ap); + va_end(ap); + +} + +void stats_print(char *format, ...) { + + va_list ap; + va_start(ap, format); + stats_vprint(stats_fd, format, ap); + va_end(ap); + +} + +void stats_write(void) { + + if (stats_parent_pid == getpid()) { return; } + + GDateTime *date_time = g_date_time_new_now_local(); + char *date_time_string = g_date_time_format(date_time, "%Y-%m-%e %H:%M:%S"); + + stats_print("stats\n"); + stats_print("-----\n"); + + stats_print("Index: %" G_GINT64_MODIFIER "u\n", + stats_data->stats_idx++); + stats_print("Pid: %d\n", getpid()); + stats_print("Time: %s\n", date_time_string); + stats_print("Blocks: %" G_GINT64_MODIFIER "u\n", + stats_data->num_blocks); + stats_print("Instructions: %" G_GINT64_MODIFIER "u\n", + stats_data->num_instructions); + stats_print("Avg Instructions / Block: %" G_GINT64_MODIFIER "u\n", + stats_data->num_instructions / stats_data->num_blocks); + + stats_print("\n"); + + g_free(date_time_string); + g_date_time_unref(date_time); + + stats_write_arch(); + + if (stats_transitions) { + + GDateTime *date_time = g_date_time_new_now_local(); + char *date_time_string = g_date_time_format(date_time, "%Y-%m-%e %H:%M:%S"); + + stats_print_fd(STDERR_FILENO, "stats\n"); + stats_print_fd(STDERR_FILENO, "-----\n"); + stats_print_fd(STDERR_FILENO, "Index: %" G_GINT64_MODIFIER "u\n", + stats_data->transitions_idx++); + stats_print_fd(STDERR_FILENO, "Pid: %d\n", getpid()); + stats_print_fd(STDERR_FILENO, "Time: %s\n", date_time_string); + + g_free(date_time_string); + g_date_time_unref(date_time); + gum_stalker_dump_counters(); + + } + +} + +static void stats_maybe_write(void) { + + guint64 current_time; + + if (stats_interval == 0) { return; } + + current_time = g_get_monotonic_time(); + + if ((current_time - stats_data->stats_last_time) > + (stats_interval * MICRO_TO_SEC)) { + + stats_write(); + stats_data->stats_last_time = current_time; + + } + +} + +void stats_collect(const cs_insn *instr, gboolean begin) { + + UNUSED_PARAMETER(instr); + UNUSED_PARAMETER(begin); + + if (stats_fd < 0) { return; } + + if (begin) { stats_data->num_blocks++; } + stats_data->num_instructions++; + + stats_collect_arch(instr); + + stats_maybe_write(); + +} + diff --git a/frida_mode/src/stats/stats_arm.c b/frida_mode/src/stats/stats_arm.c new file mode 100644 index 00000000..7eea7f91 --- /dev/null +++ b/frida_mode/src/stats/stats_arm.c @@ -0,0 +1,36 @@ +#include "frida-gum.h" + +#include "debug.h" + +#include "stats.h" +#include "util.h" + +#if defined(__arm__) + +gboolean stats_is_supported_arch(void) { + + return FALSE; + +} + +size_t stats_data_size_arch(void) { + + FATAL("Stats not supported on this architecture"); + +} + +void stats_write_arch(void) { + + FATAL("Stats not supported on this architecture"); + +} + +void stats_collect_arch(const cs_insn *instr) { + + UNUSED_PARAMETER(instr); + FATAL("Stats not supported on this architecture"); + +} + +#endif + diff --git a/frida_mode/src/stats/stats_arm64.c b/frida_mode/src/stats/stats_arm64.c new file mode 100644 index 00000000..592af87a --- /dev/null +++ b/frida_mode/src/stats/stats_arm64.c @@ -0,0 +1,36 @@ +#include "frida-gum.h" + +#include "debug.h" + +#include "stats.h" +#include "util.h" + +#if defined(__aarch64__) + +gboolean stats_is_supported_arch(void) { + + return FALSE; + +} + +size_t stats_data_size_arch(void) { + + FATAL("Stats not supported on this architecture"); + +} + +void stats_write_arch(void) { + + FATAL("Stats not supported on this architecture"); + +} + +void stats_collect_arch(const cs_insn *instr) { + + UNUSED_PARAMETER(instr); + FATAL("Stats not supported on this architecture"); + +} + +#endif + diff --git a/frida_mode/src/stats/stats_x64.c b/frida_mode/src/stats/stats_x64.c new file mode 100644 index 00000000..c3e8742a --- /dev/null +++ b/frida_mode/src/stats/stats_x64.c @@ -0,0 +1,307 @@ +#include "frida-gum.h" + +#include "debug.h" + +#include "ranges.h" +#include "stats.h" +#include "util.h" + +#if defined(__x86_64__) + +typedef struct { + + stats_data_header_t header; + + guint64 num_call_imm; + guint64 num_call_imm_excluded; + guint64 num_call_reg; + guint64 num_call_mem; + + guint64 num_jmp_imm; + guint64 num_jmp_reg; + guint64 num_jmp_mem; + + guint64 num_jmp_cond_imm; + guint64 num_jmp_cond_reg; + guint64 num_jmp_cond_mem; + + guint64 num_jmp_cond_jcxz; + + guint64 num_ret; + + guint64 num_rip_relative; + +} stats_data_arch_t; + +gboolean stats_is_supported_arch(void) { + + return TRUE; + +} + +size_t stats_data_size_arch(void) { + + return sizeof(stats_data_arch_t); + +} + +void stats_write_arch(void) { + + stats_data_arch_t *stats_data_arch = (stats_data_arch_t *)stats_data; + guint64 num_instructions = stats_data_arch->header.num_instructions; + + stats_print( + "Call Immediates: %" G_GINT64_MODIFIER + "u " + "(%3.2f%%)\n", + stats_data_arch->num_call_imm, + ((float)(stats_data_arch->num_call_imm * 100) / num_instructions)); + stats_print("Call Immediates Excluded: %" G_GINT64_MODIFIER + "u " + "(%3.2f%%)\n", + stats_data_arch->num_call_imm_excluded, + ((float)(stats_data_arch->num_call_imm_excluded * 100) / + num_instructions)); + stats_print( + "Call Register: %" G_GINT64_MODIFIER + "u " + "(%3.2f%%)\n", + stats_data_arch->num_call_reg, + ((float)(stats_data_arch->num_call_reg * 100) / num_instructions)); + stats_print( + "Call Memory: %" G_GINT64_MODIFIER + "u " + "(%3.2f%%)\n", + stats_data_arch->num_call_mem, + ((float)(stats_data_arch->num_call_mem * 100) / num_instructions)); + + stats_print("\n"); + + stats_print("Jump Immediates: %" G_GINT64_MODIFIER + "u " + "(%3.2f%%)\n", + stats_data_arch->num_jmp_imm, + ((float)(stats_data_arch->num_jmp_imm * 100) / num_instructions)); + stats_print("Jump Register: %" G_GINT64_MODIFIER + "u " + "(%3.2f%%)\n", + stats_data_arch->num_jmp_reg, + ((float)(stats_data_arch->num_jmp_reg * 100) / num_instructions)); + stats_print("Jump Memory: %" G_GINT64_MODIFIER + "u " + "(%3.2f%%)\n", + stats_data_arch->num_jmp_mem, + ((float)(stats_data_arch->num_jmp_mem * 100) / num_instructions)); + + stats_print("\n"); + + stats_print( + "Conditional Jump Immediates: %" G_GINT64_MODIFIER + "u " + "(%3.2f%%)\n", + stats_data_arch->num_jmp_cond_imm, + ((float)(stats_data_arch->num_jmp_cond_imm * 100) / num_instructions)); + stats_print( + "Conditional Jump CX Immediate: %" G_GINT64_MODIFIER + "u " + "(%3.2f%%)\n", + stats_data_arch->num_jmp_cond_jcxz, + ((float)(stats_data_arch->num_jmp_cond_jcxz * 100) / num_instructions)); + stats_print( + "Conditional Jump Register: %" G_GINT64_MODIFIER + "u " + "(%3.2f%%)\n", + stats_data_arch->num_jmp_cond_reg, + ((float)(stats_data_arch->num_jmp_cond_reg * 100) / num_instructions)); + stats_print( + "Conditional Jump Memory: %" G_GINT64_MODIFIER + "u " + "(%3.2f%%)\n", + stats_data_arch->num_jmp_cond_mem, + ((float)(stats_data_arch->num_jmp_cond_mem * 100) / num_instructions)); + + stats_print("\n"); + + stats_print("Returns: %" G_GINT64_MODIFIER + "u " + "(%3.2f%%)\n", + stats_data_arch->num_ret, + (stats_data_arch->num_ret * 100 / num_instructions)); + + stats_print("\n"); + + stats_print("Rip Relative: %" G_GINT64_MODIFIER + "u " + "(%3.2f%%)\n", + stats_data_arch->num_rip_relative, + (stats_data_arch->num_rip_relative * 100 / num_instructions)); + + stats_print("\n"); + stats_print("\n"); + +} + +static x86_op_type stats_get_operand_type(const cs_insn *instr) { + + cs_x86 * x86 = &instr->detail->x86; + cs_x86_op *operand; + + if (x86->op_count != 1) { + + FATAL("Unexpected operand count (%d): %s %s\n", x86->op_count, + instr->mnemonic, instr->op_str); + + } + + operand = &x86->operands[0]; + + return operand->type; + +} + +static void stats_collect_call_imm_excluded_arch(const cs_insn *instr) { + + stats_data_arch_t *stats_data_arch = (stats_data_arch_t *)stats_data; + cs_x86 * x86 = &instr->detail->x86; + cs_x86_op * operand = &x86->operands[0]; + + if (range_is_excluded((gpointer)operand->imm)) { + + stats_data_arch->num_call_imm_excluded++; + + } + +} + +static void stats_collect_call_arch(const cs_insn *instr) { + + stats_data_arch_t *stats_data_arch = (stats_data_arch_t *)stats_data; + x86_op_type type = stats_get_operand_type(instr); + switch (type) { + + case X86_OP_IMM: + stats_data_arch->num_call_imm++; + stats_collect_call_imm_excluded_arch(instr); + break; + case X86_OP_REG: + stats_data_arch->num_call_reg++; + break; + case X86_OP_MEM: + stats_data_arch->num_call_mem++; + break; + default: + FATAL("Invalid operand type: %s %s\n", instr->mnemonic, instr->op_str); + + } + +} + +static void stats_collect_jump_arch(const cs_insn *instr) { + + stats_data_arch_t *stats_data_arch = (stats_data_arch_t *)stats_data; + x86_op_type type = stats_get_operand_type(instr); + switch (type) { + + case X86_OP_IMM: + stats_data_arch->num_jmp_imm++; + break; + case X86_OP_REG: + stats_data_arch->num_jmp_reg++; + break; + case X86_OP_MEM: + stats_data_arch->num_jmp_mem++; + break; + default: + FATAL("Invalid operand type: %s %s\n", instr->mnemonic, instr->op_str); + + } + +} + +static void stats_collect_jump_cond_arch(const cs_insn *instr) { + + stats_data_arch_t *stats_data_arch = (stats_data_arch_t *)stats_data; + x86_op_type type = stats_get_operand_type(instr); + switch (type) { + + case X86_OP_IMM: + stats_data_arch->num_jmp_cond_imm++; + break; + case X86_OP_REG: + stats_data_arch->num_jmp_cond_reg++; + break; + case X86_OP_MEM: + stats_data_arch->num_jmp_cond_mem++; + break; + default: + FATAL("Invalid operand type: %s %s\n", instr->mnemonic, instr->op_str); + + } + +} + +static void stats_collect_rip_relative_arch(const cs_insn *instr) { + + stats_data_arch_t *stats_data_arch = (stats_data_arch_t *)stats_data; + cs_x86 * x86 = &instr->detail->x86; + guint mod; + guint rm; + + if (x86->encoding.modrm_offset == 0) { return; } + + mod = (x86->modrm & 0xc0) >> 6; + if (mod != 0) { return; } + + rm = (x86->modrm & 0x07) >> 0; + if (rm != 5) { return; } + + stats_data_arch->num_rip_relative++; + +} + +void stats_collect_arch(const cs_insn *instr) { + + stats_data_arch_t *stats_data_arch = (stats_data_arch_t *)stats_data; + switch (instr->id) { + + case X86_INS_CALL: + stats_collect_call_arch(instr); + break; + case X86_INS_JMP: + stats_collect_jump_arch(instr); + break; + case X86_INS_JA: + case X86_INS_JAE: + case X86_INS_JB: + case X86_INS_JBE: + case X86_INS_JE: + case X86_INS_JG: + case X86_INS_JGE: + case X86_INS_JL: + case X86_INS_JLE: + case X86_INS_JNE: + case X86_INS_JNO: + case X86_INS_JNP: + case X86_INS_JNS: + case X86_INS_JO: + case X86_INS_JP: + case X86_INS_JS: + stats_collect_jump_cond_arch(instr); + break; + case X86_INS_JECXZ: + case X86_INS_JRCXZ: + stats_data_arch->num_jmp_cond_jcxz++; + break; + case X86_INS_RET: + stats_data_arch->num_ret++; + break; + default: + stats_collect_rip_relative_arch(instr); + break; + + } + +} + +#endif + diff --git a/frida_mode/src/stats/stats_x86.c b/frida_mode/src/stats/stats_x86.c new file mode 100644 index 00000000..1906e809 --- /dev/null +++ b/frida_mode/src/stats/stats_x86.c @@ -0,0 +1,36 @@ +#include "frida-gum.h" + +#include "debug.h" + +#include "stats.h" +#include "util.h" + +#if defined(__i386__) + +gboolean stats_is_supported_arch(void) { + + return FALSE; + +} + +size_t stats_data_size_arch(void) { + + FATAL("Stats not supported on this architecture"); + +} + +void stats_write_arch(void) { + + FATAL("Stats not supported on this architecture"); + +} + +void stats_collect_arch(const cs_insn *instr) { + + UNUSED_PARAMETER(instr); + FATAL("Stats not supported on this architecture"); + +} + +#endif + diff --git a/frida_mode/src/util.c b/frida_mode/src/util.c index 86b94970..09e8a58b 100644 --- a/frida_mode/src/util.c +++ b/frida_mode/src/util.c @@ -10,7 +10,7 @@ guint64 util_read_address(char *key) { if (!g_str_has_prefix(value_str, "0x")) { - FATAL("Invalid address should have 0x prefix: %s\n", value_str); + FATAL("Invalid address should have 0x prefix: %s=%s\n", key, value_str); } @@ -20,8 +20,8 @@ guint64 util_read_address(char *key) { if (!g_ascii_isxdigit(*c)) { - FATAL("Invalid address not formed of hex digits: %s ('%c')\n", value_str, - *c); + FATAL("Invalid address not formed of hex digits: %s=%s ('%c')\n", key, + value_str, *c); } @@ -30,7 +30,7 @@ guint64 util_read_address(char *key) { guint64 value = g_ascii_strtoull(value_str2, NULL, 16); if (value == 0) { - FATAL("Invalid address failed hex conversion: %s\n", value_str2); + FATAL("Invalid address failed hex conversion: %s=%s\n", key, value_str2); } @@ -48,7 +48,8 @@ guint64 util_read_num(char *key) { if (!g_ascii_isdigit(*c)) { - FATAL("Invalid address not formed of decimal digits: %s\n", value_str); + FATAL("Invalid address not formed of decimal digits: %s=%s\n", key, + value_str); } @@ -57,7 +58,7 @@ guint64 util_read_num(char *key) { guint64 value = g_ascii_strtoull(value_str, NULL, 10); if (value == 0) { - FATAL("Invalid address failed numeric conversion: %s\n", value_str); + FATAL("Invalid address failed numeric conversion: %s=%s\n", key, value_str); } diff --git a/frida_mode/test/deferred/GNUmakefile b/frida_mode/test/deferred/GNUmakefile new file mode 100644 index 00000000..c268ef66 --- /dev/null +++ b/frida_mode/test/deferred/GNUmakefile @@ -0,0 +1,71 @@ +PWD:=$(shell pwd)/ +ROOT:=$(shell realpath $(PWD)../../..)/ +BUILD_DIR:=$(PWD)build/ +TESTINSTR_DATA_DIR:=$(BUILD_DIR)in/ +TESTINSTR_DATA_FILE:=$(TESTINSTR_DATA_DIR)in + +TESTINSTBIN:=$(BUILD_DIR)testinstr +TESTINSTSRC:=$(PWD)testinstr.c + +QEMU_OUT:=$(BUILD_DIR)qemu-out +FRIDA_OUT:=$(BUILD_DIR)frida-out + +GET_SYMBOL_ADDR:=$(ROOT)frida_mode/test/png/persistent/get_symbol_addr.py + +ifndef ARCH + +ARCH=$(shell uname -m) +ifeq "$(ARCH)" "aarch64" + ARCH:=arm64 +endif + +ifeq "$(ARCH)" "i686" + ARCH:=x86 +endif +endif + +ARCH=$(shell uname -m) +ifeq "$(ARCH)" "aarch64" + AFL_ENTRYPOINT=$(shell $(GET_SYMBOL_ADDR) -f $(TESTINSTBIN) -s run -b 0x0000aaaaaaaaa000) +endif + +ifeq "$(ARCH)" "x86_64" + AFL_ENTRYPOINT=$(shell $(GET_SYMBOL_ADDR) -f $(TESTINSTBIN) -s run -b 0x0000555555554000) +endif + +ifeq "$(ARCH)" "x86" + AFL_ENTRYPOINT=$(shell $(GET_SYMBOL_ADDR) -f $(TESTINSTBIN) -s run -b 0x56555000) +endif + +.PHONY: all clean qemu frida + +all: $(TESTINSTBIN) + make -C $(ROOT)frida_mode/ + +32: + CFLAGS="-m32" LDFLAGS="-m32" ARCH="x86" make all + +$(BUILD_DIR): + mkdir -p $@ + +$(TESTINSTR_DATA_DIR): | $(BUILD_DIR) + mkdir -p $@ + +$(TESTINSTR_DATA_FILE): | $(TESTINSTR_DATA_DIR) + echo -n "000" > $@ + +$(TESTINSTBIN): $(TESTINSTSRC) | $(BUILD_DIR) + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< + +clean: + rm -rf $(BUILD_DIR) + +frida: $(TESTINSTBIN) $(TESTINSTR_DATA_FILE) + AFL_ENTRYPOINT=$(AFL_ENTRYPOINT) \ + $(ROOT)afl-fuzz \ + -D \ + -O \ + -i $(TESTINSTR_DATA_DIR) \ + -o $(FRIDA_OUT) \ + -- \ + $(TESTINSTBIN) @@ diff --git a/frida_mode/test/deferred/Makefile b/frida_mode/test/deferred/Makefile new file mode 100644 index 00000000..07b139e9 --- /dev/null +++ b/frida_mode/test/deferred/Makefile @@ -0,0 +1,13 @@ +all: + @echo trying to use GNU make... + @gmake all || echo please install GNUmake + +32: + @echo trying to use GNU make... + @gmake 32 || echo please install GNUmake + +clean: + @gmake clean + +frida: + @gmake frida diff --git a/frida_mode/test/deferred/testinstr.c b/frida_mode/test/deferred/testinstr.c new file mode 100644 index 00000000..8b3688d7 --- /dev/null +++ b/frida_mode/test/deferred/testinstr.c @@ -0,0 +1,125 @@ +/* + american fuzzy lop++ - a trivial program to test the build + -------------------------------------------------------- + Originally written by Michal Zalewski + Copyright 2014 Google Inc. All rights reserved. + Copyright 2019-2020 AFLplusplus Project. All rights reserved. + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at: + http://www.apache.org/licenses/LICENSE-2.0 + */ + +#include +#include +#include +#include +#include + +#ifdef __APPLE__ + #define TESTINSTR_SECTION +#else + #define TESTINSTR_SECTION __attribute__((section(".testinstr"))) +#endif + +void testinstr(char *buf, int len) { + + if (len < 1) return; + buf[len] = 0; + + // we support three input cases + if (buf[0] == '0') + printf("Looks like a zero to me!\n"); + else if (buf[0] == '1') + printf("Pretty sure that is a one!\n"); + else + printf("Neither one or zero? How quaint!\n"); + +} + +int run(char *file) { + + int fd = -1; + off_t len; + char * buf = NULL; + size_t n_read; + int result = -1; + + do { + + dprintf(STDERR_FILENO, "Running: %s\n", file); + + fd = open(file, O_RDONLY); + if (fd < 0) { + + perror("open"); + break; + + } + + len = lseek(fd, 0, SEEK_END); + if (len < 0) { + + perror("lseek (SEEK_END)"); + break; + + } + + if (lseek(fd, 0, SEEK_SET) != 0) { + + perror("lseek (SEEK_SET)"); + break; + + } + + buf = malloc(len); + if (buf == NULL) { + + perror("malloc"); + break; + + } + + n_read = read(fd, buf, len); + if (n_read != len) { + + perror("read"); + break; + + } + + dprintf(STDERR_FILENO, "Running: %s: (%zd bytes)\n", file, n_read); + + testinstr(buf, len); + dprintf(STDERR_FILENO, "Done: %s: (%zd bytes)\n", file, n_read); + + result = 0; + + } while (false); + + if (buf != NULL) { free(buf); } + + if (fd != -1) { close(fd); } + + return result; + +} + +void slow() { + + usleep(100000); + +} + +TESTINSTR_SECTION int do_run(char * file) { + return run(file); +} + +int main(int argc, char **argv) { + + if (argc != 2) { return 1; } + slow(); + return do_run(argv[1]); + +} + diff --git a/frida_mode/test/libpcap/GNUmakefile b/frida_mode/test/libpcap/GNUmakefile new file mode 100644 index 00000000..e30f2049 --- /dev/null +++ b/frida_mode/test/libpcap/GNUmakefile @@ -0,0 +1,188 @@ +PWD:=$(shell pwd)/ +ROOT:=$(shell realpath $(PWD)../../..)/ +BUILD_DIR:=$(PWD)build/ + +AFLPP_DRIVER_HOOK_SRC=$(PWD)aflpp_qemu_driver_hook.c +AFLPP_DRIVER_HOOK_OBJ=$(BUILD_DIR)aflpp_qemu_driver_hook.so + +LIBPCAP_BUILD_DIR:=$(BUILD_DIR)libpcap/ +HARNESS_BUILD_DIR:=$(BUILD_DIR)harness/ +PCAPTEST_BUILD_DIR:=$(BUILD_DIR)libpcaptest/ +TCPDUMP_BUILD_DIR:=$(BUILD_DIR)tcpdump/ + +LIBPCAP_PATCH_URL:=https://raw.githubusercontent.com/google/fuzzbench/master/benchmarks/libpcap_fuzz_both/patch.diff +LIBPCAP_PATCH_FILE:=$(LIBPCAP_BUILD_DIR)patch.diff +LIBPCAP_URL:=https://github.com/the-tcpdump-group/libpcap.git +LIBPCAP_DIR:=$(LIBPCAP_BUILD_DIR)libpcap/ +LIBPCAP_CMAKEFILE:=$(LIBPCAP_DIR)CMakeLists.txt +LIBPCAP_MAKEFILE:=$(LIBPCAP_DIR)Makefile +LIBPCAP_LIB:=$(LIBPCAP_DIR)libpcap.a + +HARNESS_FILE:=$(HARNESS_BUILD_DIR)StandaloneFuzzTargetMain.c +HARNESS_OBJ:=$(HARNESS_BUILD_DIR)StandaloneFuzzTargetMain.o +HARNESS_URL:="https://raw.githubusercontent.com/llvm/llvm-project/main/compiler-rt/lib/fuzzer/standalone/StandaloneFuzzTargetMain.c" + +PCAPTEST_SRC_DIR:=$(LIBPCAP_DIR)testprogs/fuzz/ +PCAPTEST_FILE:=$(PCAPTEST_SRC_DIR)fuzz_both.c +PCAPTEST_OBJ:=$(PCAPTEST_BUILD_DIR)fuzz_both.o + +TCPDUMP_URL:=https://github.com/the-tcpdump-group/tcpdump.git +TCPDUMP_TESTS_DIR:=$(TCPDUMP_BUILD_DIR)tests/ + +CFLAGS += -fpermissive + +LDFLAGS += -lpthread + +TEST_BIN:=$(BUILD_DIR)test +ifeq "$(shell uname)" "Darwin" +TEST_BIN_LDFLAGS:=-undefined dynamic_lookup +endif + +AFLPP_DRIVER_DUMMY_INPUT:=$(TCPDUMP_TESTS_DIR)in + +QEMU_OUT:=$(BUILD_DIR)qemu-out +FRIDA_OUT:=$(BUILD_DIR)frida-out + +ifndef ARCH + +ARCH=$(shell uname -m) +ifeq "$(ARCH)" "aarch64" + ARCH:=arm64 +endif + +ifeq "$(ARCH)" "i686" + ARCH:=x86 +endif +endif + +AFL_QEMU_PERSISTENT_ADDR=$(shell $(PWD)get_symbol_addr.py -f $(TEST_BIN) -s LLVMFuzzerTestOneInput -b 0x4000000000) + +ifeq "$(ARCH)" "aarch64" + AFL_FRIDA_PERSISTENT_ADDR=$(shell $(PWD)get_symbol_addr.py -f $(TEST_BIN) -s LLVMFuzzerTestOneInput -b 0x0000aaaaaaaaa000) +endif + +ifeq "$(ARCH)" "x86_64" + AFL_FRIDA_PERSISTENT_ADDR=$(shell $(PWD)get_symbol_addr.py -f $(TEST_BIN) -s LLVMFuzzerTestOneInput -b 0x0000555555554000) +endif + +ifeq "$(ARCH)" "x86" + AFL_FRIDA_PERSISTENT_ADDR=$(shell $(PWD)get_symbol_addr.py -f $(TEST_BIN) -s LLVMFuzzerTestOneInput -b 0x56555000) +endif + +.PHONY: all clean qemu frida hook + +all: $(TEST_BIN) + make -C $(ROOT)frida_mode/ + +32: + CXXFLAGS="-m32" LDFLAGS="-m32" ARCH="x86" make all + +$(BUILD_DIR): + mkdir -p $@ + +######### HARNESS ######## +$(HARNESS_BUILD_DIR): | $(BUILD_DIR) + mkdir -p $@ + +$(HARNESS_FILE): | $(HARNESS_BUILD_DIR) + wget -O $@ $(HARNESS_URL) + +$(HARNESS_OBJ): $(HARNESS_FILE) + $(CC) $(CXXFLAGS) $(LDFLAGS) -o $@ -c $< + +######### PCAPTEST ######## + +$(PCAPTEST_BUILD_DIR): | $(BUILD_DIR) + mkdir -p $@ + +$(PCAPTEST_FILE): | $(LIBPCAP_CMAKEFILE) + +$(PCAPTEST_OBJ): $(PCAPTEST_FILE) | $(PCAPTEST_BUILD_DIR) + $(CC) $(CFLAGS) $(LDFLAGS) -I $(LIBPCAP_DIR) -o $@ -c $< + +######### LIBPCAP ######## + +$(LIBPCAP_BUILD_DIR): | $(BUILD_DIR) + mkdir -p $@ + +$(LIBPCAP_PATCH_FILE): | $(LIBPCAP_BUILD_DIR) + wget -O $@ $(LIBPCAP_PATCH_URL) + +$(LIBPCAP_CMAKEFILE): $(LIBPCAP_PATCH_FILE) | $(LIBPCAP_BUILD_DIR) + git clone --depth 1 $(LIBPCAP_URL) $(LIBPCAP_DIR) + git apply $(LIBPCAP_PATCH_FILE) + +$(LIBPCAP_MAKEFILE): $(LIBPCAP_CMAKEFILE) + cd $(LIBPCAP_DIR) && cmake . + +$(LIBPCAP_LIB): $(LIBPCAP_MAKEFILE) $(LIBPCAP_PATCH_FILE) + make -C $(LIBPCAP_DIR) + +######## TCPDUMP ###### + +$(TCPDUMP_BUILD_DIR): | $(BUILD_DIR) + mkdir -p $@ + +$(TCPDUMP_TESTS_DIR): | $(TCPDUMP_BUILD_DIR) + git clone --depth=1 $(TCPDUMP_URL) $(TCPDUMP_BUILD_DIR) + +######### TEST ######## + +$(TEST_BIN): $(HARNESS_OBJ) $(PCAPTEST_OBJ) $(LIBPCAP_LIB) + $(CXX) \ + $(CFLAGS) \ + -o $@ \ + $(HARNESS_OBJ) $(PCAPTEST_OBJ) $(LIBPCAP_LIB) \ + -lz \ + $(LDFLAGS) \ + $(TEST_BIN_LDFLAGS) \ + +########## HOOK ######## + +$(AFLPP_DRIVER_HOOK_OBJ): $(AFLPP_DRIVER_HOOK_SRC) | $(BUILD_DIR) + $(CC) -shared $(CFLAGS) $(LDFLAGS) $< -o $@ + +########## DUMMY ####### + +$(AFLPP_DRIVER_DUMMY_INPUT): | $(TCPDUMP_TESTS_DIR) + truncate -s 1M $@ + +###### TEST DATA ####### + +hook: $(AFLPP_DRIVER_HOOK_OBJ) + +clean: + rm -rf $(BUILD_DIR) + +qemu: $(TEST_BIN) $(AFLPP_DRIVER_HOOK_OBJ) $(AFLPP_DRIVER_DUMMY_INPUT) | $(TCPDUMP_TESTS_DIR) + AFL_QEMU_PERSISTENT_HOOK=$(AFLPP_DRIVER_HOOK_OBJ) \ + AFL_ENTRYPOINT=$(AFL_QEMU_PERSISTENT_ADDR) \ + AFL_QEMU_PERSISTENT_ADDR=$(AFL_QEMU_PERSISTENT_ADDR) \ + AFL_QEMU_PERSISTENT_GPR=1 \ + $(ROOT)afl-fuzz \ + -D \ + -V 30 \ + -Q \ + -i $(TCPDUMP_TESTS_DIR) \ + -o $(QEMU_OUT) \ + -- \ + $(TEST_BIN) $(AFLPP_DRIVER_DUMMY_INPUT) + +frida: $(TEST_BIN) $(AFLPP_DRIVER_HOOK_OBJ) $(AFLPP_DRIVER_DUMMY_INPUT) | $(TCPDUMP_TESTS_DIR) + AFL_FRIDA_PERSISTENT_HOOK=$(AFLPP_DRIVER_HOOK_OBJ) \ + AFL_FRIDA_PERSISTENT_ADDR=$(AFL_FRIDA_PERSISTENT_ADDR) \ + AFL_ENTRYPOINT=$(AFL_FRIDA_PERSISTENT_ADDR) \ + $(ROOT)afl-fuzz \ + -D \ + -V 30 \ + -O \ + -i $(TCPDUMP_TESTS_DIR) \ + -o $(FRIDA_OUT) \ + -- \ + $(TEST_BIN) $(AFLPP_DRIVER_DUMMY_INPUT) + +debug: + gdb \ + --ex 'set environment LD_PRELOAD=$(ROOT)afl-frida-trace.so' \ + --ex 'set disassembly-flavor intel' \ + --args $(TEST_BIN) $(AFLPP_DRIVER_DUMMY_INPUT) diff --git a/frida_mode/test/libpcap/Makefile b/frida_mode/test/libpcap/Makefile new file mode 100644 index 00000000..31cacb67 --- /dev/null +++ b/frida_mode/test/libpcap/Makefile @@ -0,0 +1,1143 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 3.16 + +# Default target executed when no arguments are given to make. +default_target: all + +.PHONY : default_target + +# Allow only one "make -f Makefile2" at a time, but pass parallelism. +.NOTPARALLEL: + + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + + +# Remove some rules from gmake that .SUFFIXES does not remove. +SUFFIXES = + +.SUFFIXES: .hpux_make_needs_suffix_list + + +# Suppress display of executed commands. +$(VERBOSE).SILENT: + + +# A target that is always out of date. +cmake_force: + +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E remove -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/jon/git/AFLplusplus/frida_mode/test/libpcap/build/libpcap/libpcap + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/jon/git/AFLplusplus/frida_mode/test/libpcap + +#============================================================================= +# Targets provided globally by CMake. + +# Special rule for the target install/strip +install/strip: preinstall + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Installing the project stripped..." + /usr/bin/cmake -DCMAKE_INSTALL_DO_STRIP=1 -P cmake_install.cmake +.PHONY : install/strip + +# Special rule for the target install/strip +install/strip/fast: preinstall/fast + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Installing the project stripped..." + /usr/bin/cmake -DCMAKE_INSTALL_DO_STRIP=1 -P cmake_install.cmake +.PHONY : install/strip/fast + +# Special rule for the target install/local +install/local: preinstall + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Installing only the local directory..." + /usr/bin/cmake -DCMAKE_INSTALL_LOCAL_ONLY=1 -P cmake_install.cmake +.PHONY : install/local + +# Special rule for the target install/local +install/local/fast: preinstall/fast + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Installing only the local directory..." + /usr/bin/cmake -DCMAKE_INSTALL_LOCAL_ONLY=1 -P cmake_install.cmake +.PHONY : install/local/fast + +# Special rule for the target install +install: preinstall + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Install the project..." + /usr/bin/cmake -P cmake_install.cmake +.PHONY : install + +# Special rule for the target install +install/fast: preinstall/fast + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Install the project..." + /usr/bin/cmake -P cmake_install.cmake +.PHONY : install/fast + +# Special rule for the target list_install_components +list_install_components: + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Available install components are: \"Unspecified\"" +.PHONY : list_install_components + +# Special rule for the target list_install_components +list_install_components/fast: list_install_components + +.PHONY : list_install_components/fast + +# Special rule for the target rebuild_cache +rebuild_cache: + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Running CMake to regenerate build system..." + /usr/bin/cmake -S$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) +.PHONY : rebuild_cache + +# Special rule for the target rebuild_cache +rebuild_cache/fast: rebuild_cache + +.PHONY : rebuild_cache/fast + +# Special rule for the target edit_cache +edit_cache: + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "No interactive CMake dialog available..." + /usr/bin/cmake -E echo No\ interactive\ CMake\ dialog\ available. +.PHONY : edit_cache + +# Special rule for the target edit_cache +edit_cache/fast: edit_cache + +.PHONY : edit_cache/fast + +# The main all target +all: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/jon/git/AFLplusplus/frida_mode/test/libpcap/CMakeFiles /home/jon/git/AFLplusplus/frida_mode/test/libpcap/CMakeFiles/progress.marks + $(MAKE) -f CMakeFiles/Makefile2 all + $(CMAKE_COMMAND) -E cmake_progress_start /home/jon/git/AFLplusplus/frida_mode/test/libpcap/CMakeFiles 0 +.PHONY : all + +# The main clean target +clean: + $(MAKE) -f CMakeFiles/Makefile2 clean +.PHONY : clean + +# The main clean target +clean/fast: clean + +.PHONY : clean/fast + +# Prepare targets for installation. +preinstall: all + $(MAKE) -f CMakeFiles/Makefile2 preinstall +.PHONY : preinstall + +# Prepare targets for installation. +preinstall/fast: + $(MAKE) -f CMakeFiles/Makefile2 preinstall +.PHONY : preinstall/fast + +# clear depends +depend: + $(CMAKE_COMMAND) -S$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles/Makefile.cmake 1 +.PHONY : depend + +#============================================================================= +# Target rules for targets named pcap + +# Build rule for target. +pcap: cmake_check_build_system + $(MAKE) -f CMakeFiles/Makefile2 pcap +.PHONY : pcap + +# fast build rule for target. +pcap/fast: + $(MAKE) -f CMakeFiles/pcap.dir/build.make CMakeFiles/pcap.dir/build +.PHONY : pcap/fast + +#============================================================================= +# Target rules for targets named uninstall + +# Build rule for target. +uninstall: cmake_check_build_system + $(MAKE) -f CMakeFiles/Makefile2 uninstall +.PHONY : uninstall + +# fast build rule for target. +uninstall/fast: + $(MAKE) -f CMakeFiles/uninstall.dir/build.make CMakeFiles/uninstall.dir/build +.PHONY : uninstall/fast + +#============================================================================= +# Target rules for targets named pcap_static + +# Build rule for target. +pcap_static: cmake_check_build_system + $(MAKE) -f CMakeFiles/Makefile2 pcap_static +.PHONY : pcap_static + +# fast build rule for target. +pcap_static/fast: + $(MAKE) -f CMakeFiles/pcap_static.dir/build.make CMakeFiles/pcap_static.dir/build +.PHONY : pcap_static/fast + +#============================================================================= +# Target rules for targets named SerializeTarget + +# Build rule for target. +SerializeTarget: cmake_check_build_system + $(MAKE) -f CMakeFiles/Makefile2 SerializeTarget +.PHONY : SerializeTarget + +# fast build rule for target. +SerializeTarget/fast: + $(MAKE) -f CMakeFiles/SerializeTarget.dir/build.make CMakeFiles/SerializeTarget.dir/build +.PHONY : SerializeTarget/fast + +#============================================================================= +# Target rules for targets named testprogs + +# Build rule for target. +testprogs: cmake_check_build_system + $(MAKE) -f CMakeFiles/Makefile2 testprogs +.PHONY : testprogs + +# fast build rule for target. +testprogs/fast: + $(MAKE) -f testprogs/CMakeFiles/testprogs.dir/build.make testprogs/CMakeFiles/testprogs.dir/build +.PHONY : testprogs/fast + +#============================================================================= +# Target rules for targets named capturetest + +# Build rule for target. +capturetest: cmake_check_build_system + $(MAKE) -f CMakeFiles/Makefile2 capturetest +.PHONY : capturetest + +# fast build rule for target. +capturetest/fast: + $(MAKE) -f testprogs/CMakeFiles/capturetest.dir/build.make testprogs/CMakeFiles/capturetest.dir/build +.PHONY : capturetest/fast + +#============================================================================= +# Target rules for targets named findalldevstest + +# Build rule for target. +findalldevstest: cmake_check_build_system + $(MAKE) -f CMakeFiles/Makefile2 findalldevstest +.PHONY : findalldevstest + +# fast build rule for target. +findalldevstest/fast: + $(MAKE) -f testprogs/CMakeFiles/findalldevstest.dir/build.make testprogs/CMakeFiles/findalldevstest.dir/build +.PHONY : findalldevstest/fast + +#============================================================================= +# Target rules for targets named filtertest + +# Build rule for target. +filtertest: cmake_check_build_system + $(MAKE) -f CMakeFiles/Makefile2 filtertest +.PHONY : filtertest + +# fast build rule for target. +filtertest/fast: + $(MAKE) -f testprogs/CMakeFiles/filtertest.dir/build.make testprogs/CMakeFiles/filtertest.dir/build +.PHONY : filtertest/fast + +#============================================================================= +# Target rules for targets named findalldevstest-perf + +# Build rule for target. +findalldevstest-perf: cmake_check_build_system + $(MAKE) -f CMakeFiles/Makefile2 findalldevstest-perf +.PHONY : findalldevstest-perf + +# fast build rule for target. +findalldevstest-perf/fast: + $(MAKE) -f testprogs/CMakeFiles/findalldevstest-perf.dir/build.make testprogs/CMakeFiles/findalldevstest-perf.dir/build +.PHONY : findalldevstest-perf/fast + +#============================================================================= +# Target rules for targets named can_set_rfmon_test + +# Build rule for target. +can_set_rfmon_test: cmake_check_build_system + $(MAKE) -f CMakeFiles/Makefile2 can_set_rfmon_test +.PHONY : can_set_rfmon_test + +# fast build rule for target. +can_set_rfmon_test/fast: + $(MAKE) -f testprogs/CMakeFiles/can_set_rfmon_test.dir/build.make testprogs/CMakeFiles/can_set_rfmon_test.dir/build +.PHONY : can_set_rfmon_test/fast + +#============================================================================= +# Target rules for targets named opentest + +# Build rule for target. +opentest: cmake_check_build_system + $(MAKE) -f CMakeFiles/Makefile2 opentest +.PHONY : opentest + +# fast build rule for target. +opentest/fast: + $(MAKE) -f testprogs/CMakeFiles/opentest.dir/build.make testprogs/CMakeFiles/opentest.dir/build +.PHONY : opentest/fast + +#============================================================================= +# Target rules for targets named reactivatetest + +# Build rule for target. +reactivatetest: cmake_check_build_system + $(MAKE) -f CMakeFiles/Makefile2 reactivatetest +.PHONY : reactivatetest + +# fast build rule for target. +reactivatetest/fast: + $(MAKE) -f testprogs/CMakeFiles/reactivatetest.dir/build.make testprogs/CMakeFiles/reactivatetest.dir/build +.PHONY : reactivatetest/fast + +#============================================================================= +# Target rules for targets named writecaptest + +# Build rule for target. +writecaptest: cmake_check_build_system + $(MAKE) -f CMakeFiles/Makefile2 writecaptest +.PHONY : writecaptest + +# fast build rule for target. +writecaptest/fast: + $(MAKE) -f testprogs/CMakeFiles/writecaptest.dir/build.make testprogs/CMakeFiles/writecaptest.dir/build +.PHONY : writecaptest/fast + +#============================================================================= +# Target rules for targets named selpolltest + +# Build rule for target. +selpolltest: cmake_check_build_system + $(MAKE) -f CMakeFiles/Makefile2 selpolltest +.PHONY : selpolltest + +# fast build rule for target. +selpolltest/fast: + $(MAKE) -f testprogs/CMakeFiles/selpolltest.dir/build.make testprogs/CMakeFiles/selpolltest.dir/build +.PHONY : selpolltest/fast + +#============================================================================= +# Target rules for targets named threadsignaltest + +# Build rule for target. +threadsignaltest: cmake_check_build_system + $(MAKE) -f CMakeFiles/Makefile2 threadsignaltest +.PHONY : threadsignaltest + +# fast build rule for target. +threadsignaltest/fast: + $(MAKE) -f testprogs/CMakeFiles/threadsignaltest.dir/build.make testprogs/CMakeFiles/threadsignaltest.dir/build +.PHONY : threadsignaltest/fast + +#============================================================================= +# Target rules for targets named valgrindtest + +# Build rule for target. +valgrindtest: cmake_check_build_system + $(MAKE) -f CMakeFiles/Makefile2 valgrindtest +.PHONY : valgrindtest + +# fast build rule for target. +valgrindtest/fast: + $(MAKE) -f testprogs/CMakeFiles/valgrindtest.dir/build.make testprogs/CMakeFiles/valgrindtest.dir/build +.PHONY : valgrindtest/fast + +#============================================================================= +# Target rules for targets named fuzz_both + +# Build rule for target. +fuzz_both: cmake_check_build_system + $(MAKE) -f CMakeFiles/Makefile2 fuzz_both +.PHONY : fuzz_both + +# fast build rule for target. +fuzz_both/fast: + $(MAKE) -f testprogs/fuzz/CMakeFiles/fuzz_both.dir/build.make testprogs/fuzz/CMakeFiles/fuzz_both.dir/build +.PHONY : fuzz_both/fast + +#============================================================================= +# Target rules for targets named fuzz_filter + +# Build rule for target. +fuzz_filter: cmake_check_build_system + $(MAKE) -f CMakeFiles/Makefile2 fuzz_filter +.PHONY : fuzz_filter + +# fast build rule for target. +fuzz_filter/fast: + $(MAKE) -f testprogs/fuzz/CMakeFiles/fuzz_filter.dir/build.make testprogs/fuzz/CMakeFiles/fuzz_filter.dir/build +.PHONY : fuzz_filter/fast + +#============================================================================= +# Target rules for targets named fuzz_pcap + +# Build rule for target. +fuzz_pcap: cmake_check_build_system + $(MAKE) -f CMakeFiles/Makefile2 fuzz_pcap +.PHONY : fuzz_pcap + +# fast build rule for target. +fuzz_pcap/fast: + $(MAKE) -f testprogs/fuzz/CMakeFiles/fuzz_pcap.dir/build.make testprogs/fuzz/CMakeFiles/fuzz_pcap.dir/build +.PHONY : fuzz_pcap/fast + +bpf_dump.o: bpf_dump.c.o + +.PHONY : bpf_dump.o + +# target to build an object file +bpf_dump.c.o: + $(MAKE) -f CMakeFiles/pcap.dir/build.make CMakeFiles/pcap.dir/bpf_dump.c.o + $(MAKE) -f CMakeFiles/pcap_static.dir/build.make CMakeFiles/pcap_static.dir/bpf_dump.c.o +.PHONY : bpf_dump.c.o + +bpf_dump.i: bpf_dump.c.i + +.PHONY : bpf_dump.i + +# target to preprocess a source file +bpf_dump.c.i: + $(MAKE) -f CMakeFiles/pcap.dir/build.make CMakeFiles/pcap.dir/bpf_dump.c.i + $(MAKE) -f CMakeFiles/pcap_static.dir/build.make CMakeFiles/pcap_static.dir/bpf_dump.c.i +.PHONY : bpf_dump.c.i + +bpf_dump.s: bpf_dump.c.s + +.PHONY : bpf_dump.s + +# target to generate assembly for a file +bpf_dump.c.s: + $(MAKE) -f CMakeFiles/pcap.dir/build.make CMakeFiles/pcap.dir/bpf_dump.c.s + $(MAKE) -f CMakeFiles/pcap_static.dir/build.make CMakeFiles/pcap_static.dir/bpf_dump.c.s +.PHONY : bpf_dump.c.s + +bpf_filter.o: bpf_filter.c.o + +.PHONY : bpf_filter.o + +# target to build an object file +bpf_filter.c.o: + $(MAKE) -f CMakeFiles/pcap.dir/build.make CMakeFiles/pcap.dir/bpf_filter.c.o + $(MAKE) -f CMakeFiles/pcap_static.dir/build.make CMakeFiles/pcap_static.dir/bpf_filter.c.o +.PHONY : bpf_filter.c.o + +bpf_filter.i: bpf_filter.c.i + +.PHONY : bpf_filter.i + +# target to preprocess a source file +bpf_filter.c.i: + $(MAKE) -f CMakeFiles/pcap.dir/build.make CMakeFiles/pcap.dir/bpf_filter.c.i + $(MAKE) -f CMakeFiles/pcap_static.dir/build.make CMakeFiles/pcap_static.dir/bpf_filter.c.i +.PHONY : bpf_filter.c.i + +bpf_filter.s: bpf_filter.c.s + +.PHONY : bpf_filter.s + +# target to generate assembly for a file +bpf_filter.c.s: + $(MAKE) -f CMakeFiles/pcap.dir/build.make CMakeFiles/pcap.dir/bpf_filter.c.s + $(MAKE) -f CMakeFiles/pcap_static.dir/build.make CMakeFiles/pcap_static.dir/bpf_filter.c.s +.PHONY : bpf_filter.c.s + +bpf_image.o: bpf_image.c.o + +.PHONY : bpf_image.o + +# target to build an object file +bpf_image.c.o: + $(MAKE) -f CMakeFiles/pcap.dir/build.make CMakeFiles/pcap.dir/bpf_image.c.o + $(MAKE) -f CMakeFiles/pcap_static.dir/build.make CMakeFiles/pcap_static.dir/bpf_image.c.o +.PHONY : bpf_image.c.o + +bpf_image.i: bpf_image.c.i + +.PHONY : bpf_image.i + +# target to preprocess a source file +bpf_image.c.i: + $(MAKE) -f CMakeFiles/pcap.dir/build.make CMakeFiles/pcap.dir/bpf_image.c.i + $(MAKE) -f CMakeFiles/pcap_static.dir/build.make CMakeFiles/pcap_static.dir/bpf_image.c.i +.PHONY : bpf_image.c.i + +bpf_image.s: bpf_image.c.s + +.PHONY : bpf_image.s + +# target to generate assembly for a file +bpf_image.c.s: + $(MAKE) -f CMakeFiles/pcap.dir/build.make CMakeFiles/pcap.dir/bpf_image.c.s + $(MAKE) -f CMakeFiles/pcap_static.dir/build.make CMakeFiles/pcap_static.dir/bpf_image.c.s +.PHONY : bpf_image.c.s + +etherent.o: etherent.c.o + +.PHONY : etherent.o + +# target to build an object file +etherent.c.o: + $(MAKE) -f CMakeFiles/pcap.dir/build.make CMakeFiles/pcap.dir/etherent.c.o + $(MAKE) -f CMakeFiles/pcap_static.dir/build.make CMakeFiles/pcap_static.dir/etherent.c.o +.PHONY : etherent.c.o + +etherent.i: etherent.c.i + +.PHONY : etherent.i + +# target to preprocess a source file +etherent.c.i: + $(MAKE) -f CMakeFiles/pcap.dir/build.make CMakeFiles/pcap.dir/etherent.c.i + $(MAKE) -f CMakeFiles/pcap_static.dir/build.make CMakeFiles/pcap_static.dir/etherent.c.i +.PHONY : etherent.c.i + +etherent.s: etherent.c.s + +.PHONY : etherent.s + +# target to generate assembly for a file +etherent.c.s: + $(MAKE) -f CMakeFiles/pcap.dir/build.make CMakeFiles/pcap.dir/etherent.c.s + $(MAKE) -f CMakeFiles/pcap_static.dir/build.make CMakeFiles/pcap_static.dir/etherent.c.s +.PHONY : etherent.c.s + +fad-getad.o: fad-getad.c.o + +.PHONY : fad-getad.o + +# target to build an object file +fad-getad.c.o: + $(MAKE) -f CMakeFiles/pcap.dir/build.make CMakeFiles/pcap.dir/fad-getad.c.o + $(MAKE) -f CMakeFiles/pcap_static.dir/build.make CMakeFiles/pcap_static.dir/fad-getad.c.o +.PHONY : fad-getad.c.o + +fad-getad.i: fad-getad.c.i + +.PHONY : fad-getad.i + +# target to preprocess a source file +fad-getad.c.i: + $(MAKE) -f CMakeFiles/pcap.dir/build.make CMakeFiles/pcap.dir/fad-getad.c.i + $(MAKE) -f CMakeFiles/pcap_static.dir/build.make CMakeFiles/pcap_static.dir/fad-getad.c.i +.PHONY : fad-getad.c.i + +fad-getad.s: fad-getad.c.s + +.PHONY : fad-getad.s + +# target to generate assembly for a file +fad-getad.c.s: + $(MAKE) -f CMakeFiles/pcap.dir/build.make CMakeFiles/pcap.dir/fad-getad.c.s + $(MAKE) -f CMakeFiles/pcap_static.dir/build.make CMakeFiles/pcap_static.dir/fad-getad.c.s +.PHONY : fad-getad.c.s + +fmtutils.o: fmtutils.c.o + +.PHONY : fmtutils.o + +# target to build an object file +fmtutils.c.o: + $(MAKE) -f CMakeFiles/pcap.dir/build.make CMakeFiles/pcap.dir/fmtutils.c.o + $(MAKE) -f CMakeFiles/pcap_static.dir/build.make CMakeFiles/pcap_static.dir/fmtutils.c.o +.PHONY : fmtutils.c.o + +fmtutils.i: fmtutils.c.i + +.PHONY : fmtutils.i + +# target to preprocess a source file +fmtutils.c.i: + $(MAKE) -f CMakeFiles/pcap.dir/build.make CMakeFiles/pcap.dir/fmtutils.c.i + $(MAKE) -f CMakeFiles/pcap_static.dir/build.make CMakeFiles/pcap_static.dir/fmtutils.c.i +.PHONY : fmtutils.c.i + +fmtutils.s: fmtutils.c.s + +.PHONY : fmtutils.s + +# target to generate assembly for a file +fmtutils.c.s: + $(MAKE) -f CMakeFiles/pcap.dir/build.make CMakeFiles/pcap.dir/fmtutils.c.s + $(MAKE) -f CMakeFiles/pcap_static.dir/build.make CMakeFiles/pcap_static.dir/fmtutils.c.s +.PHONY : fmtutils.c.s + +gencode.o: gencode.c.o + +.PHONY : gencode.o + +# target to build an object file +gencode.c.o: + $(MAKE) -f CMakeFiles/pcap.dir/build.make CMakeFiles/pcap.dir/gencode.c.o + $(MAKE) -f CMakeFiles/pcap_static.dir/build.make CMakeFiles/pcap_static.dir/gencode.c.o +.PHONY : gencode.c.o + +gencode.i: gencode.c.i + +.PHONY : gencode.i + +# target to preprocess a source file +gencode.c.i: + $(MAKE) -f CMakeFiles/pcap.dir/build.make CMakeFiles/pcap.dir/gencode.c.i + $(MAKE) -f CMakeFiles/pcap_static.dir/build.make CMakeFiles/pcap_static.dir/gencode.c.i +.PHONY : gencode.c.i + +gencode.s: gencode.c.s + +.PHONY : gencode.s + +# target to generate assembly for a file +gencode.c.s: + $(MAKE) -f CMakeFiles/pcap.dir/build.make CMakeFiles/pcap.dir/gencode.c.s + $(MAKE) -f CMakeFiles/pcap_static.dir/build.make CMakeFiles/pcap_static.dir/gencode.c.s +.PHONY : gencode.c.s + +grammar.o: grammar.c.o + +.PHONY : grammar.o + +# target to build an object file +grammar.c.o: + $(MAKE) -f CMakeFiles/pcap.dir/build.make CMakeFiles/pcap.dir/grammar.c.o + $(MAKE) -f CMakeFiles/pcap_static.dir/build.make CMakeFiles/pcap_static.dir/grammar.c.o +.PHONY : grammar.c.o + +grammar.i: grammar.c.i + +.PHONY : grammar.i + +# target to preprocess a source file +grammar.c.i: + $(MAKE) -f CMakeFiles/pcap.dir/build.make CMakeFiles/pcap.dir/grammar.c.i + $(MAKE) -f CMakeFiles/pcap_static.dir/build.make CMakeFiles/pcap_static.dir/grammar.c.i +.PHONY : grammar.c.i + +grammar.s: grammar.c.s + +.PHONY : grammar.s + +# target to generate assembly for a file +grammar.c.s: + $(MAKE) -f CMakeFiles/pcap.dir/build.make CMakeFiles/pcap.dir/grammar.c.s + $(MAKE) -f CMakeFiles/pcap_static.dir/build.make CMakeFiles/pcap_static.dir/grammar.c.s +.PHONY : grammar.c.s + +missing/strlcat.o: missing/strlcat.c.o + +.PHONY : missing/strlcat.o + +# target to build an object file +missing/strlcat.c.o: + $(MAKE) -f CMakeFiles/pcap.dir/build.make CMakeFiles/pcap.dir/missing/strlcat.c.o + $(MAKE) -f CMakeFiles/pcap_static.dir/build.make CMakeFiles/pcap_static.dir/missing/strlcat.c.o +.PHONY : missing/strlcat.c.o + +missing/strlcat.i: missing/strlcat.c.i + +.PHONY : missing/strlcat.i + +# target to preprocess a source file +missing/strlcat.c.i: + $(MAKE) -f CMakeFiles/pcap.dir/build.make CMakeFiles/pcap.dir/missing/strlcat.c.i + $(MAKE) -f CMakeFiles/pcap_static.dir/build.make CMakeFiles/pcap_static.dir/missing/strlcat.c.i +.PHONY : missing/strlcat.c.i + +missing/strlcat.s: missing/strlcat.c.s + +.PHONY : missing/strlcat.s + +# target to generate assembly for a file +missing/strlcat.c.s: + $(MAKE) -f CMakeFiles/pcap.dir/build.make CMakeFiles/pcap.dir/missing/strlcat.c.s + $(MAKE) -f CMakeFiles/pcap_static.dir/build.make CMakeFiles/pcap_static.dir/missing/strlcat.c.s +.PHONY : missing/strlcat.c.s + +missing/strlcpy.o: missing/strlcpy.c.o + +.PHONY : missing/strlcpy.o + +# target to build an object file +missing/strlcpy.c.o: + $(MAKE) -f CMakeFiles/pcap.dir/build.make CMakeFiles/pcap.dir/missing/strlcpy.c.o + $(MAKE) -f CMakeFiles/pcap_static.dir/build.make CMakeFiles/pcap_static.dir/missing/strlcpy.c.o +.PHONY : missing/strlcpy.c.o + +missing/strlcpy.i: missing/strlcpy.c.i + +.PHONY : missing/strlcpy.i + +# target to preprocess a source file +missing/strlcpy.c.i: + $(MAKE) -f CMakeFiles/pcap.dir/build.make CMakeFiles/pcap.dir/missing/strlcpy.c.i + $(MAKE) -f CMakeFiles/pcap_static.dir/build.make CMakeFiles/pcap_static.dir/missing/strlcpy.c.i +.PHONY : missing/strlcpy.c.i + +missing/strlcpy.s: missing/strlcpy.c.s + +.PHONY : missing/strlcpy.s + +# target to generate assembly for a file +missing/strlcpy.c.s: + $(MAKE) -f CMakeFiles/pcap.dir/build.make CMakeFiles/pcap.dir/missing/strlcpy.c.s + $(MAKE) -f CMakeFiles/pcap_static.dir/build.make CMakeFiles/pcap_static.dir/missing/strlcpy.c.s +.PHONY : missing/strlcpy.c.s + +nametoaddr.o: nametoaddr.c.o + +.PHONY : nametoaddr.o + +# target to build an object file +nametoaddr.c.o: + $(MAKE) -f CMakeFiles/pcap.dir/build.make CMakeFiles/pcap.dir/nametoaddr.c.o + $(MAKE) -f CMakeFiles/pcap_static.dir/build.make CMakeFiles/pcap_static.dir/nametoaddr.c.o +.PHONY : nametoaddr.c.o + +nametoaddr.i: nametoaddr.c.i + +.PHONY : nametoaddr.i + +# target to preprocess a source file +nametoaddr.c.i: + $(MAKE) -f CMakeFiles/pcap.dir/build.make CMakeFiles/pcap.dir/nametoaddr.c.i + $(MAKE) -f CMakeFiles/pcap_static.dir/build.make CMakeFiles/pcap_static.dir/nametoaddr.c.i +.PHONY : nametoaddr.c.i + +nametoaddr.s: nametoaddr.c.s + +.PHONY : nametoaddr.s + +# target to generate assembly for a file +nametoaddr.c.s: + $(MAKE) -f CMakeFiles/pcap.dir/build.make CMakeFiles/pcap.dir/nametoaddr.c.s + $(MAKE) -f CMakeFiles/pcap_static.dir/build.make CMakeFiles/pcap_static.dir/nametoaddr.c.s +.PHONY : nametoaddr.c.s + +optimize.o: optimize.c.o + +.PHONY : optimize.o + +# target to build an object file +optimize.c.o: + $(MAKE) -f CMakeFiles/pcap.dir/build.make CMakeFiles/pcap.dir/optimize.c.o + $(MAKE) -f CMakeFiles/pcap_static.dir/build.make CMakeFiles/pcap_static.dir/optimize.c.o +.PHONY : optimize.c.o + +optimize.i: optimize.c.i + +.PHONY : optimize.i + +# target to preprocess a source file +optimize.c.i: + $(MAKE) -f CMakeFiles/pcap.dir/build.make CMakeFiles/pcap.dir/optimize.c.i + $(MAKE) -f CMakeFiles/pcap_static.dir/build.make CMakeFiles/pcap_static.dir/optimize.c.i +.PHONY : optimize.c.i + +optimize.s: optimize.c.s + +.PHONY : optimize.s + +# target to generate assembly for a file +optimize.c.s: + $(MAKE) -f CMakeFiles/pcap.dir/build.make CMakeFiles/pcap.dir/optimize.c.s + $(MAKE) -f CMakeFiles/pcap_static.dir/build.make CMakeFiles/pcap_static.dir/optimize.c.s +.PHONY : optimize.c.s + +pcap-common.o: pcap-common.c.o + +.PHONY : pcap-common.o + +# target to build an object file +pcap-common.c.o: + $(MAKE) -f CMakeFiles/pcap.dir/build.make CMakeFiles/pcap.dir/pcap-common.c.o + $(MAKE) -f CMakeFiles/pcap_static.dir/build.make CMakeFiles/pcap_static.dir/pcap-common.c.o +.PHONY : pcap-common.c.o + +pcap-common.i: pcap-common.c.i + +.PHONY : pcap-common.i + +# target to preprocess a source file +pcap-common.c.i: + $(MAKE) -f CMakeFiles/pcap.dir/build.make CMakeFiles/pcap.dir/pcap-common.c.i + $(MAKE) -f CMakeFiles/pcap_static.dir/build.make CMakeFiles/pcap_static.dir/pcap-common.c.i +.PHONY : pcap-common.c.i + +pcap-common.s: pcap-common.c.s + +.PHONY : pcap-common.s + +# target to generate assembly for a file +pcap-common.c.s: + $(MAKE) -f CMakeFiles/pcap.dir/build.make CMakeFiles/pcap.dir/pcap-common.c.s + $(MAKE) -f CMakeFiles/pcap_static.dir/build.make CMakeFiles/pcap_static.dir/pcap-common.c.s +.PHONY : pcap-common.c.s + +pcap-linux.o: pcap-linux.c.o + +.PHONY : pcap-linux.o + +# target to build an object file +pcap-linux.c.o: + $(MAKE) -f CMakeFiles/pcap.dir/build.make CMakeFiles/pcap.dir/pcap-linux.c.o + $(MAKE) -f CMakeFiles/pcap_static.dir/build.make CMakeFiles/pcap_static.dir/pcap-linux.c.o +.PHONY : pcap-linux.c.o + +pcap-linux.i: pcap-linux.c.i + +.PHONY : pcap-linux.i + +# target to preprocess a source file +pcap-linux.c.i: + $(MAKE) -f CMakeFiles/pcap.dir/build.make CMakeFiles/pcap.dir/pcap-linux.c.i + $(MAKE) -f CMakeFiles/pcap_static.dir/build.make CMakeFiles/pcap_static.dir/pcap-linux.c.i +.PHONY : pcap-linux.c.i + +pcap-linux.s: pcap-linux.c.s + +.PHONY : pcap-linux.s + +# target to generate assembly for a file +pcap-linux.c.s: + $(MAKE) -f CMakeFiles/pcap.dir/build.make CMakeFiles/pcap.dir/pcap-linux.c.s + $(MAKE) -f CMakeFiles/pcap_static.dir/build.make CMakeFiles/pcap_static.dir/pcap-linux.c.s +.PHONY : pcap-linux.c.s + +pcap-netfilter-linux.o: pcap-netfilter-linux.c.o + +.PHONY : pcap-netfilter-linux.o + +# target to build an object file +pcap-netfilter-linux.c.o: + $(MAKE) -f CMakeFiles/pcap.dir/build.make CMakeFiles/pcap.dir/pcap-netfilter-linux.c.o + $(MAKE) -f CMakeFiles/pcap_static.dir/build.make CMakeFiles/pcap_static.dir/pcap-netfilter-linux.c.o +.PHONY : pcap-netfilter-linux.c.o + +pcap-netfilter-linux.i: pcap-netfilter-linux.c.i + +.PHONY : pcap-netfilter-linux.i + +# target to preprocess a source file +pcap-netfilter-linux.c.i: + $(MAKE) -f CMakeFiles/pcap.dir/build.make CMakeFiles/pcap.dir/pcap-netfilter-linux.c.i + $(MAKE) -f CMakeFiles/pcap_static.dir/build.make CMakeFiles/pcap_static.dir/pcap-netfilter-linux.c.i +.PHONY : pcap-netfilter-linux.c.i + +pcap-netfilter-linux.s: pcap-netfilter-linux.c.s + +.PHONY : pcap-netfilter-linux.s + +# target to generate assembly for a file +pcap-netfilter-linux.c.s: + $(MAKE) -f CMakeFiles/pcap.dir/build.make CMakeFiles/pcap.dir/pcap-netfilter-linux.c.s + $(MAKE) -f CMakeFiles/pcap_static.dir/build.make CMakeFiles/pcap_static.dir/pcap-netfilter-linux.c.s +.PHONY : pcap-netfilter-linux.c.s + +pcap-usb-linux.o: pcap-usb-linux.c.o + +.PHONY : pcap-usb-linux.o + +# target to build an object file +pcap-usb-linux.c.o: + $(MAKE) -f CMakeFiles/pcap.dir/build.make CMakeFiles/pcap.dir/pcap-usb-linux.c.o + $(MAKE) -f CMakeFiles/pcap_static.dir/build.make CMakeFiles/pcap_static.dir/pcap-usb-linux.c.o +.PHONY : pcap-usb-linux.c.o + +pcap-usb-linux.i: pcap-usb-linux.c.i + +.PHONY : pcap-usb-linux.i + +# target to preprocess a source file +pcap-usb-linux.c.i: + $(MAKE) -f CMakeFiles/pcap.dir/build.make CMakeFiles/pcap.dir/pcap-usb-linux.c.i + $(MAKE) -f CMakeFiles/pcap_static.dir/build.make CMakeFiles/pcap_static.dir/pcap-usb-linux.c.i +.PHONY : pcap-usb-linux.c.i + +pcap-usb-linux.s: pcap-usb-linux.c.s + +.PHONY : pcap-usb-linux.s + +# target to generate assembly for a file +pcap-usb-linux.c.s: + $(MAKE) -f CMakeFiles/pcap.dir/build.make CMakeFiles/pcap.dir/pcap-usb-linux.c.s + $(MAKE) -f CMakeFiles/pcap_static.dir/build.make CMakeFiles/pcap_static.dir/pcap-usb-linux.c.s +.PHONY : pcap-usb-linux.c.s + +pcap.o: pcap.c.o + +.PHONY : pcap.o + +# target to build an object file +pcap.c.o: + $(MAKE) -f CMakeFiles/pcap.dir/build.make CMakeFiles/pcap.dir/pcap.c.o + $(MAKE) -f CMakeFiles/pcap_static.dir/build.make CMakeFiles/pcap_static.dir/pcap.c.o +.PHONY : pcap.c.o + +pcap.i: pcap.c.i + +.PHONY : pcap.i + +# target to preprocess a source file +pcap.c.i: + $(MAKE) -f CMakeFiles/pcap.dir/build.make CMakeFiles/pcap.dir/pcap.c.i + $(MAKE) -f CMakeFiles/pcap_static.dir/build.make CMakeFiles/pcap_static.dir/pcap.c.i +.PHONY : pcap.c.i + +pcap.s: pcap.c.s + +.PHONY : pcap.s + +# target to generate assembly for a file +pcap.c.s: + $(MAKE) -f CMakeFiles/pcap.dir/build.make CMakeFiles/pcap.dir/pcap.c.s + $(MAKE) -f CMakeFiles/pcap_static.dir/build.make CMakeFiles/pcap_static.dir/pcap.c.s +.PHONY : pcap.c.s + +savefile.o: savefile.c.o + +.PHONY : savefile.o + +# target to build an object file +savefile.c.o: + $(MAKE) -f CMakeFiles/pcap.dir/build.make CMakeFiles/pcap.dir/savefile.c.o + $(MAKE) -f CMakeFiles/pcap_static.dir/build.make CMakeFiles/pcap_static.dir/savefile.c.o +.PHONY : savefile.c.o + +savefile.i: savefile.c.i + +.PHONY : savefile.i + +# target to preprocess a source file +savefile.c.i: + $(MAKE) -f CMakeFiles/pcap.dir/build.make CMakeFiles/pcap.dir/savefile.c.i + $(MAKE) -f CMakeFiles/pcap_static.dir/build.make CMakeFiles/pcap_static.dir/savefile.c.i +.PHONY : savefile.c.i + +savefile.s: savefile.c.s + +.PHONY : savefile.s + +# target to generate assembly for a file +savefile.c.s: + $(MAKE) -f CMakeFiles/pcap.dir/build.make CMakeFiles/pcap.dir/savefile.c.s + $(MAKE) -f CMakeFiles/pcap_static.dir/build.make CMakeFiles/pcap_static.dir/savefile.c.s +.PHONY : savefile.c.s + +scanner.o: scanner.c.o + +.PHONY : scanner.o + +# target to build an object file +scanner.c.o: + $(MAKE) -f CMakeFiles/pcap.dir/build.make CMakeFiles/pcap.dir/scanner.c.o + $(MAKE) -f CMakeFiles/pcap_static.dir/build.make CMakeFiles/pcap_static.dir/scanner.c.o +.PHONY : scanner.c.o + +scanner.i: scanner.c.i + +.PHONY : scanner.i + +# target to preprocess a source file +scanner.c.i: + $(MAKE) -f CMakeFiles/pcap.dir/build.make CMakeFiles/pcap.dir/scanner.c.i + $(MAKE) -f CMakeFiles/pcap_static.dir/build.make CMakeFiles/pcap_static.dir/scanner.c.i +.PHONY : scanner.c.i + +scanner.s: scanner.c.s + +.PHONY : scanner.s + +# target to generate assembly for a file +scanner.c.s: + $(MAKE) -f CMakeFiles/pcap.dir/build.make CMakeFiles/pcap.dir/scanner.c.s + $(MAKE) -f CMakeFiles/pcap_static.dir/build.make CMakeFiles/pcap_static.dir/scanner.c.s +.PHONY : scanner.c.s + +sf-pcap.o: sf-pcap.c.o + +.PHONY : sf-pcap.o + +# target to build an object file +sf-pcap.c.o: + $(MAKE) -f CMakeFiles/pcap.dir/build.make CMakeFiles/pcap.dir/sf-pcap.c.o + $(MAKE) -f CMakeFiles/pcap_static.dir/build.make CMakeFiles/pcap_static.dir/sf-pcap.c.o +.PHONY : sf-pcap.c.o + +sf-pcap.i: sf-pcap.c.i + +.PHONY : sf-pcap.i + +# target to preprocess a source file +sf-pcap.c.i: + $(MAKE) -f CMakeFiles/pcap.dir/build.make CMakeFiles/pcap.dir/sf-pcap.c.i + $(MAKE) -f CMakeFiles/pcap_static.dir/build.make CMakeFiles/pcap_static.dir/sf-pcap.c.i +.PHONY : sf-pcap.c.i + +sf-pcap.s: sf-pcap.c.s + +.PHONY : sf-pcap.s + +# target to generate assembly for a file +sf-pcap.c.s: + $(MAKE) -f CMakeFiles/pcap.dir/build.make CMakeFiles/pcap.dir/sf-pcap.c.s + $(MAKE) -f CMakeFiles/pcap_static.dir/build.make CMakeFiles/pcap_static.dir/sf-pcap.c.s +.PHONY : sf-pcap.c.s + +sf-pcapng.o: sf-pcapng.c.o + +.PHONY : sf-pcapng.o + +# target to build an object file +sf-pcapng.c.o: + $(MAKE) -f CMakeFiles/pcap.dir/build.make CMakeFiles/pcap.dir/sf-pcapng.c.o + $(MAKE) -f CMakeFiles/pcap_static.dir/build.make CMakeFiles/pcap_static.dir/sf-pcapng.c.o +.PHONY : sf-pcapng.c.o + +sf-pcapng.i: sf-pcapng.c.i + +.PHONY : sf-pcapng.i + +# target to preprocess a source file +sf-pcapng.c.i: + $(MAKE) -f CMakeFiles/pcap.dir/build.make CMakeFiles/pcap.dir/sf-pcapng.c.i + $(MAKE) -f CMakeFiles/pcap_static.dir/build.make CMakeFiles/pcap_static.dir/sf-pcapng.c.i +.PHONY : sf-pcapng.c.i + +sf-pcapng.s: sf-pcapng.c.s + +.PHONY : sf-pcapng.s + +# target to generate assembly for a file +sf-pcapng.c.s: + $(MAKE) -f CMakeFiles/pcap.dir/build.make CMakeFiles/pcap.dir/sf-pcapng.c.s + $(MAKE) -f CMakeFiles/pcap_static.dir/build.make CMakeFiles/pcap_static.dir/sf-pcapng.c.s +.PHONY : sf-pcapng.c.s + +# Help Target +help: + @echo "The following are some of the valid targets for this Makefile:" + @echo "... all (the default if no target is provided)" + @echo "... clean" + @echo "... depend" + @echo "... install/strip" + @echo "... install/local" + @echo "... install" + @echo "... list_install_components" + @echo "... rebuild_cache" + @echo "... edit_cache" + @echo "... pcap" + @echo "... uninstall" + @echo "... pcap_static" + @echo "... SerializeTarget" + @echo "... testprogs" + @echo "... capturetest" + @echo "... findalldevstest" + @echo "... filtertest" + @echo "... findalldevstest-perf" + @echo "... can_set_rfmon_test" + @echo "... opentest" + @echo "... reactivatetest" + @echo "... writecaptest" + @echo "... selpolltest" + @echo "... threadsignaltest" + @echo "... valgrindtest" + @echo "... fuzz_both" + @echo "... fuzz_filter" + @echo "... fuzz_pcap" + @echo "... bpf_dump.o" + @echo "... bpf_dump.i" + @echo "... bpf_dump.s" + @echo "... bpf_filter.o" + @echo "... bpf_filter.i" + @echo "... bpf_filter.s" + @echo "... bpf_image.o" + @echo "... bpf_image.i" + @echo "... bpf_image.s" + @echo "... etherent.o" + @echo "... etherent.i" + @echo "... etherent.s" + @echo "... fad-getad.o" + @echo "... fad-getad.i" + @echo "... fad-getad.s" + @echo "... fmtutils.o" + @echo "... fmtutils.i" + @echo "... fmtutils.s" + @echo "... gencode.o" + @echo "... gencode.i" + @echo "... gencode.s" + @echo "... grammar.o" + @echo "... grammar.i" + @echo "... grammar.s" + @echo "... missing/strlcat.o" + @echo "... missing/strlcat.i" + @echo "... missing/strlcat.s" + @echo "... missing/strlcpy.o" + @echo "... missing/strlcpy.i" + @echo "... missing/strlcpy.s" + @echo "... nametoaddr.o" + @echo "... nametoaddr.i" + @echo "... nametoaddr.s" + @echo "... optimize.o" + @echo "... optimize.i" + @echo "... optimize.s" + @echo "... pcap-common.o" + @echo "... pcap-common.i" + @echo "... pcap-common.s" + @echo "... pcap-linux.o" + @echo "... pcap-linux.i" + @echo "... pcap-linux.s" + @echo "... pcap-netfilter-linux.o" + @echo "... pcap-netfilter-linux.i" + @echo "... pcap-netfilter-linux.s" + @echo "... pcap-usb-linux.o" + @echo "... pcap-usb-linux.i" + @echo "... pcap-usb-linux.s" + @echo "... pcap.o" + @echo "... pcap.i" + @echo "... pcap.s" + @echo "... savefile.o" + @echo "... savefile.i" + @echo "... savefile.s" + @echo "... scanner.o" + @echo "... scanner.i" + @echo "... scanner.s" + @echo "... sf-pcap.o" + @echo "... sf-pcap.i" + @echo "... sf-pcap.s" + @echo "... sf-pcapng.o" + @echo "... sf-pcapng.i" + @echo "... sf-pcapng.s" +.PHONY : help + + + +#============================================================================= +# Special targets to cleanup operation of make. + +# Special rule to run CMake to check the build system integrity. +# No rule that depends on this can have commands that come from listfiles +# because they might be regenerated. +cmake_check_build_system: + $(CMAKE_COMMAND) -S$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles/Makefile.cmake 0 +.PHONY : cmake_check_build_system + diff --git a/frida_mode/test/libpcap/aflpp_qemu_driver_hook.c b/frida_mode/test/libpcap/aflpp_qemu_driver_hook.c new file mode 100644 index 00000000..059d438d --- /dev/null +++ b/frida_mode/test/libpcap/aflpp_qemu_driver_hook.c @@ -0,0 +1,97 @@ +#include +#include + +#if defined(__x86_64__) + +struct x86_64_regs { + + uint64_t rax, rbx, rcx, rdx, rdi, rsi, rbp, r8, r9, r10, r11, r12, r13, r14, + r15; + + union { + + uint64_t rip; + uint64_t pc; + + }; + + union { + + uint64_t rsp; + uint64_t sp; + + }; + + union { + + uint64_t rflags; + uint64_t flags; + + }; + + uint8_t zmm_regs[32][64]; + +}; + +void afl_persistent_hook(struct x86_64_regs *regs, uint64_t guest_base, + uint8_t *input_buf, uint32_t input_buf_len) { + + memcpy((void *)regs->rdi, input_buf, input_buf_len); + regs->rsi = input_buf_len; + +} + +#elif defined(__i386__) + +struct x86_regs { + + uint32_t eax, ebx, ecx, edx, edi, esi, ebp; + + union { + + uint32_t eip; + uint32_t pc; + + }; + + union { + + uint32_t esp; + uint32_t sp; + + }; + + union { + + uint32_t eflags; + uint32_t flags; + + }; + + uint8_t xmm_regs[8][16]; + +}; + +void afl_persistent_hook(struct x86_regs *regs, uint64_t guest_base, + uint8_t *input_buf, uint32_t input_buf_len) { + + void **esp = (void **)regs->esp; + void * arg1 = esp[1]; + void **arg2 = &esp[2]; + memcpy(arg1, input_buf, input_buf_len); + *arg2 = (void *)input_buf_len; + +} + +#else + #pragma error "Unsupported architecture" +#endif + +int afl_persistent_hook_init(void) { + + // 1 for shared memory input (faster), 0 for normal input (you have to use + // read(), input_buf will be NULL) + return 1; + +} + diff --git a/frida_mode/test/libpcap/get_symbol_addr.py b/frida_mode/test/libpcap/get_symbol_addr.py new file mode 100755 index 00000000..1c46e010 --- /dev/null +++ b/frida_mode/test/libpcap/get_symbol_addr.py @@ -0,0 +1,36 @@ +#!/usr/bin/python3 +import argparse +from elftools.elf.elffile import ELFFile + +def process_file(file, symbol, base): + with open(file, 'rb') as f: + elf = ELFFile(f) + symtab = elf.get_section_by_name('.symtab') + mains = symtab.get_symbol_by_name(symbol) + if len(mains) != 1: + print ("Failed to find main") + return 1 + + main_addr = mains[0]['st_value'] + main = base + main_addr + print ("0x%016x" % main) + return 0 + +def hex_value(x): + return int(x, 16) + +def main(): + parser = argparse.ArgumentParser(description='Process some integers.') + parser.add_argument('-f', '--file', dest='file', type=str, + help='elf file name', required=True) + parser.add_argument('-s', '--symbol', dest='symbol', type=str, + help='symbol name', required=True) + parser.add_argument('-b', '--base', dest='base', type=hex_value, + help='elf base address', required=True) + + args = parser.parse_args() + return process_file (args.file, args.symbol, args.base) + +if __name__ == "__main__": + ret = main() + exit(ret) diff --git a/frida_mode/test/output/GNUmakefile b/frida_mode/test/output/GNUmakefile new file mode 100644 index 00000000..eaa1c4dc --- /dev/null +++ b/frida_mode/test/output/GNUmakefile @@ -0,0 +1,47 @@ +PWD:=$(shell pwd)/ +ROOT:=$(shell realpath $(PWD)../../..)/ +BUILD_DIR:=$(PWD)build/ +TESTINSTR_DATA_DIR:=$(BUILD_DIR)in/ +TESTINSTR_DATA_FILE:=$(TESTINSTR_DATA_DIR)in + +TESTINSTBIN:=$(BUILD_DIR)testinstr +TESTINSTSRC:=$(PWD)testinstr.c + +QEMU_OUT:=$(BUILD_DIR)qemu-out +FRIDA_OUT:=$(BUILD_DIR)frida-out + +.PHONY: all 32 clean qemu frida + +all: $(TESTINSTBIN) + make -C $(ROOT)frida_mode/ + +32: + CFLAGS="-m32" LDFLAGS="-m32" ARCH="x86" make all + +$(BUILD_DIR): + mkdir -p $@ + +$(TESTINSTR_DATA_DIR): | $(BUILD_DIR) + mkdir -p $@ + +$(TESTINSTR_DATA_FILE): | $(TESTINSTR_DATA_DIR) + echo -n "000" > $@ + +$(TESTINSTBIN): $(TESTINSTSRC) | $(BUILD_DIR) + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< + +clean: + rm -rf $(BUILD_DIR) + +frida: $(TESTINSTBIN) $(TESTINSTR_DATA_FILE) + AFL_FRIDA_OUTPUT_STDOUT=frida_stdout.txt \ + AFL_FRIDA_OUTPUT_STDERR=frida_stderr.txt \ + AFL_FRIDA_STATS_FILE=frida_stats.txt \ + AFL_FRIDA_STATS_INTERVAL=1 \ + $(ROOT)afl-fuzz \ + -D \ + -O \ + -i $(TESTINSTR_DATA_DIR) \ + -o $(FRIDA_OUT) \ + -- \ + $(TESTINSTBIN) @@ diff --git a/frida_mode/test/output/Makefile b/frida_mode/test/output/Makefile new file mode 100644 index 00000000..07b139e9 --- /dev/null +++ b/frida_mode/test/output/Makefile @@ -0,0 +1,13 @@ +all: + @echo trying to use GNU make... + @gmake all || echo please install GNUmake + +32: + @echo trying to use GNU make... + @gmake 32 || echo please install GNUmake + +clean: + @gmake clean + +frida: + @gmake frida diff --git a/frida_mode/test/output/frida_stderr.txt b/frida_mode/test/output/frida_stderr.txt new file mode 100644 index 00000000..103216cf --- /dev/null +++ b/frida_mode/test/output/frida_stderr.txt @@ -0,0 +1,2824 @@ + + +total_transitions: 9 + call_imms: 1 + call_regs: 0 + call_mems: 0 + post_call_invokes: 0 + excluded_call_imms: 2 + ret_slow_paths: 1 + + jmp_imms: 1 + jmp_mems: 2 + jmp_regs: 0 + + jmp_cond_imms: 2 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 19 + call_imms: 4 + call_regs: 0 + call_mems: 0 + post_call_invokes: 2 + excluded_call_imms: 2 + ret_slow_paths: 1 + + jmp_imms: 1 + jmp_mems: 3 + jmp_regs: 0 + + jmp_cond_imms: 6 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 29 + call_imms: 6 + call_regs: 1 + call_mems: 0 + post_call_invokes: 3 + excluded_call_imms: 2 + ret_slow_paths: 1 + + jmp_imms: 2 + jmp_mems: 3 + jmp_regs: 0 + + jmp_cond_imms: 11 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 39 + call_imms: 6 + call_regs: 2 + call_mems: 0 + post_call_invokes: 5 + excluded_call_imms: 2 + ret_slow_paths: 1 + + jmp_imms: 2 + jmp_mems: 3 + jmp_regs: 0 + + jmp_cond_imms: 18 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 49 + call_imms: 7 + call_regs: 2 + call_mems: 1 + post_call_invokes: 6 + excluded_call_imms: 2 + ret_slow_paths: 1 + + jmp_imms: 2 + jmp_mems: 3 + jmp_regs: 0 + + jmp_cond_imms: 25 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 59 + call_imms: 8 + call_regs: 2 + call_mems: 3 + post_call_invokes: 6 + excluded_call_imms: 2 + ret_slow_paths: 1 + + jmp_imms: 3 + jmp_mems: 3 + jmp_regs: 0 + + jmp_cond_imms: 31 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 69 + call_imms: 9 + call_regs: 2 + call_mems: 3 + post_call_invokes: 7 + excluded_call_imms: 2 + ret_slow_paths: 1 + + jmp_imms: 3 + jmp_mems: 4 + jmp_regs: 0 + + jmp_cond_imms: 38 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 79 + call_imms: 10 + call_regs: 2 + call_mems: 3 + post_call_invokes: 7 + excluded_call_imms: 2 + ret_slow_paths: 1 + + jmp_imms: 4 + jmp_mems: 4 + jmp_regs: 0 + + jmp_cond_imms: 46 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 89 + call_imms: 10 + call_regs: 2 + call_mems: 3 + post_call_invokes: 7 + excluded_call_imms: 2 + ret_slow_paths: 1 + + jmp_imms: 4 + jmp_mems: 4 + jmp_regs: 0 + + jmp_cond_imms: 56 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 99 + call_imms: 11 + call_regs: 2 + call_mems: 3 + post_call_invokes: 9 + excluded_call_imms: 2 + ret_slow_paths: 1 + + jmp_imms: 4 + jmp_mems: 4 + jmp_regs: 0 + + jmp_cond_imms: 63 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 109 + call_imms: 12 + call_regs: 2 + call_mems: 3 + post_call_invokes: 12 + excluded_call_imms: 2 + ret_slow_paths: 1 + + jmp_imms: 5 + jmp_mems: 4 + jmp_regs: 0 + + jmp_cond_imms: 68 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 119 + call_imms: 12 + call_regs: 2 + call_mems: 4 + post_call_invokes: 14 + excluded_call_imms: 2 + ret_slow_paths: 1 + + jmp_imms: 6 + jmp_mems: 4 + jmp_regs: 0 + + jmp_cond_imms: 74 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 129 + call_imms: 14 + call_regs: 2 + call_mems: 4 + post_call_invokes: 16 + excluded_call_imms: 2 + ret_slow_paths: 1 + + jmp_imms: 6 + jmp_mems: 4 + jmp_regs: 0 + + jmp_cond_imms: 80 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 139 + call_imms: 14 + call_regs: 2 + call_mems: 5 + post_call_invokes: 17 + excluded_call_imms: 2 + ret_slow_paths: 1 + + jmp_imms: 6 + jmp_mems: 5 + jmp_regs: 0 + + jmp_cond_imms: 87 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 149 + call_imms: 14 + call_regs: 2 + call_mems: 6 + post_call_invokes: 17 + excluded_call_imms: 2 + ret_slow_paths: 1 + + jmp_imms: 6 + jmp_mems: 5 + jmp_regs: 0 + + jmp_cond_imms: 96 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 159 + call_imms: 15 + call_regs: 2 + call_mems: 6 + post_call_invokes: 18 + excluded_call_imms: 2 + ret_slow_paths: 1 + + jmp_imms: 8 + jmp_mems: 5 + jmp_regs: 0 + + jmp_cond_imms: 102 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 170 + call_imms: 15 + call_regs: 2 + call_mems: 6 + post_call_invokes: 18 + excluded_call_imms: 2 + ret_slow_paths: 1 + + jmp_imms: 10 + jmp_mems: 5 + jmp_regs: 0 + + jmp_cond_imms: 111 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 180 + call_imms: 15 + call_regs: 2 + call_mems: 6 + post_call_invokes: 20 + excluded_call_imms: 2 + ret_slow_paths: 1 + + jmp_imms: 11 + jmp_mems: 5 + jmp_regs: 0 + + jmp_cond_imms: 118 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 190 + call_imms: 16 + call_regs: 2 + call_mems: 6 + post_call_invokes: 20 + excluded_call_imms: 2 + ret_slow_paths: 1 + + jmp_imms: 11 + jmp_mems: 6 + jmp_regs: 1 + + jmp_cond_imms: 125 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 201 + call_imms: 16 + call_regs: 2 + call_mems: 7 + post_call_invokes: 21 + excluded_call_imms: 2 + ret_slow_paths: 1 + + jmp_imms: 13 + jmp_mems: 6 + jmp_regs: 1 + + jmp_cond_imms: 132 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 211 + call_imms: 17 + call_regs: 2 + call_mems: 7 + post_call_invokes: 22 + excluded_call_imms: 2 + ret_slow_paths: 1 + + jmp_imms: 14 + jmp_mems: 7 + jmp_regs: 1 + + jmp_cond_imms: 138 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 223 + call_imms: 18 + call_regs: 2 + call_mems: 8 + post_call_invokes: 24 + excluded_call_imms: 2 + ret_slow_paths: 1 + + jmp_imms: 15 + jmp_mems: 7 + jmp_regs: 1 + + jmp_cond_imms: 145 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 233 + call_imms: 18 + call_regs: 2 + call_mems: 8 + post_call_invokes: 25 + excluded_call_imms: 2 + ret_slow_paths: 1 + + jmp_imms: 16 + jmp_mems: 7 + jmp_regs: 1 + + jmp_cond_imms: 153 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 244 + call_imms: 19 + call_regs: 2 + call_mems: 9 + post_call_invokes: 26 + excluded_call_imms: 2 + ret_slow_paths: 1 + + jmp_imms: 16 + jmp_mems: 7 + jmp_regs: 1 + + jmp_cond_imms: 161 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 +Running: /home/jon/git/AFLplusplus/frida_mode/test/output/build/frida-out/default/.cur_input + + +total_transitions: 254 + call_imms: 20 + call_regs: 2 + call_mems: 9 + post_call_invokes: 27 + excluded_call_imms: 2 + ret_slow_paths: 1 + + jmp_imms: 18 + jmp_mems: 7 + jmp_regs: 1 + + jmp_cond_imms: 167 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 264 + call_imms: 20 + call_regs: 2 + call_mems: 9 + post_call_invokes: 29 + excluded_call_imms: 2 + ret_slow_paths: 1 + + jmp_imms: 20 + jmp_mems: 7 + jmp_regs: 1 + + jmp_cond_imms: 173 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 275 + call_imms: 21 + call_regs: 2 + call_mems: 10 + post_call_invokes: 30 + excluded_call_imms: 2 + ret_slow_paths: 1 + + jmp_imms: 22 + jmp_mems: 7 + jmp_regs: 1 + + jmp_cond_imms: 179 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 285 + call_imms: 22 + call_regs: 2 + call_mems: 10 + post_call_invokes: 30 + excluded_call_imms: 2 + ret_slow_paths: 1 + + jmp_imms: 23 + jmp_mems: 8 + jmp_regs: 1 + + jmp_cond_imms: 186 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 295 + call_imms: 22 + call_regs: 2 + call_mems: 10 + post_call_invokes: 30 + excluded_call_imms: 2 + ret_slow_paths: 1 + + jmp_imms: 23 + jmp_mems: 8 + jmp_regs: 1 + + jmp_cond_imms: 196 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 305 + call_imms: 22 + call_regs: 2 + call_mems: 10 + post_call_invokes: 30 + excluded_call_imms: 2 + ret_slow_paths: 1 + + jmp_imms: 24 + jmp_mems: 8 + jmp_regs: 1 + + jmp_cond_imms: 205 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 315 + call_imms: 22 + call_regs: 2 + call_mems: 10 + post_call_invokes: 31 + excluded_call_imms: 2 + ret_slow_paths: 1 + + jmp_imms: 26 + jmp_mems: 8 + jmp_regs: 1 + + jmp_cond_imms: 212 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 326 + call_imms: 22 + call_regs: 3 + call_mems: 10 + post_call_invokes: 32 + excluded_call_imms: 2 + ret_slow_paths: 1 + + jmp_imms: 27 + jmp_mems: 8 + jmp_regs: 1 + + jmp_cond_imms: 220 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 337 + call_imms: 23 + call_regs: 4 + call_mems: 10 + post_call_invokes: 36 + excluded_call_imms: 2 + ret_slow_paths: 1 + + jmp_imms: 27 + jmp_mems: 9 + jmp_regs: 1 + + jmp_cond_imms: 224 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 348 + call_imms: 24 + call_regs: 4 + call_mems: 10 + post_call_invokes: 38 + excluded_call_imms: 2 + ret_slow_paths: 1 + + jmp_imms: 27 + jmp_mems: 10 + jmp_regs: 1 + + jmp_cond_imms: 231 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 362 + call_imms: 26 + call_regs: 4 + call_mems: 10 + post_call_invokes: 39 + excluded_call_imms: 2 + ret_slow_paths: 1 + + jmp_imms: 28 + jmp_mems: 11 + jmp_regs: 1 + + jmp_cond_imms: 240 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 375 + call_imms: 27 + call_regs: 4 + call_mems: 10 + post_call_invokes: 40 + excluded_call_imms: 2 + ret_slow_paths: 1 + + jmp_imms: 28 + jmp_mems: 12 + jmp_regs: 1 + + jmp_cond_imms: 250 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 387 + call_imms: 28 + call_regs: 4 + call_mems: 10 + post_call_invokes: 41 + excluded_call_imms: 2 + ret_slow_paths: 1 + + jmp_imms: 28 + jmp_mems: 12 + jmp_regs: 3 + + jmp_cond_imms: 258 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 397 + call_imms: 29 + call_regs: 4 + call_mems: 10 + post_call_invokes: 42 + excluded_call_imms: 2 + ret_slow_paths: 1 + + jmp_imms: 30 + jmp_mems: 12 + jmp_regs: 3 + + jmp_cond_imms: 264 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 407 + call_imms: 29 + call_regs: 4 + call_mems: 10 + post_call_invokes: 42 + excluded_call_imms: 2 + ret_slow_paths: 1 + + jmp_imms: 31 + jmp_mems: 12 + jmp_regs: 3 + + jmp_cond_imms: 273 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 418 + call_imms: 29 + call_regs: 4 + call_mems: 11 + post_call_invokes: 43 + excluded_call_imms: 2 + ret_slow_paths: 1 + + jmp_imms: 32 + jmp_mems: 12 + jmp_regs: 3 + + jmp_cond_imms: 281 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 +Running: /home/jon/git/AFLplusplus/frida_mode/test/output/build/frida-out/default/.cur_input: (3 bytes) + + +total_transitions: 430 + call_imms: 32 + call_regs: 4 + call_mems: 11 + post_call_invokes: 45 + excluded_call_imms: 2 + ret_slow_paths: 1 + + jmp_imms: 33 + jmp_mems: 13 + jmp_regs: 3 + + jmp_cond_imms: 286 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 441 + call_imms: 32 + call_regs: 4 + call_mems: 12 + post_call_invokes: 46 + excluded_call_imms: 2 + ret_slow_paths: 1 + + jmp_imms: 33 + jmp_mems: 13 + jmp_regs: 3 + + jmp_cond_imms: 295 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 +Done: /home/jon/git/AFLplusplus/frida_mode/test/output/build/frida-out/default/.cur_input: (3 bytes) + + +total_transitions: 453 + call_imms: 33 + call_regs: 4 + call_mems: 12 + post_call_invokes: 49 + excluded_call_imms: 2 + ret_slow_paths: 1 + + jmp_imms: 34 + jmp_mems: 13 + jmp_regs: 3 + + jmp_cond_imms: 302 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 465 + call_imms: 35 + call_regs: 4 + call_mems: 12 + post_call_invokes: 50 + excluded_call_imms: 2 + ret_slow_paths: 1 + + jmp_imms: 35 + jmp_mems: 15 + jmp_regs: 3 + + jmp_cond_imms: 308 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 475 + call_imms: 38 + call_regs: 4 + call_mems: 12 + post_call_invokes: 51 + excluded_call_imms: 3 + ret_slow_paths: 3 + + jmp_imms: 35 + jmp_mems: 16 + jmp_regs: 3 + + jmp_cond_imms: 310 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 485 + call_imms: 38 + call_regs: 5 + call_mems: 12 + post_call_invokes: 52 + excluded_call_imms: 3 + ret_slow_paths: 3 + + jmp_imms: 36 + jmp_mems: 16 + jmp_regs: 3 + + jmp_cond_imms: 317 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 495 + call_imms: 38 + call_regs: 5 + call_mems: 13 + post_call_invokes: 52 + excluded_call_imms: 3 + ret_slow_paths: 3 + + jmp_imms: 38 + jmp_mems: 16 + jmp_regs: 3 + + jmp_cond_imms: 324 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 506 + call_imms: 38 + call_regs: 5 + call_mems: 13 + post_call_invokes: 53 + excluded_call_imms: 3 + ret_slow_paths: 3 + + jmp_imms: 39 + jmp_mems: 16 + jmp_regs: 3 + + jmp_cond_imms: 333 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 516 + call_imms: 40 + call_regs: 5 + call_mems: 13 + post_call_invokes: 53 + excluded_call_imms: 3 + ret_slow_paths: 3 + + jmp_imms: 40 + jmp_mems: 16 + jmp_regs: 3 + + jmp_cond_imms: 340 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 526 + call_imms: 40 + call_regs: 5 + call_mems: 13 + post_call_invokes: 54 + excluded_call_imms: 3 + ret_slow_paths: 3 + + jmp_imms: 40 + jmp_mems: 16 + jmp_regs: 3 + + jmp_cond_imms: 349 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 540 + call_imms: 42 + call_regs: 5 + call_mems: 13 + post_call_invokes: 55 + excluded_call_imms: 3 + ret_slow_paths: 3 + + jmp_imms: 42 + jmp_mems: 16 + jmp_regs: 3 + + jmp_cond_imms: 358 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 552 + call_imms: 43 + call_regs: 5 + call_mems: 13 + post_call_invokes: 57 + excluded_call_imms: 3 + ret_slow_paths: 3 + + jmp_imms: 43 + jmp_mems: 16 + jmp_regs: 3 + + jmp_cond_imms: 366 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 563 + call_imms: 43 + call_regs: 5 + call_mems: 14 + post_call_invokes: 58 + excluded_call_imms: 3 + ret_slow_paths: 3 + + jmp_imms: 43 + jmp_mems: 16 + jmp_regs: 3 + + jmp_cond_imms: 375 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 573 + call_imms: 43 + call_regs: 5 + call_mems: 15 + post_call_invokes: 59 + excluded_call_imms: 3 + ret_slow_paths: 3 + + jmp_imms: 44 + jmp_mems: 16 + jmp_regs: 3 + + jmp_cond_imms: 382 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 583 + call_imms: 44 + call_regs: 5 + call_mems: 15 + post_call_invokes: 59 + excluded_call_imms: 3 + ret_slow_paths: 3 + + jmp_imms: 45 + jmp_mems: 17 + jmp_regs: 3 + + jmp_cond_imms: 389 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 593 + call_imms: 45 + call_regs: 5 + call_mems: 15 + post_call_invokes: 60 + excluded_call_imms: 3 + ret_slow_paths: 3 + + jmp_imms: 46 + jmp_mems: 17 + jmp_regs: 3 + + jmp_cond_imms: 396 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 603 + call_imms: 46 + call_regs: 6 + call_mems: 15 + post_call_invokes: 64 + excluded_call_imms: 3 + ret_slow_paths: 3 + + jmp_imms: 46 + jmp_mems: 17 + jmp_regs: 3 + + jmp_cond_imms: 400 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 615 + call_imms: 46 + call_regs: 7 + call_mems: 17 + post_call_invokes: 64 + excluded_call_imms: 5 + ret_slow_paths: 3 + + jmp_imms: 46 + jmp_mems: 17 + jmp_regs: 3 + + jmp_cond_imms: 407 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 626 + call_imms: 48 + call_regs: 8 + call_mems: 18 + post_call_invokes: 66 + excluded_call_imms: 5 + ret_slow_paths: 3 + + jmp_imms: 46 + jmp_mems: 18 + jmp_regs: 3 + + jmp_cond_imms: 411 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 637 + call_imms: 50 + call_regs: 9 + call_mems: 19 + post_call_invokes: 68 + excluded_call_imms: 5 + ret_slow_paths: 3 + + jmp_imms: 47 + jmp_mems: 19 + jmp_regs: 3 + + jmp_cond_imms: 414 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 648 + call_imms: 52 + call_regs: 9 + call_mems: 20 + post_call_invokes: 70 + excluded_call_imms: 5 + ret_slow_paths: 3 + + jmp_imms: 47 + jmp_mems: 20 + jmp_regs: 3 + + jmp_cond_imms: 419 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 660 + call_imms: 52 + call_regs: 10 + call_mems: 20 + post_call_invokes: 72 + excluded_call_imms: 5 + ret_slow_paths: 3 + + jmp_imms: 49 + jmp_mems: 20 + jmp_regs: 3 + + jmp_cond_imms: 426 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 672 + call_imms: 52 + call_regs: 10 + call_mems: 20 + post_call_invokes: 72 + excluded_call_imms: 5 + ret_slow_paths: 3 + + jmp_imms: 51 + jmp_mems: 20 + jmp_regs: 3 + + jmp_cond_imms: 436 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 683 + call_imms: 53 + call_regs: 11 + call_mems: 21 + post_call_invokes: 73 + excluded_call_imms: 5 + ret_slow_paths: 3 + + jmp_imms: 52 + jmp_mems: 20 + jmp_regs: 3 + + jmp_cond_imms: 442 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 697 + call_imms: 53 + call_regs: 11 + call_mems: 22 + post_call_invokes: 74 + excluded_call_imms: 5 + ret_slow_paths: 3 + + jmp_imms: 53 + jmp_mems: 20 + jmp_regs: 3 + + jmp_cond_imms: 453 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 709 + call_imms: 53 + call_regs: 13 + call_mems: 22 + post_call_invokes: 77 + excluded_call_imms: 5 + ret_slow_paths: 3 + + jmp_imms: 53 + jmp_mems: 20 + jmp_regs: 3 + + jmp_cond_imms: 460 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 720 + call_imms: 53 + call_regs: 13 + call_mems: 22 + post_call_invokes: 77 + excluded_call_imms: 5 + ret_slow_paths: 3 + + jmp_imms: 55 + jmp_mems: 20 + jmp_regs: 3 + + jmp_cond_imms: 469 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 730 + call_imms: 54 + call_regs: 13 + call_mems: 24 + post_call_invokes: 77 + excluded_call_imms: 5 + ret_slow_paths: 3 + + jmp_imms: 56 + jmp_mems: 20 + jmp_regs: 3 + + jmp_cond_imms: 475 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 740 + call_imms: 54 + call_regs: 13 + call_mems: 24 + post_call_invokes: 80 + excluded_call_imms: 5 + ret_slow_paths: 3 + + jmp_imms: 57 + jmp_mems: 20 + jmp_regs: 3 + + jmp_cond_imms: 481 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 753 + call_imms: 54 + call_regs: 14 + call_mems: 24 + post_call_invokes: 81 + excluded_call_imms: 5 + ret_slow_paths: 3 + + jmp_imms: 58 + jmp_mems: 20 + jmp_regs: 3 + + jmp_cond_imms: 491 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 3 + call_imms: 0 + call_regs: 0 + call_mems: 0 + post_call_invokes: 0 + excluded_call_imms: 0 + ret_slow_paths: 0 + + jmp_imms: 1 + jmp_mems: 1 + jmp_regs: 0 + + jmp_cond_imms: 1 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 3 + call_imms: 0 + call_regs: 0 + call_mems: 0 + post_call_invokes: 0 + excluded_call_imms: 0 + ret_slow_paths: 0 + + jmp_imms: 1 + jmp_mems: 1 + jmp_regs: 0 + + jmp_cond_imms: 1 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 3 + call_imms: 0 + call_regs: 0 + call_mems: 0 + post_call_invokes: 0 + excluded_call_imms: 0 + ret_slow_paths: 0 + + jmp_imms: 1 + jmp_mems: 1 + jmp_regs: 0 + + jmp_cond_imms: 1 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 3 + call_imms: 0 + call_regs: 0 + call_mems: 0 + post_call_invokes: 0 + excluded_call_imms: 0 + ret_slow_paths: 0 + + jmp_imms: 1 + jmp_mems: 1 + jmp_regs: 0 + + jmp_cond_imms: 1 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 3 + call_imms: 0 + call_regs: 0 + call_mems: 0 + post_call_invokes: 0 + excluded_call_imms: 0 + ret_slow_paths: 0 + + jmp_imms: 1 + jmp_mems: 1 + jmp_regs: 0 + + jmp_cond_imms: 1 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 3 + call_imms: 0 + call_regs: 0 + call_mems: 0 + post_call_invokes: 0 + excluded_call_imms: 0 + ret_slow_paths: 0 + + jmp_imms: 1 + jmp_mems: 1 + jmp_regs: 0 + + jmp_cond_imms: 1 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 3 + call_imms: 0 + call_regs: 0 + call_mems: 0 + post_call_invokes: 0 + excluded_call_imms: 0 + ret_slow_paths: 0 + + jmp_imms: 1 + jmp_mems: 1 + jmp_regs: 0 + + jmp_cond_imms: 1 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 3 + call_imms: 0 + call_regs: 0 + call_mems: 0 + post_call_invokes: 0 + excluded_call_imms: 0 + ret_slow_paths: 0 + + jmp_imms: 1 + jmp_mems: 1 + jmp_regs: 0 + + jmp_cond_imms: 1 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 3 + call_imms: 0 + call_regs: 0 + call_mems: 0 + post_call_invokes: 0 + excluded_call_imms: 0 + ret_slow_paths: 0 + + jmp_imms: 1 + jmp_mems: 1 + jmp_regs: 0 + + jmp_cond_imms: 1 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 3 + call_imms: 0 + call_regs: 0 + call_mems: 0 + post_call_invokes: 0 + excluded_call_imms: 0 + ret_slow_paths: 0 + + jmp_imms: 1 + jmp_mems: 1 + jmp_regs: 0 + + jmp_cond_imms: 1 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 3 + call_imms: 0 + call_regs: 0 + call_mems: 0 + post_call_invokes: 0 + excluded_call_imms: 0 + ret_slow_paths: 0 + + jmp_imms: 1 + jmp_mems: 1 + jmp_regs: 0 + + jmp_cond_imms: 1 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 3 + call_imms: 0 + call_regs: 0 + call_mems: 0 + post_call_invokes: 0 + excluded_call_imms: 0 + ret_slow_paths: 0 + + jmp_imms: 1 + jmp_mems: 1 + jmp_regs: 0 + + jmp_cond_imms: 1 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 3 + call_imms: 0 + call_regs: 0 + call_mems: 0 + post_call_invokes: 0 + excluded_call_imms: 0 + ret_slow_paths: 0 + + jmp_imms: 1 + jmp_mems: 1 + jmp_regs: 0 + + jmp_cond_imms: 1 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 3 + call_imms: 0 + call_regs: 0 + call_mems: 0 + post_call_invokes: 0 + excluded_call_imms: 0 + ret_slow_paths: 0 + + jmp_imms: 1 + jmp_mems: 1 + jmp_regs: 0 + + jmp_cond_imms: 1 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 3 + call_imms: 0 + call_regs: 0 + call_mems: 0 + post_call_invokes: 0 + excluded_call_imms: 0 + ret_slow_paths: 0 + + jmp_imms: 1 + jmp_mems: 1 + jmp_regs: 0 + + jmp_cond_imms: 1 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 3 + call_imms: 0 + call_regs: 0 + call_mems: 0 + post_call_invokes: 0 + excluded_call_imms: 0 + ret_slow_paths: 0 + + jmp_imms: 1 + jmp_mems: 1 + jmp_regs: 0 + + jmp_cond_imms: 1 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 3 + call_imms: 0 + call_regs: 0 + call_mems: 0 + post_call_invokes: 0 + excluded_call_imms: 0 + ret_slow_paths: 0 + + jmp_imms: 1 + jmp_mems: 1 + jmp_regs: 0 + + jmp_cond_imms: 1 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 3 + call_imms: 0 + call_regs: 0 + call_mems: 0 + post_call_invokes: 0 + excluded_call_imms: 0 + ret_slow_paths: 0 + + jmp_imms: 1 + jmp_mems: 1 + jmp_regs: 0 + + jmp_cond_imms: 1 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 3 + call_imms: 0 + call_regs: 0 + call_mems: 0 + post_call_invokes: 0 + excluded_call_imms: 0 + ret_slow_paths: 0 + + jmp_imms: 1 + jmp_mems: 1 + jmp_regs: 0 + + jmp_cond_imms: 1 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 3 + call_imms: 0 + call_regs: 0 + call_mems: 0 + post_call_invokes: 0 + excluded_call_imms: 0 + ret_slow_paths: 0 + + jmp_imms: 1 + jmp_mems: 1 + jmp_regs: 0 + + jmp_cond_imms: 1 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 3 + call_imms: 0 + call_regs: 0 + call_mems: 0 + post_call_invokes: 0 + excluded_call_imms: 0 + ret_slow_paths: 0 + + jmp_imms: 1 + jmp_mems: 1 + jmp_regs: 0 + + jmp_cond_imms: 1 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 3 + call_imms: 0 + call_regs: 0 + call_mems: 0 + post_call_invokes: 0 + excluded_call_imms: 0 + ret_slow_paths: 0 + + jmp_imms: 1 + jmp_mems: 1 + jmp_regs: 0 + + jmp_cond_imms: 1 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 3 + call_imms: 0 + call_regs: 0 + call_mems: 0 + post_call_invokes: 0 + excluded_call_imms: 0 + ret_slow_paths: 0 + + jmp_imms: 1 + jmp_mems: 1 + jmp_regs: 0 + + jmp_cond_imms: 1 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 3 + call_imms: 0 + call_regs: 0 + call_mems: 0 + post_call_invokes: 0 + excluded_call_imms: 0 + ret_slow_paths: 0 + + jmp_imms: 1 + jmp_mems: 1 + jmp_regs: 0 + + jmp_cond_imms: 1 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 3 + call_imms: 0 + call_regs: 0 + call_mems: 0 + post_call_invokes: 0 + excluded_call_imms: 0 + ret_slow_paths: 0 + + jmp_imms: 1 + jmp_mems: 1 + jmp_regs: 0 + + jmp_cond_imms: 1 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 3 + call_imms: 0 + call_regs: 0 + call_mems: 0 + post_call_invokes: 0 + excluded_call_imms: 0 + ret_slow_paths: 0 + + jmp_imms: 1 + jmp_mems: 1 + jmp_regs: 0 + + jmp_cond_imms: 1 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 3 + call_imms: 0 + call_regs: 0 + call_mems: 0 + post_call_invokes: 0 + excluded_call_imms: 0 + ret_slow_paths: 0 + + jmp_imms: 1 + jmp_mems: 1 + jmp_regs: 0 + + jmp_cond_imms: 1 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 3 + call_imms: 0 + call_regs: 0 + call_mems: 0 + post_call_invokes: 0 + excluded_call_imms: 0 + ret_slow_paths: 0 + + jmp_imms: 1 + jmp_mems: 1 + jmp_regs: 0 + + jmp_cond_imms: 1 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 3 + call_imms: 0 + call_regs: 0 + call_mems: 0 + post_call_invokes: 0 + excluded_call_imms: 0 + ret_slow_paths: 0 + + jmp_imms: 1 + jmp_mems: 1 + jmp_regs: 0 + + jmp_cond_imms: 1 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 3 + call_imms: 0 + call_regs: 0 + call_mems: 0 + post_call_invokes: 0 + excluded_call_imms: 0 + ret_slow_paths: 0 + + jmp_imms: 1 + jmp_mems: 1 + jmp_regs: 0 + + jmp_cond_imms: 1 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 3 + call_imms: 0 + call_regs: 0 + call_mems: 0 + post_call_invokes: 0 + excluded_call_imms: 0 + ret_slow_paths: 0 + + jmp_imms: 1 + jmp_mems: 1 + jmp_regs: 0 + + jmp_cond_imms: 1 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 3 + call_imms: 0 + call_regs: 0 + call_mems: 0 + post_call_invokes: 0 + excluded_call_imms: 0 + ret_slow_paths: 0 + + jmp_imms: 1 + jmp_mems: 1 + jmp_regs: 0 + + jmp_cond_imms: 1 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 3 + call_imms: 0 + call_regs: 0 + call_mems: 0 + post_call_invokes: 0 + excluded_call_imms: 0 + ret_slow_paths: 0 + + jmp_imms: 1 + jmp_mems: 1 + jmp_regs: 0 + + jmp_cond_imms: 1 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 3 + call_imms: 0 + call_regs: 0 + call_mems: 0 + post_call_invokes: 0 + excluded_call_imms: 0 + ret_slow_paths: 0 + + jmp_imms: 1 + jmp_mems: 1 + jmp_regs: 0 + + jmp_cond_imms: 1 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 3 + call_imms: 0 + call_regs: 0 + call_mems: 0 + post_call_invokes: 0 + excluded_call_imms: 0 + ret_slow_paths: 0 + + jmp_imms: 1 + jmp_mems: 1 + jmp_regs: 0 + + jmp_cond_imms: 1 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 3 + call_imms: 0 + call_regs: 0 + call_mems: 0 + post_call_invokes: 0 + excluded_call_imms: 0 + ret_slow_paths: 0 + + jmp_imms: 1 + jmp_mems: 1 + jmp_regs: 0 + + jmp_cond_imms: 1 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 3 + call_imms: 0 + call_regs: 0 + call_mems: 0 + post_call_invokes: 0 + excluded_call_imms: 0 + ret_slow_paths: 0 + + jmp_imms: 1 + jmp_mems: 1 + jmp_regs: 0 + + jmp_cond_imms: 1 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 3 + call_imms: 0 + call_regs: 0 + call_mems: 0 + post_call_invokes: 0 + excluded_call_imms: 0 + ret_slow_paths: 0 + + jmp_imms: 1 + jmp_mems: 1 + jmp_regs: 0 + + jmp_cond_imms: 1 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 3 + call_imms: 0 + call_regs: 0 + call_mems: 0 + post_call_invokes: 0 + excluded_call_imms: 0 + ret_slow_paths: 0 + + jmp_imms: 1 + jmp_mems: 1 + jmp_regs: 0 + + jmp_cond_imms: 1 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 3 + call_imms: 0 + call_regs: 0 + call_mems: 0 + post_call_invokes: 0 + excluded_call_imms: 0 + ret_slow_paths: 0 + + jmp_imms: 1 + jmp_mems: 1 + jmp_regs: 0 + + jmp_cond_imms: 1 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 3 + call_imms: 0 + call_regs: 0 + call_mems: 0 + post_call_invokes: 0 + excluded_call_imms: 0 + ret_slow_paths: 0 + + jmp_imms: 1 + jmp_mems: 1 + jmp_regs: 0 + + jmp_cond_imms: 1 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 3 + call_imms: 0 + call_regs: 0 + call_mems: 0 + post_call_invokes: 0 + excluded_call_imms: 0 + ret_slow_paths: 0 + + jmp_imms: 1 + jmp_mems: 1 + jmp_regs: 0 + + jmp_cond_imms: 1 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 3 + call_imms: 0 + call_regs: 0 + call_mems: 0 + post_call_invokes: 0 + excluded_call_imms: 0 + ret_slow_paths: 0 + + jmp_imms: 1 + jmp_mems: 1 + jmp_regs: 0 + + jmp_cond_imms: 1 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 3 + call_imms: 0 + call_regs: 0 + call_mems: 0 + post_call_invokes: 0 + excluded_call_imms: 0 + ret_slow_paths: 0 + + jmp_imms: 1 + jmp_mems: 1 + jmp_regs: 0 + + jmp_cond_imms: 1 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 3 + call_imms: 0 + call_regs: 0 + call_mems: 0 + post_call_invokes: 0 + excluded_call_imms: 0 + ret_slow_paths: 0 + + jmp_imms: 1 + jmp_mems: 1 + jmp_regs: 0 + + jmp_cond_imms: 1 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 3 + call_imms: 0 + call_regs: 0 + call_mems: 0 + post_call_invokes: 0 + excluded_call_imms: 0 + ret_slow_paths: 0 + + jmp_imms: 1 + jmp_mems: 1 + jmp_regs: 0 + + jmp_cond_imms: 1 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 3 + call_imms: 0 + call_regs: 0 + call_mems: 0 + post_call_invokes: 0 + excluded_call_imms: 0 + ret_slow_paths: 0 + + jmp_imms: 1 + jmp_mems: 1 + jmp_regs: 0 + + jmp_cond_imms: 1 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 3 + call_imms: 0 + call_regs: 0 + call_mems: 0 + post_call_invokes: 0 + excluded_call_imms: 0 + ret_slow_paths: 0 + + jmp_imms: 1 + jmp_mems: 1 + jmp_regs: 0 + + jmp_cond_imms: 1 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 3 + call_imms: 0 + call_regs: 0 + call_mems: 0 + post_call_invokes: 0 + excluded_call_imms: 0 + ret_slow_paths: 0 + + jmp_imms: 1 + jmp_mems: 1 + jmp_regs: 0 + + jmp_cond_imms: 1 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 3 + call_imms: 0 + call_regs: 0 + call_mems: 0 + post_call_invokes: 0 + excluded_call_imms: 0 + ret_slow_paths: 0 + + jmp_imms: 1 + jmp_mems: 1 + jmp_regs: 0 + + jmp_cond_imms: 1 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 3 + call_imms: 0 + call_regs: 0 + call_mems: 0 + post_call_invokes: 0 + excluded_call_imms: 0 + ret_slow_paths: 0 + + jmp_imms: 1 + jmp_mems: 1 + jmp_regs: 0 + + jmp_cond_imms: 1 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 3 + call_imms: 0 + call_regs: 0 + call_mems: 0 + post_call_invokes: 0 + excluded_call_imms: 0 + ret_slow_paths: 0 + + jmp_imms: 1 + jmp_mems: 1 + jmp_regs: 0 + + jmp_cond_imms: 1 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 3 + call_imms: 0 + call_regs: 0 + call_mems: 0 + post_call_invokes: 0 + excluded_call_imms: 0 + ret_slow_paths: 0 + + jmp_imms: 1 + jmp_mems: 1 + jmp_regs: 0 + + jmp_cond_imms: 1 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 3 + call_imms: 0 + call_regs: 0 + call_mems: 0 + post_call_invokes: 0 + excluded_call_imms: 0 + ret_slow_paths: 0 + + jmp_imms: 1 + jmp_mems: 1 + jmp_regs: 0 + + jmp_cond_imms: 1 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 3 + call_imms: 0 + call_regs: 0 + call_mems: 0 + post_call_invokes: 0 + excluded_call_imms: 0 + ret_slow_paths: 0 + + jmp_imms: 1 + jmp_mems: 1 + jmp_regs: 0 + + jmp_cond_imms: 1 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 3 + call_imms: 0 + call_regs: 0 + call_mems: 0 + post_call_invokes: 0 + excluded_call_imms: 0 + ret_slow_paths: 0 + + jmp_imms: 1 + jmp_mems: 1 + jmp_regs: 0 + + jmp_cond_imms: 1 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 3 + call_imms: 0 + call_regs: 0 + call_mems: 0 + post_call_invokes: 0 + excluded_call_imms: 0 + ret_slow_paths: 0 + + jmp_imms: 1 + jmp_mems: 1 + jmp_regs: 0 + + jmp_cond_imms: 1 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 3 + call_imms: 0 + call_regs: 0 + call_mems: 0 + post_call_invokes: 0 + excluded_call_imms: 0 + ret_slow_paths: 0 + + jmp_imms: 1 + jmp_mems: 1 + jmp_regs: 0 + + jmp_cond_imms: 1 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 3 + call_imms: 0 + call_regs: 0 + call_mems: 0 + post_call_invokes: 0 + excluded_call_imms: 0 + ret_slow_paths: 0 + + jmp_imms: 1 + jmp_mems: 1 + jmp_regs: 0 + + jmp_cond_imms: 1 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 3 + call_imms: 0 + call_regs: 0 + call_mems: 0 + post_call_invokes: 0 + excluded_call_imms: 0 + ret_slow_paths: 0 + + jmp_imms: 1 + jmp_mems: 1 + jmp_regs: 0 + + jmp_cond_imms: 1 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 3 + call_imms: 0 + call_regs: 0 + call_mems: 0 + post_call_invokes: 0 + excluded_call_imms: 0 + ret_slow_paths: 0 + + jmp_imms: 1 + jmp_mems: 1 + jmp_regs: 0 + + jmp_cond_imms: 1 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 3 + call_imms: 0 + call_regs: 0 + call_mems: 0 + post_call_invokes: 0 + excluded_call_imms: 0 + ret_slow_paths: 0 + + jmp_imms: 1 + jmp_mems: 1 + jmp_regs: 0 + + jmp_cond_imms: 1 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 3 + call_imms: 0 + call_regs: 0 + call_mems: 0 + post_call_invokes: 0 + excluded_call_imms: 0 + ret_slow_paths: 0 + + jmp_imms: 1 + jmp_mems: 1 + jmp_regs: 0 + + jmp_cond_imms: 1 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 3 + call_imms: 0 + call_regs: 0 + call_mems: 0 + post_call_invokes: 0 + excluded_call_imms: 0 + ret_slow_paths: 0 + + jmp_imms: 1 + jmp_mems: 1 + jmp_regs: 0 + + jmp_cond_imms: 1 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 3 + call_imms: 0 + call_regs: 0 + call_mems: 0 + post_call_invokes: 0 + excluded_call_imms: 0 + ret_slow_paths: 0 + + jmp_imms: 1 + jmp_mems: 1 + jmp_regs: 0 + + jmp_cond_imms: 1 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 3 + call_imms: 0 + call_regs: 0 + call_mems: 0 + post_call_invokes: 0 + excluded_call_imms: 0 + ret_slow_paths: 0 + + jmp_imms: 1 + jmp_mems: 1 + jmp_regs: 0 + + jmp_cond_imms: 1 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 3 + call_imms: 0 + call_regs: 0 + call_mems: 0 + post_call_invokes: 0 + excluded_call_imms: 0 + ret_slow_paths: 0 + + jmp_imms: 1 + jmp_mems: 1 + jmp_regs: 0 + + jmp_cond_imms: 1 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 3 + call_imms: 0 + call_regs: 0 + call_mems: 0 + post_call_invokes: 0 + excluded_call_imms: 0 + ret_slow_paths: 0 + + jmp_imms: 1 + jmp_mems: 1 + jmp_regs: 0 + + jmp_cond_imms: 1 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 3 + call_imms: 0 + call_regs: 0 + call_mems: 0 + post_call_invokes: 0 + excluded_call_imms: 0 + ret_slow_paths: 0 + + jmp_imms: 1 + jmp_mems: 1 + jmp_regs: 0 + + jmp_cond_imms: 1 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 + + +total_transitions: 3 + call_imms: 0 + call_regs: 0 + call_mems: 0 + post_call_invokes: 0 + excluded_call_imms: 0 + ret_slow_paths: 0 + + jmp_imms: 1 + jmp_mems: 1 + jmp_regs: 0 + + jmp_cond_imms: 1 + jmp_cond_mems: 0 + jmp_cond_regs: 0 + jmp_cond_jcxzs: 0 + + jmp_continuations: 0 +Running: /home/jon/git/AFLplusplus/frida_mode/test/output/build/frida-out/default/.cur_input +Running: /home/jon/git/AFLplusplus/frida_mode/test/output/build/frida-out/default/.cur_input: (3 bytes) +Done: /home/jon/git/AFLplusplus/frida_mode/test/output/build/frida-out/default/.cur_input: (3 bytes) +Running: /home/jon/git/AFLplusplus/frida_mode/test/output/build/frida-out/default/.cur_input +Running: /home/jon/git/AFLplusplus/frida_mode/test/output/build/frida-out/default/.cur_input: (3 bytes) +Done: /home/jon/git/AFLplusplus/frida_mode/test/output/build/frida-out/default/.cur_input: (3 bytes) +Running: /home/jon/git/AFLplusplus/frida_mode/test/output/build/frida-out/default/.cur_input +Running: /home/jon/git/AFLplusplus/frida_mode/test/output/build/frida-out/default/.cur_input: (3 bytes) +Done: /home/jon/git/AFLplusplus/frida_mode/test/output/build/frida-out/default/.cur_input: (3 bytes) +Running: /home/jon/git/AFLplusplus/frida_mode/test/output/build/frida-out/default/.cur_input +Running: /home/jon/git/AFLplusplus/frida_mode/test/output/build/frida-out/default/.cur_input: (3 bytes) +Done: /home/jon/git/AFLplusplus/frida_mode/test/output/build/frida-out/default/.cur_input: (3 bytes) +Running: /home/jon/git/AFLplusplus/frida_mode/test/output/build/frida-out/default/.cur_input +Running: /home/jon/git/AFLplusplus/frida_mode/test/output/build/frida-out/default/.cur_input: (3 bytes) +Done: /home/jon/git/AFLplusplus/frida_mode/test/output/build/frida-out/default/.cur_input: (3 bytes) +Running: /home/jon/git/AFLplusplus/frida_mode/test/output/build/frida-out/default/.cur_input +Running: /home/jon/git/AFLplusplus/frida_mode/test/output/build/frida-out/default/.cur_input: (3 bytes) +Done: /home/jon/git/AFLplusplus/frida_mode/test/output/build/frida-out/default/.cur_input: (3 bytes) +Running: /home/jon/git/AFLplusplus/frida_mode/test/output/build/frida-out/default/.cur_input +Running: /home/jon/git/AFLplusplus/frida_mode/test/output/build/frida-out/default/.cur_input: (3 bytes) +Done: /home/jon/git/AFLplusplus/frida_mode/test/output/build/frida-out/default/.cur_input: (3 bytes) diff --git a/frida_mode/test/output/frida_stdout.txt b/frida_mode/test/output/frida_stdout.txt new file mode 100644 index 00000000..8832681d --- /dev/null +++ b/frida_mode/test/output/frida_stdout.txt @@ -0,0 +1,349 @@ +OG Range - 0x00007FFFF7FFE000 - 0x00007FFFF7FFF000 +[+] CMPLOG Range - 0x00007FFFF7FFD000 - 0x00007FFFF7FFE000 +[+] CMPLOG Range - 0x00007FFFF7FFC000 - 0x00007FFFF7FFD000 +[+] CMPLOG Range - 0x00007FFFF7FF3000 - 0x00007FFFF7FFB000 +[+] CMPLOG Range - 0x00007FFFF7FD0000 - 0x00007FFFF7FF3000 +[+] CMPLOG Range - 0x00007FFFF7FCF000 - 0x00007FFFF7FD0000 +[+] CMPLOG Range - 0x00007FFFF7FCE000 - 0x00007FFFF7FCF000 +[+] CMPLOG Range - 0x00007FFFF7FCB000 - 0x00007FFFF7FCE000 +[+] CMPLOG Range - 0x00007FFFF7DC4000 - 0x00007FFFF7FCB000 +[+] CMPLOG Range - 0x00007FFFF7DBC000 - 0x00007FFFF7DC4000 +[+] CMPLOG Range - 0x00007FFFF7DB0000 - 0x00007FFFF7DBC000 +[+] CMPLOG Range - 0x00007FFFF7A94000 - 0x00007FFFF7DB0000 +[+] CMPLOG Range - 0x00007FFFF7942000 - 0x00007FFFF7A94000 +[+] CMPLOG Range - 0x00007FFFF78BF000 - 0x00007FFFF7942000 +[+] CMPLOG Range - 0x00007FFFF78AF000 - 0x00007FFFF78BF000 +[+] CMPLOG Range - 0x00007FFFF78AA000 - 0x00007FFFF78AB000 +[+] CMPLOG Range - 0x00007FFFF78A9000 - 0x00007FFFF78AA000 +[+] CMPLOG Range - 0x00007FFFF78A2000 - 0x00007FFFF78A6000 +[+] CMPLOG Range - 0x00007FFFF789F000 - 0x00007FFFF78A2000 +[+] CMPLOG Range - 0x00007FFFF789C000 - 0x00007FFFF789F000 +[+] CMPLOG Range - 0x00007FFFF7851000 - 0x00007FFFF789B000 +[+] CMPLOG Range - 0x00007FFFF76DB000 - 0x00007FFFF7851000 +[+] CMPLOG Range - 0x00007FFFF76DA000 - 0x00007FFFF76DB000 +[+] CMPLOG Range - 0x00007FFFF76D9000 - 0x00007FFFF76DA000 +[+] CMPLOG Range - 0x00007FFFF76B4000 - 0x00007FFFF76D9000 +[+] CMPLOG Range - 0x00007FFFF76B0000 - 0x00007FFFF76B4000 +[+] CMPLOG Range - 0x00007FFFF76AF000 - 0x00007FFFF76B0000 +[+] CMPLOG Range - 0x00007FFFF76AE000 - 0x00007FFFF76AF000 +[+] CMPLOG Range - 0x00007FFFF76A9000 - 0x00007FFFF76AE000 +[+] CMPLOG Range - 0x00007FFFF7698000 - 0x00007FFFF76A9000 +[+] CMPLOG Range - 0x00007FFFF7691000 - 0x00007FFFF7698000 +[+] CMPLOG Range - 0x00007FFFF768F000 - 0x00007FFFF7691000 +[+] CMPLOG Range - 0x00007FFFF768E000 - 0x00007FFFF768F000 +[+] CMPLOG Range - 0x00007FFFF768D000 - 0x00007FFFF768E000 +[+] CMPLOG Range - 0x00007FFFF7689000 - 0x00007FFFF768C000 +[+] CMPLOG Range - 0x00007FFFF7679000 - 0x00007FFFF7689000 +[+] CMPLOG Range - 0x00007FFFF7675000 - 0x00007FFFF7679000 +[+] CMPLOG Range - 0x00007FFFF7674000 - 0x00007FFFF7675000 +[+] CMPLOG Range - 0x00007FFFF7673000 - 0x00007FFFF7674000 +[+] CMPLOG Range - 0x00007FFFF7672000 - 0x00007FFFF7673000 +[+] CMPLOG Range - 0x00007FFFF7670000 - 0x00007FFFF7672000 +[+] CMPLOG Range - 0x00007FFFF766F000 - 0x00007FFFF7670000 +[+] CMPLOG Range - 0x00007FFFF766D000 - 0x00007FFFF766F000 +[+] Redirect 1 -> '/home/jon/git/AFLplusplus/frida_mode/test/output/frida_stdout.txt' +[+] Redirect 2 -> '/home/jon/git/AFLplusplus/frida_mode/test/output/frida_stderr.txt' +[+] Instrumentation - persistent mode [ ] (0x0000000000000000) +[+] Instrumentation - persistent count [ ] (0) +[+] Instrumentation - hook [(null)] +[+] Instrumentation - persistent ret [ ] (0x0000000000000000) +[+] Instrumentation - persistent ret offset [ ] (0) +[+] Instrumentation - prefetch [X] +[+] Range: Modules Length: 54 +[+] Range: Modules Idx: 0 - 0x0000555555554000-0x0000555555555000 +[+] Range: Modules Idx: 1 - 0x0000555555555000-0x0000555555556000 +[+] Range: Modules Idx: 2 - 0x0000555555556000-0x0000555555557000 +[+] Range: Modules Idx: 3 - 0x0000555555557000-0x0000555555558000 +[+] Range: Modules Idx: 4 - 0x0000555555558000-0x0000555555559000 +[+] Range: Modules Idx: 5 - 0x0000555555559000-0x000055555557a000 +[+] Range: Modules Idx: 6 - 0x00007ffff7615000-0x00007ffff7625000 +[+] Range: Modules Idx: 7 - 0x00007ffff766d000-0x00007ffff766f000 +[+] Range: Modules Idx: 8 - 0x00007ffff766f000-0x00007ffff7670000 +[+] Range: Modules Idx: 9 - 0x00007ffff7670000-0x00007ffff7672000 +[+] Range: Modules Idx: 10 - 0x00007ffff7672000-0x00007ffff7673000 +[+] Range: Modules Idx: 11 - 0x00007ffff7673000-0x00007ffff7674000 +[+] Range: Modules Idx: 12 - 0x00007ffff7674000-0x00007ffff7675000 +[+] Range: Modules Idx: 13 - 0x00007ffff7675000-0x00007ffff7679000 +[+] Range: Modules Idx: 14 - 0x00007ffff7679000-0x00007ffff7689000 +[+] Range: Modules Idx: 15 - 0x00007ffff7689000-0x00007ffff768c000 +[+] Range: Modules Idx: 16 - 0x00007ffff768c000-0x00007ffff768d000 +[+] Range: Modules Idx: 17 - 0x00007ffff768d000-0x00007ffff768e000 +[+] Range: Modules Idx: 18 - 0x00007ffff768e000-0x00007ffff768f000 +[+] Range: Modules Idx: 19 - 0x00007ffff768f000-0x00007ffff7691000 +[+] Range: Modules Idx: 20 - 0x00007ffff7691000-0x00007ffff7698000 +[+] Range: Modules Idx: 21 - 0x00007ffff7698000-0x00007ffff76a9000 +[+] Range: Modules Idx: 22 - 0x00007ffff76a9000-0x00007ffff76ae000 +[+] Range: Modules Idx: 23 - 0x00007ffff76ae000-0x00007ffff76af000 +[+] Range: Modules Idx: 24 - 0x00007ffff76af000-0x00007ffff76b0000 +[+] Range: Modules Idx: 25 - 0x00007ffff76b0000-0x00007ffff76b4000 +[+] Range: Modules Idx: 26 - 0x00007ffff76b4000-0x00007ffff76d9000 +[+] Range: Modules Idx: 27 - 0x00007ffff76d9000-0x00007ffff76da000 +[+] Range: Modules Idx: 28 - 0x00007ffff76da000-0x00007ffff76db000 +[+] Range: Modules Idx: 29 - 0x00007ffff76db000-0x00007ffff7851000 +[+] Range: Modules Idx: 30 - 0x00007ffff7851000-0x00007ffff789b000 +[+] Range: Modules Idx: 31 - 0x00007ffff789b000-0x00007ffff789c000 +[+] Range: Modules Idx: 32 - 0x00007ffff789c000-0x00007ffff789f000 +[+] Range: Modules Idx: 33 - 0x00007ffff789f000-0x00007ffff78a2000 +[+] Range: Modules Idx: 34 - 0x00007ffff78a2000-0x00007ffff78a6000 +[+] Range: Modules Idx: 35 - 0x00007ffff78a9000-0x00007ffff78aa000 +[+] Range: Modules Idx: 36 - 0x00007ffff78aa000-0x00007ffff78ab000 +[+] Range: Modules Idx: 37 - 0x00007ffff78af000-0x00007ffff78bf000 +[+] Range: Modules Idx: 38 - 0x00007ffff78bf000-0x00007ffff7942000 +[+] Range: Modules Idx: 39 - 0x00007ffff7942000-0x00007ffff7a94000 +[+] Range: Modules Idx: 40 - 0x00007ffff7a94000-0x00007ffff7db0000 +[+] Range: Modules Idx: 41 - 0x00007ffff7db0000-0x00007ffff7dbc000 +[+] Range: Modules Idx: 42 - 0x00007ffff7dbc000-0x00007ffff7dc4000 +[+] Range: Modules Idx: 43 - 0x00007ffff7dc4000-0x00007ffff7fcb000 +[+] Range: Modules Idx: 44 - 0x00007ffff7fcb000-0x00007ffff7fce000 +[+] Range: Modules Idx: 45 - 0x00007ffff7fce000-0x00007ffff7fcf000 +[+] Range: Modules Idx: 46 - 0x00007ffff7fcf000-0x00007ffff7fd0000 +[+] Range: Modules Idx: 47 - 0x00007ffff7fd0000-0x00007ffff7ff3000 +[+] Range: Modules Idx: 48 - 0x00007ffff7ff3000-0x00007ffff7ffb000 +[+] Range: Modules Idx: 49 - 0x00007ffff7ffc000-0x00007ffff7ffd000 +[+] Range: Modules Idx: 50 - 0x00007ffff7ffd000-0x00007ffff7ffe000 +[+] Range: Modules Idx: 51 - 0x00007ffff7ffe000-0x00007ffff7fff000 +[+] Range: Modules Idx: 52 - 0x00007ffffffdd000-0x00007ffffffff000 +[+] Range: Modules Idx: 53 - 0xffffffffff600000-0xffffffffff601000 +[+] Range: AFL_INST_LIBS Length: 1 +[+] Range: AFL_INST_LIBS Idx: 0 - 0x0000555555555160-0x0000555555555335 +[+] Range: step1 Length: 1 +[+] Range: step1 Idx: 0 - 0x0000555555555160-0x0000555555555335 +[+] Range: step2 Length: 1 +[+] Range: step2 Idx: 0 - 0x0000555555555160-0x0000555555555335 +[+] Range: step3 Length: 1 +[+] Range: step3 Idx: 0 - 0x0000555555555160-0x0000555555555335 +[+] Range: step4 Length: 55 +[+] Range: step4 Idx: 0 - 0x0000555555554000-0x0000555555555000 +[+] Range: step4 Idx: 1 - 0x0000555555555000-0x0000555555555160 +[+] Range: step4 Idx: 2 - 0x0000555555555335-0x0000555555556000 +[+] Range: step4 Idx: 3 - 0x0000555555556000-0x0000555555557000 +[+] Range: step4 Idx: 4 - 0x0000555555557000-0x0000555555558000 +[+] Range: step4 Idx: 5 - 0x0000555555558000-0x0000555555559000 +[+] Range: step4 Idx: 6 - 0x0000555555559000-0x000055555557a000 +[+] Range: step4 Idx: 7 - 0x00007ffff7615000-0x00007ffff7625000 +[+] Range: step4 Idx: 8 - 0x00007ffff766d000-0x00007ffff766f000 +[+] Range: step4 Idx: 9 - 0x00007ffff766f000-0x00007ffff7670000 +[+] Range: step4 Idx: 10 - 0x00007ffff7670000-0x00007ffff7672000 +[+] Range: step4 Idx: 11 - 0x00007ffff7672000-0x00007ffff7673000 +[+] Range: step4 Idx: 12 - 0x00007ffff7673000-0x00007ffff7674000 +[+] Range: step4 Idx: 13 - 0x00007ffff7674000-0x00007ffff7675000 +[+] Range: step4 Idx: 14 - 0x00007ffff7675000-0x00007ffff7679000 +[+] Range: step4 Idx: 15 - 0x00007ffff7679000-0x00007ffff7689000 +[+] Range: step4 Idx: 16 - 0x00007ffff7689000-0x00007ffff768c000 +[+] Range: step4 Idx: 17 - 0x00007ffff768c000-0x00007ffff768d000 +[+] Range: step4 Idx: 18 - 0x00007ffff768d000-0x00007ffff768e000 +[+] Range: step4 Idx: 19 - 0x00007ffff768e000-0x00007ffff768f000 +[+] Range: step4 Idx: 20 - 0x00007ffff768f000-0x00007ffff7691000 +[+] Range: step4 Idx: 21 - 0x00007ffff7691000-0x00007ffff7698000 +[+] Range: step4 Idx: 22 - 0x00007ffff7698000-0x00007ffff76a9000 +[+] Range: step4 Idx: 23 - 0x00007ffff76a9000-0x00007ffff76ae000 +[+] Range: step4 Idx: 24 - 0x00007ffff76ae000-0x00007ffff76af000 +[+] Range: step4 Idx: 25 - 0x00007ffff76af000-0x00007ffff76b0000 +[+] Range: step4 Idx: 26 - 0x00007ffff76b0000-0x00007ffff76b4000 +[+] Range: step4 Idx: 27 - 0x00007ffff76b4000-0x00007ffff76d9000 +[+] Range: step4 Idx: 28 - 0x00007ffff76d9000-0x00007ffff76da000 +[+] Range: step4 Idx: 29 - 0x00007ffff76da000-0x00007ffff76db000 +[+] Range: step4 Idx: 30 - 0x00007ffff76db000-0x00007ffff7851000 +[+] Range: step4 Idx: 31 - 0x00007ffff7851000-0x00007ffff789b000 +[+] Range: step4 Idx: 32 - 0x00007ffff789b000-0x00007ffff789c000 +[+] Range: step4 Idx: 33 - 0x00007ffff789c000-0x00007ffff789f000 +[+] Range: step4 Idx: 34 - 0x00007ffff789f000-0x00007ffff78a2000 +[+] Range: step4 Idx: 35 - 0x00007ffff78a2000-0x00007ffff78a6000 +[+] Range: step4 Idx: 36 - 0x00007ffff78a9000-0x00007ffff78aa000 +[+] Range: step4 Idx: 37 - 0x00007ffff78aa000-0x00007ffff78ab000 +[+] Range: step4 Idx: 38 - 0x00007ffff78af000-0x00007ffff78bf000 +[+] Range: step4 Idx: 39 - 0x00007ffff78bf000-0x00007ffff7942000 +[+] Range: step4 Idx: 40 - 0x00007ffff7942000-0x00007ffff7a94000 +[+] Range: step4 Idx: 41 - 0x00007ffff7a94000-0x00007ffff7db0000 +[+] Range: step4 Idx: 42 - 0x00007ffff7db0000-0x00007ffff7dbc000 +[+] Range: step4 Idx: 43 - 0x00007ffff7dbc000-0x00007ffff7dc4000 +[+] Range: step4 Idx: 44 - 0x00007ffff7dc4000-0x00007ffff7fcb000 +[+] Range: step4 Idx: 45 - 0x00007ffff7fcb000-0x00007ffff7fce000 +[+] Range: step4 Idx: 46 - 0x00007ffff7fce000-0x00007ffff7fcf000 +[+] Range: step4 Idx: 47 - 0x00007ffff7fcf000-0x00007ffff7fd0000 +[+] Range: step4 Idx: 48 - 0x00007ffff7fd0000-0x00007ffff7ff3000 +[+] Range: step4 Idx: 49 - 0x00007ffff7ff3000-0x00007ffff7ffb000 +[+] Range: step4 Idx: 50 - 0x00007ffff7ffc000-0x00007ffff7ffd000 +[+] Range: step4 Idx: 51 - 0x00007ffff7ffd000-0x00007ffff7ffe000 +[+] Range: step4 Idx: 52 - 0x00007ffff7ffe000-0x00007ffff7fff000 +[+] Range: step4 Idx: 53 - 0x00007ffffffdd000-0x00007ffffffff000 +[+] Range: step4 Idx: 54 - 0xffffffffff600000-0xffffffffff601000 +[+] Range: final Length: 9 +[+] Range: final Idx: 0 - 0x0000555555554000-0x0000555555555160 +[+] Range: final Idx: 1 - 0x0000555555555335-0x000055555557a000 +[+] Range: final Idx: 2 - 0x00007ffff7615000-0x00007ffff7625000 +[+] Range: final Idx: 3 - 0x00007ffff766d000-0x00007ffff78a6000 +[+] Range: final Idx: 4 - 0x00007ffff78a9000-0x00007ffff78ab000 +[+] Range: final Idx: 5 - 0x00007ffff78af000-0x00007ffff7ffb000 +[+] Range: final Idx: 6 - 0x00007ffff7ffc000-0x00007ffff7fff000 +[+] Range: final Idx: 7 - 0x00007ffffffdd000-0x00007ffffffff000 +[+] Range: final Idx: 8 - 0xffffffffff600000-0xffffffffff601000 +Looks like a zero to me! +0x00007ffff7dbc000 +[+] Range: step4 Idx: 43 - 0x00007ffff7dbc000-0x00007ffff7dc4000 +[+] Range: step4 Idx: 44 - 0x00007ffff7dc4000-0x00007ffff7fcb000 +[+] Range: step4 Idx: 45 - 0x00007ffff7fcb000-0x00007ffff7fce000 +[+] Range: step4 Idx: 46 - 0x00007ffff7fce000-0x00007ffff7fcf000 +[+] Range: step4 Idx: 47 - 0x00007ffff7fcf000-0x00007ffff7fd0000 +[+] Range: step4 Idx: 48 - 0x00007ffff7fd0000-0x00007ffff7ff3000 +[+] Range: step4 Idx: 49 - 0x00007ffff7ff3000-0x00007ffff7ffb000 +[+] Range: step4 Idx: 50 - 0x00007ffff7ffc000-0x00007ffff7ffd000 +[+] Range: step4 Idx: 51 - 0x00007ffff7ffd000-0x00007ffff7ffe000 +[+] Range: step4 Idx: 52 - 0x00007ffff7ffe000-0x00007ffff7fff000 +[+] Range: step4 Idx: 53 - 0x00007ffffffdd000-0x00007ffffffff000 +[+] Range: step4 Idx: 54 - 0xffffffffff600000-0xffffffffff601000 +[+] Range: final Length: 9 +[+] Range: final Idx: 0 - 0x0000555555554000-0x0000555555555160 +[+] Range: final Idx: 1 - 0x0000555555555335-0x000055555557a000 +[+] Range: final Idx: 2 - 0x00007ffff7615000-0x00007ffff7625000 +[+] Range: final Idx: 3 - 0x00007ffff766d000-0x00007ffff78a6000 +[+] Range: final Idx: 4 - 0x00007ffff78a9000-0x00007ffff78ab000 +[+] Range: final Idx: 5 - 0x00007ffff78af000-0x00007ffff7ffb000 +[+] Range: final Idx: 6 - 0x00007ffff7ffc000-0x00007ffff7fff000 +[+] Range: final Idx: 7 - 0x00007ffffffdd000-0x00007ffffffff000 +[+] Range: final Idx: 8 - 0xffffffffff600000-0xffffffffff601000 +Looks like a zero to me! +0x00007ffff7dbc000 +[+] Range: step4 Idx: 43 - 0x00007ffff7dbc000-0x00007ffff7dc4000 +[+] Range: step4 Idx: 44 - 0x00007ffff7dc4000-0x00007ffff7fcb000 +[+] Range: step4 Idx: 45 - 0x00007ffff7fcb000-0x00007ffff7fce000 +[+] Range: step4 Idx: 46 - 0x00007ffff7fce000-0x00007ffff7fcf000 +[+] Range: step4 Idx: 47 - 0x00007ffff7fcf000-0x00007ffff7fd0000 +[+] Range: step4 Idx: 48 - 0x00007ffff7fd0000-0x00007ffff7ff3000 +[+] Range: step4 Idx: 49 - 0x00007ffff7ff3000-0x00007ffff7ffb000 +[+] Range: step4 Idx: 50 - 0x00007ffff7ffc000-0x00007ffff7ffd000 +[+] Range: step4 Idx: 51 - 0x00007ffff7ffd000-0x00007ffff7ffe000 +[+] Range: step4 Idx: 52 - 0x00007ffff7ffe000-0x00007ffff7fff000 +[+] Range: step4 Idx: 53 - 0x00007ffffffdd000-0x00007ffffffff000 +[+] Range: step4 Idx: 54 - 0xffffffffff600000-0xffffffffff601000 +[+] Range: final Length: 9 +[+] Range: final Idx: 0 - 0x0000555555554000-0x0000555555555160 +[+] Range: final Idx: 1 - 0x0000555555555335-0x000055555557a000 +[+] Range: final Idx: 2 - 0x00007ffff7615000-0x00007ffff7625000 +[+] Range: final Idx: 3 - 0x00007ffff766d000-0x00007ffff78a6000 +[+] Range: final Idx: 4 - 0x00007ffff78a9000-0x00007ffff78ab000 +[+] Range: final Idx: 5 - 0x00007ffff78af000-0x00007ffff7ffb000 +[+] Range: final Idx: 6 - 0x00007ffff7ffc000-0x00007ffff7fff000 +[+] Range: final Idx: 7 - 0x00007ffffffdd000-0x00007ffffffff000 +[+] Range: final Idx: 8 - 0xffffffffff600000-0xffffffffff601000 +Looks like a zero to me! +0x00007ffff7dbc000 +[+] Range: step4 Idx: 43 - 0x00007ffff7dbc000-0x00007ffff7dc4000 +[+] Range: step4 Idx: 44 - 0x00007ffff7dc4000-0x00007ffff7fcb000 +[+] Range: step4 Idx: 45 - 0x00007ffff7fcb000-0x00007ffff7fce000 +[+] Range: step4 Idx: 46 - 0x00007ffff7fce000-0x00007ffff7fcf000 +[+] Range: step4 Idx: 47 - 0x00007ffff7fcf000-0x00007ffff7fd0000 +[+] Range: step4 Idx: 48 - 0x00007ffff7fd0000-0x00007ffff7ff3000 +[+] Range: step4 Idx: 49 - 0x00007ffff7ff3000-0x00007ffff7ffb000 +[+] Range: step4 Idx: 50 - 0x00007ffff7ffc000-0x00007ffff7ffd000 +[+] Range: step4 Idx: 51 - 0x00007ffff7ffd000-0x00007ffff7ffe000 +[+] Range: step4 Idx: 52 - 0x00007ffff7ffe000-0x00007ffff7fff000 +[+] Range: step4 Idx: 53 - 0x00007ffffffdd000-0x00007ffffffff000 +[+] Range: step4 Idx: 54 - 0xffffffffff600000-0xffffffffff601000 +[+] Range: final Length: 9 +[+] Range: final Idx: 0 - 0x0000555555554000-0x0000555555555160 +[+] Range: final Idx: 1 - 0x0000555555555335-0x000055555557a000 +[+] Range: final Idx: 2 - 0x00007ffff7615000-0x00007ffff7625000 +[+] Range: final Idx: 3 - 0x00007ffff766d000-0x00007ffff78a6000 +[+] Range: final Idx: 4 - 0x00007ffff78a9000-0x00007ffff78ab000 +[+] Range: final Idx: 5 - 0x00007ffff78af000-0x00007ffff7ffb000 +[+] Range: final Idx: 6 - 0x00007ffff7ffc000-0x00007ffff7fff000 +[+] Range: final Idx: 7 - 0x00007ffffffdd000-0x00007ffffffff000 +[+] Range: final Idx: 8 - 0xffffffffff600000-0xffffffffff601000 +Looks like a zero to me! +0x00007ffff7dbc000 +[+] Range: step4 Idx: 43 - 0x00007ffff7dbc000-0x00007ffff7dc4000 +[+] Range: step4 Idx: 44 - 0x00007ffff7dc4000-0x00007ffff7fcb000 +[+] Range: step4 Idx: 45 - 0x00007ffff7fcb000-0x00007ffff7fce000 +[+] Range: step4 Idx: 46 - 0x00007ffff7fce000-0x00007ffff7fcf000 +[+] Range: step4 Idx: 47 - 0x00007ffff7fcf000-0x00007ffff7fd0000 +[+] Range: step4 Idx: 48 - 0x00007ffff7fd0000-0x00007ffff7ff3000 +[+] Range: step4 Idx: 49 - 0x00007ffff7ff3000-0x00007ffff7ffb000 +[+] Range: step4 Idx: 50 - 0x00007ffff7ffc000-0x00007ffff7ffd000 +[+] Range: step4 Idx: 51 - 0x00007ffff7ffd000-0x00007ffff7ffe000 +[+] Range: step4 Idx: 52 - 0x00007ffff7ffe000-0x00007ffff7fff000 +[+] Range: step4 Idx: 53 - 0x00007ffffffdd000-0x00007ffffffff000 +[+] Range: step4 Idx: 54 - 0xffffffffff600000-0xffffffffff601000 +[+] Range: final Length: 9 +[+] Range: final Idx: 0 - 0x0000555555554000-0x0000555555555160 +[+] Range: final Idx: 1 - 0x0000555555555335-0x000055555557a000 +[+] Range: final Idx: 2 - 0x00007ffff7615000-0x00007ffff7625000 +[+] Range: final Idx: 3 - 0x00007ffff766d000-0x00007ffff78a6000 +[+] Range: final Idx: 4 - 0x00007ffff78a9000-0x00007ffff78ab000 +[+] Range: final Idx: 5 - 0x00007ffff78af000-0x00007ffff7ffb000 +[+] Range: final Idx: 6 - 0x00007ffff7ffc000-0x00007ffff7fff000 +[+] Range: final Idx: 7 - 0x00007ffffffdd000-0x00007ffffffff000 +[+] Range: final Idx: 8 - 0xffffffffff600000-0xffffffffff601000 +Looks like a zero to me! +0x00007ffff7dbc000 +[+] Range: step4 Idx: 43 - 0x00007ffff7dbc000-0x00007ffff7dc4000 +[+] Range: step4 Idx: 44 - 0x00007ffff7dc4000-0x00007ffff7fcb000 +[+] Range: step4 Idx: 45 - 0x00007ffff7fcb000-0x00007ffff7fce000 +[+] Range: step4 Idx: 46 - 0x00007ffff7fce000-0x00007ffff7fcf000 +[+] Range: step4 Idx: 47 - 0x00007ffff7fcf000-0x00007ffff7fd0000 +[+] Range: step4 Idx: 48 - 0x00007ffff7fd0000-0x00007ffff7ff3000 +[+] Range: step4 Idx: 49 - 0x00007ffff7ff3000-0x00007ffff7ffb000 +[+] Range: step4 Idx: 50 - 0x00007ffff7ffc000-0x00007ffff7ffd000 +[+] Range: step4 Idx: 51 - 0x00007ffff7ffd000-0x00007ffff7ffe000 +[+] Range: step4 Idx: 52 - 0x00007ffff7ffe000-0x00007ffff7fff000 +[+] Range: step4 Idx: 53 - 0x00007ffffffdd000-0x00007ffffffff000 +[+] Range: step4 Idx: 54 - 0xffffffffff600000-0xffffffffff601000 +[+] Range: final Length: 9 +[+] Range: final Idx: 0 - 0x0000555555554000-0x0000555555555160 +[+] Range: final Idx: 1 - 0x0000555555555335-0x000055555557a000 +[+] Range: final Idx: 2 - 0x00007ffff7615000-0x00007ffff7625000 +[+] Range: final Idx: 3 - 0x00007ffff766d000-0x00007ffff78a6000 +[+] Range: final Idx: 4 - 0x00007ffff78a9000-0x00007ffff78ab000 +[+] Range: final Idx: 5 - 0x00007ffff78af000-0x00007ffff7ffb000 +[+] Range: final Idx: 6 - 0x00007ffff7ffc000-0x00007ffff7fff000 +[+] Range: final Idx: 7 - 0x00007ffffffdd000-0x00007ffffffff000 +[+] Range: final Idx: 8 - 0xffffffffff600000-0xffffffffff601000 +Looks like a zero to me! +0x00007ffff7dbc000 +[+] Range: step4 Idx: 43 - 0x00007ffff7dbc000-0x00007ffff7dc4000 +[+] Range: step4 Idx: 44 - 0x00007ffff7dc4000-0x00007ffff7fcb000 +[+] Range: step4 Idx: 45 - 0x00007ffff7fcb000-0x00007ffff7fce000 +[+] Range: step4 Idx: 46 - 0x00007ffff7fce000-0x00007ffff7fcf000 +[+] Range: step4 Idx: 47 - 0x00007ffff7fcf000-0x00007ffff7fd0000 +[+] Range: step4 Idx: 48 - 0x00007ffff7fd0000-0x00007ffff7ff3000 +[+] Range: step4 Idx: 49 - 0x00007ffff7ff3000-0x00007ffff7ffb000 +[+] Range: step4 Idx: 50 - 0x00007ffff7ffc000-0x00007ffff7ffd000 +[+] Range: step4 Idx: 51 - 0x00007ffff7ffd000-0x00007ffff7ffe000 +[+] Range: step4 Idx: 52 - 0x00007ffff7ffe000-0x00007ffff7fff000 +[+] Range: step4 Idx: 53 - 0x00007ffffffdd000-0x00007ffffffff000 +[+] Range: step4 Idx: 54 - 0xffffffffff600000-0xffffffffff601000 +[+] Range: final Length: 9 +[+] Range: final Idx: 0 - 0x0000555555554000-0x0000555555555160 +[+] Range: final Idx: 1 - 0x0000555555555335-0x000055555557a000 +[+] Range: final Idx: 2 - 0x00007ffff7615000-0x00007ffff7625000 +[+] Range: final Idx: 3 - 0x00007ffff766d000-0x00007ffff78a6000 +[+] Range: final Idx: 4 - 0x00007ffff78a9000-0x00007ffff78ab000 +[+] Range: final Idx: 5 - 0x00007ffff78af000-0x00007ffff7ffb000 +[+] Range: final Idx: 6 - 0x00007ffff7ffc000-0x00007ffff7fff000 +[+] Range: final Idx: 7 - 0x00007ffffffdd000-0x00007ffffffff000 +[+] Range: final Idx: 8 - 0xffffffffff600000-0xffffffffff601000 +Looks like a zero to me! +0x00007ffff7dbc000 +[+] Range: step4 Idx: 43 - 0x00007ffff7dbc000-0x00007ffff7dc4000 +[+] Range: step4 Idx: 44 - 0x00007ffff7dc4000-0x00007ffff7fcb000 +[+] Range: step4 Idx: 45 - 0x00007ffff7fcb000-0x00007ffff7fce000 +[+] Range: step4 Idx: 46 - 0x00007ffff7fce000-0x00007ffff7fcf000 +[+] Range: step4 Idx: 47 - 0x00007ffff7fcf000-0x00007ffff7fd0000 +[+] Range: step4 Idx: 48 - 0x00007ffff7fd0000-0x00007ffff7ff3000 +[+] Range: step4 Idx: 49 - 0x00007ffff7ff3000-0x00007ffff7ffb000 +[+] Range: step4 Idx: 50 - 0x00007ffff7ffc000-0x00007ffff7ffd000 +[+] Range: step4 Idx: 51 - 0x00007ffff7ffd000-0x00007ffff7ffe000 +[+] Range: step4 Idx: 52 - 0x00007ffff7ffe000-0x00007ffff7fff000 +[+] Range: step4 Idx: 53 - 0x00007ffffffdd000-0x00007ffffffff000 +[+] Range: step4 Idx: 54 - 0xffffffffff600000-0xffffffffff601000 +[+] Range: final Length: 9 +[+] Range: final Idx: 0 - 0x0000555555554000-0x0000555555555160 +[+] Range: final Idx: 1 - 0x0000555555555335-0x000055555557a000 +[+] Range: final Idx: 2 - 0x00007ffff7615000-0x00007ffff7625000 +[+] Range: final Idx: 3 - 0x00007ffff766d000-0x00007ffff78a6000 +[+] Range: final Idx: 4 - 0x00007ffff78a9000-0x00007ffff78ab000 +[+] Range: final Idx: 5 - 0x00007ffff78af000-0x00007ffff7ffb000 +[+] Range: final Idx: 6 - 0x00007ffff7ffc000-0x00007ffff7fff000 +[+] Range: final Idx: 7 - 0x00007ffffffdd000-0x00007ffffffff000 +[+] Range: final Idx: 8 - 0xffffffffff600000-0xffffffffff601000 +Looks like a zero to me! diff --git a/frida_mode/test/output/testinstr.c b/frida_mode/test/output/testinstr.c new file mode 100644 index 00000000..5e26fc46 --- /dev/null +++ b/frida_mode/test/output/testinstr.c @@ -0,0 +1,112 @@ +/* + american fuzzy lop++ - a trivial program to test the build + -------------------------------------------------------- + Originally written by Michal Zalewski + Copyright 2014 Google Inc. All rights reserved. + Copyright 2019-2020 AFLplusplus Project. All rights reserved. + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at: + http://www.apache.org/licenses/LICENSE-2.0 + */ + +#include +#include +#include +#include +#include + +#ifdef __APPLE__ + #define TESTINSTR_SECTION +#else + #define TESTINSTR_SECTION __attribute__((section(".testinstr"))) +#endif + +void testinstr(char *buf, int len) { + + if (len < 1) return; + buf[len] = 0; + + // we support three input cases + if (buf[0] == '0') + printf("Looks like a zero to me!\n"); + else if (buf[0] == '1') + printf("Pretty sure that is a one!\n"); + else + printf("Neither one or zero? How quaint!\n"); + +} + +TESTINSTR_SECTION int main(int argc, char **argv) { + + char * file; + int fd = -1; + off_t len; + char * buf = NULL; + size_t n_read; + int result = -1; + + if (argc != 2) { return 1; } + + do { + + file = argv[1]; + + dprintf(STDERR_FILENO, "Running: %s\n", file); + + fd = open(file, O_RDONLY); + if (fd < 0) { + + perror("open"); + break; + + } + + len = lseek(fd, 0, SEEK_END); + if (len < 0) { + + perror("lseek (SEEK_END)"); + break; + + } + + if (lseek(fd, 0, SEEK_SET) != 0) { + + perror("lseek (SEEK_SET)"); + break; + + } + + buf = malloc(len); + if (buf == NULL) { + + perror("malloc"); + break; + + } + + n_read = read(fd, buf, len); + if (n_read != len) { + + perror("read"); + break; + + } + + dprintf(STDERR_FILENO, "Running: %s: (%zd bytes)\n", file, n_read); + + testinstr(buf, len); + dprintf(STDERR_FILENO, "Done: %s: (%zd bytes)\n", file, n_read); + + result = 0; + + } while (false); + + if (buf != NULL) { free(buf); } + + if (fd != -1) { close(fd); } + + return result; + +} + diff --git a/frida_mode/test/persistent_ret/GNUmakefile b/frida_mode/test/persistent_ret/GNUmakefile new file mode 100644 index 00000000..df48d065 --- /dev/null +++ b/frida_mode/test/persistent_ret/GNUmakefile @@ -0,0 +1,105 @@ +PWD:=$(shell pwd)/ +ROOT:=$(shell realpath $(PWD)../../..)/ +BUILD_DIR:=$(PWD)build/ +TESTINSTR_DATA_DIR:=$(BUILD_DIR)in/ +TESTINSTR_DATA_FILE:=$(TESTINSTR_DATA_DIR)in + +TESTINSTBIN:=$(BUILD_DIR)testinstr +TESTINSTSRC:=$(PWD)testinstr.c + +QEMU_OUT:=$(BUILD_DIR)qemu-out +FRIDA_OUT:=$(BUILD_DIR)frida-out + +ifndef ARCH + +ARCH=$(shell uname -m) +ifeq "$(ARCH)" "aarch64" + ARCH:=arm64 +endif + +ifeq "$(ARCH)" "i686" + ARCH:=x86 +endif +endif + +ARCH=$(shell uname -m) +ifeq "$(ARCH)" "aarch64" + AFL_FRIDA_PERSISTENT_ADDR=$(shell $(PWD)get_symbol_addr.py -f $(TESTINSTBIN) -s main -b 0x0000aaaaaaaaa000) + AFL_FRIDA_PERSISTENT_RET=$(shell $(PWD)get_symbol_addr.py -f $(TESTINSTBIN) -s slow -b 0x0000aaaaaaaaa000) +endif + +ifeq "$(ARCH)" "x86_64" + AFL_FRIDA_PERSISTENT_ADDR=$(shell $(PWD)get_symbol_addr.py -f $(TESTINSTBIN) -s main -b 0x0000555555554000) + AFL_FRIDA_PERSISTENT_RET=$(shell $(PWD)get_symbol_addr.py -f $(TESTINSTBIN) -s slow -b 0x0000555555554000) +endif + +ifeq "$(ARCH)" "x86" + AFL_FRIDA_PERSISTENT_ADDR=$(shell $(PWD)get_symbol_addr.py -f $(TESTINSTBIN) -s main -b 0x56555000) + AFL_FRIDA_PERSISTENT_RET=$(shell $(PWD)get_symbol_addr.py -f $(TESTINSTBIN) -s slow -b 0x56555000) +endif + +AFL_FRIDA_PERSISTENT_RETADDR_OFFSET:=0x50 + +.PHONY: all 32 clean qemu frida + +all: $(TESTINSTBIN) + make -C $(ROOT)frida_mode/ + +32: + CFLAGS="-m32" LDFLAGS="-m32" ARCH="x86" make all + +$(BUILD_DIR): + mkdir -p $@ + +$(TESTINSTR_DATA_DIR): | $(BUILD_DIR) + mkdir -p $@ + +$(TESTINSTR_DATA_FILE): | $(TESTINSTR_DATA_DIR) + echo -n "000" > $@ + +$(TESTINSTBIN): $(TESTINSTSRC) | $(BUILD_DIR) + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< + +clean: + rm -rf $(BUILD_DIR) + +frida: $(TESTINSTBIN) $(TESTINSTR_DATA_FILE) + AFL_FRIDA_PERSISTENT_ADDR=$(AFL_FRIDA_PERSISTENT_ADDR) \ + $(ROOT)afl-fuzz \ + -D \ + -O \ + -i $(TESTINSTR_DATA_DIR) \ + -o $(FRIDA_OUT) \ + -- \ + $(TESTINSTBIN) @@ + +frida_ret: $(TESTINSTBIN) $(TESTINSTR_DATA_FILE) + AFL_FRIDA_PERSISTENT_ADDR=$(AFL_FRIDA_PERSISTENT_ADDR) \ + AFL_FRIDA_PERSISTENT_RET=$(AFL_FRIDA_PERSISTENT_RET) \ + AFL_FRIDA_PERSISTENT_RETADDR_OFFSET=$(AFL_FRIDA_PERSISTENT_RETADDR_OFFSET) \ + $(ROOT)afl-fuzz \ + -D \ + -O \ + -i $(TESTINSTR_DATA_DIR) \ + -o $(FRIDA_OUT) \ + -- \ + $(TESTINSTBIN) @@ + +debug: $(TESTINSTR_DATA_FILE) + gdb \ + --ex 'set environment AFL_FRIDA_PERSISTENT_ADDR=$(AFL_FRIDA_PERSISTENT_ADDR)' \ + --ex 'set environment AFL_FRIDA_PERSISTENT_RET=$(AFL_FRIDA_PERSISTENT_RET)' \ + --ex 'set environment AFL_FRIDA_PERSISTENT_RETADDR_OFFSET=$(AFL_FRIDA_PERSISTENT_RETADDR_OFFSET)' \ + --ex 'set environment AFL_FRIDA_PERSISTENT_DEBUG=1' \ + --ex 'set environment AFL_DEBUG_CHILD=1' \ + --ex 'set environment LD_PRELOAD=$(ROOT)afl-frida-trace.so' \ + --ex 'set disassembly-flavor intel' \ + --args $(TESTINSTBIN) $(TESTINSTR_DATA_FILE) + +run: $(TESTINSTR_DATA_FILE) + AFL_FRIDA_PERSISTENT_ADDR=$(AFL_FRIDA_PERSISTENT_ADDR) \ + AFL_FRIDA_PERSISTENT_RET=$(AFL_FRIDA_PERSISTENT_RET) \ + AFL_FRIDA_PERSISTENT_RETADDR_OFFSET=$(AFL_FRIDA_PERSISTENT_RETADDR_OFFSET) \ + AFL_DEBUG_CHILD=1 \ + LD_PRELOAD=$(ROOT)afl-frida-trace.so \ + $(TESTINSTBIN) $(TESTINSTR_DATA_FILE) diff --git a/frida_mode/test/persistent_ret/Makefile b/frida_mode/test/persistent_ret/Makefile new file mode 100644 index 00000000..e3deddbd --- /dev/null +++ b/frida_mode/test/persistent_ret/Makefile @@ -0,0 +1,22 @@ +all: + @echo trying to use GNU make... + @gmake all || echo please install GNUmake + +32: + @echo trying to use GNU make... + @gmake 32 || echo please install GNUmake + +clean: + @gmake clean + +frida: + @gmake frida + +frida_ret: + @gmake frida_ret + +debug: + @gmake debug + +run: + @gmake run diff --git a/frida_mode/test/persistent_ret/get_symbol_addr.py b/frida_mode/test/persistent_ret/get_symbol_addr.py new file mode 100755 index 00000000..1c46e010 --- /dev/null +++ b/frida_mode/test/persistent_ret/get_symbol_addr.py @@ -0,0 +1,36 @@ +#!/usr/bin/python3 +import argparse +from elftools.elf.elffile import ELFFile + +def process_file(file, symbol, base): + with open(file, 'rb') as f: + elf = ELFFile(f) + symtab = elf.get_section_by_name('.symtab') + mains = symtab.get_symbol_by_name(symbol) + if len(mains) != 1: + print ("Failed to find main") + return 1 + + main_addr = mains[0]['st_value'] + main = base + main_addr + print ("0x%016x" % main) + return 0 + +def hex_value(x): + return int(x, 16) + +def main(): + parser = argparse.ArgumentParser(description='Process some integers.') + parser.add_argument('-f', '--file', dest='file', type=str, + help='elf file name', required=True) + parser.add_argument('-s', '--symbol', dest='symbol', type=str, + help='symbol name', required=True) + parser.add_argument('-b', '--base', dest='base', type=hex_value, + help='elf base address', required=True) + + args = parser.parse_args() + return process_file (args.file, args.symbol, args.base) + +if __name__ == "__main__": + ret = main() + exit(ret) diff --git a/frida_mode/test/persistent_ret/testinstr.c b/frida_mode/test/persistent_ret/testinstr.c new file mode 100644 index 00000000..6cb88a50 --- /dev/null +++ b/frida_mode/test/persistent_ret/testinstr.c @@ -0,0 +1,120 @@ +/* + american fuzzy lop++ - a trivial program to test the build + -------------------------------------------------------- + Originally written by Michal Zalewski + Copyright 2014 Google Inc. All rights reserved. + Copyright 2019-2020 AFLplusplus Project. All rights reserved. + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at: + http://www.apache.org/licenses/LICENSE-2.0 + */ + +#include +#include +#include +#include +#include + +#ifdef __APPLE__ + #define TESTINSTR_SECTION +#else + #define TESTINSTR_SECTION __attribute__((section(".testinstr"))) +#endif + +void testinstr(char *buf, int len) { + + if (len < 1) return; + buf[len] = 0; + + // we support three input cases + if (buf[0] == '0') + printf("Looks like a zero to me!\n"); + else if (buf[0] == '1') + printf("Pretty sure that is a one!\n"); + else + printf("Neither one or zero? How quaint!\n"); + +} + +void slow() { + + usleep(100000); + +} + +TESTINSTR_SECTION int main(int argc, char **argv) { + + char * file; + int fd = -1; + off_t len; + char * buf = NULL; + size_t n_read; + int result = -1; + + if (argc != 2) { return 1; } + + do { + + file = argv[1]; + + dprintf(STDERR_FILENO, "Running: %s\n", file); + + fd = open(file, O_RDONLY); + if (fd < 0) { + + perror("open"); + break; + + } + + len = lseek(fd, 0, SEEK_END); + if (len < 0) { + + perror("lseek (SEEK_END)"); + break; + + } + + if (lseek(fd, 0, SEEK_SET) != 0) { + + perror("lseek (SEEK_SET)"); + break; + + } + + buf = malloc(len); + if (buf == NULL) { + + perror("malloc"); + break; + + } + + n_read = read(fd, buf, len); + if (n_read != len) { + + perror("read"); + break; + + } + + dprintf(STDERR_FILENO, "Running: %s: (%zd bytes)\n", file, n_read); + + testinstr(buf, len); + dprintf(STDERR_FILENO, "Done: %s: (%zd bytes)\n", file, n_read); + + slow(); + + result = 0; + + } while (false); + + if (buf != NULL) { free(buf); } + + if (fd != -1) { close(fd); } + + return result; + +} + diff --git a/frida_mode/test/re2/GNUmakefile b/frida_mode/test/re2/GNUmakefile new file mode 100644 index 00000000..9f0b31d3 --- /dev/null +++ b/frida_mode/test/re2/GNUmakefile @@ -0,0 +1,170 @@ +PWD:=$(shell pwd)/ +ROOT:=$(shell realpath $(PWD)../../..)/ +BUILD_DIR:=$(PWD)build/ + +AFLPP_DRIVER_HOOK_SRC=$(PWD)aflpp_qemu_driver_hook.c +AFLPP_DRIVER_HOOK_OBJ=$(BUILD_DIR)aflpp_qemu_driver_hook.so + +LIBRE2_BUILD_DIR:=$(BUILD_DIR)libre2/ +HARNESS_BUILD_DIR:=$(BUILD_DIR)harness/ +RE2TEST_BUILD_DIR:=$(BUILD_DIR)re2test/ + +LIBRE2_URL:=https://github.com/google/re2.git +LIBRE2_DIR:=$(LIBRE2_BUILD_DIR)libre2/ +LIBRE2_MAKEFILE:=$(LIBRE2_DIR)Makefile +LIBRE2_LIB:=$(LIBRE2_DIR)obj/libre2.a + +HARNESS_FILE:=$(HARNESS_BUILD_DIR)StandaloneFuzzTargetMain.c +HARNESS_OBJ:=$(HARNESS_BUILD_DIR)StandaloneFuzzTargetMain.o +HARNESS_URL:="https://raw.githubusercontent.com/llvm/llvm-project/main/compiler-rt/lib/fuzzer/standalone/StandaloneFuzzTargetMain.c" + +RE2TEST_FILE:=$(RE2TEST_BUILD_DIR)target.cc +RE2TEST_OBJ:=$(RE2TEST_BUILD_DIR)target.o +RE2TEST_URL:="https://raw.githubusercontent.com/google/fuzzbench/master/benchmarks/re2-2014-12-09/target.cc" + +LDFLAGS += -lpthread + +TEST_BIN:=$(BUILD_DIR)test +ifeq "$(shell uname)" "Darwin" +TEST_BIN_LDFLAGS:=-undefined dynamic_lookup +endif + +TEST_DATA_DIR:=$(BUILD_DIR)in/ +AFLPP_DRIVER_DUMMY_INPUT:=$(TEST_DATA_DIR)in + +QEMU_OUT:=$(BUILD_DIR)qemu-out +FRIDA_OUT:=$(BUILD_DIR)frida-out + +ifndef ARCH + +ARCH=$(shell uname -m) +ifeq "$(ARCH)" "aarch64" + ARCH:=arm64 +endif + +ifeq "$(ARCH)" "i686" + ARCH:=x86 +endif +endif + +AFL_QEMU_PERSISTENT_ADDR=$(shell $(PWD)get_symbol_addr.py -f $(TEST_BIN) -s LLVMFuzzerTestOneInput -b 0x4000000000) + +ifeq "$(ARCH)" "aarch64" + AFL_FRIDA_PERSISTENT_ADDR=$(shell $(PWD)get_symbol_addr.py -f $(TEST_BIN) -s LLVMFuzzerTestOneInput -b 0x0000aaaaaaaaa000) +endif + +ifeq "$(ARCH)" "x86_64" + AFL_FRIDA_PERSISTENT_ADDR=$(shell $(PWD)get_symbol_addr.py -f $(TEST_BIN) -s LLVMFuzzerTestOneInput -b 0x0000555555554000) +endif + +ifeq "$(ARCH)" "x86" + AFL_FRIDA_PERSISTENT_ADDR=$(shell $(PWD)get_symbol_addr.py -f $(TEST_BIN) -s LLVMFuzzerTestOneInput -b 0x56555000) +endif + +.PHONY: all clean qemu frida hook + +all: $(TEST_BIN) + make -C $(ROOT)frida_mode/ + +32: + CXXFLAGS="-m32" LDFLAGS="-m32" ARCH="x86" make all + +$(BUILD_DIR): + mkdir -p $@ + +######### HARNESS ######## +$(HARNESS_BUILD_DIR): | $(BUILD_DIR) + mkdir -p $@ + +$(HARNESS_FILE): | $(HARNESS_BUILD_DIR) + wget -O $@ $(HARNESS_URL) + +$(HARNESS_OBJ): $(HARNESS_FILE) + $(CC) $(CXXFLAGS) $(LDFLAGS) -o $@ -c $< + +######### RE2TEST ######## + +$(RE2TEST_BUILD_DIR): | $(BUILD_DIR) + mkdir -p $@ + +$(RE2TEST_FILE): | $(RE2TEST_BUILD_DIR) + wget -O $@ $(RE2TEST_URL) + +$(RE2TEST_OBJ): $(RE2TEST_FILE) | $(LIBRE2_MAKEFILE) + $(CXX) $(CXXFLAGS) $(LDFLAGS) -std=c++11 -I $(LIBRE2_DIR) -o $@ -c $< + +######### LIBRE2 ######## + +$(LIBRE2_BUILD_DIR): | $(BUILD_DIR) + mkdir -p $@ + +$(LIBRE2_MAKEFILE): $(LIBRE2_BUILD_DIR) + git clone https://github.com/google/re2.git $(LIBRE2_DIR) + cd $(LIBRE2_DIR) && git checkout 499ef7eff7455ce9c9fae86111d4a77b6ac335de + +$(LIBRE2_LIB): $(LIBRE2_MAKEFILE) + make -C $(LIBRE2_DIR) -j $(shell nproc) + +######### TEST ######## + +$(TEST_BIN): $(HARNESS_OBJ) $(RE2TEST_OBJ) $(LIBRE2_LIB) + $(CXX) \ + $(CFLAGS) \ + -o $@ \ + $(HARNESS_OBJ) $(RE2TEST_OBJ) $(LIBRE2_LIB) \ + -lz \ + $(LDFLAGS) \ + $(TEST_BIN_LDFLAGS) \ + +########## HOOK ######## + +$(AFLPP_DRIVER_HOOK_OBJ): $(AFLPP_DRIVER_HOOK_SRC) | $(BUILD_DIR) + $(CC) -shared $(CFLAGS) $(LDFLAGS) $< -o $@ + +########## DUMMY ####### + +$(TEST_DATA_DIR): | $(BUILD_DIR) + mkdir -p $@ + +$(AFLPP_DRIVER_DUMMY_INPUT): | $(TEST_DATA_DIR) + truncate -s 1M $@ + +###### TEST DATA ####### + +hook: $(AFLPP_DRIVER_HOOK_OBJ) + +clean: + rm -rf $(BUILD_DIR) + +qemu: $(TEST_BIN) $(AFLPP_DRIVER_HOOK_OBJ) $(AFLPP_DRIVER_DUMMY_INPUT) + AFL_QEMU_PERSISTENT_HOOK=$(AFLPP_DRIVER_HOOK_OBJ) \ + AFL_ENTRYPOINT=$(AFL_QEMU_PERSISTENT_ADDR) \ + AFL_QEMU_PERSISTENT_ADDR=$(AFL_QEMU_PERSISTENT_ADDR) \ + AFL_QEMU_PERSISTENT_GPR=1 \ + $(ROOT)afl-fuzz \ + -D \ + -V 30 \ + -Q \ + -i $(TEST_DATA_DIR) \ + -o $(QEMU_OUT) \ + -- \ + $(TEST_BIN) $(AFLPP_DRIVER_DUMMY_INPUT) + +frida: $(TEST_BIN) $(AFLPP_DRIVER_HOOK_OBJ) $(AFLPP_DRIVER_DUMMY_INPUT) + AFL_FRIDA_PERSISTENT_HOOK=$(AFLPP_DRIVER_HOOK_OBJ) \ + AFL_FRIDA_PERSISTENT_ADDR=$(AFL_FRIDA_PERSISTENT_ADDR) \ + AFL_ENTRYPOINT=$(AFL_FRIDA_PERSISTENT_ADDR) \ + $(ROOT)afl-fuzz \ + -D \ + -V 30 \ + -O \ + -i $(TEST_DATA_DIR) \ + -o $(FRIDA_OUT) \ + -- \ + $(TEST_BIN) $(AFLPP_DRIVER_DUMMY_INPUT) + +debug: + gdb \ + --ex 'set environment LD_PRELOAD=$(ROOT)afl-frida-trace.so' \ + --ex 'set disassembly-flavor intel' \ + --args $(TEST_BIN) $(TEST_DATA_DIR)basn0g01.re2 diff --git a/frida_mode/test/re2/Makefile b/frida_mode/test/re2/Makefile new file mode 100644 index 00000000..00b2b287 --- /dev/null +++ b/frida_mode/test/re2/Makefile @@ -0,0 +1,22 @@ +all: + @echo trying to use GNU make... + @gmake all || echo please install GNUmake + +32: + @echo trying to use GNU make... + @gmake 32 || echo please install GNUmake + +clean: + @gmake clean + +qemu: + @gmake qemu + +frida: + @gmake frida + +debug: + @gmake debug + +hook: + @gmake hook diff --git a/frida_mode/test/re2/aflpp_qemu_driver_hook.c b/frida_mode/test/re2/aflpp_qemu_driver_hook.c new file mode 100644 index 00000000..059d438d --- /dev/null +++ b/frida_mode/test/re2/aflpp_qemu_driver_hook.c @@ -0,0 +1,97 @@ +#include +#include + +#if defined(__x86_64__) + +struct x86_64_regs { + + uint64_t rax, rbx, rcx, rdx, rdi, rsi, rbp, r8, r9, r10, r11, r12, r13, r14, + r15; + + union { + + uint64_t rip; + uint64_t pc; + + }; + + union { + + uint64_t rsp; + uint64_t sp; + + }; + + union { + + uint64_t rflags; + uint64_t flags; + + }; + + uint8_t zmm_regs[32][64]; + +}; + +void afl_persistent_hook(struct x86_64_regs *regs, uint64_t guest_base, + uint8_t *input_buf, uint32_t input_buf_len) { + + memcpy((void *)regs->rdi, input_buf, input_buf_len); + regs->rsi = input_buf_len; + +} + +#elif defined(__i386__) + +struct x86_regs { + + uint32_t eax, ebx, ecx, edx, edi, esi, ebp; + + union { + + uint32_t eip; + uint32_t pc; + + }; + + union { + + uint32_t esp; + uint32_t sp; + + }; + + union { + + uint32_t eflags; + uint32_t flags; + + }; + + uint8_t xmm_regs[8][16]; + +}; + +void afl_persistent_hook(struct x86_regs *regs, uint64_t guest_base, + uint8_t *input_buf, uint32_t input_buf_len) { + + void **esp = (void **)regs->esp; + void * arg1 = esp[1]; + void **arg2 = &esp[2]; + memcpy(arg1, input_buf, input_buf_len); + *arg2 = (void *)input_buf_len; + +} + +#else + #pragma error "Unsupported architecture" +#endif + +int afl_persistent_hook_init(void) { + + // 1 for shared memory input (faster), 0 for normal input (you have to use + // read(), input_buf will be NULL) + return 1; + +} + diff --git a/frida_mode/test/re2/get_symbol_addr.py b/frida_mode/test/re2/get_symbol_addr.py new file mode 100755 index 00000000..1c46e010 --- /dev/null +++ b/frida_mode/test/re2/get_symbol_addr.py @@ -0,0 +1,36 @@ +#!/usr/bin/python3 +import argparse +from elftools.elf.elffile import ELFFile + +def process_file(file, symbol, base): + with open(file, 'rb') as f: + elf = ELFFile(f) + symtab = elf.get_section_by_name('.symtab') + mains = symtab.get_symbol_by_name(symbol) + if len(mains) != 1: + print ("Failed to find main") + return 1 + + main_addr = mains[0]['st_value'] + main = base + main_addr + print ("0x%016x" % main) + return 0 + +def hex_value(x): + return int(x, 16) + +def main(): + parser = argparse.ArgumentParser(description='Process some integers.') + parser.add_argument('-f', '--file', dest='file', type=str, + help='elf file name', required=True) + parser.add_argument('-s', '--symbol', dest='symbol', type=str, + help='symbol name', required=True) + parser.add_argument('-b', '--base', dest='base', type=hex_value, + help='elf base address', required=True) + + args = parser.parse_args() + return process_file (args.file, args.symbol, args.base) + +if __name__ == "__main__": + ret = main() + exit(ret) diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h index 72f956b9..4aba3bdf 100644 --- a/include/afl-fuzz.h +++ b/include/afl-fuzz.h @@ -385,10 +385,10 @@ typedef struct afl_env_vars { afl_force_ui, afl_i_dont_care_about_missing_crashes, afl_bench_just_one, afl_bench_until_crash, afl_debug_child, afl_autoresume, afl_cal_fast, afl_cycle_schedules, afl_expand_havoc, afl_statsd, afl_cmplog_only_new, - afl_exit_on_seed_issues; + afl_exit_on_seed_issues, afl_try_affinity; u8 *afl_tmpdir, *afl_custom_mutator_library, *afl_python_module, *afl_path, - *afl_hang_tmout, *afl_forksrv_init_tmout, *afl_skip_crashes, *afl_preload, + *afl_hang_tmout, *afl_forksrv_init_tmout, *afl_preload, *afl_max_det_extras, *afl_statsd_host, *afl_statsd_port, *afl_crash_exitcode, *afl_statsd_tags_flavor, *afl_testcache_size, *afl_testcache_entries, *afl_kill_signal, *afl_target_env, diff --git a/include/config.h b/include/config.h index aa24ea6c..80cdb684 100644 --- a/include/config.h +++ b/include/config.h @@ -154,7 +154,7 @@ cases that show variable behavior): */ #define CAL_CYCLES 8U -#define CAL_CYCLES_LONG 40U +#define CAL_CYCLES_LONG 20U /* Number of subsequent timeouts before abandoning an input file: */ @@ -163,7 +163,7 @@ /* Maximum number of unique hangs or crashes to record: */ #define KEEP_UNIQUE_HANG 500U -#define KEEP_UNIQUE_CRASH 5000U +#define KEEP_UNIQUE_CRASH 10000U /* Baseline number of random tweaks during a single 'havoc' stage: */ diff --git a/include/envs.h b/include/envs.h index f1314bad..08b3284a 100644 --- a/include/envs.h +++ b/include/envs.h @@ -55,14 +55,22 @@ static char *afl_environment_variables[] = { "AFL_FORCE_UI", "AFL_FRIDA_DEBUG_MAPS", "AFL_FRIDA_EXCLUDE_RANGES", + "AFL_FRIDA_INST_DEBUG_FILE", "AFL_FRIDA_INST_NO_OPTIMIZE", "AFL_FRIDA_INST_NO_PREFETCH", "AFL_FRIDA_INST_RANGES", - "AFL_FRIDA_INST_STRICT", "AFL_FRIDA_INST_TRACE", + "AFL_FRIDA_OUTPUT_STDOUT", + "AFL_FRIDA_OUTPUT_STDERR", "AFL_FRIDA_PERSISTENT_ADDR", "AFL_FRIDA_PERSISTENT_CNT", + "AFL_FRIDA_PERSISTENT_DEBUG", "AFL_FRIDA_PERSISTENT_HOOK", + "AFL_FRIDA_PERSISTENT_RET", + "AFL_FRIDA_PERSISTENT_RETADDR_OFFSET", + "AFL_FRIDA_STATS_FILE", + "AFL_FRIDA_STATS_INTERVAL", + "AFL_FRIDA_STATS_TRANSITIONS", "AFL_FUZZER_ARGS", // oss-fuzz "AFL_GDB", "AFL_GCC_ALLOWLIST", @@ -120,6 +128,7 @@ static char *afl_environment_variables[] = { "AFL_LLVM_INSTRUMENT_FILE", "AFL_LLVM_SKIP_NEVERZERO", "AFL_NO_AFFINITY", + "AFL_TRY_AFFINITY", "AFL_LLVM_LTO_STARTID", "AFL_LLVM_LTO_DONTWRITEID", "AFL_NO_ARITH", diff --git a/qemu_mode/README.md b/qemu_mode/README.md index 38cb5ba6..d28479d9 100644 --- a/qemu_mode/README.md +++ b/qemu_mode/README.md @@ -110,22 +110,23 @@ takes priority over any included ranges or AFL_INST_LIBS. CompareCoverage is a sub-instrumentation with effects similar to laf-intel. -The environment variable that enables QEMU CompareCoverage is AFL_COMPCOV_LEVEL. -There is also ./libcompcov/ which implements CompareCoverage for *cmp functions -(splitting memcmp, strncmp, etc. to make these conditions easier solvable by -afl-fuzz). +You have to set `AFL_PRELOAD=/path/to/libcompcov.so` together with +setting the AFL_COMPCOV_LEVEL you want to enable it. AFL_COMPCOV_LEVEL=1 is to instrument comparisons with only immediate -values / read-only memory. AFL_COMPCOV_LEVEL=2 instruments all -comparison instructions and memory comparison functions when libcompcov -is preloaded. -AFL_COMPCOV_LEVEL=3 has the same effects of AFL_COMPCOV_LEVEL=2 but enables also -the instrumentation of the floating-point comparisons on x86 and x86_64 (experimental). +values / read-only memory. + +AFL_COMPCOV_LEVEL=2 instruments all comparison instructions and memory +comparison functions when libcompcov is preloaded. + +AFL_COMPCOV_LEVEL=3 has the same effects of AFL_COMPCOV_LEVEL=2 but enables +also the instrumentation of the floating-point comparisons on x86 and x86_64 +(experimental). Integer comparison instructions are currently instrumented only on the x86, x86_64, arm and aarch64 targets. -Highly recommended. +Recommended, but not as good as CMPLOG mode (see below). ## 8) CMPLOG mode diff --git a/src/afl-cc.c b/src/afl-cc.c index ebe11525..8af8e7b0 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -1224,6 +1224,14 @@ int main(int argc, char **argv, char **envp) { if (strncmp(argv[i], "--afl", 5) == 0) { + if (!strcmp(argv[i], "--afl_noopt") || !strcmp(argv[i], "--afl-noopt")) { + + passthrough = 1; + argv[i] = "-g"; // we have to overwrite it, -g is always good + continue; + + } + if (compiler_mode) WARNF( "--afl-... compiler mode supersedes the AFL_CC_COMPILER and " @@ -1821,6 +1829,12 @@ int main(int argc, char **argv, char **envp) { "If anything fails - be sure to read README.lto.md!\n"); #endif + SAYF( + "\nYou can supply --afl-noopt to not instrument, like AFL_NOOPT. " + "(this is helpful\n" + "in some build systems if you do not want to instrument " + "everything.\n"); + } SAYF( diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index b277802b..88b5bc02 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -113,7 +113,7 @@ void bind_to_free_cpu(afl_state_t *afl) { u8 lockfile[PATH_MAX] = ""; s32 i; - if (afl->afl_env.afl_no_affinity) { + if (afl->afl_env.afl_no_affinity && !afl->afl_env.afl_try_affinity) { if (afl->cpu_to_bind != -1) { @@ -130,10 +130,21 @@ void bind_to_free_cpu(afl_state_t *afl) { if (!bind_cpu(afl, afl->cpu_to_bind)) { - FATAL( - "Could not bind to requested CPU %d! Make sure you passed a valid " - "-b.", - afl->cpu_to_bind); + if (afl->afl_env.afl_try_affinity) { + + WARNF( + "Could not bind to requested CPU %d! Make sure you passed a valid " + "-b.", + afl->cpu_to_bind); + + } else { + + FATAL( + "Could not bind to requested CPU %d! Make sure you passed a valid " + "-b.", + afl->cpu_to_bind); + + } } @@ -420,11 +431,14 @@ void bind_to_free_cpu(afl_state_t *afl) { "Uh-oh, looks like all %d CPU cores on your system are allocated to\n" " other instances of afl-fuzz (or similar CPU-locked tasks). " "Starting\n" - " another fuzzer on this machine is probably a bad plan, but if " - "you are\n" - " absolutely sure, you can set AFL_NO_AFFINITY and try again.\n", - afl->cpu_core_count); - FATAL("No more free CPU cores"); + " another fuzzer on this machine is probably a bad plan.\n" + "%s", + afl->cpu_core_count, + afl->afl_env.afl_try_affinity ? "" + : " If you are sure, you can set " + "AFL_NO_AFFINITY and try again.\n"); + + if (!afl->afl_env.afl_try_affinity) { FATAL("No more free CPU cores"); } } @@ -823,7 +837,6 @@ void perform_dry_run(afl_state_t *afl) { struct queue_entry *q; u32 cal_failures = 0, idx; - u8 * skip_crashes = afl->afl_env.afl_skip_crashes; u8 * use_mem; for (idx = 0; idx < afl->queued_paths; idx++) { @@ -923,27 +936,6 @@ void perform_dry_run(afl_state_t *afl) { if (afl->crash_mode) { break; } - if (skip_crashes) { - - if (afl->fsrv.uses_crash_exitcode) { - - WARNF( - "Test case results in a crash or AFL_CRASH_EXITCODE %d " - "(skipping)", - (int)(s8)afl->fsrv.crash_exitcode); - - } else { - - WARNF("Test case results in a crash (skipping)"); - - } - - q->cal_failed = CAL_CHANCES; - ++cal_failures; - break; - - } - if (afl->fsrv.mem_limit) { u8 val_buf[STRINGIFY_VAL_SIZE_MAX]; @@ -1117,14 +1109,12 @@ void perform_dry_run(afl_state_t *afl) { if (cal_failures == afl->queued_paths) { - FATAL("All test cases time out%s, giving up!", - skip_crashes ? " or crash" : ""); + FATAL("All test cases time out or crash, giving up!"); } - WARNF("Skipped %u test cases (%0.02f%%) due to timeouts%s.", cal_failures, - ((double)cal_failures) * 100 / afl->queued_paths, - skip_crashes ? " or crashes" : ""); + WARNF("Skipped %u test cases (%0.02f%%) due to timeouts or crashes.", + cal_failures, ((double)cal_failures) * 100 / afl->queued_paths); if (cal_failures * 5 > afl->queued_paths) { diff --git a/src/afl-fuzz-python.c b/src/afl-fuzz-python.c index 8760194c..3aa97635 100644 --- a/src/afl-fuzz-python.c +++ b/src/afl-fuzz-python.c @@ -212,7 +212,7 @@ static py_mutator_t *init_py_module(afl_state_t *afl, u8 *module_name) { PyObject_GetAttrString(py_module, "introspection"); py_functions[PY_FUNC_DEINIT] = PyObject_GetAttrString(py_module, "deinit"); if (!py_functions[PY_FUNC_DEINIT]) - FATAL("deinit function not found in python module"); + WARNF("deinit function not found in python module"); for (py_idx = 0; py_idx < PY_FUNC_COUNT; ++py_idx) { diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index 6e5210b8..5a481639 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -410,7 +410,7 @@ u8 calibrate_case(afl_state_t *afl, struct queue_entry *q, u8 *use_mem, } var_detected = 1; - afl->stage_max = CAL_CYCLES_LONG; + afl->stage_max = afl->fast_cal ? CAL_CYCLES : CAL_CYCLES_LONG; } else { diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c index c886cb28..0658070e 100644 --- a/src/afl-fuzz-state.c +++ b/src/afl-fuzz-state.c @@ -202,12 +202,18 @@ void read_afl_environment(afl_state_t *afl, char **envp) { afl->afl_env.afl_no_affinity = get_afl_env(afl_environment_variables[i]) ? 1 : 0; + } else if (!strncmp(env, "AFL_TRY_AFFINITY", + + afl_environment_variable_len)) { + + afl->afl_env.afl_try_affinity = + get_afl_env(afl_environment_variables[i]) ? 1 : 0; + } else if (!strncmp(env, "AFL_SKIP_CRASHES", afl_environment_variable_len)) { - afl->afl_env.afl_skip_crashes = - (u8 *)get_afl_env(afl_environment_variables[i]); + // we should mark this obsolete in a few versions } else if (!strncmp(env, "AFL_HANG_TMOUT", diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 35fb2d04..a3a623d9 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -35,6 +35,10 @@ #include #endif +#ifdef __APPLE__ + #include +#endif + #ifdef PROFILING extern u64 time_spent_working; #endif @@ -220,6 +224,7 @@ static void usage(u8 *argv0, int more_help) { " then they are randomly selected instead all of them being\n" " used. Defaults to 200.\n" "AFL_NO_AFFINITY: do not check for an unused cpu core to use for fuzzing\n" + "AFL_TRY_AFFINITY: try to bind to an unused core, but don't fail if unsuccessful\n" "AFL_NO_ARITH: skip arithmetic mutations in deterministic stage\n" "AFL_NO_AUTODICT: do not load an offered auto dictionary compiled into a target\n" "AFL_NO_CPU_RED: avoid red color for showing very high cpu usage\n" @@ -240,7 +245,7 @@ static void usage(u8 *argv0, int more_help) { "AFL_SHUFFLE_QUEUE: reorder the input queue randomly on startup\n" "AFL_SKIP_BIN_CHECK: skip afl compatibility checks, also disables auto map size\n" "AFL_SKIP_CPUFREQ: do not warn about variable cpu clocking\n" - "AFL_SKIP_CRASHES: during initial dry run do not terminate for crashing inputs\n" + //"AFL_SKIP_CRASHES: during initial dry run do not terminate for crashing inputs\n" "AFL_STATSD: enables StatsD metrics collection\n" "AFL_STATSD_HOST: change default statsd host (default 127.0.0.1)\n" "AFL_STATSD_PORT: change default statsd port (default: 8125)\n" @@ -2296,26 +2301,9 @@ stop_fuzzing: afl_fsrv_deinit(&afl->fsrv); /* remove tmpfile */ - if (afl->tmp_dir != NULL && !afl->in_place_resume) { - - char tmpfile[PATH_MAX]; - - if (afl->file_extension) { - - snprintf(tmpfile, PATH_MAX, "%s/.cur_input.%s", afl->tmp_dir, - afl->file_extension); + if (afl->tmp_dir != NULL && !afl->in_place_resume && afl->fsrv.out_file) { - } else { - - snprintf(tmpfile, PATH_MAX, "%s/.cur_input", afl->tmp_dir); - - } - - if (unlink(tmpfile) != 0) { - - FATAL("Could not unlink current input file: %s.", tmpfile); - - } + (void)unlink(afl->fsrv.out_file); } diff --git a/src/afl-showmap.c b/src/afl-showmap.c index d7af668c..96b72dd9 100644 --- a/src/afl-showmap.c +++ b/src/afl-showmap.c @@ -235,6 +235,9 @@ static u32 write_results_to_file(afl_forkserver_t *fsrv, u8 *outfile) { if (cmin_mode && (fsrv->last_run_timed_out || (!caa && child_crashed != cco))) { + // create empty file to prevent error messages in afl-cmin + fd = open(outfile, O_WRONLY | O_CREAT | O_EXCL, DEFAULT_PERMISSION); + close(fd); return ret; } diff --git a/utils/aflpp_driver/README.md b/utils/aflpp_driver/README.md index 01bd10c0..f03c2fe3 100644 --- a/utils/aflpp_driver/README.md +++ b/utils/aflpp_driver/README.md @@ -13,6 +13,12 @@ If this is the clang compile command to build for libfuzzer: then just switch `clang++` with `afl-clang-fast++` and our compiler will magically insert libAFLDriver.a :) +To use shared-memory testcases, you need nothing to do. +To use stdin testcases give `-` as the only command line parameter. +To use file input testcases give `@@` as the only command line parameter. + +IMPORTANT: if you use `afl-cmin` or `afl-cmin.bash` then either pass `-` +or `@@` as command line parameters. ## aflpp_qemu_driver diff --git a/utils/aflpp_driver/aflpp_driver.c b/utils/aflpp_driver/aflpp_driver.c index ad781e64..c094c425 100644 --- a/utils/aflpp_driver/aflpp_driver.c +++ b/utils/aflpp_driver/aflpp_driver.c @@ -174,11 +174,17 @@ size_t LLVMFuzzerMutate(uint8_t *Data, size_t Size, size_t MaxSize) { static int ExecuteFilesOnyByOne(int argc, char **argv) { unsigned char *buf = (unsigned char *)malloc(MAX_FILE); + for (int i = 1; i < argc; i++) { - int fd = open(argv[i], O_RDONLY); - if (fd == -1) continue; + int fd = 0; + + if (strcmp(argv[i], "-") != 0) { fd = open(argv[i], O_RDONLY); } + + if (fd == -1) { continue; } + ssize_t length = read(fd, buf, MAX_FILE); + if (length > 0) { printf("Reading %zu bytes from %s\n", length, argv[i]); @@ -187,7 +193,7 @@ static int ExecuteFilesOnyByOne(int argc, char **argv) { } - close(fd); + if (fd > 0) { close(fd); } } @@ -199,15 +205,19 @@ static int ExecuteFilesOnyByOne(int argc, char **argv) { int main(int argc, char **argv) { printf( - "======================= INFO =========================\n" + "============================== INFO ================================\n" "This binary is built for afl++.\n" + "To use with afl-cmin or afl-cmin.bash pass '-' as single command line " + "option\n" "To run the target function on individual input(s) execute this:\n" " %s INPUT_FILE1 [INPUT_FILE2 ... ]\n" "To fuzz with afl-fuzz execute this:\n" " afl-fuzz [afl-flags] -- %s [-N]\n" "afl-fuzz will run N iterations before re-spawning the process (default: " "INT_MAX)\n" - "======================================================\n", + "For stdin input processing, pass '-' as single command line option.\n" + "For file input processing, pass '@@' as single command line option.\n" + "===================================================================\n", argv[0], argv[0]); if (getenv("AFL_GDB")) { @@ -237,22 +247,35 @@ int main(int argc, char **argv) { memcpy(dummy_input, (void *)AFL_PERSISTENT, sizeof(AFL_PERSISTENT)); memcpy(dummy_input + 32, (void *)AFL_DEFER_FORKSVR, sizeof(AFL_DEFER_FORKSVR)); + int N = INT_MAX; - if (argc == 2 && argv[1][0] == '-') + + if (argc == 2 && !strcmp(argv[1], "-")) { + + __afl_sharedmem_fuzzing = 0; + __afl_manual_init(); + return ExecuteFilesOnyByOne(argc, argv); + + } else if (argc == 2 && argv[1][0] == '-') { + N = atoi(argv[1] + 1); - else if (argc == 2 && (N = atoi(argv[1])) > 0) + + } else if (argc == 2 && (N = atoi(argv[1])) > 0) { + printf("WARNING: using the deprecated call style `%s %d`\n", argv[0], N); - else if (argc > 1) { + + } else if (argc > 1) { __afl_sharedmem_fuzzing = 0; - __afl_manual_init(); + + if (argc == 2) { __afl_manual_init(); } + return ExecuteFilesOnyByOne(argc, argv); } assert(N > 0); - // if (!getenv("AFL_DRIVER_DONT_DEFER")) __afl_manual_init(); // Call LLVMFuzzerTestOneInput here so that coverage caused by initialization @@ -271,6 +294,7 @@ int main(int argc, char **argv) { fprintf(stderr, "%02x", __afl_fuzz_ptr[i]); fprintf(stderr, "\n"); #endif + if (*__afl_fuzz_len) { num_runs++; -- cgit 1.4.1 From 48c878a76ddec2c133fd5708b185b2ac27740084 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Tue, 8 Jun 2021 10:10:42 +0200 Subject: push to stable (#962) * use atomic read-modify-write increment for LLVM CLASSIC * Change other LLVM modes to atomic increments * sync (#886) * Create FUNDING.yml * Update FUNDING.yml * moved custom_mutator examples * unicorn speedtest makefile cleanup * fixed example location * fix qdbi * update util readme * work in progress: not working correctly yet * Frida persistent (#880) * Added x64 support for persistent mode (function call only), in-memory teest cases and complog * Review changes, fix NeverZero and code to parse the .text section of the main executable. Excluded ranges TBC * Various minor fixes and finished support for AFL_INST_LIBS * Review changes Co-authored-by: Your Name * nits * fix frida mode * Integer overflow/underflow fixes in libdislocator (#889) * libdislocator: fixing integer overflow in 'max_mem' variable and setting 'max_mem' type to 'size_t' * libdislocator: fixing potential integer underflow in 'total_mem' variable due to its different values in different threads * Bumped warnings up to the max and fixed remaining issues (#890) Co-authored-by: Your Name * nits * frida mode - support non-pie * nits * nit * update grammar mutator * Fixes for aarch64, OSX and other minor issues (#891) Co-authored-by: Your Name * nits * nits * fix PCGUARD, build aflpp_driver with fPIC * Added representative fuzzbench test and test for libxml (#893) * Added representative fuzzbench test and test for libxml * Added support for building FRIDA from source with FRIDA_SOURCE=1 Co-authored-by: Your Name * nits * update changelog * typos * still not working * fixed potential double free in custom trim (#881) * error handling, freeing mem * frida: complog -> cmplog * fix statsd writing * let aflpp_qemu_driver_hook.so build fail gracefully * fix stdin trimming * Support for AFL_ENTRYPOINT (#898) Co-authored-by: Your Name * remove the input file .cur_input at the end of the fuzzing, if AFL_TMPDIR is used * reverse push (#901) * Create FUNDING.yml * Update FUNDING.yml * disable QEMU static pie Co-authored-by: Andrea Fioraldi * clarify that no modifications are required. * add new test for frida_mode (please review) * typos * fix persistent mode (64-bit) * set ARCH for linux intel 32-bit for frida-gum-devkit * prepare for 32-bit support (later) * not on qemu 3 anymore * unicorn mips fixes * instrumentation further move to C++11 (#900) * unicorn fixes * first working NeverZero implementation * more unicorn fixes * Fix memory errors when trim causes testcase growth (#881) (#903) * Revert "fixed potential double free in custom trim (#881)" This reverts commit e9d2f72382cab75832721d859c3e731da071435d. * Revert "fix custom trim for increasing data" This reverts commit 86a8ef168dda766d2f25f15c15c4d3ecf21d0667. * Fix memory errors when trim causes testcase growth Modify trim_case_custom to avoid writing into in_buf because some custom mutators can cause the testcase to grow rather than shrink. Instead of modifying in_buf directly, we write the update out to the disk when trimming is complete, and then the caller is responsible for refreshing the in-memory buffer from the file. This is still a bit sketchy because it does need to modify q->len in order to notify the upper layers that something changed, and it could end up telling upper layer code that the q->len is *bigger* than the buffer (q->testcase_buf) that contains it, which is asking for trouble down the line somewhere... * Fix an unlikely situation Put back some `unlikely()` calls that were in the e9d2f72382cab75832721d859c3e731da071435d commit that was reverted. * add some comments * typo * Exit on time (#904) * Variable AFL_EXIT_ON_TIME description has been added. Variables AFL_EXIT_ON_TIME and afl_exit_on_time has been added. afl->exit_on_time variable initialization has been added. The asignment of a value to the afl->afl_env.afl_exit_on_time variable from environment variables has been added. Code to exit on timeout if new path not found has been added. * Type of afl_exit_on_time variable has been changed. Variable exit_on_time has been added to the afl_state_t structure. * Command `export AFL_EXIT_WHEN_DONE=1` has been added. * Millisecond to second conversion has been added. Call get_cur_time() has been added. * Revert to using the saved current time value. * Useless check has been removed. * fix new path to custom-mutators * ensure crashes/README.txt exists * fix * Changes to bump FRIDA version and to clone FRIDA repo in to build directory rather than use a submodule as the FRIDA build scripts don't like it (#906) Co-authored-by: Your Name * Fix numeric overflow in cmplog implementation (#907) Co-authored-by: Your Name * testcase fixes for unicorn * remove merge conflict artifacts * fix afl-plot * Changes to remove binaries from frida_mode (#913) Co-authored-by: Your Name * Frida cmplog fail fast (#914) * Changes to remove binaries from frida_mode * Changes to make cmplog fail fast Co-authored-by: Your Name * afl-plot: relative time * arch linux and mac os support for afl-system-config * typo * code-format * update documentation * github workflow for qemu * OSX-specific improvements (#912) * Fix afl-cc to work correctly by default on OSX using xcode - CLANG_ENV_VAR must be set for afl-as to work - Use clang mode by default if no specific compiler selected * Add OSX-specific documentation for configuring shared memory * Fixes to memory operands for complog (#916) Co-authored-by: Your Name * fix a few cur_time uses * added bounds check to pivot_inputs (fixes #921) * additional safety checks for restarts * restrict afl-showmap in_file size * fix seed crash disable * add warning for afl-showmap partial read * no core dumps * AFL_PRINT_FILENAMES added * more documentation for AFL_EXIT_ON_TIME * Flushing for AFL_PRINT_FILENAMES * FASAN Support (#918) * FASAN Support * Fix handling of Address Sanitizer DSO * Changes to identification of Address Sanitizer DSO Co-authored-by: Your Name * Support for x86 (#920) Co-authored-by: Your Name * Update frida_mode readme (#925) * libqasan: use syscalls for read and write * update readme * Minor integration tweaks (#926) Co-authored-by: Your Name * merge * fix afl-fuzz.c frida preload * cleaned up AFL_PRINT_FILENAMES env * Changes to have persistent mode exit at the end of the loop (#928) Co-authored-by: Your Name * fix llvm-dict2file * push to stable (#931) (#932) * sync (#886) * Create FUNDING.yml * Update FUNDING.yml * moved custom_mutator examples * unicorn speedtest makefile cleanup * fixed example location * fix qdbi * update util readme * Frida persistent (#880) * Added x64 support for persistent mode (function call only), in-memory teest cases and complog * Review changes, fix NeverZero and code to parse the .text section of the main executable. Excluded ranges TBC * Various minor fixes and finished support for AFL_INST_LIBS * Review changes Co-authored-by: Your Name * nits * fix frida mode * Integer overflow/underflow fixes in libdislocator (#889) * libdislocator: fixing integer overflow in 'max_mem' variable and setting 'max_mem' type to 'size_t' * libdislocator: fixing potential integer underflow in 'total_mem' variable due to its different values in different threads * Bumped warnings up to the max and fixed remaining issues (#890) Co-authored-by: Your Name * nits * frida mode - support non-pie * nits * nit * update grammar mutator * Fixes for aarch64, OSX and other minor issues (#891) Co-authored-by: Your Name * nits * nits * fix PCGUARD, build aflpp_driver with fPIC * Added representative fuzzbench test and test for libxml (#893) * Added representative fuzzbench test and test for libxml * Added support for building FRIDA from source with FRIDA_SOURCE=1 Co-authored-by: Your Name * nits * update changelog * typos * fixed potential double free in custom trim (#881) * error handling, freeing mem * frida: complog -> cmplog * fix statsd writing * let aflpp_qemu_driver_hook.so build fail gracefully * fix stdin trimming * Support for AFL_ENTRYPOINT (#898) Co-authored-by: Your Name * remove the input file .cur_input at the end of the fuzzing, if AFL_TMPDIR is used * reverse push (#901) * Create FUNDING.yml * Update FUNDING.yml * disable QEMU static pie Co-authored-by: Andrea Fioraldi * clarify that no modifications are required. * add new test for frida_mode (please review) * typos * fix persistent mode (64-bit) * set ARCH for linux intel 32-bit for frida-gum-devkit * prepare for 32-bit support (later) * not on qemu 3 anymore * unicorn mips fixes * instrumentation further move to C++11 (#900) * unicorn fixes * more unicorn fixes * Fix memory errors when trim causes testcase growth (#881) (#903) * Revert "fixed potential double free in custom trim (#881)" This reverts commit e9d2f72382cab75832721d859c3e731da071435d. * Revert "fix custom trim for increasing data" This reverts commit 86a8ef168dda766d2f25f15c15c4d3ecf21d0667. * Fix memory errors when trim causes testcase growth Modify trim_case_custom to avoid writing into in_buf because some custom mutators can cause the testcase to grow rather than shrink. Instead of modifying in_buf directly, we write the update out to the disk when trimming is complete, and then the caller is responsible for refreshing the in-memory buffer from the file. This is still a bit sketchy because it does need to modify q->len in order to notify the upper layers that something changed, and it could end up telling upper layer code that the q->len is *bigger* than the buffer (q->testcase_buf) that contains it, which is asking for trouble down the line somewhere... * Fix an unlikely situation Put back some `unlikely()` calls that were in the e9d2f72382cab75832721d859c3e731da071435d commit that was reverted. * typo * Exit on time (#904) * Variable AFL_EXIT_ON_TIME description has been added. Variables AFL_EXIT_ON_TIME and afl_exit_on_time has been added. afl->exit_on_time variable initialization has been added. The asignment of a value to the afl->afl_env.afl_exit_on_time variable from environment variables has been added. Code to exit on timeout if new path not found has been added. * Type of afl_exit_on_time variable has been changed. Variable exit_on_time has been added to the afl_state_t structure. * Command `export AFL_EXIT_WHEN_DONE=1` has been added. * Millisecond to second conversion has been added. Call get_cur_time() has been added. * Revert to using the saved current time value. * Useless check has been removed. * fix new path to custom-mutators * ensure crashes/README.txt exists * fix * Changes to bump FRIDA version and to clone FRIDA repo in to build directory rather than use a submodule as the FRIDA build scripts don't like it (#906) Co-authored-by: Your Name * Fix numeric overflow in cmplog implementation (#907) Co-authored-by: Your Name * testcase fixes for unicorn * remove merge conflict artifacts * fix afl-plot * Changes to remove binaries from frida_mode (#913) Co-authored-by: Your Name * Frida cmplog fail fast (#914) * Changes to remove binaries from frida_mode * Changes to make cmplog fail fast Co-authored-by: Your Name * afl-plot: relative time * arch linux and mac os support for afl-system-config * typo * code-format * update documentation * github workflow for qemu * OSX-specific improvements (#912) * Fix afl-cc to work correctly by default on OSX using xcode - CLANG_ENV_VAR must be set for afl-as to work - Use clang mode by default if no specific compiler selected * Add OSX-specific documentation for configuring shared memory * Fixes to memory operands for complog (#916) Co-authored-by: Your Name * fix a few cur_time uses * added bounds check to pivot_inputs (fixes #921) * additional safety checks for restarts * restrict afl-showmap in_file size * fix seed crash disable * add warning for afl-showmap partial read * no core dumps * AFL_PRINT_FILENAMES added * more documentation for AFL_EXIT_ON_TIME * Flushing for AFL_PRINT_FILENAMES * FASAN Support (#918) * FASAN Support * Fix handling of Address Sanitizer DSO * Changes to identification of Address Sanitizer DSO Co-authored-by: Your Name * Support for x86 (#920) Co-authored-by: Your Name * Update frida_mode readme (#925) * libqasan: use syscalls for read and write * update readme * Minor integration tweaks (#926) Co-authored-by: Your Name * merge * fix afl-fuzz.c frida preload * cleaned up AFL_PRINT_FILENAMES env * Changes to have persistent mode exit at the end of the loop (#928) Co-authored-by: Your Name * fix llvm-dict2file Co-authored-by: Dominik Maier Co-authored-by: WorksButNotTested <62701594+WorksButNotTested@users.noreply.github.com> Co-authored-by: Your Name Co-authored-by: Dmitry Zheregelya Co-authored-by: hexcoder Co-authored-by: hexcoder- Co-authored-by: Andrea Fioraldi Co-authored-by: David CARLIER Co-authored-by: realmadsci <71108352+realmadsci@users.noreply.github.com> Co-authored-by: Roman M. Iudichev Co-authored-by: Dustin Spicuzza Co-authored-by: Dominik Maier Co-authored-by: WorksButNotTested <62701594+WorksButNotTested@users.noreply.github.com> Co-authored-by: Your Name Co-authored-by: Dmitry Zheregelya Co-authored-by: hexcoder Co-authored-by: hexcoder- Co-authored-by: Andrea Fioraldi Co-authored-by: David CARLIER Co-authored-by: realmadsci <71108352+realmadsci@users.noreply.github.com> Co-authored-by: Roman M. Iudichev Co-authored-by: Dustin Spicuzza * improve error msg * Added documentation for wine LoadLibrary workaround (#933) * Fix cmake target compilation command example (#934) - Fix typo DCMAKE_C_COMPILERC -> DCMAKE_C_COMPILER. - Add `cd build` after `mkdir build`. * showmap passes queue items in alphabetical order * added tmp files to gitignore * lenient dict parsing, no map size enum for binary fuzzing * added info about showmap queue directions * update binary-only doc * turn off map size detection if skip_bin_check is set * Typo * update docs * update afl-system-config * Set kill signal before using it in afl-showmap (#935) * fix afl-cc help output * add libafl to binary-only doc * update docs * less executions on variable paths * AFL_SKIP_CRASHES is obsolete since 3.0 * add AFL_TRY_AFFINITY * Typo * Typo * Typo/wording * tweaks * typos * fix afl-whatsup help output * fix afl-plot output * fix for MacOS * fix cmpcov doc for qemu * fix tmpfile removal * update dockerfile * Frida (#940) * Added re2 test * Added libpcap test * Fix validation of setting of ADDR_NO_RANDOMIZE * Added support for printing original and instrumented code Co-authored-by: Your Name * Support for AFL_FRIDA_PERSISTENT_RET (#941) Co-authored-by: Your Name * Changes to add missing exclusion of ranges (#943) Co-authored-by: Your Name * add --afl-noopt to afl-cc * docs: fix link to README in QuickStartGuide (#946) * Support writing Stalker stats (#945) * Support writing Stalker stats * Fixed string handling in print functions Co-authored-by: Your Name * afl-cmin help fix, aflpp_driver - + @@ support * fix for afl-showmap * support new env var AFL_LLVM_THREADSAFE_INST to enable atomic counters. add new test case for that. * add documentation for AFL_LLVM_THREADSAFE_INST * add support for AFL_LLVM_THREADSAFE_INST to other LLVM passes * add missing include for _exit() * threadsafe doc fixes, code format * Wording: "never zero" -> NeverZero * fix afl_custom_post_process with multiple custom mutators * fix docs * debug ck_write * fixed potential diff by 0 * fixes * fix classic threadsafe counters * v3.13c release * back push (#952) * Dev (#949) * use atomic read-modify-write increment for LLVM CLASSIC * Change other LLVM modes to atomic increments * sync (#886) * Create FUNDING.yml * Update FUNDING.yml * moved custom_mutator examples * unicorn speedtest makefile cleanup * fixed example location * fix qdbi * update util readme * work in progress: not working correctly yet * Frida persistent (#880) * Added x64 support for persistent mode (function call only), in-memory teest cases and complog * Review changes, fix NeverZero and code to parse the .text section of the main executable. Excluded ranges TBC * Various minor fixes and finished support for AFL_INST_LIBS * Review changes Co-authored-by: Your Name * nits * fix frida mode * Integer overflow/underflow fixes in libdislocator (#889) * libdislocator: fixing integer overflow in 'max_mem' variable and setting 'max_mem' type to 'size_t' * libdislocator: fixing potential integer underflow in 'total_mem' variable due to its different values in different threads * Bumped warnings up to the max and fixed remaining issues (#890) Co-authored-by: Your Name * nits * frida mode - support non-pie * nits * nit * update grammar mutator * Fixes for aarch64, OSX and other minor issues (#891) Co-authored-by: Your Name * nits * nits * fix PCGUARD, build aflpp_driver with fPIC * Added representative fuzzbench test and test for libxml (#893) * Added representative fuzzbench test and test for libxml * Added support for building FRIDA from source with FRIDA_SOURCE=1 Co-authored-by: Your Name * nits * update changelog * typos * still not working * fixed potential double free in custom trim (#881) * error handling, freeing mem * frida: complog -> cmplog * fix statsd writing * let aflpp_qemu_driver_hook.so build fail gracefully * fix stdin trimming * Support for AFL_ENTRYPOINT (#898) Co-authored-by: Your Name * remove the input file .cur_input at the end of the fuzzing, if AFL_TMPDIR is used * reverse push (#901) * Create FUNDING.yml * Update FUNDING.yml * disable QEMU static pie Co-authored-by: Andrea Fioraldi * clarify that no modifications are required. * add new test for frida_mode (please review) * typos * fix persistent mode (64-bit) * set ARCH for linux intel 32-bit for frida-gum-devkit * prepare for 32-bit support (later) * not on qemu 3 anymore * unicorn mips fixes * instrumentation further move to C++11 (#900) * unicorn fixes * first working NeverZero implementation * more unicorn fixes * Fix memory errors when trim causes testcase growth (#881) (#903) * Revert "fixed potential double free in custom trim (#881)" This reverts commit e9d2f72382cab75832721d859c3e731da071435d. * Revert "fix custom trim for increasing data" This reverts commit 86a8ef168dda766d2f25f15c15c4d3ecf21d0667. * Fix memory errors when trim causes testcase growth Modify trim_case_custom to avoid writing into in_buf because some custom mutators can cause the testcase to grow rather than shrink. Instead of modifying in_buf directly, we write the update out to the disk when trimming is complete, and then the caller is responsible for refreshing the in-memory buffer from the file. This is still a bit sketchy because it does need to modify q->len in order to notify the upper layers that something changed, and it could end up telling upper layer code that the q->len is *bigger* than the buffer (q->testcase_buf) that contains it, which is asking for trouble down the line somewhere... * Fix an unlikely situation Put back some `unlikely()` calls that were in the e9d2f72382cab75832721d859c3e731da071435d commit that was reverted. * add some comments * typo * Exit on time (#904) * Variable AFL_EXIT_ON_TIME description has been added. Variables AFL_EXIT_ON_TIME and afl_exit_on_time has been added. afl->exit_on_time variable initialization has been added. The asignment of a value to the afl->afl_env.afl_exit_on_time variable from environment variables has been added. Code to exit on timeout if new path not found has been added. * Type of afl_exit_on_time variable has been changed. Variable exit_on_time has been added to the afl_state_t structure. * Command `export AFL_EXIT_WHEN_DONE=1` has been added. * Millisecond to second conversion has been added. Call get_cur_time() has been added. * Revert to using the saved current time value. * Useless check has been removed. * fix new path to custom-mutators * ensure crashes/README.txt exists * fix * Changes to bump FRIDA version and to clone FRIDA repo in to build directory rather than use a submodule as the FRIDA build scripts don't like it (#906) Co-authored-by: Your Name * Fix numeric overflow in cmplog implementation (#907) Co-authored-by: Your Name * testcase fixes for unicorn * remove merge conflict artifacts * fix afl-plot * Changes to remove binaries from frida_mode (#913) Co-authored-by: Your Name * Frida cmplog fail fast (#914) * Changes to remove binaries from frida_mode * Changes to make cmplog fail fast Co-authored-by: Your Name * afl-plot: relative time * arch linux and mac os support for afl-system-config * typo * code-format * update documentation * github workflow for qemu * OSX-specific improvements (#912) * Fix afl-cc to work correctly by default on OSX using xcode - CLANG_ENV_VAR must be set for afl-as to work - Use clang mode by default if no specific compiler selected * Add OSX-specific documentation for configuring shared memory * Fixes to memory operands for complog (#916) Co-authored-by: Your Name * fix a few cur_time uses * added bounds check to pivot_inputs (fixes #921) * additional safety checks for restarts * restrict afl-showmap in_file size * fix seed crash disable * add warning for afl-showmap partial read * no core dumps * AFL_PRINT_FILENAMES added * more documentation for AFL_EXIT_ON_TIME * Flushing for AFL_PRINT_FILENAMES * FASAN Support (#918) * FASAN Support * Fix handling of Address Sanitizer DSO * Changes to identification of Address Sanitizer DSO Co-authored-by: Your Name * Support for x86 (#920) Co-authored-by: Your Name * Update frida_mode readme (#925) * libqasan: use syscalls for read and write * update readme * Minor integration tweaks (#926) Co-authored-by: Your Name * merge * fix afl-fuzz.c frida preload * cleaned up AFL_PRINT_FILENAMES env * Changes to have persistent mode exit at the end of the loop (#928) Co-authored-by: Your Name * fix llvm-dict2file * push to stable (#931) (#932) * sync (#886) * Create FUNDING.yml * Update FUNDING.yml * moved custom_mutator examples * unicorn speedtest makefile cleanup * fixed example location * fix qdbi * update util readme * Frida persistent (#880) * Added x64 support for persistent mode (function call only), in-memory teest cases and complog * Review changes, fix NeverZero and code to parse the .text section of the main executable. Excluded ranges TBC * Various minor fixes and finished support for AFL_INST_LIBS * Review changes Co-authored-by: Your Name * nits * fix frida mode * Integer overflow/underflow fixes in libdislocator (#889) * libdislocator: fixing integer overflow in 'max_mem' variable and setting 'max_mem' type to 'size_t' * libdislocator: fixing potential integer underflow in 'total_mem' variable due to its different values in different threads * Bumped warnings up to the max and fixed remaining issues (#890) Co-authored-by: Your Name * nits * frida mode - support non-pie * nits * nit * update grammar mutator * Fixes for aarch64, OSX and other minor issues (#891) Co-authored-by: Your Name * nits * nits * fix PCGUARD, build aflpp_driver with fPIC * Added representative fuzzbench test and test for libxml (#893) * Added representative fuzzbench test and test for libxml * Added support for building FRIDA from source with FRIDA_SOURCE=1 Co-authored-by: Your Name * nits * update changelog * typos * fixed potential double free in custom trim (#881) * error handling, freeing mem * frida: complog -> cmplog * fix statsd writing * let aflpp_qemu_driver_hook.so build fail gracefully * fix stdin trimming * Support for AFL_ENTRYPOINT (#898) Co-authored-by: Your Name * remove the input file .cur_input at the end of the fuzzing, if AFL_TMPDIR is used * reverse push (#901) * Create FUNDING.yml * Update FUNDING.yml * disable QEMU static pie Co-authored-by: Andrea Fioraldi * clarify that no modifications are required. * add new test for frida_mode (please review) * typos * fix persistent mode (64-bit) * set ARCH for linux intel 32-bit for frida-gum-devkit * prepare for 32-bit support (later) * not on qemu 3 anymore * unicorn mips fixes * instrumentation further move to C++11 (#900) * unicorn fixes * more unicorn fixes * Fix memory errors when trim causes testcase growth (#881) (#903) * Revert "fixed potential double free in custom trim (#881)" This reverts commit e9d2f72382cab75832721d859c3e731da071435d. * Revert "fix custom trim for increasing data" This reverts commit 86a8ef168dda766d2f25f15c15c4d3ecf21d0667. * Fix memory errors when trim causes testcase growth Modify trim_case_custom to avoid writing into in_buf because some custom mutators can cause the testcase to grow rather than shrink. Instead of modifying in_buf directly, we write the update out to the disk when trimming is complete, and then the caller is responsible for refreshing the in-memory buffer from the file. This is still a bit sketchy because it does need to modify q->len in order to notify the upper layers that something changed, and it could end up telling upper layer code that the q->len is *bigger* than the buffer (q->testcase_buf) that contains it, which is asking for trouble down the line somewhere... * Fix an unlikely situation Put back some `unlikely()` calls that were in the e9d2f72382cab75832721d859c3e731da071435d commit that was reverted. * typo * Exit on time (#904) * Variable AFL_EXIT_ON_TIME description has been added. Variables AFL_EXIT_ON_TIME and afl_exit_on_time has been added. afl->exit_on_time variable initialization has been added. The asignment of a value to the afl->afl_env.afl_exit_on_time variable from environment variables has been added. Code to exit on timeout if new path not found has been added. * Type of afl_exit_on_time variable has been changed. Variable exit_on_time has been added to the afl_state_t structure. * Command `export AFL_EXIT_WHEN_DONE=1` has been added. * Millisecond to second conversion has been added. Call get_cur_time() has been added. * Revert to using the saved current time value. * Useless check has been removed. * fix new path to custom-mutators * ensure crashes/README.txt exists * fix * Changes to bump FRIDA version and to clone FRIDA repo in to build directory rather than use a submodule as the FRIDA build scripts don't like it (#906) Co-authored-by: Your Name * Fix numeric overflow in cmplog implementation (#907) Co-authored-by: Your Name * testcase fixes for unicorn * remove merge conflict artifacts * fix afl-plot * Changes to remove binaries from frida_mode (#913) Co-authored-by: Your Name * Frida cmplog fail fast (#914) * Changes to remove binaries from frida_mode * Changes to make cmplog fail fast Co-authored-by: Your Name * afl-plot: relative time * arch linux and mac os support for afl-system-config * typo * code-format * update documentation * github workflow for qemu * OSX-specific improvements (#912) * Fix afl-cc to work correctly by default on OSX using xcode - CLANG_ENV_VAR must be set for afl-as to work - Use clang mode by default if no specific compiler selected * Add OSX-specific documentation for configuring shared memory * Fixes to memory operands for complog (#916) Co-authored-by: Your Name * fix a few cur_time uses * added bounds check to pivot_inputs (fixes #921) * additional safety checks for restarts * restrict afl-showmap in_file size * fix seed crash disable * add warning for afl-showmap partial read * no core dumps * AFL_PRINT_FILENAMES added * more documentation for AFL_EXIT_ON_TIME * Flushing for AFL_PRINT_FILENAMES * FASAN Support (#918) * FASAN Support * Fix handling of Address Sanitizer DSO * Changes to identification of Address Sanitizer DSO Co-authored-by: Your Name * Support for x86 (#920) Co-authored-by: Your Name * Update frida_mode readme (#925) * libqasan: use syscalls for read and write * update readme * Minor integration tweaks (#926) Co-authored-by: Your Name * merge * fix afl-fuzz.c frida preload * cleaned up AFL_PRINT_FILENAMES env * Changes to have persistent mode exit at the end of the loop (#928) Co-authored-by: Your Name * fix llvm-dict2file Co-authored-by: Dominik Maier Co-authored-by: WorksButNotTested <62701594+WorksButNotTested@users.noreply.github.com> Co-authored-by: Your Name Co-authored-by: Dmitry Zheregelya Co-authored-by: hexcoder Co-authored-by: hexcoder- Co-authored-by: Andrea Fioraldi Co-authored-by: David CARLIER Co-authored-by: realmadsci <71108352+realmadsci@users.noreply.github.com> Co-authored-by: Roman M. Iudichev Co-authored-by: Dustin Spicuzza Co-authored-by: Dominik Maier Co-authored-by: WorksButNotTested <62701594+WorksButNotTested@users.noreply.github.com> Co-authored-by: Your Name Co-authored-by: Dmitry Zheregelya Co-authored-by: hexcoder Co-authored-by: hexcoder- Co-authored-by: Andrea Fioraldi Co-authored-by: David CARLIER Co-authored-by: realmadsci <71108352+realmadsci@users.noreply.github.com> Co-authored-by: Roman M. Iudichev Co-authored-by: Dustin Spicuzza * improve error msg * Added documentation for wine LoadLibrary workaround (#933) * Fix cmake target compilation command example (#934) - Fix typo DCMAKE_C_COMPILERC -> DCMAKE_C_COMPILER. - Add `cd build` after `mkdir build`. * showmap passes queue items in alphabetical order * added tmp files to gitignore * lenient dict parsing, no map size enum for binary fuzzing * added info about showmap queue directions * update binary-only doc * turn off map size detection if skip_bin_check is set * Typo * update docs * update afl-system-config * Set kill signal before using it in afl-showmap (#935) * fix afl-cc help output * add libafl to binary-only doc * update docs * less executions on variable paths * AFL_SKIP_CRASHES is obsolete since 3.0 * add AFL_TRY_AFFINITY * Typo * Typo * Typo/wording * tweaks * typos * fix afl-whatsup help output * fix afl-plot output * fix for MacOS * fix cmpcov doc for qemu * fix tmpfile removal * update dockerfile * Frida (#940) * Added re2 test * Added libpcap test * Fix validation of setting of ADDR_NO_RANDOMIZE * Added support for printing original and instrumented code Co-authored-by: Your Name * Support for AFL_FRIDA_PERSISTENT_RET (#941) Co-authored-by: Your Name * Changes to add missing exclusion of ranges (#943) Co-authored-by: Your Name * add --afl-noopt to afl-cc * docs: fix link to README in QuickStartGuide (#946) * Support writing Stalker stats (#945) * Support writing Stalker stats * Fixed string handling in print functions Co-authored-by: Your Name * afl-cmin help fix, aflpp_driver - + @@ support * fix for afl-showmap * support new env var AFL_LLVM_THREADSAFE_INST to enable atomic counters. add new test case for that. * add documentation for AFL_LLVM_THREADSAFE_INST * add support for AFL_LLVM_THREADSAFE_INST to other LLVM passes * add missing include for _exit() * threadsafe doc fixes, code format * Wording: "never zero" -> NeverZero * fix afl_custom_post_process with multiple custom mutators * fix docs * debug ck_write * fixed potential diff by 0 * fixes * fix classic threadsafe counters Co-authored-by: van Hauser Co-authored-by: Dominik Maier Co-authored-by: WorksButNotTested <62701594+WorksButNotTested@users.noreply.github.com> Co-authored-by: Your Name Co-authored-by: Dmitry Zheregelya Co-authored-by: Andrea Fioraldi Co-authored-by: David CARLIER Co-authored-by: realmadsci <71108352+realmadsci@users.noreply.github.com> Co-authored-by: Roman M. Iudichev Co-authored-by: Dustin Spicuzza Co-authored-by: 0x4d5a-ctf <51098072+0x4d5a-ctf@users.noreply.github.com> Co-authored-by: Tommy Chiang Co-authored-by: buherator Co-authored-by: Dag Heyman Kajevic * v3.13c release (#950) * use atomic read-modify-write increment for LLVM CLASSIC * Change other LLVM modes to atomic increments * sync (#886) * Create FUNDING.yml * Update FUNDING.yml * moved custom_mutator examples * unicorn speedtest makefile cleanup * fixed example location * fix qdbi * update util readme * work in progress: not working correctly yet * Frida persistent (#880) * Added x64 support for persistent mode (function call only), in-memory teest cases and complog * Review changes, fix NeverZero and code to parse the .text section of the main executable. Excluded ranges TBC * Various minor fixes and finished support for AFL_INST_LIBS * Review changes Co-authored-by: Your Name * nits * fix frida mode * Integer overflow/underflow fixes in libdislocator (#889) * libdislocator: fixing integer overflow in 'max_mem' variable and setting 'max_mem' type to 'size_t' * libdislocator: fixing potential integer underflow in 'total_mem' variable due to its different values in different threads * Bumped warnings up to the max and fixed remaining issues (#890) Co-authored-by: Your Name * nits * frida mode - support non-pie * nits * nit * update grammar mutator * Fixes for aarch64, OSX and other minor issues (#891) Co-authored-by: Your Name * nits * nits * fix PCGUARD, build aflpp_driver with fPIC * Added representative fuzzbench test and test for libxml (#893) * Added representative fuzzbench test and test for libxml * Added support for building FRIDA from source with FRIDA_SOURCE=1 Co-authored-by: Your Name * nits * update changelog * typos * still not working * fixed potential double free in custom trim (#881) * error handling, freeing mem * frida: complog -> cmplog * fix statsd writing * let aflpp_qemu_driver_hook.so build fail gracefully * fix stdin trimming * Support for AFL_ENTRYPOINT (#898) Co-authored-by: Your Name * remove the input file .cur_input at the end of the fuzzing, if AFL_TMPDIR is used * reverse push (#901) * Create FUNDING.yml * Update FUNDING.yml * disable QEMU static pie Co-authored-by: Andrea Fioraldi * clarify that no modifications are required. * add new test for frida_mode (please review) * typos * fix persistent mode (64-bit) * set ARCH for linux intel 32-bit for frida-gum-devkit * prepare for 32-bit support (later) * not on qemu 3 anymore * unicorn mips fixes * instrumentation further move to C++11 (#900) * unicorn fixes * first working NeverZero implementation * more unicorn fixes * Fix memory errors when trim causes testcase growth (#881) (#903) * Revert "fixed potential double free in custom trim (#881)" This reverts commit e9d2f72382cab75832721d859c3e731da071435d. * Revert "fix custom trim for increasing data" This reverts commit 86a8ef168dda766d2f25f15c15c4d3ecf21d0667. * Fix memory errors when trim causes testcase growth Modify trim_case_custom to avoid writing into in_buf because some custom mutators can cause the testcase to grow rather than shrink. Instead of modifying in_buf directly, we write the update out to the disk when trimming is complete, and then the caller is responsible for refreshing the in-memory buffer from the file. This is still a bit sketchy because it does need to modify q->len in order to notify the upper layers that something changed, and it could end up telling upper layer code that the q->len is *bigger* than the buffer (q->testcase_buf) that contains it, which is asking for trouble down the line somewhere... * Fix an unlikely situation Put back some `unlikely()` calls that were in the e9d2f72382cab75832721d859c3e731da071435d commit that was reverted. * add some comments * typo * Exit on time (#904) * Variable AFL_EXIT_ON_TIME description has been added. Variables AFL_EXIT_ON_TIME and afl_exit_on_time has been added. afl->exit_on_time variable initialization has been added. The asignment of a value to the afl->afl_env.afl_exit_on_time variable from environment variables has been added. Code to exit on timeout if new path not found has been added. * Type of afl_exit_on_time variable has been changed. Variable exit_on_time has been added to the afl_state_t structure. * Command `export AFL_EXIT_WHEN_DONE=1` has been added. * Millisecond to second conversion has been added. Call get_cur_time() has been added. * Revert to using the saved current time value. * Useless check has been removed. * fix new path to custom-mutators * ensure crashes/README.txt exists * fix * Changes to bump FRIDA version and to clone FRIDA repo in to build directory rather than use a submodule as the FRIDA build scripts don't like it (#906) Co-authored-by: Your Name * Fix numeric overflow in cmplog implementation (#907) Co-authored-by: Your Name * testcase fixes for unicorn * remove merge conflict artifacts * fix afl-plot * Changes to remove binaries from frida_mode (#913) Co-authored-by: Your Name * Frida cmplog fail fast (#914) * Changes to remove binaries from frida_mode * Changes to make cmplog fail fast Co-authored-by: Your Name * afl-plot: relative time * arch linux and mac os support for afl-system-config * typo * code-format * update documentation * github workflow for qemu * OSX-specific improvements (#912) * Fix afl-cc to work correctly by default on OSX using xcode - CLANG_ENV_VAR must be set for afl-as to work - Use clang mode by default if no specific compiler selected * Add OSX-specific documentation for configuring shared memory * Fixes to memory operands for complog (#916) Co-authored-by: Your Name * fix a few cur_time uses * added bounds check to pivot_inputs (fixes #921) * additional safety checks for restarts * restrict afl-showmap in_file size * fix seed crash disable * add warning for afl-showmap partial read * no core dumps * AFL_PRINT_FILENAMES added * more documentation for AFL_EXIT_ON_TIME * Flushing for AFL_PRINT_FILENAMES * FASAN Support (#918) * FASAN Support * Fix handling of Address Sanitizer DSO * Changes to identification of Address Sanitizer DSO Co-authored-by: Your Name * Support for x86 (#920) Co-authored-by: Your Name * Update frida_mode readme (#925) * libqasan: use syscalls for read and write * update readme * Minor integration tweaks (#926) Co-authored-by: Your Name * merge * fix afl-fuzz.c frida preload * cleaned up AFL_PRINT_FILENAMES env * Changes to have persistent mode exit at the end of the loop (#928) Co-authored-by: Your Name * fix llvm-dict2file * push to stable (#931) (#932) * sync (#886) * Create FUNDING.yml * Update FUNDING.yml * moved custom_mutator examples * unicorn speedtest makefile cleanup * fixed example location * fix qdbi * update util readme * Frida persistent (#880) * Added x64 support for persistent mode (function call only), in-memory teest cases and complog * Review changes, fix NeverZero and code to parse the .text section of the main executable. Excluded ranges TBC * Various minor fixes and finished support for AFL_INST_LIBS * Review changes Co-authored-by: Your Name * nits * fix frida mode * Integer overflow/underflow fixes in libdislocator (#889) * libdislocator: fixing integer overflow in 'max_mem' variable and setting 'max_mem' type to 'size_t' * libdislocator: fixing potential integer underflow in 'total_mem' variable due to its different values in different threads * Bumped warnings up to the max and fixed remaining issues (#890) Co-authored-by: Your Name * nits * frida mode - support non-pie * nits * nit * update grammar mutator * Fixes for aarch64, OSX and other minor issues (#891) Co-authored-by: Your Name * nits * nits * fix PCGUARD, build aflpp_driver with fPIC * Added representative fuzzbench test and test for libxml (#893) * Added representative fuzzbench test and test for libxml * Added support for building FRIDA from source with FRIDA_SOURCE=1 Co-authored-by: Your Name * nits * update changelog * typos * fixed potential double free in custom trim (#881) * error handling, freeing mem * frida: complog -> cmplog * fix statsd writing * let aflpp_qemu_driver_hook.so build fail gracefully * fix stdin trimming * Support for AFL_ENTRYPOINT (#898) Co-authored-by: Your Name * remove the input file .cur_input at the end of the fuzzing, if AFL_TMPDIR is used * reverse push (#901) * Create FUNDING.yml * Update FUNDING.yml * disable QEMU static pie Co-authored-by: Andrea Fioraldi * clarify that no modifications are required. * add new test for frida_mode (please review) * typos * fix persistent mode (64-bit) * set ARCH for linux intel 32-bit for frida-gum-devkit * prepare for 32-bit support (later) * not on qemu 3 anymore * unicorn mips fixes * instrumentation further move to C++11 (#900) * unicorn fixes * more unicorn fixes * Fix memory errors when trim causes testcase growth (#881) (#903) * Revert "fixed potential double free in custom trim (#881)" This reverts commit e9d2f72382cab75832721d859c3e731da071435d. * Revert "fix custom trim for increasing data" This reverts commit 86a8ef168dda766d2f25f15c15c4d3ecf21d0667. * Fix memory errors when trim causes testcase growth Modify trim_case_custom to avoid writing into in_buf because some custom mutators can cause the testcase to grow rather than shrink. Instead of modifying in_buf directly, we write the update out to the disk when trimming is complete, and then the caller is responsible for refreshing the in-memory buffer from the file. This is still a bit sketchy because it does need to modify q->len in order to notify the upper layers that something changed, and it could end up telling upper layer code that the q->len is *bigger* than the buffer (q->testcase_buf) that contains it, which is asking for trouble down the line somewhere... * Fix an unlikely situation Put back some `unlikely()` calls that were in the e9d2f72382cab75832721d859c3e731da071435d commit that was reverted. * typo * Exit on time (#904) * Variable AFL_EXIT_ON_TIME description has been added. Variables AFL_EXIT_ON_TIME and afl_exit_on_time has been added. afl->exit_on_time variable initialization has been added. The asignment of a value to the afl->afl_env.afl_exit_on_time variable from environment variables has been added. Code to exit on timeout if new path not found has been added. * Type of afl_exit_on_time variable has been changed. Variable exit_on_time has been added to the afl_state_t structure. * Command `export AFL_EXIT_WHEN_DONE=1` has been added. * Millisecond to second conversion has been added. Call get_cur_time() has been added. * Revert to using the saved current time value. * Useless check has been removed. * fix new path to custom-mutators * ensure crashes/README.txt exists * fix * Changes to bump FRIDA version and to clone FRIDA repo in to build directory rather than use a submodule as the FRIDA build scripts don't like it (#906) Co-authored-by: Your Name * Fix numeric overflow in cmplog implementation (#907) Co-authored-by: Your Name * testcase fixes for unicorn * remove merge conflict artifacts * fix afl-plot * Changes to remove binaries from frida_mode (#913) Co-authored-by: Your Name * Frida cmplog fail fast (#914) * Changes to remove binaries from frida_mode * Changes to make cmplog fail fast Co-authored-by: Your Name * afl-plot: relative time * arch linux and mac os support for afl-system-config * typo * code-format * update documentation * github workflow for qemu * OSX-specific improvements (#912) * Fix afl-cc to work correctly by default on OSX using xcode - CLANG_ENV_VAR must be set for afl-as to work - Use clang mode by default if no specific compiler selected * Add OSX-specific documentation for configuring shared memory * Fixes to memory operands for complog (#916) Co-authored-by: Your Name * fix a few cur_time uses * added bounds check to pivot_inputs (fixes #921) * additional safety checks for restarts * restrict afl-showmap in_file size * fix seed crash disable * add warning for afl-showmap partial read * no core dumps * AFL_PRINT_FILENAMES added * more documentation for AFL_EXIT_ON_TIME * Flushing for AFL_PRINT_FILENAMES * FASAN Support (#918) * FASAN Support * Fix handling of Address Sanitizer DSO * Changes to identification of Address Sanitizer DSO Co-authored-by: Your Name * Support for x86 (#920) Co-authored-by: Your Name * Update frida_mode readme (#925) * libqasan: use syscalls for read and write * update readme * Minor integration tweaks (#926) Co-authored-by: Your Name * merge * fix afl-fuzz.c frida preload * cleaned up AFL_PRINT_FILENAMES env * Changes to have persistent mode exit at the end of the loop (#928) Co-authored-by: Your Name * fix llvm-dict2file Co-authored-by: Dominik Maier Co-authored-by: WorksButNotTested <62701594+WorksButNotTested@users.noreply.github.com> Co-authored-by: Your Name Co-authored-by: Dmitry Zheregelya Co-authored-by: hexcoder Co-authored-by: hexcoder- Co-authored-by: Andrea Fioraldi Co-authored-by: David CARLIER Co-authored-by: realmadsci <71108352+realmadsci@users.noreply.github.com> Co-authored-by: Roman M. Iudichev Co-authored-by: Dustin Spicuzza Co-authored-by: Dominik Maier Co-authored-by: WorksButNotTested <62701594+WorksButNotTested@users.noreply.github.com> Co-authored-by: Your Name Co-authored-by: Dmitry Zheregelya Co-authored-by: hexcoder Co-authored-by: hexcoder- Co-authored-by: Andrea Fioraldi Co-authored-by: David CARLIER Co-authored-by: realmadsci <71108352+realmadsci@users.noreply.github.com> Co-authored-by: Roman M. Iudichev Co-authored-by: Dustin Spicuzza * improve error msg * Added documentation for wine LoadLibrary workaround (#933) * Fix cmake target compilation command example (#934) - Fix typo DCMAKE_C_COMPILERC -> DCMAKE_C_COMPILER. - Add `cd build` after `mkdir build`. * showmap passes queue items in alphabetical order * added tmp files to gitignore * lenient dict parsing, no map size enum for binary fuzzing * added info about showmap queue directions * update binary-only doc * turn off map size detection if skip_bin_check is set * Typo * update docs * update afl-system-config * Set kill signal before using it in afl-showmap (#935) * fix afl-cc help output * add libafl to binary-only doc * update docs * less executions on variable paths * AFL_SKIP_CRASHES is obsolete since 3.0 * add AFL_TRY_AFFINITY * Typo * Typo * Typo/wording * tweaks * typos * fix afl-whatsup help output * fix afl-plot output * fix for MacOS * fix cmpcov doc for qemu * fix tmpfile removal * update dockerfile * Frida (#940) * Added re2 test * Added libpcap test * Fix validation of setting of ADDR_NO_RANDOMIZE * Added support for printing original and instrumented code Co-authored-by: Your Name * Support for AFL_FRIDA_PERSISTENT_RET (#941) Co-authored-by: Your Name * Changes to add missing exclusion of ranges (#943) Co-authored-by: Your Name * add --afl-noopt to afl-cc * docs: fix link to README in QuickStartGuide (#946) * Support writing Stalker stats (#945) * Support writing Stalker stats * Fixed string handling in print functions Co-authored-by: Your Name * afl-cmin help fix, aflpp_driver - + @@ support * fix for afl-showmap * support new env var AFL_LLVM_THREADSAFE_INST to enable atomic counters. add new test case for that. * add documentation for AFL_LLVM_THREADSAFE_INST * add support for AFL_LLVM_THREADSAFE_INST to other LLVM passes * add missing include for _exit() * threadsafe doc fixes, code format * Wording: "never zero" -> NeverZero * fix afl_custom_post_process with multiple custom mutators * fix docs * debug ck_write * fixed potential diff by 0 * fixes * fix classic threadsafe counters * v3.13c release Co-authored-by: hexcoder- Co-authored-by: Dominik Maier Co-authored-by: WorksButNotTested <62701594+WorksButNotTested@users.noreply.github.com> Co-authored-by: Your Name Co-authored-by: Dmitry Zheregelya Co-authored-by: hexcoder Co-authored-by: Andrea Fioraldi Co-authored-by: David CARLIER Co-authored-by: realmadsci <71108352+realmadsci@users.noreply.github.com> Co-authored-by: Roman M. Iudichev Co-authored-by: Dustin Spicuzza Co-authored-by: 0x4d5a-ctf <51098072+0x4d5a-ctf@users.noreply.github.com> Co-authored-by: Tommy Chiang Co-authored-by: buherator Co-authored-by: Dag Heyman Kajevic Co-authored-by: hexcoder Co-authored-by: Dominik Maier Co-authored-by: WorksButNotTested <62701594+WorksButNotTested@users.noreply.github.com> Co-authored-by: Your Name Co-authored-by: Dmitry Zheregelya Co-authored-by: Andrea Fioraldi Co-authored-by: David CARLIER Co-authored-by: realmadsci <71108352+realmadsci@users.noreply.github.com> Co-authored-by: Roman M. Iudichev Co-authored-by: Dustin Spicuzza Co-authored-by: 0x4d5a-ctf <51098072+0x4d5a-ctf@users.noreply.github.com> Co-authored-by: Tommy Chiang Co-authored-by: buherator Co-authored-by: Dag Heyman Kajevic Co-authored-by: hexcoder- * v3.14a init * remove redundant unsetenv (#947) * update MacOS Install information * add missing clean action for frida_mode * ensure memory is there before free * adapt to incompatible LLVM 13 API * fix stupid typos * add fix info * build afl-compiler-rt even with broken llvm * fix -F with slash option * dynamic_list and afl-compiler-rt rework * detect partial linking in afl-cc * partial linking with -Wl * Add proper name and URL for Zafl (#959) * move link * add known frontends for supported compiler infrastructures * add Rust * fix ui fuzzing stage index (#960) * fix overflowing UI fields 'now processing' * restored timeout handling (with SIGALRM for now) * On non-Linux systems make clean may fail for frida_mode * give hint how to set env var for path to llvm-config tool * setting AFL_CC for test-llvm.sh on FreeBSD is not necessary anymore * remove -D from -M * write target errors to out_dir/error.txt * add changelog entry * add changelog * format * more info for error logging * Forkserver for afl-analyze (#963) * afl-analyze forkserver * added missing vars to forkserver * synchronized a bit more with afl-tmin * more debugging, runs now, but need to suppress target output * fix dev/null setting * afl-analyze info: Co-authored-by: hexcoder- * proper newlines * reenable LLVM 3.8 ( Ubuntu 16.04 ) * FRIDA AARCH64 support (#965) Co-authored-by: Your Name * adapt docs to minimum LLVM version * adapt to minimum llvm version Co-authored-by: hexcoder- Co-authored-by: Dominik Maier Co-authored-by: WorksButNotTested <62701594+WorksButNotTested@users.noreply.github.com> Co-authored-by: Your Name Co-authored-by: Dmitry Zheregelya Co-authored-by: hexcoder Co-authored-by: Andrea Fioraldi Co-authored-by: David CARLIER Co-authored-by: realmadsci <71108352+realmadsci@users.noreply.github.com> Co-authored-by: Roman M. Iudichev Co-authored-by: Dustin Spicuzza Co-authored-by: 0x4d5a-ctf <51098072+0x4d5a-ctf@users.noreply.github.com> Co-authored-by: Tommy Chiang Co-authored-by: buherator Co-authored-by: Dag Heyman Kajevic Co-authored-by: terrynini Co-authored-by: jdhiser Co-authored-by: yuan --- GNUmakefile | 6 +- GNUmakefile.gcc_plugin | 13 +- GNUmakefile.llvm | 6 +- README.md | 6 +- docs/Changelog.md | 12 + docs/binaryonly_fuzzing.md | 3 +- docs/ideas.md | 6 + dynamic_list.txt | 62 ++-- frida_mode/README.md | 8 +- frida_mode/include/ctx.h | 11 +- frida_mode/include/instrument.h | 10 +- frida_mode/src/asan/asan_arm.c | 28 -- frida_mode/src/asan/asan_arm32.c | 28 ++ frida_mode/src/asan/asan_arm64.c | 76 ++++- frida_mode/src/cmplog/cmplog_arm.c | 19 -- frida_mode/src/cmplog/cmplog_arm32.c | 19 ++ frida_mode/src/cmplog/cmplog_arm64.c | 295 ++++++++++++++++- frida_mode/src/ctx/ctx_arm32.c | 16 + frida_mode/src/ctx/ctx_arm64.c | 303 ++++++++++++++++++ frida_mode/src/instrument/instrument.c | 5 +- frida_mode/src/instrument/instrument_arm32.c | 12 + frida_mode/src/instrument/instrument_arm64.c | 12 + frida_mode/src/instrument/instrument_debug.c | 58 ++-- frida_mode/src/instrument/instrument_x64.c | 12 + frida_mode/src/instrument/instrument_x86.c | 12 + frida_mode/src/persistent/persistent_arm64.c | 354 ++++++++++++++++++++- frida_mode/src/persistent/persistent_x64.c | 2 - frida_mode/src/persistent/persistent_x86.c | 2 - frida_mode/src/stats/stats.c | 1 - frida_mode/src/stats/stats_arm.c | 36 --- frida_mode/src/stats/stats_arm32.c | 36 +++ frida_mode/test/cmplog/GNUmakefile | 11 +- frida_mode/test/cmplog/Makefile | 4 + frida_mode/test/cmplog/cmplog.c | 2 +- frida_mode/test/fasan/GNUmakefile | 4 +- frida_mode/test/persistent_ret/GNUmakefile | 4 +- frida_mode/test/png/persistent/GNUmakefile | 14 +- frida_mode/test/png/persistent/Makefile | 3 + frida_mode/test/png/persistent/hook/GNUmakefile | 4 +- .../png/persistent/hook/aflpp_qemu_driver_hook.c | 96 ++++++ instrumentation/README.llvm.md | 2 +- instrumentation/afl-compiler-rt.o.c | 146 +++++++-- instrumentation/afl-llvm-pass.so.cc | 2 +- src/afl-analyze.c | 218 +++++-------- src/afl-cc.c | 12 +- src/afl-fuzz-init.c | 17 +- src/afl-fuzz-stats.c | 52 +-- src/afl-fuzz.c | 3 +- test/test-llvm.sh | 8 - 49 files changed, 1674 insertions(+), 397 deletions(-) delete mode 100644 frida_mode/src/asan/asan_arm.c create mode 100644 frida_mode/src/asan/asan_arm32.c delete mode 100644 frida_mode/src/cmplog/cmplog_arm.c create mode 100644 frida_mode/src/cmplog/cmplog_arm32.c create mode 100644 frida_mode/src/ctx/ctx_arm32.c create mode 100644 frida_mode/src/ctx/ctx_arm64.c delete mode 100644 frida_mode/src/stats/stats_arm.c create mode 100644 frida_mode/src/stats/stats_arm32.c (limited to 'docs/binaryonly_fuzzing.md') diff --git a/GNUmakefile b/GNUmakefile index a45f6d5c..bd206af0 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -436,8 +436,8 @@ afl-showmap: src/afl-showmap.c src/afl-common.o src/afl-sharedmem.o src/afl-fork afl-tmin: src/afl-tmin.c src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o src/afl-performance.o $(COMM_HDR) | test_x86 $(CC) $(CFLAGS) $(COMPILE_STATIC) $(CFLAGS_FLTO) src/$@.c src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o src/afl-performance.o -o $@ $(LDFLAGS) -afl-analyze: src/afl-analyze.c src/afl-common.o src/afl-sharedmem.o src/afl-performance.o $(COMM_HDR) | test_x86 - $(CC) $(CFLAGS) $(COMPILE_STATIC) $(CFLAGS_FLTO) src/$@.c src/afl-common.o src/afl-sharedmem.o src/afl-performance.o -o $@ $(LDFLAGS) +afl-analyze: src/afl-analyze.c src/afl-common.o src/afl-sharedmem.o src/afl-performance.o src/afl-forkserver.o $(COMM_HDR) | test_x86 + $(CC) $(CFLAGS) $(COMPILE_STATIC) $(CFLAGS_FLTO) src/$@.c src/afl-common.o src/afl-sharedmem.o src/afl-performance.o src/afl-forkserver.o -o $@ $(LDFLAGS) afl-gotcpu: src/afl-gotcpu.c src/afl-common.o $(COMM_HDR) | test_x86 $(CC) $(CFLAGS) $(COMPILE_STATIC) $(CFLAGS_FLTO) src/$@.c src/afl-common.o -o $@ $(LDFLAGS) @@ -572,7 +572,7 @@ clean: $(MAKE) -C qemu_mode/unsigaction clean $(MAKE) -C qemu_mode/libcompcov clean $(MAKE) -C qemu_mode/libqasan clean - $(MAKE) -C frida_mode clean + -$(MAKE) -C frida_mode clean ifeq "$(IN_REPO)" "1" test -e qemu_mode/qemuafl/Makefile && $(MAKE) -C qemu_mode/qemuafl clean || true test -e unicorn_mode/unicornafl/Makefile && $(MAKE) -C unicorn_mode/unicornafl clean || true diff --git a/GNUmakefile.gcc_plugin b/GNUmakefile.gcc_plugin index b0f90f1b..bce97b2f 100644 --- a/GNUmakefile.gcc_plugin +++ b/GNUmakefile.gcc_plugin @@ -100,7 +100,7 @@ ifeq "$(SYS)" "SunOS" endif -PROGS = ./afl-gcc-pass.so +PROGS = ./afl-gcc-pass.so ./afl-compiler-rt.o ./afl-compiler-rt-32.o ./afl-compiler-rt-64.o .PHONY: all all: test_shm test_deps $(PROGS) test_build all_done @@ -130,6 +130,17 @@ test_deps: afl-common.o: ./src/afl-common.c $(CC) $(CFLAGS) $(CPPFLAGS) -c $< -o $@ $(LDFLAGS) +./afl-compiler-rt.o: instrumentation/afl-compiler-rt.o.c + $(CC) $(CFLAGS_SAFE) $(CPPFLAGS) -O3 -Wno-unused-result -fPIC -c $< -o $@ + +./afl-compiler-rt-32.o: instrumentation/afl-compiler-rt.o.c + @printf "[*] Building 32-bit variant of the runtime (-m32)... " + @$(CC) $(CFLAGS_SAFE) $(CPPFLAGS) -O3 -Wno-unused-result -m32 -fPIC -c $< -o $@ 2>/dev/null; if [ "$$?" = "0" ]; then echo "success!"; ln -sf afl-compiler-rt-32.o afl-llvm-rt-32.o; else echo "failed (that's fine)"; fi + +./afl-compiler-rt-64.o: instrumentation/afl-compiler-rt.o.c + @printf "[*] Building 64-bit variant of the runtime (-m64)... " + @$(CC) $(CFLAGS_SAFE) $(CPPFLAGS) -O3 -Wno-unused-result -m64 -fPIC -c $< -o $@ 2>/dev/null; if [ "$$?" = "0" ]; then echo "success!"; ln -sf afl-compiler-rt-64.o afl-llvm-rt-64.o; else echo "failed (that's fine)"; fi + ./afl-gcc-pass.so: instrumentation/afl-gcc-pass.so.cc | test_deps $(CXX) $(CXXEFLAGS) $(PLUGIN_FLAGS) -shared $< -o $@ ln -sf afl-cc afl-gcc-fast diff --git a/GNUmakefile.llvm b/GNUmakefile.llvm index 2d50badc..95140cb0 100644 --- a/GNUmakefile.llvm +++ b/GNUmakefile.llvm @@ -45,7 +45,7 @@ endif LLVMVER = $(shell $(LLVM_CONFIG) --version 2>/dev/null | sed 's/git//' | sed 's/svn//' ) LLVM_MAJOR = $(shell $(LLVM_CONFIG) --version 2>/dev/null | sed 's/\..*//' ) LLVM_MINOR = $(shell $(LLVM_CONFIG) --version 2>/dev/null | sed 's/.*\.//' | sed 's/git//' | sed 's/svn//' | sed 's/ .*//' ) -LLVM_UNSUPPORTED = $(shell $(LLVM_CONFIG) --version 2>/dev/null | egrep -q '^[0-5]\.' && echo 1 || echo 0 ) +LLVM_UNSUPPORTED = $(shell $(LLVM_CONFIG) --version 2>/dev/null | egrep -q '^[0-2]\.|^3.[0-7]\.' && echo 1 || echo 0 ) LLVM_TOO_NEW = $(shell $(LLVM_CONFIG) --version 2>/dev/null | egrep -q '^1[3-9]' && echo 1 || echo 0 ) LLVM_NEW_API = $(shell $(LLVM_CONFIG) --version 2>/dev/null | egrep -q '^1[0-9]' && echo 1 || echo 0 ) LLVM_10_OK = $(shell $(LLVM_CONFIG) --version 2>/dev/null | egrep -q '^1[1-9]|^10\.[1-9]|^10\.0.[1-9]' && echo 1 || echo 0 ) @@ -57,11 +57,11 @@ LLVM_APPLE_XCODE = $(shell clang -v 2>&1 | grep -q Apple && echo 1 || echo 0) LLVM_LTO = 0 ifeq "$(LLVMVER)" "" - $(warning [!] llvm_mode needs llvm-config, which was not found) + $(warning [!] llvm_mode needs llvm-config, which was not found. Set LLVM_CONFIG to its path and retry.) endif ifeq "$(LLVM_UNSUPPORTED)" "1" - $(error llvm_mode only supports llvm from version 6.0 onwards) + $(error llvm_mode only supports llvm from version 3.8 onwards) endif ifeq "$(LLVM_TOO_NEW)" "1" diff --git a/README.md b/README.md index ba612edb..bc547b3c 100644 --- a/README.md +++ b/README.md @@ -84,7 +84,7 @@ behaviours and defaults: ## Important features of afl++ - afl++ supports llvm from 6.0 up to version 12, very fast binary fuzzing with QEMU 5.1 + afl++ supports llvm from 3.8 up to version 12, very fast binary fuzzing with QEMU 5.1 with laf-intel and redqueen, frida mode, unicorn mode, gcc plugin, full *BSD, Mac OS, Solaris and Android support and much, much, much more. @@ -296,7 +296,7 @@ anything below 9 is not recommended. | v +---------------------------------+ -| clang/clang++ 6.0+ is available | --> use LLVM mode (afl-clang-fast/afl-clang-fast++) +| clang/clang++ 3.8+ is available | --> use LLVM mode (afl-clang-fast/afl-clang-fast++) +---------------------------------+ see [instrumentation/README.llvm.md](instrumentation/README.llvm.md) | | if not, or if the target fails with LLVM afl-clang-fast/++ @@ -801,7 +801,7 @@ Alternatively you can use frida_mode, just switch `-Q` with `-O` and remove the LAF instance. Then run as many instances as you have cores left with either -Q mode or - better - -use a binary rewriter like afl-dyninst, retrowrite, zaflr, etc. +use a binary rewriter like afl-dyninst, retrowrite, zafl, etc. For Qemu and Frida mode, check out the persistent mode, it gives a huge speed improvement if it is possible to use. diff --git a/docs/Changelog.md b/docs/Changelog.md index a49c0672..6c851460 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -10,6 +10,18 @@ sending a mail to . ### Version ++3.14a (release) - Fix for llvm 13 + - afl-fuzz: + - fix -F when a '/' was part of the parameter + - removed implied -D determinstic from -M main + - if the target becomes unavailable check out out/default/error.txt for + an indicator why + - afl-cc + - support partial linking + - We do support llvm versions from 3.8 again + - afl_analyze + - fix timeout handling and support forkserver + - ensure afl-compiler-rt is built for gcc_module + - afl-analyze now uses the forkserver for increased performance ### Version ++3.13c (release) diff --git a/docs/binaryonly_fuzzing.md b/docs/binaryonly_fuzzing.md index 11e1dbeb..3b32f5ed 100644 --- a/docs/binaryonly_fuzzing.md +++ b/docs/binaryonly_fuzzing.md @@ -122,7 +122,7 @@ [https://github.com/vanhauser-thc/afl-dyninst](https://github.com/vanhauser-thc/afl-dyninst) -## RETROWRITE +## RETROWRITE, ZAFL, ... other binary rewriter If you have an x86/x86_64 binary that still has its symbols, is compiled with position independant code (PIC/PIE) and does not use most of the C++ @@ -131,6 +131,7 @@ It is at about 80-85% performance. + [https://git.zephyr-software.com/opensrc/zafl](https://git.zephyr-software.com/opensrc/zafl) [https://github.com/HexHive/retrowrite](https://github.com/HexHive/retrowrite) diff --git a/docs/ideas.md b/docs/ideas.md index e25d3ba6..0ee69851 100644 --- a/docs/ideas.md +++ b/docs/ideas.md @@ -34,6 +34,12 @@ Mentor: any Other programming languages also use llvm hence they could (easily?) supported for fuzzing, e.g. mono, swift, go, kotlin native, fortran, ... +GCC also supports: Objective-C, Fortran, Ada, Go, and D +(according to [Gcc homepage](https://gcc.gnu.org/)) + +LLVM is also used by: Rust, LLGo (Go), kaleidoscope (Haskell), flang (Fortran), emscripten (JavaScript, WASM), ilwasm (CIL (C#)) +(according to [LLVM frontends](https://gist.github.com/axic/62d66fb9d8bccca6cc48fa9841db9241)) + Mentor: vanhauser-thc ## Machine Learning diff --git a/dynamic_list.txt b/dynamic_list.txt index d1905d43..7293ae77 100644 --- a/dynamic_list.txt +++ b/dynamic_list.txt @@ -1,48 +1,56 @@ { + "__afl_already_initialized_first"; + "__afl_already_initialized_forkserver"; + "__afl_already_initialized_second"; + "__afl_already_initialized_shm"; "__afl_area_ptr"; + "__afl_auto_early"; + "__afl_auto_first"; + "__afl_auto_init"; + "__afl_auto_second"; + "__afl_coverage_discard"; + "__afl_coverage_interesting"; + "__afl_coverage_off"; + "__afl_coverage_on"; + "__afl_coverage_skip"; + "__afl_dictionary"; + "__afl_dictionary_len"; + "__afl_final_loc"; + "__afl_fuzz_len"; + "__afl_fuzz_ptr"; "__afl_manual_init"; + "__afl_map_addr"; "__afl_persistent_loop"; - "__afl_auto_init"; - "__afl_area_initial"; - "__afl_prev_loc"; "__afl_prev_caller"; "__afl_prev_ctx"; - "__afl_final_loc"; - "__afl_map_addr"; - "__afl_dictionary"; - "__afl_dictionary_len"; + "__afl_prev_loc"; "__afl_selective_coverage"; "__afl_selective_coverage_start_off"; "__afl_selective_coverage_temp"; - "__afl_coverage_discard"; - "__afl_coverage_skip"; - "__afl_coverage_on"; - "__afl_coverage_off"; - "__afl_coverage_interesting"; - "__afl_fuzz_len"; - "__afl_fuzz_ptr"; "__afl_sharedmem_fuzzing"; - "__sanitizer_cov_trace_pc_guard"; - "__sanitizer_cov_trace_pc_guard_init"; + "__afl_trace"; "__cmplog_ins_hook1"; + "__cmplog_ins_hook16"; "__cmplog_ins_hook2"; "__cmplog_ins_hook4"; + "__cmplog_ins_hook8"; "__cmplog_ins_hookN"; - "__cmplog_ins_hook16"; + "__cmplog_rtn_gcc_stdstring_cstring"; + "__cmplog_rtn_gcc_stdstring_stdstring"; + "__cmplog_rtn_hook"; + "__cmplog_rtn_llvm_stdstring_cstring"; + "__cmplog_rtn_llvm_stdstring_stdstring"; "__sanitizer_cov_trace_cmp1"; - "__sanitizer_cov_trace_const_cmp1"; + "__sanitizer_cov_trace_cmp16"; "__sanitizer_cov_trace_cmp2"; - "__sanitizer_cov_trace_const_cmp2"; "__sanitizer_cov_trace_cmp4"; - "__sanitizer_cov_trace_const_cmp4"; "__sanitizer_cov_trace_cmp8"; - "__sanitizer_cov_trace_const_cmp8"; - "__sanitizer_cov_trace_cmp16"; + "__sanitizer_cov_trace_const_cmp1"; "__sanitizer_cov_trace_const_cmp16"; + "__sanitizer_cov_trace_const_cmp2"; + "__sanitizer_cov_trace_const_cmp4"; + "__sanitizer_cov_trace_const_cmp8"; + "__sanitizer_cov_trace_pc_guard"; + "__sanitizer_cov_trace_pc_guard_init"; "__sanitizer_cov_trace_switch"; - "__cmplog_rtn_hook"; - "__cmplog_rtn_gcc_stdstring_cstring"; - "__cmplog_rtn_gcc_stdstring_stdstring"; - "__cmplog_rtn_llvm_stdstring_cstring"; - "__cmplog_rtn_llvm_stdstring_stdstring"; }; diff --git a/frida_mode/README.md b/frida_mode/README.md index 0103a395..d7dd72a0 100644 --- a/frida_mode/README.md +++ b/frida_mode/README.md @@ -21,16 +21,16 @@ perhaps leverage some of its design and implementation. | Feature/Instrumentation | frida-mode | Notes | | -------------------------|:----------:|:--------------------------------------------:| | NeverZero | x | | - | Persistent Mode | x | (x86/x64 only)(Only on function boundaries) | + | Persistent Mode | x | (x86/x64/aarch64 only) | | LAF-Intel / CompCov | - | (CMPLOG is better 90% of the time) | - | CMPLOG | x | (x86/x64 only) | + | CMPLOG | x | (x86/x64/aarch64 only) | | Selective Instrumentation| x | | | Non-Colliding Coverage | - | (Not possible in binary-only instrumentation | | Ngram prev_loc Coverage | - | | | Context Coverage | - | | | Auto Dictionary | - | | | Snapshot LKM Support | - | | - | In-Memory Test Cases | x | (x86/x64 only) | + | In-Memory Test Cases | x | (x86/x64/aarch64 only) | ## Compatibility Currently FRIDA mode supports Linux and macOS targets on both x86/x64 @@ -288,7 +288,7 @@ to validate memory accesses against the shadow memory. ## TODO -The next features to be added are Aarch64 and Aarch32 support as well as looking at +The next features to be added are Aarch32 support as well as looking at potential performance improvements. The intention is to achieve feature parity with QEMU mode in due course. Contributions are welcome, but please get in touch to ensure that efforts are deconflicted. diff --git a/frida_mode/include/ctx.h b/frida_mode/include/ctx.h index cbcc892a..67274aee 100644 --- a/frida_mode/include/ctx.h +++ b/frida_mode/include/ctx.h @@ -3,8 +3,15 @@ #include "frida-gum.h" -#if defined(__x86_64__) || defined(__i386__) -gsize ctx_read_reg(GumCpuContext *ctx, x86_reg reg); +#if defined(__x86_64__) +gsize ctx_read_reg(GumX64CpuContext *ctx, x86_reg reg); +#elif defined(__i386__) +gsize ctx_read_reg(GumIA32CpuContext *ctx, x86_reg reg); +#elif defined(__aarch64__) +gsize ctx_read_reg(GumArm64CpuContext *ctx, arm64_reg reg); +size_t ctx_get_size(const cs_insn *instr, cs_arm64_op *operand); +#elif defined(__arm__) +gsize ctx_read_reg(GumArmCpuContext *ctx, arm_reg reg); #endif #endif diff --git a/frida_mode/include/instrument.h b/frida_mode/include/instrument.h index ed92c25a..577481d1 100644 --- a/frida_mode/include/instrument.h +++ b/frida_mode/include/instrument.h @@ -19,9 +19,11 @@ gboolean instrument_is_coverage_optimize_supported(void); void instrument_coverage_optimize(const cs_insn * instr, GumStalkerOutput *output); -void instrument_debug_init(void); -void instrument_debug_start(uint64_t address, GumStalkerOutput *output); -void instrument_debug_instruction(uint64_t address, uint16_t size); -void instrument_debug_end(GumStalkerOutput *output); +void instrument_debug_init(void); +void instrument_debug_start(uint64_t address, GumStalkerOutput *output); +void instrument_debug_instruction(uint64_t address, uint16_t size); +void instrument_debug_end(GumStalkerOutput *output); +void instrument_flush(GumStalkerOutput *output); +gpointer instrument_cur(GumStalkerOutput *output); #endif diff --git a/frida_mode/src/asan/asan_arm.c b/frida_mode/src/asan/asan_arm.c deleted file mode 100644 index 79475ced..00000000 --- a/frida_mode/src/asan/asan_arm.c +++ /dev/null @@ -1,28 +0,0 @@ -#include "frida-gum.h" - -#include "debug.h" - -#include "asan.h" -#include "util.h" - -#if defined(__arm__) -void asan_instrument(const cs_insn *instr, GumStalkerIterator *iterator) { - - UNUSED_PARAMETER(instr); - UNUSED_PARAMETER(iterator); - if (asan_initialized) { - - FATAL("ASAN mode not supported on this architecture"); - - } - -} - -void asan_arch_init(void) { - - FATAL("ASAN mode not supported on this architecture"); - -} - -#endif - diff --git a/frida_mode/src/asan/asan_arm32.c b/frida_mode/src/asan/asan_arm32.c new file mode 100644 index 00000000..79475ced --- /dev/null +++ b/frida_mode/src/asan/asan_arm32.c @@ -0,0 +1,28 @@ +#include "frida-gum.h" + +#include "debug.h" + +#include "asan.h" +#include "util.h" + +#if defined(__arm__) +void asan_instrument(const cs_insn *instr, GumStalkerIterator *iterator) { + + UNUSED_PARAMETER(instr); + UNUSED_PARAMETER(iterator); + if (asan_initialized) { + + FATAL("ASAN mode not supported on this architecture"); + + } + +} + +void asan_arch_init(void) { + + FATAL("ASAN mode not supported on this architecture"); + +} + +#endif + diff --git a/frida_mode/src/asan/asan_arm64.c b/frida_mode/src/asan/asan_arm64.c index 6262ee18..66138e42 100644 --- a/frida_mode/src/asan/asan_arm64.c +++ b/frida_mode/src/asan/asan_arm64.c @@ -1,18 +1,80 @@ +#include #include "frida-gum.h" #include "debug.h" #include "asan.h" +#include "ctx.h" #include "util.h" #if defined(__aarch64__) + +typedef struct { + + size_t size; + cs_arm64_op operand; + +} asan_ctx_t; + +typedef void (*asan_loadN_t)(gsize address, uint8_t size); +typedef void (*asan_storeN_t)(gsize address, uint8_t size); + +asan_loadN_t asan_loadN = NULL; +asan_storeN_t asan_storeN = NULL; + +static void asan_callout(GumCpuContext *ctx, gpointer user_data) { + + asan_ctx_t * asan_ctx = (asan_ctx_t *)user_data; + cs_arm64_op * operand = &asan_ctx->operand; + arm64_op_mem *mem = &operand->mem; + gsize base = 0; + gsize index = 0; + gsize address; + + if (mem->base != ARM64_REG_INVALID) { base = ctx_read_reg(ctx, mem->base); } + + if (mem->index != ARM64_REG_INVALID) { + + index = ctx_read_reg(ctx, mem->index); + + } + + address = base + index + mem->disp; + + if ((operand->access & CS_AC_READ) == CS_AC_READ) { + + asan_loadN(address, asan_ctx->size); + + } + + if ((operand->access & CS_AC_WRITE) == CS_AC_WRITE) { + + asan_storeN(address, asan_ctx->size); + + } + +} + void asan_instrument(const cs_insn *instr, GumStalkerIterator *iterator) { - UNUSED_PARAMETER(instr); UNUSED_PARAMETER(iterator); - if (asan_initialized) { - FATAL("ASAN mode not supported on this architecture"); + cs_arm64 arm64 = instr->detail->arm64; + cs_arm64_op *operand; + asan_ctx_t * ctx; + + if (!asan_initialized) return; + + for (uint8_t i = 0; i < arm64.op_count; i++) { + + operand = &arm64.operands[i]; + + if (operand->type != ARM64_OP_MEM) { continue; } + + ctx = g_malloc0(sizeof(asan_ctx_t)); + ctx->size = ctx_get_size(instr, &arm64.operands[0]); + memcpy(&ctx->operand, operand, sizeof(cs_arm64_op)); + gum_stalker_iterator_put_callout(iterator, asan_callout, ctx, g_free); } @@ -20,7 +82,13 @@ void asan_instrument(const cs_insn *instr, GumStalkerIterator *iterator) { void asan_arch_init(void) { - FATAL("ASAN mode not supported on this architecture"); + asan_loadN = (asan_loadN_t)dlsym(RTLD_DEFAULT, "__asan_loadN"); + asan_storeN = (asan_loadN_t)dlsym(RTLD_DEFAULT, "__asan_storeN"); + if (asan_loadN == NULL || asan_storeN == NULL) { + + FATAL("Frida ASAN failed to find '__asan_loadN' or '__asan_storeN'"); + + } } diff --git a/frida_mode/src/cmplog/cmplog_arm.c b/frida_mode/src/cmplog/cmplog_arm.c deleted file mode 100644 index 5af28f3f..00000000 --- a/frida_mode/src/cmplog/cmplog_arm.c +++ /dev/null @@ -1,19 +0,0 @@ -#include "frida-gum.h" - -#include "debug.h" - -#include "frida_cmplog.h" -#include "util.h" - -#if defined(__arm__) -void cmplog_instrument(const cs_insn *instr, GumStalkerIterator *iterator) { - - UNUSED_PARAMETER(instr); - UNUSED_PARAMETER(iterator); - if (__afl_cmp_map == NULL) { return; } - FATAL("CMPLOG mode not supported on this architecture"); - -} - -#endif - diff --git a/frida_mode/src/cmplog/cmplog_arm32.c b/frida_mode/src/cmplog/cmplog_arm32.c new file mode 100644 index 00000000..5af28f3f --- /dev/null +++ b/frida_mode/src/cmplog/cmplog_arm32.c @@ -0,0 +1,19 @@ +#include "frida-gum.h" + +#include "debug.h" + +#include "frida_cmplog.h" +#include "util.h" + +#if defined(__arm__) +void cmplog_instrument(const cs_insn *instr, GumStalkerIterator *iterator) { + + UNUSED_PARAMETER(instr); + UNUSED_PARAMETER(iterator); + if (__afl_cmp_map == NULL) { return; } + FATAL("CMPLOG mode not supported on this architecture"); + +} + +#endif + diff --git a/frida_mode/src/cmplog/cmplog_arm64.c b/frida_mode/src/cmplog/cmplog_arm64.c index 187d0162..04631ff8 100644 --- a/frida_mode/src/cmplog/cmplog_arm64.c +++ b/frida_mode/src/cmplog/cmplog_arm64.c @@ -1,17 +1,304 @@ #include "frida-gum.h" #include "debug.h" +#include "cmplog.h" +#include "ctx.h" #include "frida_cmplog.h" #include "util.h" #if defined(__aarch64__) + +typedef struct { + + arm64_op_type type; + uint8_t size; + + union { + + arm64_op_mem mem; + arm64_reg reg; + int64_t imm; + + }; + +} cmplog_ctx_t; + +typedef struct { + + cmplog_ctx_t operand1; + cmplog_ctx_t operand2; + size_t size; + +} cmplog_pair_ctx_t; + +static gboolean cmplog_read_mem(GumCpuContext *ctx, uint8_t size, + arm64_op_mem *mem, gsize *val) { + + gsize base = 0; + gsize index = 0; + gsize address; + + if (mem->base != ARM64_REG_INVALID) { base = ctx_read_reg(ctx, mem->base); } + + if (mem->index != ARM64_REG_INVALID) { + + index = ctx_read_reg(ctx, mem->index); + + } + + address = base + index + mem->disp; + + if (!cmplog_is_readable(address, size)) { return FALSE; } + + switch (size) { + + case 1: + *val = *((guint8 *)GSIZE_TO_POINTER(address)); + return TRUE; + case 2: + *val = *((guint16 *)GSIZE_TO_POINTER(address)); + return TRUE; + case 4: + *val = *((guint32 *)GSIZE_TO_POINTER(address)); + return TRUE; + case 8: + *val = *((guint64 *)GSIZE_TO_POINTER(address)); + return TRUE; + default: + FATAL("Invalid operand size: %d\n", size); + + } + + return FALSE; + +} + +static gboolean cmplog_get_operand_value(GumCpuContext *context, + cmplog_ctx_t *ctx, gsize *val) { + + switch (ctx->type) { + + case ARM64_OP_REG: + *val = ctx_read_reg(context, ctx->reg); + return TRUE; + case ARM64_OP_IMM: + *val = ctx->imm; + return TRUE; + case ARM64_OP_MEM: + return cmplog_read_mem(context, ctx->size, &ctx->mem, val); + default: + FATAL("Invalid operand type: %d\n", ctx->type); + + } + + return FALSE; + +} + +static void cmplog_call_callout(GumCpuContext *context, gpointer user_data) { + + UNUSED_PARAMETER(user_data); + + gsize address = context->pc; + gsize x0 = ctx_read_reg(context, ARM64_REG_X0); + gsize x1 = ctx_read_reg(context, ARM64_REG_X1); + + if (((G_MAXULONG - x0) < 32) || ((G_MAXULONG - x1) < 32)) return; + + if (!cmplog_is_readable(x0, 32) || !cmplog_is_readable(x1, 32)) return; + + void *ptr1 = GSIZE_TO_POINTER(x0); + void *ptr2 = GSIZE_TO_POINTER(x1); + + uintptr_t k = address; + + k = (k >> 4) ^ (k << 8); + k &= CMP_MAP_W - 1; + + __afl_cmp_map->headers[k].type = CMP_TYPE_RTN; + + u32 hits = __afl_cmp_map->headers[k].hits; + __afl_cmp_map->headers[k].hits = hits + 1; + + __afl_cmp_map->headers[k].shape = 31; + + hits &= CMP_MAP_RTN_H - 1; + gum_memcpy(((struct cmpfn_operands *)__afl_cmp_map->log[k])[hits].v0, ptr1, + 32); + gum_memcpy(((struct cmpfn_operands *)__afl_cmp_map->log[k])[hits].v1, ptr2, + 32); + +} + +static void cmplog_instrument_put_operand(cmplog_ctx_t *ctx, + cs_arm64_op * operand) { + + ctx->type = operand->type; + switch (operand->type) { + + case ARM64_OP_REG: + gum_memcpy(&ctx->reg, &operand->reg, sizeof(arm64_reg)); + break; + case ARM64_OP_IMM: + gum_memcpy(&ctx->imm, &operand->imm, sizeof(int64_t)); + break; + case ARM64_OP_MEM: + gum_memcpy(&ctx->mem, &operand->mem, sizeof(arm64_op_mem)); + break; + default: + FATAL("Invalid operand type: %d\n", operand->type); + + } + +} + +static void cmplog_instrument_call(const cs_insn * instr, + GumStalkerIterator *iterator) { + + cs_arm64 arm64 = instr->detail->arm64; + cs_arm64_op *operand; + + switch (instr->id) { + + case ARM64_INS_BL: + case ARM64_INS_BLR: + case ARM64_INS_BLRAA: + case ARM64_INS_BLRAAZ: + case ARM64_INS_BLRAB: + case ARM64_INS_BLRABZ: + break; + default: + return; + + } + + if (arm64.op_count != 1) return; + + operand = &arm64.operands[0]; + + if (operand->type == ARM64_OP_INVALID) return; + + gum_stalker_iterator_put_callout(iterator, cmplog_call_callout, NULL, NULL); + +} + +static void cmplog_handle_cmp_sub(GumCpuContext *context, gsize operand1, + gsize operand2, uint8_t size) { + + gsize address = context->pc; + + register uintptr_t k = (uintptr_t)address; + + k = (k >> 4) ^ (k << 8); + k &= CMP_MAP_W - 1; + + __afl_cmp_map->headers[k].type = CMP_TYPE_INS; + + u32 hits = __afl_cmp_map->headers[k].hits; + __afl_cmp_map->headers[k].hits = hits + 1; + + __afl_cmp_map->headers[k].shape = (size - 1); + + hits &= CMP_MAP_H - 1; + __afl_cmp_map->log[k][hits].v0 = operand1; + __afl_cmp_map->log[k][hits].v1 = operand2; + +} + +static void cmplog_cmp_sub_callout(GumCpuContext *context, gpointer user_data) { + + cmplog_pair_ctx_t *ctx = (cmplog_pair_ctx_t *)user_data; + gsize operand1; + gsize operand2; + + if (!cmplog_get_operand_value(context, &ctx->operand1, &operand1)) { return; } + if (!cmplog_get_operand_value(context, &ctx->operand2, &operand2)) { return; } + + cmplog_handle_cmp_sub(context, operand1, operand2, ctx->size); + +} + +static void cmplog_instrument_cmp_sub_put_callout(GumStalkerIterator *iterator, + cs_arm64_op * operand1, + cs_arm64_op * operand2, + size_t size) { + + cmplog_pair_ctx_t *ctx = g_malloc(sizeof(cmplog_pair_ctx_t)); + if (ctx == NULL) return; + + cmplog_instrument_put_operand(&ctx->operand1, operand1); + cmplog_instrument_put_operand(&ctx->operand2, operand2); + ctx->size = size; + + gum_stalker_iterator_put_callout(iterator, cmplog_cmp_sub_callout, ctx, + g_free); + +} + +static void cmplog_instrument_cmp_sub(const cs_insn * instr, + GumStalkerIterator *iterator) { + + cs_arm64 arm64 = instr->detail->arm64; + cs_arm64_op *operand1; + cs_arm64_op *operand2; + size_t size; + + switch (instr->id) { + + case ARM64_INS_ADCS: + case ARM64_INS_ADDS: + case ARM64_INS_ANDS: + case ARM64_INS_BICS: + case ARM64_INS_CMN: + case ARM64_INS_CMP: + case ARM64_INS_CMPEQ: + case ARM64_INS_CMPGE: + case ARM64_INS_CMPGT: + case ARM64_INS_CMPHI: + case ARM64_INS_CMPHS: + case ARM64_INS_CMPLE: + case ARM64_INS_CMPLO: + case ARM64_INS_CMPLS: + case ARM64_INS_CMPLT: + case ARM64_INS_CMPNE: + case ARM64_INS_EORS: + case ARM64_INS_NANDS: + case ARM64_INS_NEGS: + case ARM64_INS_NGCS: + case ARM64_INS_NORS: + case ARM64_INS_NOTS: + case ARM64_INS_ORNS: + case ARM64_INS_ORRS: + case ARM64_INS_SBCS: + case ARM64_INS_SUBS: + break; + + default: + return; + + } + + if (arm64.op_count != 2) return; + + operand1 = &arm64.operands[0]; + operand2 = &arm64.operands[1]; + + if (operand1->type == ARM64_OP_INVALID) return; + if (operand2->type == ARM64_OP_INVALID) return; + + size = ctx_get_size(instr, &arm64.operands[0]); + + cmplog_instrument_cmp_sub_put_callout(iterator, operand1, operand2, size); + +} + void cmplog_instrument(const cs_insn *instr, GumStalkerIterator *iterator) { - UNUSED_PARAMETER(instr); - UNUSED_PARAMETER(iterator); - if (__afl_cmp_map == NULL) { return; } - FATAL("CMPLOG mode not supported on this architecture"); + if (__afl_cmp_map == NULL) return; + + cmplog_instrument_call(instr, iterator); + cmplog_instrument_cmp_sub(instr, iterator); } diff --git a/frida_mode/src/ctx/ctx_arm32.c b/frida_mode/src/ctx/ctx_arm32.c new file mode 100644 index 00000000..a5c6f6d4 --- /dev/null +++ b/frida_mode/src/ctx/ctx_arm32.c @@ -0,0 +1,16 @@ +#include "frida-gum.h" + +#include "debug.h" + +#include "ctx.h" + +#if defined(__arm__) + +gsize ctx_read_reg(GumIA32CpuContext *ctx, x86_reg reg) { + + FATAL("ctx_read_reg unimplemented for this architecture"); + +} + +#endif + diff --git a/frida_mode/src/ctx/ctx_arm64.c b/frida_mode/src/ctx/ctx_arm64.c new file mode 100644 index 00000000..d09896af --- /dev/null +++ b/frida_mode/src/ctx/ctx_arm64.c @@ -0,0 +1,303 @@ +#include "frida-gum.h" + +#include "debug.h" + +#include "ctx.h" + +#if defined(__aarch64__) + + #define ARM64_REG_8(LABEL, REG) \ + case LABEL: { \ + \ + return REG & GUM_INT8_MASK; \ + \ + } + + #define ARM64_REG_16(LABEL, REG) \ + case LABEL: { \ + \ + return (REG & GUM_INT16_MASK); \ + \ + } + + #define ARM64_REG_32(LABEL, REG) \ + case LABEL: { \ + \ + return (REG & GUM_INT32_MASK); \ + \ + } + + #define ARM64_REG_64(LABEL, REG) \ + case LABEL: { \ + \ + return (REG); \ + \ + } + +gsize ctx_read_reg(GumArm64CpuContext *ctx, arm64_reg reg) { + + switch (reg) { + + case ARM64_REG_WZR: + case ARM64_REG_XZR: + return 0; + + ARM64_REG_8(ARM64_REG_B0, ctx->x[0]) + ARM64_REG_8(ARM64_REG_B1, ctx->x[1]) + ARM64_REG_8(ARM64_REG_B2, ctx->x[2]) + ARM64_REG_8(ARM64_REG_B3, ctx->x[3]) + ARM64_REG_8(ARM64_REG_B4, ctx->x[4]) + ARM64_REG_8(ARM64_REG_B5, ctx->x[5]) + ARM64_REG_8(ARM64_REG_B6, ctx->x[6]) + ARM64_REG_8(ARM64_REG_B7, ctx->x[7]) + ARM64_REG_8(ARM64_REG_B8, ctx->x[8]) + ARM64_REG_8(ARM64_REG_B9, ctx->x[9]) + ARM64_REG_8(ARM64_REG_B10, ctx->x[10]) + ARM64_REG_8(ARM64_REG_B11, ctx->x[11]) + ARM64_REG_8(ARM64_REG_B12, ctx->x[12]) + ARM64_REG_8(ARM64_REG_B13, ctx->x[13]) + ARM64_REG_8(ARM64_REG_B14, ctx->x[14]) + ARM64_REG_8(ARM64_REG_B15, ctx->x[15]) + ARM64_REG_8(ARM64_REG_B16, ctx->x[16]) + ARM64_REG_8(ARM64_REG_B17, ctx->x[17]) + ARM64_REG_8(ARM64_REG_B18, ctx->x[18]) + ARM64_REG_8(ARM64_REG_B19, ctx->x[19]) + ARM64_REG_8(ARM64_REG_B20, ctx->x[20]) + ARM64_REG_8(ARM64_REG_B21, ctx->x[21]) + ARM64_REG_8(ARM64_REG_B22, ctx->x[22]) + ARM64_REG_8(ARM64_REG_B23, ctx->x[23]) + ARM64_REG_8(ARM64_REG_B24, ctx->x[24]) + ARM64_REG_8(ARM64_REG_B25, ctx->x[25]) + ARM64_REG_8(ARM64_REG_B26, ctx->x[26]) + ARM64_REG_8(ARM64_REG_B27, ctx->x[27]) + ARM64_REG_8(ARM64_REG_B28, ctx->x[28]) + ARM64_REG_8(ARM64_REG_B29, ctx->fp) + ARM64_REG_8(ARM64_REG_B30, ctx->lr) + ARM64_REG_8(ARM64_REG_B31, ctx->sp) + + ARM64_REG_16(ARM64_REG_H0, ctx->x[0]) + ARM64_REG_16(ARM64_REG_H1, ctx->x[1]) + ARM64_REG_16(ARM64_REG_H2, ctx->x[2]) + ARM64_REG_16(ARM64_REG_H3, ctx->x[3]) + ARM64_REG_16(ARM64_REG_H4, ctx->x[4]) + ARM64_REG_16(ARM64_REG_H5, ctx->x[5]) + ARM64_REG_16(ARM64_REG_H6, ctx->x[6]) + ARM64_REG_16(ARM64_REG_H7, ctx->x[7]) + ARM64_REG_16(ARM64_REG_H8, ctx->x[8]) + ARM64_REG_16(ARM64_REG_H9, ctx->x[9]) + ARM64_REG_16(ARM64_REG_H10, ctx->x[10]) + ARM64_REG_16(ARM64_REG_H11, ctx->x[11]) + ARM64_REG_16(ARM64_REG_H12, ctx->x[12]) + ARM64_REG_16(ARM64_REG_H13, ctx->x[13]) + ARM64_REG_16(ARM64_REG_H14, ctx->x[14]) + ARM64_REG_16(ARM64_REG_H15, ctx->x[15]) + ARM64_REG_16(ARM64_REG_H16, ctx->x[16]) + ARM64_REG_16(ARM64_REG_H17, ctx->x[17]) + ARM64_REG_16(ARM64_REG_H18, ctx->x[18]) + ARM64_REG_16(ARM64_REG_H19, ctx->x[19]) + ARM64_REG_16(ARM64_REG_H20, ctx->x[20]) + ARM64_REG_16(ARM64_REG_H21, ctx->x[21]) + ARM64_REG_16(ARM64_REG_H22, ctx->x[22]) + ARM64_REG_16(ARM64_REG_H23, ctx->x[23]) + ARM64_REG_16(ARM64_REG_H24, ctx->x[24]) + ARM64_REG_16(ARM64_REG_H25, ctx->x[25]) + ARM64_REG_16(ARM64_REG_H26, ctx->x[26]) + ARM64_REG_16(ARM64_REG_H27, ctx->x[27]) + ARM64_REG_16(ARM64_REG_H28, ctx->x[28]) + ARM64_REG_16(ARM64_REG_H29, ctx->fp) + ARM64_REG_16(ARM64_REG_H30, ctx->lr) + ARM64_REG_16(ARM64_REG_H31, ctx->sp) + + ARM64_REG_32(ARM64_REG_W0, ctx->x[0]) + ARM64_REG_32(ARM64_REG_W1, ctx->x[1]) + ARM64_REG_32(ARM64_REG_W2, ctx->x[2]) + ARM64_REG_32(ARM64_REG_W3, ctx->x[3]) + ARM64_REG_32(ARM64_REG_W4, ctx->x[4]) + ARM64_REG_32(ARM64_REG_W5, ctx->x[5]) + ARM64_REG_32(ARM64_REG_W6, ctx->x[6]) + ARM64_REG_32(ARM64_REG_W7, ctx->x[7]) + ARM64_REG_32(ARM64_REG_W8, ctx->x[8]) + ARM64_REG_32(ARM64_REG_W9, ctx->x[9]) + ARM64_REG_32(ARM64_REG_W10, ctx->x[10]) + ARM64_REG_32(ARM64_REG_W11, ctx->x[11]) + ARM64_REG_32(ARM64_REG_W12, ctx->x[12]) + ARM64_REG_32(ARM64_REG_W13, ctx->x[13]) + ARM64_REG_32(ARM64_REG_W14, ctx->x[14]) + ARM64_REG_32(ARM64_REG_W15, ctx->x[15]) + ARM64_REG_32(ARM64_REG_W16, ctx->x[16]) + ARM64_REG_32(ARM64_REG_W17, ctx->x[17]) + ARM64_REG_32(ARM64_REG_W18, ctx->x[18]) + ARM64_REG_32(ARM64_REG_W19, ctx->x[19]) + ARM64_REG_32(ARM64_REG_W20, ctx->x[20]) + ARM64_REG_32(ARM64_REG_W21, ctx->x[21]) + ARM64_REG_32(ARM64_REG_W22, ctx->x[22]) + ARM64_REG_32(ARM64_REG_W23, ctx->x[23]) + ARM64_REG_32(ARM64_REG_W24, ctx->x[24]) + ARM64_REG_32(ARM64_REG_W25, ctx->x[25]) + ARM64_REG_32(ARM64_REG_W26, ctx->x[26]) + ARM64_REG_32(ARM64_REG_W27, ctx->x[27]) + ARM64_REG_32(ARM64_REG_W28, ctx->x[28]) + ARM64_REG_32(ARM64_REG_W29, ctx->fp) + ARM64_REG_32(ARM64_REG_W30, ctx->lr) + + ARM64_REG_64(ARM64_REG_X0, ctx->x[0]) + ARM64_REG_64(ARM64_REG_X1, ctx->x[1]) + ARM64_REG_64(ARM64_REG_X2, ctx->x[2]) + ARM64_REG_64(ARM64_REG_X3, ctx->x[3]) + ARM64_REG_64(ARM64_REG_X4, ctx->x[4]) + ARM64_REG_64(ARM64_REG_X5, ctx->x[5]) + ARM64_REG_64(ARM64_REG_X6, ctx->x[6]) + ARM64_REG_64(ARM64_REG_X7, ctx->x[7]) + ARM64_REG_64(ARM64_REG_X8, ctx->x[8]) + ARM64_REG_64(ARM64_REG_X9, ctx->x[9]) + ARM64_REG_64(ARM64_REG_X10, ctx->x[10]) + ARM64_REG_64(ARM64_REG_X11, ctx->x[11]) + ARM64_REG_64(ARM64_REG_X12, ctx->x[12]) + ARM64_REG_64(ARM64_REG_X13, ctx->x[13]) + ARM64_REG_64(ARM64_REG_X14, ctx->x[14]) + ARM64_REG_64(ARM64_REG_X15, ctx->x[15]) + ARM64_REG_64(ARM64_REG_X16, ctx->x[16]) + ARM64_REG_64(ARM64_REG_X17, ctx->x[17]) + ARM64_REG_64(ARM64_REG_X18, ctx->x[18]) + ARM64_REG_64(ARM64_REG_X19, ctx->x[19]) + ARM64_REG_64(ARM64_REG_X20, ctx->x[20]) + ARM64_REG_64(ARM64_REG_X21, ctx->x[21]) + ARM64_REG_64(ARM64_REG_X22, ctx->x[22]) + ARM64_REG_64(ARM64_REG_X23, ctx->x[23]) + ARM64_REG_64(ARM64_REG_X24, ctx->x[24]) + ARM64_REG_64(ARM64_REG_X25, ctx->x[25]) + ARM64_REG_64(ARM64_REG_X26, ctx->x[26]) + ARM64_REG_64(ARM64_REG_X27, ctx->x[27]) + ARM64_REG_64(ARM64_REG_X28, ctx->x[28]) + ARM64_REG_64(ARM64_REG_FP, ctx->fp) + ARM64_REG_64(ARM64_REG_LR, ctx->lr) + ARM64_REG_64(ARM64_REG_SP, ctx->sp) + + default: + FATAL("Failed to read register: %d", reg); + return 0; + + } + +} + +size_t ctx_get_size(const cs_insn *instr, cs_arm64_op *operand) { + + uint8_t num_registers; + uint8_t count_byte; + char vas_digit; + size_t mnemonic_len; + + switch (instr->id) { + + case ARM64_INS_STP: + case ARM64_INS_STXP: + case ARM64_INS_STNP: + case ARM64_INS_STLXP: + case ARM64_INS_LDP: + case ARM64_INS_LDXP: + case ARM64_INS_LDNP: + num_registers = 2; + break; + default: + num_registers = 1; + break; + + } + + mnemonic_len = strlen(instr->mnemonic); + if (mnemonic_len == 0) { FATAL("No mnemonic found"); }; + + char last = instr->mnemonic[mnemonic_len - 1]; + switch (last) { + + case 'b': + return 1; + case 'h': + return 2; + case 'w': + return 4 * num_registers; + + } + + if (operand->vas == ARM64_VAS_INVALID) { + + if (operand->type == ARM64_OP_REG) { + + switch (operand->reg) { + + case ARM64_REG_WZR: + case ARM64_REG_WSP: + case ARM64_REG_W0 ... ARM64_REG_W30: + case ARM64_REG_S0 ... ARM64_REG_S31: + return 4 * num_registers; + case ARM64_REG_D0 ... ARM64_REG_D31: + return 8 * num_registers; + case ARM64_REG_Q0 ... ARM64_REG_Q31: + return 16; + default: + return 8 * num_registers; + ; + + } + + } + + return 8 * num_registers; + + } + + if (g_str_has_prefix(instr->mnemonic, "st") || + g_str_has_prefix(instr->mnemonic, "ld")) { + + if (mnemonic_len < 3) { + + FATAL("VAS Mnemonic too short: %s\n", instr->mnemonic); + + } + + vas_digit = instr->mnemonic[2]; + if (vas_digit < '0' || vas_digit > '9') { + + FATAL("VAS Mnemonic digit out of range: %s\n", instr->mnemonic); + + } + + count_byte = vas_digit - '0'; + + } else { + + count_byte = 1; + + } + + switch (operand->vas) { + + case ARM64_VAS_1B: + return 1 * count_byte; + case ARM64_VAS_1H: + return 2 * count_byte; + case ARM64_VAS_4B: + case ARM64_VAS_1S: + case ARM64_VAS_1D: + case ARM64_VAS_2H: + return 4 * count_byte; + case ARM64_VAS_8B: + case ARM64_VAS_4H: + case ARM64_VAS_2S: + case ARM64_VAS_2D: + case ARM64_VAS_1Q: + return 8 * count_byte; + case ARM64_VAS_8H: + case ARM64_VAS_4S: + case ARM64_VAS_16B: + return 16 * count_byte; + default: + FATAL("Unexpected VAS type: %s %d", instr->mnemonic, operand->vas); + + } + +} + +#endif + diff --git a/frida_mode/src/instrument/instrument.c b/frida_mode/src/instrument/instrument.c index cd1ac0be..f261e79a 100644 --- a/frida_mode/src/instrument/instrument.c +++ b/frida_mode/src/instrument/instrument.c @@ -84,6 +84,8 @@ static void instr_basic_block(GumStalkerIterator *iterator, while (gum_stalker_iterator_next(iterator, &instr)) { + if (unlikely(begin)) { instrument_debug_start(instr->address, output); } + if (instr->address == entry_start) { entry_prologue(iterator, output); } if (instr->address == persistent_start) { persistent_prologue(output); } if (instr->address == persistent_ret) { persistent_epilogue(output); } @@ -119,8 +121,6 @@ static void instr_basic_block(GumStalkerIterator *iterator, if (unlikely(begin)) { - instrument_debug_start(instr->address, output); - prefetch_write(GSIZE_TO_POINTER(instr->address)); if (likely(!excluded)) { @@ -155,6 +155,7 @@ static void instr_basic_block(GumStalkerIterator *iterator, } + instrument_flush(output); instrument_debug_end(output); } diff --git a/frida_mode/src/instrument/instrument_arm32.c b/frida_mode/src/instrument/instrument_arm32.c index 1a3c40bb..450a69a3 100644 --- a/frida_mode/src/instrument/instrument_arm32.c +++ b/frida_mode/src/instrument/instrument_arm32.c @@ -22,5 +22,17 @@ void instrument_coverage_optimize(const cs_insn * instr, } +void instrument_flush(GumStalkerOutput *output) { + + gum_arm_writer_flush(output->writer.arm); + +} + +gpointer instrument_cur(GumStalkerOutput *output) { + + return gum_arm_writer_cur(output->writer.arm); + +} + #endif diff --git a/frida_mode/src/instrument/instrument_arm64.c b/frida_mode/src/instrument/instrument_arm64.c index fa3afb48..49ee86a2 100644 --- a/frida_mode/src/instrument/instrument_arm64.c +++ b/frida_mode/src/instrument/instrument_arm64.c @@ -93,5 +93,17 @@ void instrument_coverage_optimize(const cs_insn * instr, } +void instrument_flush(GumStalkerOutput *output) { + + gum_arm64_writer_flush(output->writer.arm64); + +} + +gpointer instrument_cur(GumStalkerOutput *output) { + + return gum_arm64_writer_cur(output->writer.arm64); + +} + #endif diff --git a/frida_mode/src/instrument/instrument_debug.c b/frida_mode/src/instrument/instrument_debug.c index f8c1df77..0ce26a1c 100644 --- a/frida_mode/src/instrument/instrument_debug.c +++ b/frida_mode/src/instrument/instrument_debug.c @@ -7,6 +7,7 @@ #include "debug.h" +#include "instrument.h" #include "util.h" static int debugging_fd = -1; @@ -31,44 +32,50 @@ static void instrument_debug(char *format, ...) { } -static void instrument_disasm(guint8 *code, guint size) { +static void instrument_disasm(guint8 *start, guint8 *end) { csh capstone; cs_err err; + uint16_t size; cs_insn *insn; - size_t count, i; + size_t count = 0; + size_t i; + uint16_t len; err = cs_open(GUM_DEFAULT_CS_ARCH, GUM_DEFAULT_CS_MODE | GUM_DEFAULT_CS_ENDIAN, &capstone); g_assert(err == CS_ERR_OK); - count = cs_disasm(capstone, code, size, GPOINTER_TO_SIZE(code), 0, &insn); - g_assert(insn != NULL); + size = GPOINTER_TO_SIZE(end) - GPOINTER_TO_SIZE(start); - for (i = 0; i != count; i++) { + for (guint8 *curr = start; curr < end; curr += len, size -= len, len = 0) { - instrument_debug("\t0x%" G_GINT64_MODIFIER "x\t%s %s\n", insn[i].address, - insn[i].mnemonic, insn[i].op_str); + count = cs_disasm(capstone, curr, size, GPOINTER_TO_SIZE(curr), 0, &insn); + if (insn == NULL) { - } + instrument_debug("\t0x%" G_GINT64_MODIFIER "x\t* 0x%016" G_GSIZE_MODIFIER + "x\n", + curr, *(size_t *)curr); - cs_free(insn, count); + len += sizeof(size_t); + continue; - cs_close(&capstone); + } -} + for (i = 0; i != count; i++) { + + instrument_debug("\t0x%" G_GINT64_MODIFIER "x\t%s %s\n", insn[i].address, + insn[i].mnemonic, insn[i].op_str); + + len += insn[i].size; -static gpointer instrument_cur(GumStalkerOutput *output) { + } -#if defined(__i386__) || defined(__x86_64__) - return gum_x86_writer_cur(output->writer.x86); -#elif defined(__aarch64__) - return gum_arm64_writer_cur(output->writer.arm64); -#elif defined(__arm__) - return gum_arm_writer_cur(output->writer.arm); -#else - #error "Unsupported architecture" -#endif + } + + cs_free(insn, count); + + cs_close(&capstone); } @@ -111,7 +118,7 @@ void instrument_debug_instruction(uint64_t address, uint16_t size) { if (likely(debugging_fd < 0)) { return; } uint8_t *start = (uint8_t *)GSIZE_TO_POINTER(address); - instrument_disasm(start, size); + instrument_disasm(start, start + size); } @@ -119,11 +126,10 @@ void instrument_debug_end(GumStalkerOutput *output) { if (likely(debugging_fd < 0)) { return; } gpointer instrument_gen_end = instrument_cur(output); - uint16_t size = GPOINTER_TO_SIZE(instrument_gen_end) - - GPOINTER_TO_SIZE(instrument_gen_start); - instrument_debug("\nGenerated block %p\n", instrument_gen_start); - instrument_disasm(instrument_gen_start, size); + instrument_debug("\nGenerated block %p-%p\n", instrument_gen_start, + instrument_gen_end); + instrument_disasm(instrument_gen_start, instrument_gen_end); } diff --git a/frida_mode/src/instrument/instrument_x64.c b/frida_mode/src/instrument/instrument_x64.c index 901f3bd0..7000e65d 100644 --- a/frida_mode/src/instrument/instrument_x64.c +++ b/frida_mode/src/instrument/instrument_x64.c @@ -89,5 +89,17 @@ void instrument_coverage_optimize(const cs_insn * instr, } +void instrument_flush(GumStalkerOutput *output) { + + gum_x86_writer_flush(output->writer.x86); + +} + +gpointer instrument_cur(GumStalkerOutput *output) { + + return gum_x86_writer_cur(output->writer.x86); + +} + #endif diff --git a/frida_mode/src/instrument/instrument_x86.c b/frida_mode/src/instrument/instrument_x86.c index 585bb5b8..04a19e08 100644 --- a/frida_mode/src/instrument/instrument_x86.c +++ b/frida_mode/src/instrument/instrument_x86.c @@ -81,5 +81,17 @@ void instrument_coverage_optimize(const cs_insn * instr, } +void instrument_flush(GumStalkerOutput *output) { + + gum_x86_writer_flush(output->writer.x86); + +} + +gpointer instrument_cur(GumStalkerOutput *output) { + + return gum_x86_writer_cur(output->writer.x86); + +} + #endif diff --git a/frida_mode/src/persistent/persistent_arm64.c b/frida_mode/src/persistent/persistent_arm64.c index 1215d8da..b23693fe 100644 --- a/frida_mode/src/persistent/persistent_arm64.c +++ b/frida_mode/src/persistent/persistent_arm64.c @@ -1,9 +1,11 @@ +#include #include "frida-gum.h" #include "config.h" #include "debug.h" #include "instrument.h" +#include "persistent.h" #include "util.h" #if defined(__aarch64__) @@ -98,23 +100,365 @@ struct arm64_regs { typedef struct arm64_regs arch_api_regs; +static arch_api_regs saved_regs = {0}; +static gpointer saved_lr = NULL; + gboolean persistent_is_supported(void) { - return false; + return true; + +} + +static void instrument_persitent_save_regs(GumArm64Writer * cw, + struct arm64_regs *regs) { + + GumAddress regs_address = GUM_ADDRESS(regs); + const guint32 mrs_x1_nzcv = 0xd53b4201; + + gum_arm64_writer_put_stp_reg_reg_reg_offset( + cw, ARM64_REG_X0, ARM64_REG_X1, ARM64_REG_SP, -(16 + GUM_RED_ZONE_SIZE), + GUM_INDEX_PRE_ADJUST); + gum_arm64_writer_put_stp_reg_reg_reg_offset(cw, ARM64_REG_X2, ARM64_REG_X3, + ARM64_REG_SP, -(16), + GUM_INDEX_PRE_ADJUST); + + gum_arm64_writer_put_instruction(cw, mrs_x1_nzcv); + + gum_arm64_writer_put_ldr_reg_address(cw, ARM64_REG_X0, + GUM_ADDRESS(regs_address)); + + /* Skip x0 & x1 we'll do that later */ + + gum_arm64_writer_put_stp_reg_reg_reg_offset(cw, ARM64_REG_X2, ARM64_REG_X3, + ARM64_REG_X0, (16 * 1), + GUM_INDEX_SIGNED_OFFSET); + gum_arm64_writer_put_stp_reg_reg_reg_offset(cw, ARM64_REG_X4, ARM64_REG_X5, + ARM64_REG_X0, (16 * 2), + GUM_INDEX_SIGNED_OFFSET); + gum_arm64_writer_put_stp_reg_reg_reg_offset(cw, ARM64_REG_X6, ARM64_REG_X7, + ARM64_REG_X0, (16 * 3), + GUM_INDEX_SIGNED_OFFSET); + gum_arm64_writer_put_stp_reg_reg_reg_offset(cw, ARM64_REG_X8, ARM64_REG_X9, + ARM64_REG_X0, (16 * 4), + GUM_INDEX_SIGNED_OFFSET); + gum_arm64_writer_put_stp_reg_reg_reg_offset(cw, ARM64_REG_X10, ARM64_REG_X11, + ARM64_REG_X0, (16 * 5), + GUM_INDEX_SIGNED_OFFSET); + gum_arm64_writer_put_stp_reg_reg_reg_offset(cw, ARM64_REG_X12, ARM64_REG_X13, + ARM64_REG_X0, (16 * 6), + GUM_INDEX_SIGNED_OFFSET); + gum_arm64_writer_put_stp_reg_reg_reg_offset(cw, ARM64_REG_X14, ARM64_REG_X15, + ARM64_REG_X0, (16 * 7), + GUM_INDEX_SIGNED_OFFSET); + gum_arm64_writer_put_stp_reg_reg_reg_offset(cw, ARM64_REG_X16, ARM64_REG_X17, + ARM64_REG_X0, (16 * 8), + GUM_INDEX_SIGNED_OFFSET); + gum_arm64_writer_put_stp_reg_reg_reg_offset(cw, ARM64_REG_X18, ARM64_REG_X19, + ARM64_REG_X0, (16 * 9), + GUM_INDEX_SIGNED_OFFSET); + gum_arm64_writer_put_stp_reg_reg_reg_offset(cw, ARM64_REG_X20, ARM64_REG_X21, + ARM64_REG_X0, (16 * 10), + GUM_INDEX_SIGNED_OFFSET); + gum_arm64_writer_put_stp_reg_reg_reg_offset(cw, ARM64_REG_X22, ARM64_REG_X23, + ARM64_REG_X0, (16 * 11), + GUM_INDEX_SIGNED_OFFSET); + gum_arm64_writer_put_stp_reg_reg_reg_offset(cw, ARM64_REG_X24, ARM64_REG_X25, + ARM64_REG_X0, (16 * 12), + GUM_INDEX_SIGNED_OFFSET); + gum_arm64_writer_put_stp_reg_reg_reg_offset(cw, ARM64_REG_X26, ARM64_REG_X27, + ARM64_REG_X0, (16 * 13), + GUM_INDEX_SIGNED_OFFSET); + gum_arm64_writer_put_stp_reg_reg_reg_offset(cw, ARM64_REG_X28, ARM64_REG_X29, + ARM64_REG_X0, (16 * 14), + GUM_INDEX_SIGNED_OFFSET); + + /* LR & Adjusted SP */ + gum_arm64_writer_put_add_reg_reg_imm(cw, ARM64_REG_X2, ARM64_REG_SP, + (GUM_RED_ZONE_SIZE + 32)); + gum_arm64_writer_put_stp_reg_reg_reg_offset(cw, ARM64_REG_X30, ARM64_REG_X2, + ARM64_REG_X0, (16 * 15), + GUM_INDEX_SIGNED_OFFSET); + + /* PC & CPSR */ + gum_arm64_writer_put_ldr_reg_address(cw, ARM64_REG_X2, + GUM_ADDRESS(persistent_start)); + gum_arm64_writer_put_stp_reg_reg_reg_offset(cw, ARM64_REG_X2, ARM64_REG_X1, + ARM64_REG_X0, (16 * 16), + GUM_INDEX_SIGNED_OFFSET); + + gum_arm64_writer_put_stp_reg_reg_reg_offset(cw, ARM64_REG_Q0, ARM64_REG_Q1, + ARM64_REG_X0, (16 * 17), + GUM_INDEX_SIGNED_OFFSET); + gum_arm64_writer_put_stp_reg_reg_reg_offset(cw, ARM64_REG_Q2, ARM64_REG_Q3, + ARM64_REG_X0, (16 * 18), + GUM_INDEX_SIGNED_OFFSET); + gum_arm64_writer_put_stp_reg_reg_reg_offset(cw, ARM64_REG_Q4, ARM64_REG_Q5, + ARM64_REG_X0, (16 * 19), + GUM_INDEX_SIGNED_OFFSET); + gum_arm64_writer_put_stp_reg_reg_reg_offset(cw, ARM64_REG_Q6, ARM64_REG_Q7, + ARM64_REG_X0, (16 * 20), + GUM_INDEX_SIGNED_OFFSET); + + /* x0 & x1 */ + gum_arm64_writer_put_ldp_reg_reg_reg_offset(cw, ARM64_REG_X2, ARM64_REG_X3, + ARM64_REG_SP, 16, + GUM_INDEX_SIGNED_OFFSET); + gum_arm64_writer_put_stp_reg_reg_reg_offset(cw, ARM64_REG_X2, ARM64_REG_X3, + ARM64_REG_X0, (16 * 0), + GUM_INDEX_SIGNED_OFFSET); + + /* Pop the saved values */ + gum_arm64_writer_put_ldp_reg_reg_reg_offset( + cw, ARM64_REG_X2, ARM64_REG_X3, ARM64_REG_SP, 16, GUM_INDEX_POST_ADJUST); + + gum_arm64_writer_put_ldp_reg_reg_reg_offset( + cw, ARM64_REG_X0, ARM64_REG_X1, ARM64_REG_SP, 16 + GUM_RED_ZONE_SIZE, + GUM_INDEX_POST_ADJUST); + +} + +static void instrument_persitent_restore_regs(GumArm64Writer * cw, + struct arm64_regs *regs) { + + GumAddress regs_address = GUM_ADDRESS(regs); + const guint32 msr_nzcv_x1 = 0xd51b4201; + + gum_arm64_writer_put_ldr_reg_address(cw, ARM64_REG_X0, + GUM_ADDRESS(regs_address)); + + /* Skip x0 - x3 we'll do that last */ + + gum_arm64_writer_put_ldp_reg_reg_reg_offset(cw, ARM64_REG_X4, ARM64_REG_X5, + ARM64_REG_X0, (16 * 2), + GUM_INDEX_SIGNED_OFFSET); + gum_arm64_writer_put_ldp_reg_reg_reg_offset(cw, ARM64_REG_X6, ARM64_REG_X7, + ARM64_REG_X0, (16 * 3), + GUM_INDEX_SIGNED_OFFSET); + gum_arm64_writer_put_ldp_reg_reg_reg_offset(cw, ARM64_REG_X8, ARM64_REG_X9, + ARM64_REG_X0, (16 * 4), + GUM_INDEX_SIGNED_OFFSET); + gum_arm64_writer_put_ldp_reg_reg_reg_offset(cw, ARM64_REG_X10, ARM64_REG_X11, + ARM64_REG_X0, (16 * 5), + GUM_INDEX_SIGNED_OFFSET); + gum_arm64_writer_put_ldp_reg_reg_reg_offset(cw, ARM64_REG_X12, ARM64_REG_X13, + ARM64_REG_X0, (16 * 6), + GUM_INDEX_SIGNED_OFFSET); + gum_arm64_writer_put_ldp_reg_reg_reg_offset(cw, ARM64_REG_X14, ARM64_REG_X15, + ARM64_REG_X0, (16 * 7), + GUM_INDEX_SIGNED_OFFSET); + gum_arm64_writer_put_ldp_reg_reg_reg_offset(cw, ARM64_REG_X16, ARM64_REG_X17, + ARM64_REG_X0, (16 * 8), + GUM_INDEX_SIGNED_OFFSET); + gum_arm64_writer_put_ldp_reg_reg_reg_offset(cw, ARM64_REG_X18, ARM64_REG_X19, + ARM64_REG_X0, (16 * 9), + GUM_INDEX_SIGNED_OFFSET); + gum_arm64_writer_put_ldp_reg_reg_reg_offset(cw, ARM64_REG_X20, ARM64_REG_X21, + ARM64_REG_X0, (16 * 10), + GUM_INDEX_SIGNED_OFFSET); + gum_arm64_writer_put_ldp_reg_reg_reg_offset(cw, ARM64_REG_X22, ARM64_REG_X23, + ARM64_REG_X0, (16 * 11), + GUM_INDEX_SIGNED_OFFSET); + gum_arm64_writer_put_ldp_reg_reg_reg_offset(cw, ARM64_REG_X24, ARM64_REG_X25, + ARM64_REG_X0, (16 * 12), + GUM_INDEX_SIGNED_OFFSET); + gum_arm64_writer_put_ldp_reg_reg_reg_offset(cw, ARM64_REG_X26, ARM64_REG_X27, + ARM64_REG_X0, (16 * 13), + GUM_INDEX_SIGNED_OFFSET); + gum_arm64_writer_put_ldp_reg_reg_reg_offset(cw, ARM64_REG_X28, ARM64_REG_X29, + ARM64_REG_X0, (16 * 14), + GUM_INDEX_SIGNED_OFFSET); + + /* Don't restore RIP or RSP, use x1-x3 as clobber */ + + /* LR & Adjusted SP (clobber x1) */ + gum_arm64_writer_put_ldp_reg_reg_reg_offset(cw, ARM64_REG_X30, ARM64_REG_X1, + ARM64_REG_X0, (16 * 15), + GUM_INDEX_SIGNED_OFFSET); + + /* PC (x2) & CPSR (x1) */ + gum_arm64_writer_put_ldp_reg_reg_reg_offset(cw, ARM64_REG_X2, ARM64_REG_X1, + ARM64_REG_X0, (16 * 16), + GUM_INDEX_SIGNED_OFFSET); + gum_arm64_writer_put_instruction(cw, msr_nzcv_x1); + + gum_arm64_writer_put_ldp_reg_reg_reg_offset(cw, ARM64_REG_Q0, ARM64_REG_Q1, + ARM64_REG_X0, (16 * 17), + GUM_INDEX_SIGNED_OFFSET); + gum_arm64_writer_put_ldp_reg_reg_reg_offset(cw, ARM64_REG_Q2, ARM64_REG_Q3, + ARM64_REG_X0, (16 * 18), + GUM_INDEX_SIGNED_OFFSET); + gum_arm64_writer_put_ldp_reg_reg_reg_offset(cw, ARM64_REG_Q4, ARM64_REG_Q5, + ARM64_REG_X0, (16 * 19), + GUM_INDEX_SIGNED_OFFSET); + gum_arm64_writer_put_ldp_reg_reg_reg_offset(cw, ARM64_REG_Q6, ARM64_REG_Q7, + ARM64_REG_X0, (16 * 20), + GUM_INDEX_SIGNED_OFFSET); + + /* x2 & x3 */ + gum_arm64_writer_put_ldp_reg_reg_reg_offset(cw, ARM64_REG_X2, ARM64_REG_X3, + ARM64_REG_X0, (16 * 1), + GUM_INDEX_SIGNED_OFFSET); + /* x0 & x1 */ + gum_arm64_writer_put_ldp_reg_reg_reg_offset(cw, ARM64_REG_X0, ARM64_REG_X1, + ARM64_REG_X0, (16 * 0), + GUM_INDEX_SIGNED_OFFSET); + +} + +static void instrument_exit(GumArm64Writer *cw) { + + gum_arm64_writer_put_mov_reg_reg(cw, ARM64_REG_X0, ARM64_REG_XZR); + gum_arm64_writer_put_call_address_with_arguments( + cw, GUM_ADDRESS(_exit), 1, GUM_ARG_REGISTER, ARM64_REG_X0); + +} + +static int instrument_afl_persistent_loop_func(void) { + + int ret = __afl_persistent_loop(persistent_count); + previous_pc = 0; + return ret; + +} + +static void instrument_afl_persistent_loop(GumArm64Writer *cw) { + + gum_arm64_writer_put_sub_reg_reg_imm(cw, ARM64_REG_SP, ARM64_REG_SP, + GUM_RED_ZONE_SIZE); + gum_arm64_writer_put_call_address_with_arguments( + cw, GUM_ADDRESS(instrument_afl_persistent_loop_func), 0); + gum_arm64_writer_put_add_reg_reg_imm(cw, ARM64_REG_SP, ARM64_REG_SP, + GUM_RED_ZONE_SIZE); + +} + +static void persistent_prologue_hook(GumArm64Writer * cw, + struct arm64_regs *regs) { + + if (hook == NULL) return; + + gum_arm64_writer_put_sub_reg_reg_imm(cw, ARM64_REG_SP, ARM64_REG_SP, + GUM_RED_ZONE_SIZE); + gum_arm64_writer_put_ldr_reg_address(cw, ARM64_REG_X3, + GUM_ADDRESS(&__afl_fuzz_len)); + gum_arm64_writer_put_ldr_reg_reg_offset(cw, ARM64_REG_X3, ARM64_REG_X3, 0); + gum_arm64_writer_put_ldr_reg_reg_offset(cw, ARM64_REG_X3, ARM64_REG_X3, 0); + + gum_arm64_writer_put_and_reg_reg_imm(cw, ARM64_REG_X3, ARM64_REG_X3, + G_MAXULONG); + + gum_arm64_writer_put_ldr_reg_address(cw, ARM64_REG_X2, + GUM_ADDRESS(&__afl_fuzz_ptr)); + gum_arm64_writer_put_ldr_reg_reg_offset(cw, ARM64_REG_X2, ARM64_REG_X2, 0); + + gum_arm64_writer_put_call_address_with_arguments( + cw, GUM_ADDRESS(hook), 4, GUM_ARG_ADDRESS, GUM_ADDRESS(regs), + GUM_ARG_ADDRESS, GUM_ADDRESS(0), GUM_ARG_REGISTER, ARM64_REG_X2, + GUM_ARG_REGISTER, ARM64_REG_X3); + + gum_arm64_writer_put_add_reg_reg_imm(cw, ARM64_REG_SP, ARM64_REG_SP, + GUM_RED_ZONE_SIZE); + +} + +static void instrument_persitent_save_lr(GumArm64Writer *cw) { + + gum_arm64_writer_put_stp_reg_reg_reg_offset( + cw, ARM64_REG_X0, ARM64_REG_X1, ARM64_REG_SP, -(16 + GUM_RED_ZONE_SIZE), + GUM_INDEX_PRE_ADJUST); + + gum_arm64_writer_put_ldr_reg_address(cw, ARM64_REG_X0, + GUM_ADDRESS(&saved_lr)); + + gum_arm64_writer_put_str_reg_reg_offset(cw, ARM64_REG_LR, ARM64_REG_X0, 0); + + gum_arm64_writer_put_ldp_reg_reg_reg_offset( + cw, ARM64_REG_X0, ARM64_REG_X1, ARM64_REG_SP, 16 + GUM_RED_ZONE_SIZE, + GUM_INDEX_POST_ADJUST); } void persistent_prologue(GumStalkerOutput *output) { - UNUSED_PARAMETER(output); - FATAL("Persistent mode not supported on this architecture"); + /* + * SAVE REGS + * SAVE RET + * POP RET + * loop: + * CALL instrument_afl_persistent_loop + * TEST EAX, EAX + * JZ end: + * call hook (optionally) + * RESTORE REGS + * call original + * jmp loop: + * + * end: + * JMP SAVED RET + * + * original: + * INSTRUMENTED PERSISTENT FUNC + */ + + GumArm64Writer *cw = output->writer.arm64; + + gconstpointer loop = cw->code + 1; + + /* Stack must be 16-byte aligned per ABI */ + instrument_persitent_save_regs(cw, &saved_regs); + + /* loop: */ + gum_arm64_writer_put_label(cw, loop); + + /* call instrument_prologue_func */ + instrument_afl_persistent_loop(cw); + + /* jz done */ + gconstpointer done = cw->code + 1; + gum_arm64_writer_put_cmp_reg_reg(cw, ARM64_REG_X0, ARM64_REG_XZR); + gum_arm64_writer_put_b_cond_label(cw, ARM64_CC_EQ, done); + + /* Optionally call the persistent hook */ + persistent_prologue_hook(cw, &saved_regs); + + instrument_persitent_restore_regs(cw, &saved_regs); + gconstpointer original = cw->code + 1; + /* call original */ + + gum_arm64_writer_put_bl_label(cw, original); + + /* jmp loop */ + gum_arm64_writer_put_b_label(cw, loop); + + /* done: */ + gum_arm64_writer_put_label(cw, done); + + instrument_exit(cw); + + /* original: */ + gum_arm64_writer_put_label(cw, original); + + instrument_persitent_save_lr(cw); + + if (persistent_debug) { gum_arm64_writer_put_brk_imm(cw, 0); } } void persistent_epilogue(GumStalkerOutput *output) { - UNUSED_PARAMETER(output); - FATAL("Persistent mode not supported on this architecture"); + GumArm64Writer *cw = output->writer.arm64; + + if (persistent_debug) { gum_arm64_writer_put_brk_imm(cw, 0); } + + gum_arm64_writer_put_add_reg_reg_imm(cw, ARM64_REG_SP, ARM64_REG_SP, + persistent_ret_offset); + + gum_arm64_writer_put_ldr_reg_address(cw, ARM64_REG_X0, + GUM_ADDRESS(&saved_lr)); + + gum_arm64_writer_put_ldr_reg_reg_offset(cw, ARM64_REG_X0, ARM64_REG_X0, 0); + + gum_arm64_writer_put_br_reg(cw, ARM64_REG_X0); } diff --git a/frida_mode/src/persistent/persistent_x64.c b/frida_mode/src/persistent/persistent_x64.c index 4cb960fc..858ad38e 100644 --- a/frida_mode/src/persistent/persistent_x64.c +++ b/frida_mode/src/persistent/persistent_x64.c @@ -306,8 +306,6 @@ void persistent_prologue(GumStalkerOutput *output) { if (persistent_debug) { gum_x86_writer_put_breakpoint(cw); } - gum_x86_writer_flush(cw); - } void persistent_epilogue(GumStalkerOutput *output) { diff --git a/frida_mode/src/persistent/persistent_x86.c b/frida_mode/src/persistent/persistent_x86.c index b30dfadf..0675edf4 100644 --- a/frida_mode/src/persistent/persistent_x86.c +++ b/frida_mode/src/persistent/persistent_x86.c @@ -246,8 +246,6 @@ void persistent_prologue(GumStalkerOutput *output) { if (persistent_debug) { gum_x86_writer_put_breakpoint(cw); } - gum_x86_writer_flush(cw); - } void persistent_epilogue(GumStalkerOutput *output) { diff --git a/frida_mode/src/stats/stats.c b/frida_mode/src/stats/stats.c index 662fb6d5..0d7b9fb0 100644 --- a/frida_mode/src/stats/stats.c +++ b/frida_mode/src/stats/stats.c @@ -96,7 +96,6 @@ void stats_init(void) { void stats_vprint(int fd, char *format, va_list ap) { char buffer[4096] = {0}; - int ret; int len; if (vsnprintf(buffer, sizeof(buffer) - 1, format, ap) < 0) { return; } diff --git a/frida_mode/src/stats/stats_arm.c b/frida_mode/src/stats/stats_arm.c deleted file mode 100644 index 7eea7f91..00000000 --- a/frida_mode/src/stats/stats_arm.c +++ /dev/null @@ -1,36 +0,0 @@ -#include "frida-gum.h" - -#include "debug.h" - -#include "stats.h" -#include "util.h" - -#if defined(__arm__) - -gboolean stats_is_supported_arch(void) { - - return FALSE; - -} - -size_t stats_data_size_arch(void) { - - FATAL("Stats not supported on this architecture"); - -} - -void stats_write_arch(void) { - - FATAL("Stats not supported on this architecture"); - -} - -void stats_collect_arch(const cs_insn *instr) { - - UNUSED_PARAMETER(instr); - FATAL("Stats not supported on this architecture"); - -} - -#endif - diff --git a/frida_mode/src/stats/stats_arm32.c b/frida_mode/src/stats/stats_arm32.c new file mode 100644 index 00000000..7eea7f91 --- /dev/null +++ b/frida_mode/src/stats/stats_arm32.c @@ -0,0 +1,36 @@ +#include "frida-gum.h" + +#include "debug.h" + +#include "stats.h" +#include "util.h" + +#if defined(__arm__) + +gboolean stats_is_supported_arch(void) { + + return FALSE; + +} + +size_t stats_data_size_arch(void) { + + FATAL("Stats not supported on this architecture"); + +} + +void stats_write_arch(void) { + + FATAL("Stats not supported on this architecture"); + +} + +void stats_collect_arch(const cs_insn *instr) { + + UNUSED_PARAMETER(instr); + FATAL("Stats not supported on this architecture"); + +} + +#endif + diff --git a/frida_mode/test/cmplog/GNUmakefile b/frida_mode/test/cmplog/GNUmakefile index 40de6a09..4c71bb33 100644 --- a/frida_mode/test/cmplog/GNUmakefile +++ b/frida_mode/test/cmplog/GNUmakefile @@ -13,7 +13,7 @@ CMP_LOG_INPUT:=$(TEST_DATA_DIR)in QEMU_OUT:=$(BUILD_DIR)qemu-out FRIDA_OUT:=$(BUILD_DIR)frida-out -.PHONY: all 32 clean qemu frida format +.PHONY: all 32 clean qemu frida frida-nocmplog format all: $(TEST_CMPLOG_OBJ) make -C $(ROOT)frida_mode/ @@ -55,6 +55,15 @@ frida: $(TEST_CMPLOG_OBJ) $(CMP_LOG_INPUT) -- \ $(TEST_CMPLOG_OBJ) @@ +frida-nocmplog: $(TEST_CMPLOG_OBJ) $(CMP_LOG_INPUT) + $(ROOT)afl-fuzz \ + -O \ + -i $(TEST_DATA_DIR) \ + -o $(FRIDA_OUT) \ + -Z \ + -- \ + $(TEST_CMPLOG_OBJ) @@ + debug: $(TEST_CMPLOG_OBJ) $(CMP_LOG_INPUT) gdb \ --ex 'set environment LD_PRELOAD=$(ROOT)afl-frida-trace.so' \ diff --git a/frida_mode/test/cmplog/Makefile b/frida_mode/test/cmplog/Makefile index 606b43a5..7ca9a9a5 100644 --- a/frida_mode/test/cmplog/Makefile +++ b/frida_mode/test/cmplog/Makefile @@ -15,6 +15,10 @@ qemu: frida: @gmake frida + +frida-nocmplog: + @gmake frida-nocmplog + format: @gmake format diff --git a/frida_mode/test/cmplog/cmplog.c b/frida_mode/test/cmplog/cmplog.c index 99010645..ce5cf20e 100644 --- a/frida_mode/test/cmplog/cmplog.c +++ b/frida_mode/test/cmplog/cmplog.c @@ -53,7 +53,7 @@ int main(int argc, char **argv) { } -#if defined(__x86_64__) +#if defined(__x86_64__) || defined(__aarch64__) uint64_t x = 0; fread(&x, sizeof(x), 1, file); if (x != 0xCAFEBABECAFEBABE) { diff --git a/frida_mode/test/fasan/GNUmakefile b/frida_mode/test/fasan/GNUmakefile index 08b271de..c971c724 100644 --- a/frida_mode/test/fasan/GNUmakefile +++ b/frida_mode/test/fasan/GNUmakefile @@ -46,7 +46,7 @@ ifeq "$(ARCH)" "x86_64" LIBASAN_FILE:=libclang_rt.asan-x86_64.so endif -ifeq "$(ARCH)" "aarch64" +ifeq "$(ARCH)" "arm64" LIBASAN_FILE:=libclang_rt.asan-aarch64.so endif @@ -110,7 +110,7 @@ $(TEST_DATA_DIR): | $(BUILD_DIR) mkdir -p $@ $(TEST_DATA_FILE): | $(TEST_DATA_DIR) - echo -n "TUODATM" > $@ + echo -n "XUODATM" > $@ frida-noasan: $(TEST_BIN) $(TEST_DATA_FILE) $(ROOT)afl-fuzz \ diff --git a/frida_mode/test/persistent_ret/GNUmakefile b/frida_mode/test/persistent_ret/GNUmakefile index df48d065..4c9d8a19 100644 --- a/frida_mode/test/persistent_ret/GNUmakefile +++ b/frida_mode/test/persistent_ret/GNUmakefile @@ -85,7 +85,7 @@ frida_ret: $(TESTINSTBIN) $(TESTINSTR_DATA_FILE) -- \ $(TESTINSTBIN) @@ -debug: $(TESTINSTR_DATA_FILE) +debug: $(TESTINSTBIN) $(TESTINSTR_DATA_FILE) gdb \ --ex 'set environment AFL_FRIDA_PERSISTENT_ADDR=$(AFL_FRIDA_PERSISTENT_ADDR)' \ --ex 'set environment AFL_FRIDA_PERSISTENT_RET=$(AFL_FRIDA_PERSISTENT_RET)' \ @@ -96,7 +96,7 @@ debug: $(TESTINSTR_DATA_FILE) --ex 'set disassembly-flavor intel' \ --args $(TESTINSTBIN) $(TESTINSTR_DATA_FILE) -run: $(TESTINSTR_DATA_FILE) +run: $(TESTINSTBIN) $(TESTINSTR_DATA_FILE) AFL_FRIDA_PERSISTENT_ADDR=$(AFL_FRIDA_PERSISTENT_ADDR) \ AFL_FRIDA_PERSISTENT_RET=$(AFL_FRIDA_PERSISTENT_RET) \ AFL_FRIDA_PERSISTENT_RETADDR_OFFSET=$(AFL_FRIDA_PERSISTENT_RETADDR_OFFSET) \ diff --git a/frida_mode/test/png/persistent/GNUmakefile b/frida_mode/test/png/persistent/GNUmakefile index ca6f0ff2..5af64822 100644 --- a/frida_mode/test/png/persistent/GNUmakefile +++ b/frida_mode/test/png/persistent/GNUmakefile @@ -5,6 +5,7 @@ BUILD_DIR:=$(PWD)build/ TEST_BIN:=$(PWD)../build/test TEST_DATA_DIR:=../build/libpng/libpng-1.2.56/contrib/pngsuite/ +AFLPP_DRIVER_DUMMY_INPUT:=$(BUILD_DIR)in QEMU_OUT:=$(BUILD_DIR)qemu-out FRIDA_OUT:=$(BUILD_DIR)frida-out @@ -22,8 +23,7 @@ endif AFL_QEMU_PERSISTENT_ADDR=$(shell $(PWD)get_symbol_addr.py -f $(TEST_BIN) -s main -b 0x4000000000) -ARCH=$(shell uname -m) -ifeq "$(ARCH)" "aarch64" +ifeq "$(ARCH)" "arm64" AFL_FRIDA_PERSISTENT_ADDR=$(shell $(PWD)get_symbol_addr.py -f $(TEST_BIN) -s main -b 0x0000aaaaaaaaa000) endif @@ -46,6 +46,9 @@ all: $(BUILD_DIR): mkdir -p $@ +$(AFLPP_DRIVER_DUMMY_INPUT): | $(BUILD_DIR) + truncate -s 1M $@ + qemu: | $(BUILD_DIR) AFL_QEMU_PERSISTENT_ADDR=$(AFL_QEMU_PERSISTENT_ADDR) \ AFL_QEMU_PERSISTENT_GPR=1 \ @@ -94,5 +97,12 @@ frida_entry: | $(BUILD_DIR) -- \ $(TEST_BIN) @@ +debug: $(AFLPP_DRIVER_DUMMY_INPUT) + gdb \ + --ex 'set environment LD_PRELOAD=$(ROOT)afl-frida-trace.so' \ + --ex 'set environment AFL_FRIDA_PERSISTENT_ADDR=$(AFL_FRIDA_PERSISTENT_ADDR)' \ + --ex 'set disassembly-flavor intel' \ + --args $(TEST_BIN) $(AFLPP_DRIVER_DUMMY_INPUT) + clean: rm -rf $(BUILD_DIR) diff --git a/frida_mode/test/png/persistent/Makefile b/frida_mode/test/png/persistent/Makefile index cde0cf30..c2bd55f9 100644 --- a/frida_mode/test/png/persistent/Makefile +++ b/frida_mode/test/png/persistent/Makefile @@ -20,3 +20,6 @@ frida: frida_entry: @gmake frida_entry + +debug: + @gmake debug diff --git a/frida_mode/test/png/persistent/hook/GNUmakefile b/frida_mode/test/png/persistent/hook/GNUmakefile index 82f08fa4..b17f3775 100644 --- a/frida_mode/test/png/persistent/hook/GNUmakefile +++ b/frida_mode/test/png/persistent/hook/GNUmakefile @@ -34,7 +34,7 @@ endif AFL_QEMU_PERSISTENT_ADDR=$(shell $(PWD)../get_symbol_addr.py -f $(TEST_BIN) -s LLVMFuzzerTestOneInput -b 0x4000000000) -ifeq "$(ARCH)" "aarch64" +ifeq "$(ARCH)" "arm64" AFL_FRIDA_PERSISTENT_ADDR=$(shell $(PWD)../get_symbol_addr.py -f $(TEST_BIN) -s LLVMFuzzerTestOneInput -b 0x0000aaaaaaaaa000) endif @@ -124,7 +124,7 @@ frida_entry: $(AFLPP_DRIVER_DUMMY_INPUT) $(AFLPP_DRIVER_HOOK_OBJ) | $(BUILD_DIR) -- \ $(TEST_BIN) $(AFLPP_DRIVER_DUMMY_INPUT) -debug: +debug: $(AFLPP_DRIVER_DUMMY_INPUT) echo $(AFL_FRIDA_PERSISTENT_ADDR) gdb \ --ex 'set environment LD_PRELOAD=$(ROOT)afl-frida-trace.so' \ diff --git a/frida_mode/test/png/persistent/hook/aflpp_qemu_driver_hook.c b/frida_mode/test/png/persistent/hook/aflpp_qemu_driver_hook.c index 059d438d..1542c0bf 100644 --- a/frida_mode/test/png/persistent/hook/aflpp_qemu_driver_hook.c +++ b/frida_mode/test/png/persistent/hook/aflpp_qemu_driver_hook.c @@ -82,6 +82,102 @@ void afl_persistent_hook(struct x86_regs *regs, uint64_t guest_base, *arg2 = (void *)input_buf_len; } +#elif defined(__aarch64__) + +struct arm64_regs { + + uint64_t x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10; + + union { + + uint64_t x11; + uint32_t fp_32; + + }; + + union { + + uint64_t x12; + uint32_t ip_32; + + }; + + union { + + uint64_t x13; + uint32_t sp_32; + + }; + + union { + + uint64_t x14; + uint32_t lr_32; + + }; + + union { + + uint64_t x15; + uint32_t pc_32; + + }; + + union { + + uint64_t x16; + uint64_t ip0; + + }; + + union { + + uint64_t x17; + uint64_t ip1; + + }; + + uint64_t x18, x19, x20, x21, x22, x23, x24, x25, x26, x27, x28; + + union { + + uint64_t x29; + uint64_t fp; + + }; + + union { + + uint64_t x30; + uint64_t lr; + + }; + + union { + + uint64_t x31; + uint64_t sp; + + }; + + // the zero register is not saved here ofc + + uint64_t pc; + + uint32_t cpsr; + + uint8_t vfp_zregs[32][16 * 16]; + uint8_t vfp_pregs[17][32]; + uint32_t vfp_xregs[16]; + +}; + +void afl_persistent_hook(struct arm64_regs *regs, uint64_t guest_base, + uint8_t *input_buf, uint32_t input_buf_len) { + + memcpy((void *)regs->x0, input_buf, input_buf_len); + regs->x1 = input_buf_len; +} #else #pragma error "Unsupported architecture" diff --git a/instrumentation/README.llvm.md b/instrumentation/README.llvm.md index 8ce5afb9..2d428e6d 100644 --- a/instrumentation/README.llvm.md +++ b/instrumentation/README.llvm.md @@ -6,7 +6,7 @@ ## 1) Introduction -! llvm_mode works with llvm versions 6.0 up to 12 ! +! llvm_mode works with llvm versions 3.8 up to 12 ! The code in this directory allows you to instrument programs for AFL using true compiler-level instrumentation, instead of the more crude diff --git a/instrumentation/afl-compiler-rt.o.c b/instrumentation/afl-compiler-rt.o.c index 2089ce78..50117012 100644 --- a/instrumentation/afl-compiler-rt.o.c +++ b/instrumentation/afl-compiler-rt.o.c @@ -83,14 +83,15 @@ extern ssize_t _kern_write(int fd, off_t pos, const void *buffer, size_t bufferSize); #endif // HAIKU -u8 __afl_area_initial[MAP_INITIAL_SIZE]; -u8 * __afl_area_ptr_dummy = __afl_area_initial; -u8 * __afl_area_ptr = __afl_area_initial; -u8 * __afl_area_ptr_backup = __afl_area_initial; -u8 * __afl_dictionary; -u8 * __afl_fuzz_ptr; -u32 __afl_fuzz_len_dummy; -u32 *__afl_fuzz_len = &__afl_fuzz_len_dummy; +static u8 __afl_area_initial[MAP_INITIAL_SIZE]; +static u8 *__afl_area_ptr_dummy = __afl_area_initial; +static u8 *__afl_area_ptr_backup = __afl_area_initial; + +u8 * __afl_area_ptr = __afl_area_initial; +u8 * __afl_dictionary; +u8 * __afl_fuzz_ptr; +static u32 __afl_fuzz_len_dummy; +u32 * __afl_fuzz_len = &__afl_fuzz_len_dummy; u32 __afl_final_loc; u32 __afl_map_size = MAP_SIZE; @@ -98,9 +99,9 @@ u32 __afl_dictionary_len; u64 __afl_map_addr; // for the __AFL_COVERAGE_ON/__AFL_COVERAGE_OFF features to work: -int __afl_selective_coverage __attribute__((weak)); -int __afl_selective_coverage_start_off __attribute__((weak)); -int __afl_selective_coverage_temp = 1; +int __afl_selective_coverage __attribute__((weak)); +int __afl_selective_coverage_start_off __attribute__((weak)); +static int __afl_selective_coverage_temp = 1; #if defined(__ANDROID__) || defined(__HAIKU__) PREV_LOC_T __afl_prev_loc[NGRAM_SIZE_MAX]; @@ -147,7 +148,7 @@ static int __afl_dummy_fd[2] = {2, 2}; /* ensure we kill the child on termination */ -void at_exit(int signal) { +static void at_exit(int signal) { if (child_pid > 0) { kill(child_pid, SIGKILL); } @@ -179,7 +180,7 @@ void __afl_trace(const u32 x) { /* Error reporting to forkserver controller */ -void send_forkserver_error(int error) { +static void send_forkserver_error(int error) { u32 status; if (!error || error > 0xffff) return; @@ -629,6 +630,32 @@ static void __afl_unmap_shm(void) { } +#define write_error(text) write_error_with_location(text, __FILE__, __LINE__) + +void write_error_with_location(char *text, char* filename, int linenumber) { + + u8 * o = getenv("__AFL_OUT_DIR"); + char *e = strerror(errno); + + if (o) { + + char buf[4096]; + snprintf(buf, sizeof(buf), "%s/error.txt", o); + FILE *f = fopen(buf, "a"); + + if (f) { + + fprintf(f, "File %s, line %d: Error(%s): %s\n", filename, linenumber, text, e); + fclose(f); + + } + + } + + fprintf(stderr, "File %s, line %d: Error(%s): %s\n", filename, linenumber, text, e); + +} + #ifdef __linux__ static void __afl_start_snapshots(void) { @@ -655,7 +682,12 @@ static void __afl_start_snapshots(void) { if (__afl_sharedmem_fuzzing || (__afl_dictionary_len && __afl_dictionary)) { - if (read(FORKSRV_FD, &was_killed, 4) != 4) { _exit(1); } + if (read(FORKSRV_FD, &was_killed, 4) != 4) { + + write_error("read to afl-fuzz"); + _exit(1); + + } if (__afl_debug) { @@ -724,7 +756,12 @@ static void __afl_start_snapshots(void) { } else { /* Wait for parent by reading from the pipe. Abort if read fails. */ - if (read(FORKSRV_FD, &was_killed, 4) != 4) _exit(1); + if (read(FORKSRV_FD, &was_killed, 4) != 4) { + + write_error("reading from afl-fuzz"); + _exit(1); + + } } @@ -761,7 +798,12 @@ static void __afl_start_snapshots(void) { if (child_stopped && was_killed) { child_stopped = 0; - if (waitpid(child_pid, &status, 0) < 0) _exit(1); + if (waitpid(child_pid, &status, 0) < 0) { + + write_error("child_stopped && was_killed"); + _exit(1); // TODO why exit? + + } } @@ -770,7 +812,12 @@ static void __afl_start_snapshots(void) { /* Once woken up, create a clone of our process. */ child_pid = fork(); - if (child_pid < 0) _exit(1); + if (child_pid < 0) { + + write_error("fork"); + _exit(1); + + } /* In child process: close fds, resume execution. */ @@ -810,9 +857,19 @@ static void __afl_start_snapshots(void) { /* In parent process: write PID to pipe, then wait for child. */ - if (write(FORKSRV_FD + 1, &child_pid, 4) != 4) _exit(1); + if (write(FORKSRV_FD + 1, &child_pid, 4) != 4) { + + write_error("write to afl-fuzz"); + _exit(1); - if (waitpid(child_pid, &status, WUNTRACED) < 0) _exit(1); + } + + if (waitpid(child_pid, &status, WUNTRACED) < 0) { + + write_error("waitpid"); + _exit(1); + + } /* In persistent mode, the child stops itself with SIGSTOP to indicate a successful run. In this case, we want to wake it up without forking @@ -822,7 +879,12 @@ static void __afl_start_snapshots(void) { /* Relay wait status to pipe, then loop back. */ - if (write(FORKSRV_FD + 1, &status, 4) != 4) _exit(1); + if (write(FORKSRV_FD + 1, &status, 4) != 4) { + + write_error("writing to afl-fuzz"); + _exit(1); + + } } @@ -955,7 +1017,12 @@ static void __afl_start_forkserver(void) { } else { - if (read(FORKSRV_FD, &was_killed, 4) != 4) _exit(1); + if (read(FORKSRV_FD, &was_killed, 4) != 4) { + + write_error("read from afl-fuzz"); + _exit(1); + + } } @@ -992,7 +1059,12 @@ static void __afl_start_forkserver(void) { if (child_stopped && was_killed) { child_stopped = 0; - if (waitpid(child_pid, &status, 0) < 0) _exit(1); + if (waitpid(child_pid, &status, 0) < 0) { + + write_error("child_stopped && was_killed"); + _exit(1); + + } } @@ -1001,7 +1073,12 @@ static void __afl_start_forkserver(void) { /* Once woken up, create a clone of our process. */ child_pid = fork(); - if (child_pid < 0) _exit(1); + if (child_pid < 0) { + + write_error("fork"); + _exit(1); + + } /* In child process: close fds, resume execution. */ @@ -1030,11 +1107,20 @@ static void __afl_start_forkserver(void) { /* In parent process: write PID to pipe, then wait for child. */ - if (write(FORKSRV_FD + 1, &child_pid, 4) != 4) _exit(1); + if (write(FORKSRV_FD + 1, &child_pid, 4) != 4) { + + write_error("write to afl-fuzz"); + _exit(1); + + } + + if (waitpid(child_pid, &status, is_persistent ? WUNTRACED : 0) < 0) { - if (waitpid(child_pid, &status, is_persistent ? WUNTRACED : 0) < 0) + write_error("waitpid"); _exit(1); + } + /* In persistent mode, the child stops itself with SIGSTOP to indicate a successful run. In this case, we want to wake it up without forking again. */ @@ -1043,7 +1129,12 @@ static void __afl_start_forkserver(void) { /* Relay wait status to pipe, then loop back. */ - if (write(FORKSRV_FD + 1, &status, 4) != 4) _exit(1); + if (write(FORKSRV_FD + 1, &status, 4) != 4) { + + write_error("writing to afl-fuzz"); + _exit(1); + + } } @@ -1668,7 +1759,7 @@ void __sanitizer_cov_trace_cmp4(uint32_t arg1, uint32_t arg2) { } -void __sanitizer_cov_trace_cost_cmp4(uint32_t arg1, uint32_t arg2) { +void __sanitizer_cov_trace_const_cmp4(uint32_t arg1, uint32_t arg2) { __cmplog_ins_hook4(arg1, arg2, 0); @@ -1990,3 +2081,4 @@ void __afl_coverage_interesting(u8 val, u32 id) { } +#undef write_error diff --git a/instrumentation/afl-llvm-pass.so.cc b/instrumentation/afl-llvm-pass.so.cc index 6fe34ccd..94b77f7d 100644 --- a/instrumentation/afl-llvm-pass.so.cc +++ b/instrumentation/afl-llvm-pass.so.cc @@ -676,7 +676,7 @@ bool AFLCoverage::runOnModule(Module &M) { todo.push_back(MapPtrIdx); } else { - + */ IRB.CreateAtomicRMW(llvm::AtomicRMWInst::BinOp::Add, MapPtrIdx, One, #if LLVM_VERSION_MAJOR >= 13 diff --git a/src/afl-analyze.c b/src/afl-analyze.c index aabdbf1a..606254d9 100644 --- a/src/afl-analyze.c +++ b/src/afl-analyze.c @@ -55,12 +55,7 @@ #include #include -static s32 child_pid; /* PID of the tested program */ - -static u8 *trace_bits; /* SHM with instrumentation bitmap */ - -static u8 *in_file, /* Analyzer input test case */ - *prog_in; /* Targeted program input file */ +static u8 *in_file; /* Analyzer input test case */ static u8 *in_data; /* Input data for analysis */ @@ -73,20 +68,19 @@ static u64 orig_cksum; /* Original checksum */ static u64 mem_limit = MEM_LIMIT; /* Memory limit (MB) */ -static s32 dev_null_fd = -1; /* FD to /dev/null */ - static bool edges_only, /* Ignore hit counts? */ use_hex_offsets, /* Show hex offsets? */ use_stdin = true; /* Use stdin for program input? */ -static volatile u8 stop_soon, /* Ctrl-C pressed? */ - child_timed_out; /* Child timed out? */ +static volatile u8 stop_soon; /* Ctrl-C pressed? */ static u8 *target_path; static u8 frida_mode; static u8 qemu_mode; static u32 map_size = MAP_SIZE; +static afl_forkserver_t fsrv = {0}; /* The forkserver */ + /* Constants used for describing byte behavior. */ #define RESP_NONE 0x00 /* Changing byte is a no-op. */ @@ -156,7 +150,7 @@ static void classify_counts(u8 *mem) { static inline u8 anything_set(void) { - u32 *ptr = (u32 *)trace_bits; + u32 *ptr = (u32 *)fsrv.trace_bits; u32 i = (map_size >> 2); while (i--) { @@ -173,7 +167,7 @@ static inline u8 anything_set(void) { static void at_exit_handler(void) { - unlink(prog_in); /* Ignore errors */ + unlink(fsrv.out_file); /* Ignore errors */ } @@ -205,116 +199,29 @@ static void read_initial_file(void) { } -/* Write output file. */ - -static s32 write_to_file(u8 *path, u8 *mem, u32 len) { - - s32 ret; - - unlink(path); /* Ignore errors */ - - ret = open(path, O_RDWR | O_CREAT | O_EXCL, DEFAULT_PERMISSION); - - if (ret < 0) { PFATAL("Unable to create '%s'", path); } - - ck_write(ret, mem, len, path); - - lseek(ret, 0, SEEK_SET); - - return ret; - -} - /* Execute target application. Returns exec checksum, or 0 if program times out. */ -static u32 analyze_run_target(char **argv, u8 *mem, u32 len, u8 first_run) { - - static struct itimerval it; - int status = 0; - - s32 prog_in_fd; - u64 cksum; - - memset(trace_bits, 0, map_size); - MEM_BARRIER(); - - prog_in_fd = write_to_file(prog_in, mem, len); - - child_pid = fork(); - - if (child_pid < 0) { PFATAL("fork() failed"); } - - if (!child_pid) { - - struct rlimit r; - - if (dup2(use_stdin ? prog_in_fd : dev_null_fd, 0) < 0 || - dup2(dev_null_fd, 1) < 0 || dup2(dev_null_fd, 2) < 0) { - - *(u32 *)trace_bits = EXEC_FAIL_SIG; - PFATAL("dup2() failed"); - - } - - close(dev_null_fd); - close(prog_in_fd); - - if (mem_limit) { - - r.rlim_max = r.rlim_cur = ((rlim_t)mem_limit) << 20; - -#ifdef RLIMIT_AS - - setrlimit(RLIMIT_AS, &r); /* Ignore errors */ +static u32 analyze_run_target(u8 *mem, u32 len, u8 first_run) { -#else - - setrlimit(RLIMIT_DATA, &r); /* Ignore errors */ - -#endif /* ^RLIMIT_AS */ - - } - - r.rlim_max = r.rlim_cur = 0; - setrlimit(RLIMIT_CORE, &r); /* Ignore errors */ - - execv(target_path, argv); - - *(u32 *)trace_bits = EXEC_FAIL_SIG; - exit(0); + afl_fsrv_write_to_testcase(&fsrv, mem, len); + fsrv_run_result_t ret = afl_fsrv_run_target(&fsrv, exec_tmout, &stop_soon); - } - - close(prog_in_fd); - - /* Configure timeout, wait for child, cancel timeout. */ - - child_timed_out = 0; - it.it_value.tv_sec = (exec_tmout / 1000); - it.it_value.tv_usec = (exec_tmout % 1000) * 1000; + if (ret == FSRV_RUN_ERROR) { - setitimer(ITIMER_REAL, &it, NULL); + FATAL("Error in forkserver"); - if (waitpid(child_pid, &status, 0) <= 0) { FATAL("waitpid() failed"); } + } else if (ret == FSRV_RUN_NOINST) { - child_pid = 0; - it.it_value.tv_sec = 0; - it.it_value.tv_usec = 0; + FATAL("Target not instrumented"); - setitimer(ITIMER_REAL, &it, NULL); + } else if (ret == FSRV_RUN_NOBITS) { - MEM_BARRIER(); - - /* Clean up bitmap, analyze exit condition, etc. */ - - if (*(u32 *)trace_bits == EXEC_FAIL_SIG) { - - FATAL("Unable to execute '%s'", argv[0]); + FATAL("Failed to run target"); } - classify_counts(trace_bits); + classify_counts(fsrv.trace_bits); total_execs++; if (stop_soon) { @@ -326,21 +233,19 @@ static u32 analyze_run_target(char **argv, u8 *mem, u32 len, u8 first_run) { /* Always discard inputs that time out. */ - if (child_timed_out) { + if (fsrv.last_run_timed_out) { exec_hangs++; return 0; } - cksum = hash64(trace_bits, map_size, HASH_CONST); + u64 cksum = hash64(fsrv.trace_bits, fsrv.map_size, HASH_CONST); - /* We don't actually care if the target is crashing or not, - except that when it does, the checksum should be different. */ + if (ret == FSRV_RUN_CRASH) { - if (WIFSIGNALED(status) || - (WIFEXITED(status) && WEXITSTATUS(status) == MSAN_ERROR) || - (WIFEXITED(status) && WEXITSTATUS(status))) { + /* We don't actually care if the target is crashing or not, + except that when it does, the checksum should be different. */ cksum ^= 0xffffffff; @@ -604,7 +509,7 @@ static void dump_hex(u32 len, u8 *b_data) { /* Actually analyze! */ -static void analyze(char **argv) { +static void analyze() { u32 i; u32 boring_len = 0, prev_xff = 0, prev_x01 = 0, prev_s10 = 0, prev_a10 = 0; @@ -630,16 +535,16 @@ static void analyze(char **argv) { code. */ in_data[i] ^= 0xff; - xor_ff = analyze_run_target(argv, in_data, in_len, 0); + xor_ff = analyze_run_target(in_data, in_len, 0); in_data[i] ^= 0xfe; - xor_01 = analyze_run_target(argv, in_data, in_len, 0); + xor_01 = analyze_run_target(in_data, in_len, 0); in_data[i] = (in_data[i] ^ 0x01) - 0x10; - sub_10 = analyze_run_target(argv, in_data, in_len, 0); + sub_10 = analyze_run_target(in_data, in_len, 0); in_data[i] += 0x20; - add_10 = analyze_run_target(argv, in_data, in_len, 0); + add_10 = analyze_run_target(in_data, in_len, 0); in_data[i] -= 0x10; /* Classify current behavior. */ @@ -712,7 +617,7 @@ static void handle_stop_sig(int sig) { (void)sig; stop_soon = 1; - if (child_pid > 0) { kill(child_pid, SIGKILL); } + afl_fsrv_killall(); } @@ -724,10 +629,10 @@ static void set_up_environment(char **argv) { char *afl_preload; char *frida_afl_preload = NULL; - dev_null_fd = open("/dev/null", O_RDWR); - if (dev_null_fd < 0) { PFATAL("Unable to open /dev/null"); } + fsrv.dev_null_fd = open("/dev/null", O_RDWR); + if (fsrv.dev_null_fd < 0) { PFATAL("Unable to open /dev/null"); } - if (!prog_in) { + if (!fsrv.out_file) { u8 *use_dir = "."; @@ -738,10 +643,15 @@ static void set_up_environment(char **argv) { } - prog_in = alloc_printf("%s/.afl-analyze-temp-%u", use_dir, (u32)getpid()); + fsrv.out_file = alloc_printf("%s/.afl-analyze-temp-%u", use_dir, (u32)getpid()); } + unlink(fsrv.out_file); + fsrv.out_fd = open(fsrv.out_file, O_RDWR | O_CREAT | O_EXCL, DEFAULT_PERMISSION); + + if (fsrv.out_fd < 0) { PFATAL("Unable to create '%s'", fsrv.out_file); } + /* Set sane defaults... */ x = get_afl_env("ASAN_OPTIONS"); @@ -965,6 +875,8 @@ int main(int argc, char **argv_orig, char **envp) { SAYF(cCYA "afl-analyze" VERSION cRST " by Michal Zalewski\n"); + afl_fsrv_init(&fsrv); + while ((opt = getopt(argc, argv, "+i:f:m:t:eOQUWh")) > 0) { switch (opt) { @@ -977,9 +889,9 @@ int main(int argc, char **argv_orig, char **envp) { case 'f': - if (prog_in) { FATAL("Multiple -f options not supported"); } - use_stdin = 0; - prog_in = optarg; + if (fsrv.out_file) { FATAL("Multiple -f options not supported"); } + fsrv.use_stdin = 0; + fsrv.out_file = ck_strdup(optarg); break; case 'e': @@ -1000,6 +912,7 @@ int main(int argc, char **argv_orig, char **envp) { if (!strcmp(optarg, "none")) { mem_limit = 0; + fsrv.mem_limit = 0; break; } @@ -1038,6 +951,8 @@ int main(int argc, char **argv_orig, char **envp) { } + fsrv.mem_limit = mem_limit; + } break; @@ -1057,6 +972,8 @@ int main(int argc, char **argv_orig, char **envp) { } + fsrv.exec_tmout = exec_tmout; + break; case 'O': /* FRIDA mode */ @@ -1064,6 +981,7 @@ int main(int argc, char **argv_orig, char **envp) { if (frida_mode) { FATAL("Multiple -O options not supported"); } frida_mode = 1; + fsrv.frida_mode = frida_mode; break; @@ -1073,6 +991,8 @@ int main(int argc, char **argv_orig, char **envp) { if (!mem_limit_given) { mem_limit = MEM_LIMIT_QEMU; } qemu_mode = 1; + fsrv.mem_limit = mem_limit; + fsrv.qemu_mode = qemu_mode; break; case 'U': @@ -1081,6 +1001,7 @@ int main(int argc, char **argv_orig, char **envp) { if (!mem_limit_given) { mem_limit = MEM_LIMIT_UNICORN; } unicorn_mode = 1; + fsrv.mem_limit = mem_limit; break; case 'W': /* Wine+QEMU mode */ @@ -1090,6 +1011,8 @@ int main(int argc, char **argv_orig, char **envp) { use_wine = 1; if (!mem_limit_given) { mem_limit = 0; } + fsrv.qemu_mode = qemu_mode; + fsrv.mem_limit = mem_limit; break; @@ -1108,6 +1031,7 @@ int main(int argc, char **argv_orig, char **envp) { if (optind == argc || !in_file) { usage(argv[0]); } map_size = get_map_size(); + fsrv.map_size = map_size; use_hex_offsets = !!get_afl_env("AFL_ANALYZE_HEX"); @@ -1117,14 +1041,15 @@ int main(int argc, char **argv_orig, char **envp) { /* initialize cmplog_mode */ shm.cmplog_mode = 0; - trace_bits = afl_shm_init(&shm, map_size, 0); + atexit(at_exit_handler); setup_signal_handlers(); set_up_environment(argv); - target_path = find_binary(argv[optind]); - detect_file_args(argv + optind, prog_in, &use_stdin); + fsrv.target_path = find_binary(argv[optind]); + fsrv.trace_bits = afl_shm_init(&shm, map_size, 0); + detect_file_args(argv + optind, fsrv.out_file, &use_stdin); if (qemu_mode) { @@ -1148,14 +1073,31 @@ int main(int argc, char **argv_orig, char **envp) { SAYF("\n"); + if (getenv("AFL_FORKSRV_INIT_TMOUT")) { + + s32 forksrv_init_tmout = atoi(getenv("AFL_FORKSRV_INIT_TMOUT")); + if (forksrv_init_tmout < 1) { + + FATAL("Bad value specified for AFL_FORKSRV_INIT_TMOUT"); + + } + + fsrv.init_tmout = (u32)forksrv_init_tmout; + + } + + fsrv.kill_signal = + parse_afl_kill_signal_env(getenv("AFL_KILL_SIGNAL"), SIGKILL); + read_initial_file(); ACTF("Performing dry run (mem limit = %llu MB, timeout = %u ms%s)...", mem_limit, exec_tmout, edges_only ? ", edges only" : ""); - analyze_run_target(use_argv, in_data, in_len, 1); + afl_fsrv_start(&fsrv, use_argv, &stop_soon, false); + analyze_run_target(in_data, in_len, 1); - if (child_timed_out) { + if (fsrv.last_run_timed_out) { FATAL("Target binary times out (adjusting -t may help)."); @@ -1167,13 +1109,15 @@ int main(int argc, char **argv_orig, char **envp) { } - analyze(use_argv); + analyze(); OKF("We're done here. Have a nice day!\n"); - if (target_path) { ck_free(target_path); } - afl_shm_deinit(&shm); + afl_fsrv_deinit(&fsrv); + if (fsrv.target_path) { ck_free(fsrv.target_path); } + if (in_data) { ck_free(in_data); } + exit(0); diff --git a/src/afl-cc.c b/src/afl-cc.c index 486f7468..980e5d86 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -315,7 +315,7 @@ static void edit_params(u32 argc, char **argv, char **envp) { u8 fortify_set = 0, asan_set = 0, x_set = 0, bit_mode = 0, shared_linking = 0, preprocessor_only = 0, have_unroll = 0, have_o = 0, have_pic = 0, - have_c = 0; + have_c = 0, partial_linking = 0; cc_params = ck_alloc((argc + 128) * sizeof(u8 *)); @@ -767,6 +767,8 @@ static void edit_params(u32 argc, char **argv, char **envp) { if (!strcmp(cur, "-x")) x_set = 1; if (!strcmp(cur, "-E")) preprocessor_only = 1; if (!strcmp(cur, "-shared")) shared_linking = 1; + if (!strcmp(cur, "-Wl,-r")) partial_linking = 1; + if (!strcmp(cur, "-Wl,-i")) partial_linking = 1; if (!strcmp(cur, "-c")) have_c = 1; if (!strncmp(cur, "-O", 2)) have_o = 1; @@ -996,7 +998,7 @@ static void edit_params(u32 argc, char **argv, char **envp) { switch (bit_mode) { case 0: - if (!shared_linking) + if (!shared_linking && !partial_linking) cc_params[cc_par_cnt++] = alloc_printf("%s/afl-compiler-rt.o", obj_path); if (lto_mode) @@ -1005,7 +1007,7 @@ static void edit_params(u32 argc, char **argv, char **envp) { break; case 32: - if (!shared_linking) { + if (!shared_linking && !partial_linking) { cc_params[cc_par_cnt++] = alloc_printf("%s/afl-compiler-rt-32.o", obj_path); @@ -1026,7 +1028,7 @@ static void edit_params(u32 argc, char **argv, char **envp) { break; case 64: - if (!shared_linking) { + if (!shared_linking && !partial_linking) { cc_params[cc_par_cnt++] = alloc_printf("%s/afl-compiler-rt-64.o", obj_path); @@ -1049,7 +1051,7 @@ static void edit_params(u32 argc, char **argv, char **envp) { } #if !defined(__APPLE__) && !defined(__sun) - if (!shared_linking) + if (!shared_linking && !partial_linking) cc_params[cc_par_cnt++] = alloc_printf("-Wl,--dynamic-list=%s/dynamic_list.txt", obj_path); #endif diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index 88b5bc02..872e3a32 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -480,13 +480,22 @@ void read_foreign_testcases(afl_state_t *afl, int first) { for (iter = 0; iter < afl->foreign_sync_cnt; iter++) { - if (afl->foreign_syncs[iter].dir != NULL && - afl->foreign_syncs[iter].dir[0] != 0) { + if (afl->foreign_syncs[iter].dir && afl->foreign_syncs[iter].dir[0]) { if (first) ACTF("Scanning '%s'...", afl->foreign_syncs[iter].dir); time_t mtime_max = 0; - u8 * name = strrchr(afl->foreign_syncs[iter].dir, '/'); - if (!name) { name = afl->foreign_syncs[iter].dir; } + + u8 *name = strrchr(afl->foreign_syncs[iter].dir, '/'); + if (!name) { + + name = afl->foreign_syncs[iter].dir; + + } else { + + ++name; + + } + if (!strcmp(name, "queue") || !strcmp(name, "out") || !strcmp(name, "default")) { diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c index 4884b942..9648d795 100644 --- a/src/afl-fuzz-stats.c +++ b/src/afl-fuzz-stats.c @@ -766,9 +766,9 @@ void show_stats(afl_state_t *afl) { " uniq hangs : " cRST "%-6s" bSTG bV "\n", time_tmp, tmp); - SAYF(bVR bH bSTOP cCYA - " cycle progress " bSTG bH10 bH5 bH2 bH2 bHB bH bSTOP cCYA - " map coverage " bSTG bH bHT bH20 bH2 bVL "\n"); + SAYF(bVR bH bSTOP cCYA + " cycle progress " bSTG bH10 bH5 bH2 bH2 bH2 bHB bH bSTOP cCYA + " map coverage" bSTG bHT bH20 bH2 bVL "\n"); /* This gets funny because we want to print several variable-length variables together, but then cram them into a fixed-width field - so we need to @@ -778,13 +778,13 @@ void show_stats(afl_state_t *afl) { afl->queue_cur->favored ? "." : "*", afl->queue_cur->fuzz_level, ((double)afl->current_entry * 100) / afl->queued_paths); - SAYF(bV bSTOP " now processing : " cRST "%-16s " bSTG bV bSTOP, tmp); + SAYF(bV bSTOP " now processing : " cRST "%-18s " bSTG bV bSTOP, tmp); sprintf(tmp, "%0.02f%% / %0.02f%%", ((double)afl->queue_cur->bitmap_size) * 100 / afl->fsrv.map_size, t_byte_ratio); - SAYF(" map density : %s%-21s" bSTG bV "\n", + SAYF(" map density : %s%-19s" bSTG bV "\n", t_byte_ratio > 70 ? cLRD : ((t_bytes < 200 && !afl->non_instrumented_mode) ? cPIN : cRST), @@ -793,23 +793,23 @@ void show_stats(afl_state_t *afl) { sprintf(tmp, "%s (%0.02f%%)", u_stringify_int(IB(0), afl->cur_skipped_paths), ((double)afl->cur_skipped_paths * 100) / afl->queued_paths); - SAYF(bV bSTOP " paths timed out : " cRST "%-16s " bSTG bV, tmp); + SAYF(bV bSTOP " paths timed out : " cRST "%-18s " bSTG bV, tmp); sprintf(tmp, "%0.02f bits/tuple", t_bytes ? (((double)t_bits) / t_bytes) : 0); - SAYF(bSTOP " count coverage : " cRST "%-21s" bSTG bV "\n", tmp); + SAYF(bSTOP " count coverage : " cRST "%-19s" bSTG bV "\n", tmp); - SAYF(bVR bH bSTOP cCYA - " stage progress " bSTG bH10 bH5 bH2 bH2 bX bH bSTOP cCYA - " findings in depth " bSTG bH10 bH5 bH2 bH2 bVL "\n"); + SAYF(bVR bH bSTOP cCYA + " stage progress " bSTG bH10 bH5 bH2 bH2 bH2 bX bH bSTOP cCYA + " findings in depth " bSTG bH10 bH5 bH2 bVL "\n"); sprintf(tmp, "%s (%0.02f%%)", u_stringify_int(IB(0), afl->queued_favored), ((double)afl->queued_favored) * 100 / afl->queued_paths); /* Yeah... it's still going on... halp? */ - SAYF(bV bSTOP " now trying : " cRST "%-20s " bSTG bV bSTOP - " favored paths : " cRST "%-22s" bSTG bV "\n", + SAYF(bV bSTOP " now trying : " cRST "%-22s " bSTG bV bSTOP + " favored paths : " cRST "%-20s" bSTG bV "\n", afl->stage_name, tmp); if (!afl->stage_max) { @@ -824,12 +824,12 @@ void show_stats(afl_state_t *afl) { } - SAYF(bV bSTOP " stage execs : " cRST "%-21s" bSTG bV bSTOP, tmp); + SAYF(bV bSTOP " stage execs : " cRST "%-23s" bSTG bV bSTOP, tmp); sprintf(tmp, "%s (%0.02f%%)", u_stringify_int(IB(0), afl->queued_with_cov), ((double)afl->queued_with_cov) * 100 / afl->queued_paths); - SAYF(" new edges on : " cRST "%-22s" bSTG bV "\n", tmp); + SAYF(" new edges on : " cRST "%-20s" bSTG bV "\n", tmp); sprintf(tmp, "%s (%s%s unique)", u_stringify_int(IB(0), afl->total_crashes), u_stringify_int(IB(1), afl->unique_crashes), @@ -837,14 +837,14 @@ void show_stats(afl_state_t *afl) { if (afl->crash_mode) { - SAYF(bV bSTOP " total execs : " cRST "%-20s " bSTG bV bSTOP - " new crashes : %s%-22s" bSTG bV "\n", + SAYF(bV bSTOP " total execs : " cRST "%-22s " bSTG bV bSTOP + " new crashes : %s%-20s" bSTG bV "\n", u_stringify_int(IB(0), afl->fsrv.total_execs), crash_color, tmp); } else { - SAYF(bV bSTOP " total execs : " cRST "%-20s " bSTG bV bSTOP - " total crashes : %s%-22s" bSTG bV "\n", + SAYF(bV bSTOP " total execs : " cRST "%-22s " bSTG bV bSTOP + " total crashes : %s%-20s" bSTG bV "\n", u_stringify_int(IB(0), afl->fsrv.total_execs), crash_color, tmp); } @@ -856,12 +856,12 @@ void show_stats(afl_state_t *afl) { sprintf(tmp, "%s/sec (%s)", u_stringify_float(IB(0), afl->stats_avg_exec), afl->stats_avg_exec < 20 ? "zzzz..." : "slow!"); - SAYF(bV bSTOP " exec speed : " cLRD "%-20s ", tmp); + SAYF(bV bSTOP " exec speed : " cLRD "%-22s ", tmp); } else { sprintf(tmp, "%s/sec", u_stringify_float(IB(0), afl->stats_avg_exec)); - SAYF(bV bSTOP " exec speed : " cRST "%-20s ", tmp); + SAYF(bV bSTOP " exec speed : " cRST "%-22s ", tmp); } @@ -869,13 +869,12 @@ void show_stats(afl_state_t *afl) { u_stringify_int(IB(1), afl->unique_tmouts), (afl->unique_hangs >= KEEP_UNIQUE_HANG) ? "+" : ""); - SAYF(bSTG bV bSTOP " total tmouts : " cRST "%-22s" bSTG bV "\n", tmp); + SAYF(bSTG bV bSTOP " total tmouts : " cRST "%-20s" bSTG bV "\n", tmp); /* Aaaalmost there... hold on! */ - SAYF(bVR bH cCYA bSTOP - " fuzzing strategy yields " bSTG bH10 bHT bH10 bH5 bHB bH bSTOP cCYA - " path geometry " bSTG bH5 bH2 bVL "\n"); + SAYF(bVR bH cCYA bSTOP " fuzzing strategy yields " bSTG bH10 bH2 bHT bH10 bH2 + bH bHB bH bSTOP cCYA " path geometry " bSTG bH5 bH2 bVL "\n"); if (unlikely(afl->custom_only)) { @@ -1017,9 +1016,10 @@ void show_stats(afl_state_t *afl) { if (unlikely(afl->afl_env.afl_custom_mutator_library)) { strcat(tmp, " "); - strcat(tmp, u_stringify_int(IB(2), afl->stage_finds[STAGE_PYTHON])); + strcat(tmp, u_stringify_int(IB(2), afl->stage_finds[STAGE_CUSTOM_MUTATOR])); strcat(tmp, "/"); - strcat(tmp, u_stringify_int(IB(3), afl->stage_cycles[STAGE_PYTHON])); + strcat(tmp, + u_stringify_int(IB(3), afl->stage_cycles[STAGE_CUSTOM_MUTATOR])); strcat(tmp, ","); } else { diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 196547f4..9a3780fb 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -575,7 +575,6 @@ int main(int argc, char **argv_orig, char **envp) { } afl->sync_id = ck_strdup(optarg); - afl->skip_deterministic = 0; // force deterministic fuzzing afl->old_seed_selection = 1; // force old queue walking seed selection afl->disable_trim = 1; // disable trimming @@ -1206,6 +1205,8 @@ int main(int argc, char **argv_orig, char **envp) { } + setenv("__AFL_OUT_DIR", afl->out_dir, 1); + if (get_afl_env("AFL_DISABLE_TRIM")) { afl->disable_trim = 1; } if (getenv("AFL_NO_UI") && getenv("AFL_FORCE_UI")) { diff --git a/test/test-llvm.sh b/test/test-llvm.sh index 1152cc4e..7cdc83cb 100755 --- a/test/test-llvm.sh +++ b/test/test-llvm.sh @@ -4,14 +4,6 @@ $ECHO "$BLUE[*] Testing: llvm_mode, afl-showmap, afl-fuzz, afl-cmin and afl-tmin" test -e ../afl-clang-fast -a -e ../split-switches-pass.so && { - # on FreeBSD need to set AFL_CC - test `uname -s` = 'FreeBSD' && { - if type clang >/dev/null; then - export AFL_CC=`command -v clang` - else - export AFL_CC=`$LLVM_CONFIG --bindir`/clang - fi - } ../afl-clang-fast -o test-instr.plain ../test-instr.c > /dev/null 2>&1 AFL_HARDEN=1 ../afl-clang-fast -o test-compcov.harden test-compcov.c > /dev/null 2>&1 test -e test-instr.plain && { -- cgit 1.4.1