Giter Club home page Giter Club logo

afl-cov's Introduction

afl-cov - AFL Fuzzing Code Coverage

Introduction

afl-cov uses test case files produced by the AFL fuzzer afl-fuzz to generate gcov code coverage results for a targeted binary. Code coverage is interpreted from one case to the next by afl-cov in order to determine which new functions and lines are hit by AFL with each new test case. Further, afl-cov allows for specific lines or functions to be searched for within coverage results, and when a match is found the corresponding test case file is displayed. This allows the user to discover which AFL test case is the first to exercise a particular function. In addition, afl-cov produces a "zero coverage" report of functions and lines that were never executed during any AFL fuzzing run.

Although of no use to AFL itself, the main application of afl-cov is to wrap some automation around gcov together with AFL test cases and thereby provide data on how to maximize code coverage with AFL fuzzing runs. Manual interpretation of cumulative gcov results from AFL test cases is usually still required, but the "fiddly" steps of iterating over all test cases and generating code coverage reports (along with the "zero coverage" report) is automated by afl-cov.

Producing code coverage data for AFL test cases is an important step to try and maximize code coverage, and thereby help to maximize the effectiveness of AFL. For example, some binaries have code that is reachable only after a complicated (or even cryptographic) test is passed, and AFL may not be able to exercise this code without taking special measures. These measures commonly include patching the project code to bypass such tests. (For example, there is a patch to solve this problem for a CRC test in libpng included in the AFL sources at experimental/libpng_no_checksum/libpng-nocrc.patch.) When a project implements a patch to assist AFL in reaching code that would otherwise be inaccessible, a natural question to ask is whether the patch is effective. Code coverage results can help to verify this.

Prerequisites

afl-cov requires the following software:

  • afl-fuzz
  • python
  • gcov, lcov, genhtml

Note that afl-cov can parse files created by afl-fuzz from a different system, so technically afl-fuzz does not need to be installed on the same system as afl-cov. This supports scenarios where fuzzing output is collected, say, within a git repository on one system, and coverage results are produced on a different system. However, most workflows typically focus on producing afl-cov results simultaneously for current fuzzing runs on the same system.

Workflow

At a high level, the general workflow for afl-cov against a targeted project is:

  1. Have a target project compiled and known to work with AFL.
  2. Create a spare copy of the project sources, and compile this copy with gcov profiling support.
  3. Run afl-cov against the copy either while afl-fuzz is building test cases against the original sources, or after afl-fuzz has been stopped.
  4. Review the cumulative code coverage results in the final web report.
  5. Iterate to achieve higher coverage results. This might involve building better initial test cases for AFL, or sometimes changing project sources themselves.

Now, in more detail:

  • Copy the project sources to a new directory, /path/to/project-gcov/. This directory should contain the project binaries compiled for gcov profiling support (gcc -fprofile-arcs -ftest-coverage).

  • Start up afl-cov in --live mode before also starting the afl-fuzz fuzzing cycle. The command line arguments to afl-cov must specify the path to the output directory used by afl-fuzz, and the command to execute along with associated arguments. This command and arguments should closely resemble the manner in which afl-fuzz executes the targeted binary during the fuzzing cycle. If there is already an existing directory of AFL fuzzing results, then just omit the --live argument to process the existing results. Here is an example:

$ cd /path/to/project-gcov/
$ afl-cov -d /path/to/afl-fuzz-output/ --live --coverage-cmd \
"cat AFL_FILE | LD_LIBRARY_PATH=./lib/.libs ./bin/.libs/somebin -a -b -c" \
--code-dir .

/path/to/afl-fuzz-output/ is the output directory of afl-fuzz.

The AFL_FILE string above refers to the test case file that AFL will build in the queue/ directory under /path/to/afl-fuzz-output. Just leave this string as-is since afl-cov will automatically substitute it with each AFL queue/id:NNNNNN* in succession as it builds the code coverage reports.

Also, in the above command, this handles the case where the AFL fuzzing cycle is fuzzing the targeted binary via stdin. This explains the cat AFL_FILE | ... ./bin/.lib/somebin ... invocation. For the other style of fuzzing with AFL where a file is read from the filesystem, here is an example:

$ cd /path/to/project-gcov/
$ afl-cov -d /path/to/afl-fuzz-output/ --live --coverage-cmd \
"LD_LIBRARY_PATH=./lib/.libs ./bin/.libs/somebin -f AFL_FILE -a -b -c" \
--code-dir .
  • With afl-cov running, open a separate terminal/shell, and launch afl-fuzz:
$ LD_LIBRARY_PATH=./lib/.libs afl-fuzz -T somebin -t 1000 \
-i /path/to/test-cases/ -o /path/to/afl-fuzz-output/ ./bin/.libs/somebin -a -b -c

The familiar AFL status screen will be displayed, and afl-cov will start generating code coverage data.

alt text

Note that by default afl-cov does not direct lcov to include branch coverage results. This is because there are commonly many hundreds of AFL test cases in the queue/ directory, and generating branch coverage across all of these cases may slow afl-cov down significantly. If branch coverage is desired, just add the --enable-branch-coverage argument to afl-cov.

Here is a sample of what the afl-cov output looks like (note this includes the --enable-branch-coverage argument as described above):

$ afl-cov -d /path/to/afl-fuzz-output/ --live --coverage-cmd \
"LD_LIBRARY_PATH=./lib/.libs ./bin/.libs/somebin -f AFL_FILE -a -b -c" \
--code-dir . --enable-branch-coverage
[+] Imported 184 files from: /path/to/afl-fuzz-output/queue
[+] AFL file: id:000000,orig:somestr.start (1 / 184), cycle: 0
    lines......: 18.6% (1122 of 6032 lines)
    functions..: 30.7% (100 of 326 functions)
    branches...: 14.0% (570 of 4065 branches)
[+] AFL file: id:000001,orig:somestr256.start (2 / 184), cycle: 2
    lines......: 18.7% (1127 of 6032 lines)
    functions..: 30.7% (100 of 326 functions)
    branches...: 14.1% (572 of 4065 branches)
[+] Coverage diff id:000000,orig:somestr.start id:000001,orig:somestr256.start
    Src file: /path/to/project-gcov/lib/proj_decode.c
      New 'line' coverage: 140
      New 'line' coverage: 141
      New 'line' coverage: 142
    Src file: /path/to/project-gcov/lib/proj_util.c
      New 'line' coverage: 217
      New 'line' coverage: 218
[+] AFL file: id:000002,orig:somestr384.start (3 / 184), cycle: 10
    lines......: 18.8% (1132 of 6032 lines)
    functions..: 30.7% (100 of 326 functions)
    branches...: 14.1% (574 of 4065 branches)
[+] Coverage diff id:000001,orig:somestr256.start id:000002,orig:somestr384.start
    Src file: /path/to/project-gcov/lib/proj_decode.c
      New 'line' coverage: 145
      New 'line' coverage: 146
      New 'line' coverage: 147
    Src file: /path/to/project-gcov/lib/proj_util.c
      New 'line' coverage: 220
      New 'line' coverage: 221
[+] AFL file: id:000003,orig:somestr.start (4 / 184), cycle: 5
    lines......: 18.9% (1141 of 6032 lines)
    functions..: 31.0% (101 of 326 functions)
    branches...: 14.3% (581 of 4065 branches)
[+] Coverage diff id:000002,orig:somestr384.start id:000003,orig:somestr.start
    Src file: /path/to/project-gcov/lib/proj_message.c
      New 'function' coverage: validate_cmd_msg()
      New 'line' coverage: 244
      New 'line' coverage: 247
      New 'line' coverage: 248
      New 'line' coverage: 250
      New 'line' coverage: 255
      New 'line' coverage: 262
      New 'line' coverage: 263
      New 'line' coverage: 266
.
.
.
[+] Coverage diff id:000182,src:000000,op:havoc,rep:64 id:000184,src:000000,op:havoc,rep:4
[+] Processed 184 / 184 files

[+] Final zero coverage report: /path/to/afl-fuzz-output/cov/zero-cov
[+] Final positive coverage report: /path/to/afl-fuzz-output/cov/pos-cov
[+] Final lcov web report: /path/to/afl-fuzz-output/cov/web/lcov-web-final.html

In the last few lines above, the locations of the final web coverage and zero coverage reports are shown. The zero coverage reports contains function names that were never executed across the entire afl-fuzz run.

The code coverage results in /path/to/afl-fuzz-output/cov/web/lcov-web-final represent cumulative code coverage across all AFL test cases. This data can then be reviewed to ensure that all expected functions are indeed exercised by AFL - just point a web browser at /path/to/afl-fuzz-output/cov/web/lcov-web-final.html. Below is a sample of what this report looks like for a cumulative AFL fuzzing run - this is against the fwknop project, and the full report is available here. Note that even though fwknop has a dedicated set of AFL wrappers, it is still difficult to achieve high percentages of code coverage. This provides evidence that measuring code coverage under AFL fuzzing runs is an important aspect of trying to achieve maximal fuzzing results. Every branch/line/function that is not exercised by AFL represents a location for which AFL has not been given the opportunity to find bugs.

alt text

Parallelized AFL Execution

With the 0.4 release, afl-cov supports parallelized execution runs of afl-fuzz. All that is required is to point afl-cov -d sync_dir at the top level sync directory that is used by all afl-fuzz instances (afl-fuzz -o sync_dir). The coverage results are calculated globally across all fuzzing instances, and in --live mode new instances will be added to the coverage results as they are created.

Other Examples

The workflow above is probably the main strategy for using afl-cov. However, additional use cases are supported such as:

  1. Suppose there are a set of wrapper scripts around afl-fuzz to run fuzzing cycles against various aspects of a project. By building a set of corresponding afl-cov wrappers, and then using the --disable-coverage-init option on all but the first of these wrappers, it is possible to generate code coverage results across the entire set of afl-fuzz fuzzing runs. (By default, afl-cov resets gcov counters to zero at start time, but the --disable-coverage-init argument stops this behavior.) The end result is a global picture of code coverage across all invocations of afl-fuzz.

  2. Specific functions can be searched for in the code coverage results, and afl-cov will return the first afl-fuzz test case where a given function is executed. This allows afl-cov to be used as a validation tool by other scripts and testing infrastructure. For example, a test case could be written around whether an important function is executed by afl-fuzz to validate a patching strategy mentioned in the introduction.

Here is an example where the first test case that executes the function validate_cmd_msg() is returned (this is after all afl-cov results have been produced in the main workflow above):

$ ./afl-cov -d /path/to/afl-fuzz-output --func-search "validate_cmd_msg"
[+] Function 'validate_cmd_mag()' executed by: id:000002,orig:somestr384.start

An equivalent way of searching the coverage results is to just grep the function from the cov/id-delta-cov file described below. The number "3" in the output below is the AFL cycle number where the function is first executed:

$ grep validate_cmd_msg /path/to/afl-fuzz-output/cov/id-delta-cov
id:000002,orig:somestr384.start, 3, /path/to/project-gcov/file.c, function, validate_cmd_msg()

Directory and File Structure

afl-cov creates a few files and directories for coverage results within the specified afl-fuzz directory (-d). These files and directories are displayed below, and all are contained within the main /path/to/afl-fuzz-output/cov/ directory and <dirname> refers to the top level directory name for the fuzzing instance. When AFL is parallelized, there will be one <dirname> directory path for each afl-fuzz instance.

  • cov/diff/<dirname> - contains new code coverage results when a queue/id:NNNNNN* file causes afl-fuzz to execute new code.
  • cov/lcov/<dirname> - contains raw code coverage data produced by the lcov front-end to gcov.
  • cov/web/<dirname> - contains code coverage results in web format produced by genhtml.
  • cov/zero-cov - file that globally lists all functions (and optionally lines) that are never executed by any afl-fuzz test case.
  • cov/pos-cov - file that globally lists all functions (and optionally lines) that are executed at least once by an afl-fuzz test case.
  • cov/id-delta-cov - lists the functions (and optionally lines) that are executed by the first id:000000* test case, and then lists all new functions/lines executed in subsequent test cases.
  • cov/afl-cov.log - log file for afl-cov logging output.
  • cov/afl-cov-status - status file for afl-cov PID, version number , and command line arguments.

Usage Information

Basic --help output appears below:

usage: afl-cov [-h] [-e COVERAGE_CMD] [-d AFL_FUZZING_DIR] [-c CODE_DIR] [-O]
           [--disable-cmd-redirection] [--disable-lcov-web]
           [--disable-coverage-init] [--coverage-include-lines]
           [--enable-branch-coverage] [--live] [--cover-corpus]
           [--coverage-at-exit] [--sleep SLEEP] [--gcov-check]
           [--gcov-check-bin GCOV_CHECK_BIN] [--background]
           [--lcov-web-all] [--disable-lcov-exclude-pattern]
           [--lcov-exclude-pattern LCOV_EXCLUDE_PATTERN]
           [--func-search FUNC_SEARCH] [--line-search LINE_SEARCH]
           [--src-file SRC_FILE] [--afl-queue-id-limit AFL_QUEUE_ID_LIMIT]
           [--ignore-core-pattern] [--lcov-path LCOV_PATH]
           [--genhtml-path GENHTML_PATH] [--readelf-path READELF_PATH]
           [--stop-afl] [--validate-args] [-v] [-V] [-q]

optional arguments:
  -h, --help            show this help message and exit
  -e COVERAGE_CMD, --coverage-cmd COVERAGE_CMD
                        Set command to exec (including args, and assumes code
                        coverage support)
  -d AFL_FUZZING_DIR, --afl-fuzzing-dir AFL_FUZZING_DIR
                        top level AFL fuzzing directory
  -c CODE_DIR, --code-dir CODE_DIR
                        Directory where the code lives (compiled with code
                        coverage support)
  -O, --overwrite       Overwrite existing coverage results
  --disable-cmd-redirection
                        Disable redirection of command results to /dev/null
  --disable-lcov-web    Disable generation of all lcov web code coverage
                        reports
  --disable-coverage-init
                        Disable initialization of code coverage counters at
                        afl-cov startup
  --coverage-include-lines
                        Include lines in zero-coverage status files
  --enable-branch-coverage
                        Include branch coverage in code coverage reports (may
                        be slow)
  --live                Process a live AFL directory, and afl-cov will exit
                        when it appears afl-fuzz has been stopped
  --cover-corpus        Measure coverage after running all available tests
                        instead of individually per queue file
  --coverage-at-exit    Only calculate coverage just before afl-cov exit.
  --sleep SLEEP         In --live mode, # of seconds to sleep between checking
                        for new queue files
  --gcov-check          Check to see if there is a binary in --coverage-cmd
                        (or in --gcov-check-bin) has coverage support
  --gcov-check-bin GCOV_CHECK_BIN
                        Test a specific binary for code coverage support
  --background          Background mode - if also in --live mode, will exit
                        when the alf-fuzz process is finished
  --lcov-web-all        Generate lcov web reports for all id:NNNNNN* files
                        instead of just the last one
  --disable-lcov-exclude-pattern
                        Allow default /usr/include/* pattern to be included in
                        lcov results
  --lcov-exclude-pattern LCOV_EXCLUDE_PATTERN
                        Set exclude pattern for lcov results
  --func-search FUNC_SEARCH
                        Search for coverage of a specific function
  --line-search LINE_SEARCH
                        Search for coverage of a specific line number
                        (requires --src-file)
  --src-file SRC_FILE   Restrict function or line search to a specific source
                        file
  --afl-queue-id-limit AFL_QUEUE_ID_LIMIT
                        Limit the number of id:NNNNNN* files processed in the
                        AFL queue/ directory
  --ignore-core-pattern
                        Ignore the /proc/sys/kernel/core_pattern setting in
                        --live mode
  --lcov-path LCOV_PATH
                        Path to lcov command
  --genhtml-path GENHTML_PATH
                        Path to genhtml command
  --readelf-path READELF_PATH
                        Path to readelf command
  --stop-afl            Stop all running afl-fuzz instances associated with
                        --afl-fuzzing-dir <dir>
  --validate-args       Validate args and exit
  -v, --verbose         Verbose mode
  -V, --version         Print version and exit
  -q, --quiet           Quiet mode

License

afl-cov is released as open source software under the terms of the GNU General Public License (GPL v2+). The latest release can be found at https://github.com/mrash/afl-cov/releases

Contact

All feature requests and bug fixes are managed through github issues tracking. However, you can also email me (michael.rash_AT_gmail.com), or reach me through Twitter (@michaelrash).

afl-cov's People

Contributors

dkasak avatar jwilk avatar magnusstubman avatar markusteufelberger avatar mrash avatar naphtaline avatar steele avatar strazzere avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

afl-cov's Issues

Check lcov --rc

Look for the --rc command line argument to the lcov command to enable branch coverage.

wrong use of is_dir

is this a typo to use is_dir to check file exists?

def get_cycle_num(id_num, cargs):

    ### default cycle
    cycle_num = 0

    if not is_dir(cargs.afl_fuzzing_dir + '/plot_data'):
        return cycle_num

the function is_dir is defined to check if the argument is a directory and not a file:

def is_dir(dpath):
    return os.path.exists(dpath) and os.path.isdir(dpath)

No such file or directory:"afl_out/cov/lcov/afl_out/id:000001,src:000000,op:flip1,pos:0,+cov.lcov_info_final'

Hi,I run afl-cov on ubuntu 14.04,but it reported that lcov_info_final does't exist..
AFL test case: id:000001,src:000000,op:flip1,pos:0,+cov (1 / 273), cycle: 0
Traceback (most recent call last):
File "/usr/local/share/afl-cov/afl-cov", line 1066, in
sys.exit(main())
File "/usr/local/share/afl-cov/afl-cov", line 77, in main
return not process_afl_test_cases(cargs)
File "/usr/local/share/afl-cov/afl-cov", line 174, in process_afl_test_cases
f, cov, cargs)
File "/usr/local/share/afl-cov/afl-cov", line 261, in coverage_diff
new_cov = extract_coverage(cp['lcov_info_final'], cargs)
File "/usr/local/share/afl-cov/afl-cov", line 416, in extract_coverage
with open(lcov_file, 'r') as f:
IOError: [Errno 2] No such file or directory: '/root/workspace/afl_binutils/binutils-2.26/afl_out/cov/lcov/afl_out/id:000001,src:000000,op:flip1,pos:0,+cov.lcov_info_final'

Update HTML output during live mode

Hi,

I just noticed that during live mode no HTML output is generated. It would be nice if the web output was also generated when monitoring a running fuzz job and furthermore if it was updated whenever the coverage status is printed to the console. Doing this less frequently would be ok too. I think updating the HTML every few minutes or so would be fine.

This could eliminate the overhead for regenerating the complete HTML output for every update coverage-wise. Additionally the user could simply hit F5 in the browser to check the updated coverage reports.

Thanks!

LCOV 1.14 does not support gcc9

This will result in errors from lcov, which are shown as 'command returned status 255'. Just a heads-up for everyone trying to run this with a newer version of gcc.

Hangs during processing

please tell me how to look for the cause or problem
I start without a flag (--live) or with it there is no difference all the same hangs approximately at processing 1000\25000
tell me other programs to build coating in addition to the afl-com
thanks!

A question about afl-cov with aflnet.

Hi, I use aflnet to test a network program. When I finished test, I want to use afl-cov to see the coverage of the program. But afl-cov use stdin or file as input. However aflnet's testcase is network package.
Can you help me? Thank you very much.

extend afl-cov to analyze the variable behaviors of applications?

Hi there,
Firstly, thank you for your great work!
I’m thinking if you have any interest in extending your work to analyze the variable behaviors of fuzzing targets?
If we can identify which part of source code is responsible for indeterminancy and choose to not instrument that part, we can greatly improve the stability of fuzzing.
If you have any interest, I would like to help.
Cheers,

About source code compilation

When I follow the README method and first run afl-cov with the --live parameter and then run afl-fuzz, I found that the binary compiled with the "-ftest-coverage -o afl_test_cov" option failed to run. But binary files compiled directly with the "-g" option can run successfully. The following is the error:

~/afl-cov$ afl-fuzz -T ./afl_test_cov -t 1000 -i ./in -o ./sync_dir ./afl_test_cov -a -b -c
afl-fuzz 2.51b by <[email protected]>
[+] You have 4 CPU cores and 4 runnable tasks (utilization: 100%).
[*] Checking CPU core loadout...
[+] Found a free CPU core, binding to #0.
[*] Checking core_pattern...
[*] Setting up output directories...
[+] Output directory exists but deemed OK to reuse.
[*] Deleting old session data...
[+] Output dir cleanup successful.
[*] Scanning './in'...
[+] No auto-generated dictionary tokens to reuse.
[*] Creating hard links for all input files...
[*] Validating target binary...

[-] Looks like the target binary is not instrumented! The fuzzer depends on
    compile-time instrumentation to isolate interesting test cases while
    mutating the input data. For more information, and for tips on how to
    instrument binaries, please see /usr/local/share/doc/afl/README.

    When source code is not available, you may be able to leverage QEMU
    mode support. Consult the README for tips on how to enable this.
    (It is also possible to use afl-fuzz as a traditional, "dumb" fuzzer.
    For that, you can use the -n option - but expect much worse results.)

[-] PROGRAM ABORT : No instrumentation detected
         Location : check_binary(), afl-fuzz.c:7148

Non-zero exit status '1' for CMD: /usr/bin/readelf -a cat

From your README, to run the program that need AFL_FILE as stdin:

$ cd /path/to/project-gcov/
$ afl-cov -d /path/to/afl-fuzz-output/ --live --coverage-cmd \
"cat AFL_FILE | LD_LIBRARY_PATH=./lib/.libs ./bin/.libs/somebin -a -b -c" \
--code-dir .

afl-cov/afl-cov

Lines 906 to 913 in 8d14372

for part in cargs.coverage_cmd.split(' '):
if not part or part[0] == ' ' or part[0] == '-':
continue
if (which(part)):
found_exec = True
if not cargs.disable_gcov_check and is_bin_gcov_enabled(part, cargs):
found_code_cov_binary = True
break

but this code will treat the first word cat as the exec part, leading to error message:

    Non-zero exit status '1' for CMD: /usr/bin/readelf -a cat

I would recommend change the README to:

afl-cov -d /path/to/afl-fuzz-output/ --live --coverage-cmd \
"LD_LIBRARY_PATH=./lib/.libs ./bin/.libs/somebin -a -b -c < AFL_FILE " \
--code-dir .

or change the code to add a parameter for specifing the exec part.

missing files of zero coverage in html output

afl-cov line 438 combined "base" and "info" into "final". So "final" contains data about zero coverage. However, the next step, afl-cov line 444, generate "final" again using "info" as input. Therefore, if there are some files with zero coverage, that file will be missing in the final html output.

No such file or directory: '../afl_out/cov/lcov/trace.lcov_info_final'

Hello,

I am running the newest version of afl-cov and afl on 64-bit Ubuntu 14.04. I followed the tutorial here, and I am able to successfully fuzz a test code with afl.

However, when I tried to run afl-cov, I got the following error:

☁  cov  afl-cov -d ../afl_out --live --coverage-cmd "./checksum AFL_FILE" --code-dir ../ --overwrite
    Non-zero exit status '255' for CMD: /usr/bin/lcov --no-checksum --capture --initial --directory ../ --output-file ../afl_out/cov/lcov/trace.lcov_base

*** Imported 3 new test cases from: ../afl_out/queue

[+] AFL test case: id:000000,orig:in (0 / 3), cycle: 0

    Non-zero exit status '255' for CMD: /usr/bin/lcov --no-checksum --capture --directory ../ --output-file ../afl_out/cov/lcov/trace.lcov_info
    Non-zero exit status '255' for CMD: /usr/bin/lcov --no-checksum -a ../afl_out/cov/lcov/trace.lcov_base -a ../afl_out/cov/lcov/trace.lcov_info --output-file /tmp/tmppLxYHX
Traceback (most recent call last):
 File "/data/vagrant_vms/afl-cov//afl-cov", line 1190, in <module>
  sys.exit(main())
File "/data/vagrant_vms/afl-cov//afl-cov", line 91, in main
  return not process_afl_test_cases(cargs)
File "/data/vagrant_vms/afl-cov//afl-cov", line 208, in process_afl_test_cases
cov, cargs)
File "/data/vagrant_vms/afl-cov//afl-cov", line 314, in coverage_diff
  new_cov = extract_coverage(cov_paths['lcov_info_final'], cargs)
File "/data/vagrant_vms/afl-cov//afl-cov", line 462, in extract_coverage
  with open(lcov_file, 'r') as f:
 IOError: [Errno 2] No such file or directory: '../afl_out/cov/lcov/trace.lcov_info_final'`

Could anyone shed some lights on what/how does this error happen? Thank you!

lcov: ERROR: no valid records found in tracefile

I followed the instructions given in the workflow section. Running afl-cov gives me following error:

$ afl-cov -d /home/numair/Documents/faultlocalization/evaluation/RealWorld/AFL-FUZZING/findings --live --coverage-cmd "cat AFL_FILE | LD_LIBRARY_PATH=./lib/.libs ./bin/.libs/somebin -a -b -c" --code-dir .
[-] Sleep for 60 seconds for AFL fuzzing directory to be created...
    
*** Imported 2 new test cases from: /home/numair/Documents/faultlocalization/evaluation/RealWorld/AFL-FUZZING/findings/queue

    [+] AFL test case: id:000000,orig:test1.txt (0 / 2), cycle: 0
lcov: ERROR: no valid records found in tracefile /home/numair/Documents/faultlocalization/evaluation/RealWorld/AFL-FUZZING/findings/cov/lcov/id:000000,orig:test1.txt.lcov_info
Traceback (most recent call last):
  File "/usr/bin/afl-cov", line 724, in <module>
    sys.exit(main())
  File "/usr/bin/afl-cov", line 72, in main
    return not process_afl_test_cases(gpaths, cargs)
  File "/usr/bin/afl-cov", line 140, in process_afl_test_cases
    gen_coverage(gpaths, cov_paths, f, cargs)
  File "/usr/bin/afl-cov", line 447, in gen_coverage
    + cov_paths['lcov_info_final'], cargs, WANT_OUTPUT)
  File "/usr/bin/afl-cov", line 536, in run_cmd
    out = subprocess.check_output(cmd.split())
  File "/usr/lib/python2.7/dist-packages/subprocess32.py", line 635, in check_output
    raise CalledProcessError(retcode, process.args, output=output)
subprocess32.CalledProcessError: Command '['lcov', '--rc', 'lcov_branch_coverage=1', '--no-checksum', '-r', '/home/numair/Documents/faultlocalization/evaluation/RealWorld/AFL-FUZZING/findings/cov/lcov/id:000000,orig:test1.txt.lcov_info', '/usr/include/*', '--output-file', '/home/numair/Documents/faultlocalization/evaluation/RealWorld/AFL-FUZZING/findings/cov/lcov/id:000000,orig:test1.txt.lcov_info_final']' returned non-zero exit status 255

What am I doing wrong ?

Add a --last-cmd option

Add a --last-cmd option to re-run afl-cov with the same command line args as the previous execution.

does afl-cov support QEMU

my afl command is this:
afl-fuzz -t 300+ -m none -i solidity_input_part -o output -Q -- solc --bin -o --overwrite @@
my afl-cov command is this:
./afl-cov -d output --coverage-cmd "/usr/bin/solc AFL_FILE" -c . --enable-branch-coverage --overwrit
but I get an error:
[*] Could not find an executable binary with code coverage support ('-fprofile-arcs -ftest-coverage') in --coverage-cmd '/usr/bin/solc AFL_FILE'

Difficulty of Using afl-cov on Mac OS -- lacking readelf

I am using afl-cov on Mac OS. It seems that afl-cov depends on readelf, which does not exist on Mac. What would you suggest to deal with this?

$ afl-cov -d ./out --coverage-cmd "cat AFL_FILE | ./a.out" -c .
[*] Need a valid path to readelf, use --readelf-path

Example for --disable-coverage-init

If I understood the docs correctly, --disable-coverage-init is supposed to allow updating already existing coverage information with new test cases. However, I was unable to make it work, since it either complains that an existing cov directory was found or, if told to overwrite the directory with -O, it says /tmp/afl-ramdisk/out/cov/lcov/trace.lcov_info_final.

Could you add an example of this flag's usage to the README?

afl-cov is not working with coroutines

Hi, I've encountered an issue with code coverage in C++ code that uses coroutines. Here is a repository with a demo on how to reproduce the described situation:

https://github.com/PiotrConclusive/afl-cov-coroutines/tree/master

I've been using afl-g++ in a Docker environment provided by the afl project:
https://github.com/AFLplusplus/AFLplusplus/blob/stable/Dockerfile

In the repository, there is an attached report at https://github.com/PiotrConclusive/afl-cov-coroutines/blob/master/aflOut/cov/web/index.html, where you can see that some lines in coroutine functions appear white.

image

add test step

When afl starts, it first confirms if the command it's about to fuzz even makes sense by running the test case. afl-cov should do something similar.

I had an issue where due to some error on my side, the instance that was being run to get the coverage failed even though the afl ran instance succeeded. Took me a long time to realize this :)

option to skip found_code_cov_binary test

i'm currently trying to use afl-cov to test a dlopen()ed library.

unfortunately the safety-nets in afl-cov give me a hard time, esp. the check whether the cmdline contains instrumented executables.

my main executable is not instrumented, but it loads a configuration that will trigger the dlopen()ing (and use) of an instrumented binary - so the coverage-cmd doesn't contain any hint about the binary in question.

rather than patching the afl-cov script, would it be possible to add a cmdline-flag to disable the found_code_cov_binary-test?

erroneous detection of executables with code coverage support

while trying to use afl-cov to test a dlopen()ed library, I think i discovered a small bug in the check for properly providing instrumented executables.

namely the break in L894 should be indented to the inner if.

reasoning

the coverage-cmd might contain multiple executables, with only one of them being instrumented.
the current test will stop after checking the first word that is also an executable, and if this one is not instrumented, found_code_cov_binary will stay False, thus leading to early abort.

i'm not providing a PR, given that the fix is trivial and i'm not sure whether i'm actually right.

--coverage-cmd error: could not find executable binary

Hi,
I'm trying to run AFL-cov on a finished AFL test output.
I ran AFL using the command /path/to/afl-fuzz -i inputDir/ -o outputDir/ /path/to/program @@ , and I compiled the program using AFL's clang compiler.

When using AFL-cov, I'm trying to follow the examples in the README, so after compiling the program separately with coverage support, I tried to run AFL-cov with these commands:

$ cd /emptyDir
$ /path/to/afl-cov -d /path/to/outputDir --coverage-cmd "/path/to/program -f AFL_FILE" -c /path/to/recompiled/program --enable-branch-coverage

I get this error:
[*] Could not find an executable binary --coverage-cmd ' ~/Applications/curl/AFLbuild/src/curl -f AFL_FILE'

The path I give is exactly the same as the path I used to start AFL earlier. How can I fix this? If I just specify the directory where the program is in and not the direct path to the program, I get the same error.

Any help is appreciated. Thank you.

How to improve the speed of afl-cov's calculation of coverage?

Currently, afl-cov needs the output file of afl-fuzz to calculate coverage, which means that two processes are required. But if there are multiple files and the target program is very large, the calculation speed will be very slow. Does afl-cov support reading the bitmap to calculate the coverage, which will speed up the calculation?

Or, to think about this more simply, afl-cov now generates the coverage of each file. Which option allows me to get the overall coverage without so many details?

Handle relative -d path

Links to final reports break when -d is specified with a relative path instead of an absolute path.

doesn't handle master/slave directories

If you're using "-M" and "-S" options to afl-fuzz, you get output directories "outputs/name1/" "outputs/name2/" etc. with queue directories under these. This confuses afl-cov which expects "outputs/queue" to exist.

IndexError: string index out of range in line 905

code

for part in cargs.coverage_cmd.split(' '):
            if part[0] == ' ' or part[0] == '-':
                continue
            if (which(part)):
                found_exec = True
                if not cargs.disable_gcov_check and is_bin_gcov_enabled(part, cargs):
                    found_code_cov_binary = True
                    break

if coverage_cmd has multi space, the value 'part' will get a '' and making binary exit.like this

afl-cov -d /out --live --coverage-cmd "LD_LIBRARY_PATH=../lib/  ./tiffinfo -D AFL_FILE"   --code-dir /src/libtiff --genhtml-per-min 1440 --background
Traceback (most recent call last):
  File "/usr/local/bin/afl-cov", line 1236, in <module>
    sys.exit(main())
  File "/usr/local/bin/afl-cov", line 76, in main
    if not validate_cargs(cargs):
  File "/usr/local/bin/afl-cov", line 962, in validate_cargs
    if not is_gcov_enabled(cargs):
  File "/usr/local/bin/afl-cov", line 931, in is_gcov_enabled
    if part[0] == ' ' or part[0] == '-':
IndexError: string index out of range

afl-cov not working with python-afl-fuzz

I tried to use afl-cov to statistic the coverage while execution python-afl-fuzz, but it cannot work well.
Could you provide the using guide for python-afl-fuzz?

Missing index.html in final web output

Afl-cov command was:

afl-cov -d .../fuzzout/ --coverage-cmd "./binary 1 AFL_FILE" --code-dir ~/project-gcov/

(started in ~/project-gcov/binary)

Note the missing index.html linked by lcov-web-final.html below:

fuzzout/cov/web$ ls -l
lcov-web-final.html -> /home/.../fuzzout//cov/web/f8/id:000373,sync:f2,src:000383/index.html

fuzzout/cov/web$ cd /home/.../fuzzout//cov/web/f8/id:000373,sync:f2,src:000383

cov/web/f8/id:000373,sync:f2,src:000383# ls
amber.png  emerald.png  gcov.css  glass.png  root  ruby.png  snow.png  updown.png

The only html file produced is a mock-util.c.gcov.html that only has coverage info for that mock-util.c file. Is this due to some failure to create the files or am I using some unsupported way of running afl-cov ?

How does afl-cov collect program of C/S architecture(such as mysql) code coverage?

I have using fuzzed mysql and generated some seed file.Now I want to use afl-cov to collect mysql code coverage.I use the following command:
/home/mysql/afl-cov/afl-cov -d /home/mysql/fuzzing/fuzz_output --enable-branch-coverage -c . -e "cat AFL_FILE |./bld_aflcov/bin/mysqld" or /home/mysql/afl-cov/afl-cov -d /home/mysql/fuzzing/fuzz_output --enable-branch-coverage -c . -e "cat AFL_FILE |./bld_aflcov/bin/mysql"
But it doesn't work

afl-cov with unicorn

Can afl-cov be used in conjunction with afl and unicorn to perform coverage statistics on closed source binaries?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.