{"id":15008894,"url":"https://github.com/rc0r/afl-utils","last_synced_at":"2026-01-11T00:03:31.437Z","repository":{"id":27228850,"uuid":"30700162","full_name":"rc0r/afl-utils","owner":"rc0r","description":"Utilities for automated crash sample processing/analysis, easy afl-fuzz job management and corpus optimization","archived":true,"fork":false,"pushed_at":"2018-06-06T17:45:04.000Z","size":755,"stargazers_count":417,"open_issues_count":3,"forks_count":63,"subscribers_count":32,"default_branch":"master","last_synced_at":"2025-10-03T17:57:44.887Z","etag":null,"topics":["afl","automation","crash-reporting","fuzzer","fuzzing","job-management","python-3","security","triage"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rc0r.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"docs/CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-02-12T11:49:00.000Z","updated_at":"2025-09-10T18:01:36.000Z","dependencies_parsed_at":"2022-09-01T02:42:08.385Z","dependency_job_id":null,"html_url":"https://github.com/rc0r/afl-utils","commit_stats":null,"previous_names":[],"tags_count":47,"template":false,"template_full_name":null,"purl":"pkg:github/rc0r/afl-utils","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rc0r%2Fafl-utils","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rc0r%2Fafl-utils/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rc0r%2Fafl-utils/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rc0r%2Fafl-utils/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rc0r","download_url":"https://codeload.github.com/rc0r/afl-utils/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rc0r%2Fafl-utils/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28261727,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2026-01-10T02:00:06.867Z","response_time":57,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["afl","automation","crash-reporting","fuzzer","fuzzing","job-management","python-3","security","triage"],"created_at":"2024-09-24T19:21:30.747Z","updated_at":"2026-01-11T00:03:31.361Z","avatar_url":"https://github.com/rc0r.png","language":"Python","funding_links":[],"categories":["Python"],"sub_categories":[],"readme":"# **NOTE: FUTURE DEVELOPMENT WILL HAPPEN THROUGH [GITLAB](https://gitlab.com/rc0r/afl-utils)!**\n\nAs of June, 6th 2018 this project moved to [Gitlab](https://gitlab.com/rc0r/afl-utils) that's why this repository is\narchived and thus read-only until it is entirely removed from Github. Repository removal is scheduled for September,\n15th 2018.\n\nPlease report issues and request your merges through the new [project home](https://gitlab.com/rc0r/afl-utils). All\nfurther discussion - even for existing issues - will take place there.\n\nThank you,\n\nrc0r\n\n\n# afl-utils [![Build Status](https://travis-ci.org/rc0r/afl-utils.svg?branch=master)](https://travis-ci.org/rc0r/afl-utils)[![Coverage Status](https://coveralls.io/repos/rc0r/afl-utils/badge.svg?branch=master\u0026service=github)](https://coveralls.io/github/rc0r/afl-utils?branch=master)\n\nafl-utils is a collection of utilities to assist fuzzing with\n[american-fuzzy-lop (afl)](http://lcamtuf.coredump.cx/afl/).\nafl-utils includes tools for:\n\n* automated crash sample collection, verification, reduction and analysis (`afl-collect`, `afl-vcrash`)\n* easy management of parallel (multi-core) fuzzing jobs (`afl-multicore`, `afl-multikill`)\n* corpus optimization (`afl-minimize`)\n* fuzzer stats supervision (`afl-stats`)\n* fuzzer queue synchronisation (`afl-sync`)\n* autonomous utility execution (`afl-cron`)\n\nVarious [screenshots](#Screenshots) of the tools in action can be found at the end of this file.  \n\n**For installation instructions see [docs/INSTALL.md](https://github.com/rc0r/afl-utils/blob/master/docs/INSTALL.md).**\n\n\n## afl-collect\n\n`afl-collect` basically copies all crash sample files from an afl synchronisation directory\n(used by multiple afl instances when run in parallel) into a single location providing\neasy access for further crash analysis. Beyond that `afl-collect` has some more advanced\nfeatures like invalid crash sample removing (see `afl-vcrash`) as well as generating and\nexecuting `gdb` scripts that make use of [Exploitable](https://github.com/jfoote/exploitable).\nThe purpose of these scripts is to automate crash sample classification (see screenshot below)\nand reduction.  \nVersion 1.01a introduced crash sample de-duplication using backtrace hashes calculated by\nexploitable. To use this feature invoke `afl-collect` with `-e \u003cgdb_script\u003e` switch for\nautomatic gdb+exploitable script generation and execution. For each backtrace hash only a\nsingle crash sample file will be kept.  \n`afl-collect` is quite slow when operating on large sample sets and using gdb+exploitable\nscript execution, so be patient!  \nWhen invoked with `-d \u003cdatabase\u003e`, sample information will be stored in the `database`. This\nwill only be done when the gdb-script execution step is selected (`-e`). If `database` is an\nexisting database containing sample info, `afl-collect` will skip all samples that already\nhave a database entry during sample processing. This will work also when `-e` is not requested.\nThis makes subsequent `afl-collect` runs more efficient, since only unseen samples are\nprocessed (and added to the database).  \n\nUsage examples:\n\nSimply collect all crashes from `./afl_sync_dir` into a collection directory removing\nnon-crashing samples:\n\n    $ afl-collect -r ./afl_sync_dir ./collection_dir -- /path/to/target --target-opts\n\nCollect crashes, execute `exploitable` on them and remove uninteresting crashes. Info\nfor all processed samples will be stored in an SQLite DB. The `gdb` script used to run\n`exploitable` on all samples will be saved in `gdb_script`. We're using eight threads\nhere:\n\n    $ afl-collect -d crashes.db -e gdb_script -r -rr ./afl_sync_dir ./collection_dir \\\n            -j 8 -- /path/to/target --target-opts\n\nDuring sample verification (enabled using `-r`) `afl-collect` uses a default time of\n10 seconds to allow the target process to finish processing a single sample. This ensures\nthat `afl-collect` continues to run even if you happen to encounter some DoS condition\nin the target. If you want to tweak this value use `-r` in conjunction with\n`-rt \u003ctimeout\u003e` to specify the timeout in seconds.\n\n## afl-cron\n\nThe purpose of `afl-cron` is to run different `afl-utils` tasks periodically. Example\nuse cases include grabbing `afl-stats` or syncing fuzzing queues using `afl-sync`\nrepeatedly. `afl-cron` is not limited to run top-level tools from the `afl-utils`\ncollection. For a much finer granularity you may specify an arbitrary function from\nany `afl-utils` module to be executed once the timer runs out.\n\nRunning `afl-cron` with the following configuration will execute `afl-stats.main()`\nevery 60 minutes in quiet mode using the provided sample config:\n\n```json\n{\n    \"interval\": 60,\n    \"jobs\": [\n        {\n            \"name\": \"afl-stats\",\n            \"description\": \"Job description here\",\n            \"module\": \"afl_utils.afl_stats\",\n            \"function\": \"main\",\n            \"params\": \"--quiet -c config/afl-stats.conf.sample\"\n        }\n    ]\n}\n```\n\nYou may have multiple job definitions in your configuration. Once the interval timer is up,\nall jobs are executed sequentially.\n\n\n## afl-minimize\n\nHelps to create a minimized corpus from samples of a parallel fuzzing job. It\nbasically works as follows:\n\n1. Collect all queue samples from an afl synchronisation directory in `collection_dir`.\n2. Run `afl-cmin` on the collected corpus, save minimized corpus in `collection_dir.cmin`.\n3. Run `afl-tmin` on the remaining samples to reduce them in size. Save results in\n   `collection_dir.tmin` if step two was omitted or `collection_dir.cmin.tmin` otherwise.\n4. Perform a \"dry-run\" for each sample and move crashes/timeouts out of the corpus. This\n   step will be useful prior to starting a new or resuming a parallel fuzzing job on a\n   corpus containing intermittent crashes. Crashes will be moved to a `.crashes` directory,\n   if one of steps 1, 2 or 3 were performed. If only \"dry-run\" is requested, crashing\n   samples will be moved from the `queue` to the `crashes` dirs within an afl sync dir.\n   For timeouts the behavior is similar: When operating on a collection directory timeouts\n   will be moved to a `.hangs` directory. When operating on the original afl synchronisation\n   directory timeouts will go into `hangs` dir within the corresponding afl fuzzer dir.  \n   \nAs already indicated, all these steps are optional, making the tool quite flexible. E.g.\nrunning only step four can be handy before resuming a parallel fuzzing session. In order\nto skip step one, simply provide a directory containing fuzzing samples. Then `afl-minimize`\nwill not collect any samples, instead `afl-cmin` and/or `afl-tmin` are run on the samples\nin the provided directory.  \n\nWhen operating on corpora with many samples use `--tmin` with caution. Running thousands\nof files through `afl-tmin` can take very long. So make sure the results are as expected\nand worth the effort. You don't want to waste days of CPU time just to reduce your corpus\nsize by a few bytes, don't you?!\n\nPerforming the \"dry-run\" step after running `afl-cmin` might seem pointless, but my\nexperience showed that sometimes crashes remain in the minimized corpus. So this is just\nan additional step to get rid of them. But don't expect \"dry-run\" to always clear your\ncorpus from crashes with a 100% success rate!\n\nBrandon Perry described a common fuzzing workflow in his\n[blog post](http://foxglovesecurity.com/2016/03/15/fuzzing-workflows-a-fuzz-job-from-start-to-finish/).\nIt incorporates corpus pruning and reseeding `afl-fuzz` with optimized corpora. The\ncollection and minimization steps taken in `afl-minimize` automate the pruning process\nof the presented workflow. To feed the minimized, pruned corpus back into the different\ninstances of `afl-fuzz` you may use the `--reseed` option that comes with `afl-minimize`.  \nThis effectively moves the original `queue` directories of all fuzzing instances\nout of the way (to `queue.YYYY-MM-DD-HH:MM:SS`). Next, the optimized corpus is copied\ninto the `queue` dirs of your fuzzing instances.  \nAfter reseeding, all fuzzing instances may be resumed on the same, optimized corpus.\nSo with `afl-utils` the pruning/reseeding process is just a matter of `afl-multicore`ing,\n`afl-multikill`ing and `afl-minimize`ing.\n\nUsage examples:\n\nMinimize the entire corpus of all fuzzers in `./afl_sync_dir` using `afl-cmin` and\n`afl-cmin` utilizing eight threads:\n\n    $ afl-minimize -c new_corpus --cmin --cmin-mem-limit=500 --tmin --tmin-mem-limit=500 \\\n                -j 8 ./afl_sync_dir -- /path/to/target --target-opts\n\nMinimize the entire corpus using `afl-cmin` and reseed the fuzzers:\n\n    $ afl-minimize -c new_corpus --cmin --cmin-mem-limit=500 --reseed ./afl_sync_dir \\\n                -- /path/to/target --target-opts\n\n\n## afl-multicore\n\n`afl-multicore` starts several parallel fuzzing jobs in the background using `nohup` (Note:\nSo afl's fancy interface is gone). Fuzzer outputs (`stdout` and `stderr`) will be redirected\nto `/dev/null`. Use `--verbose` to turn output redirection off. This is particularly useful\nwhen debugging `afl-fuzz` invocations. The auto-generated file `nohup.out` might also contain\nsome useful info.  \nAnother way to debug `afl-fuzz` invocations is test mode. Just start `afl-multicore` and\nprovide the `--test` flag to perform a test run. `afl-multicore` will start a single fuzzing\ninstance in interactive mode using a test output directory `\u003cout-dir\u003e_test`. The `interactive`\nsetting in your config file will be ignored.  \n**Note:** After running a test you will have to clean up the test output directory\n`\u003cout-dir\u003e_test` yourself!  \n**Note:** For interactive *test runs* `screen` is not required!\n\nIf you want to check the fuzzers' progress see `fuzzer_stats` in the respective fuzzer\ndirectory in the synchronisation dir (`sync_dir/SESSION###/fuzzer_stats`)! Another way to monitor\nfuzzing progress is to use `afl-stats`. You may also want to check out `afl-stats` database dumping\nfeature. An `afl-multicore` session can (and should!) easily be aborted with the help of\n`afl-multikill` (see below).\n\nIf you prefer to work with afl's UI instead of background processes and stat files, screen\nmode is for you. \"Interactive\" screen mode can be enabled using the `interactive` setting\nin the config file (see below). In order to use it, start `afl-multicore` from **inside** a\n`screen` session. A new screen window is created for every afl instance. Though screen mode is\nnot supported by `afl-multikill`.  \n**Attention:** When using screen mode be sure to set necessary environment variables in your\n`afl-multicore` configuration! Alternatively run\n`screen -X setenv \u003cvar_name\u003e \u003cvar_value\u003e` from inside `screen` before running `afl-multicore`.\nBoth ways the environment is inherited by all subsequently created screen windows.\n\nUsage examples:\n\n    $ afl-multicore -c target-multicore.conf start 16\n    $ afl-multicore -c target-multicore.conf add 4\n    $ afl-multicore -c target-multicore.conf resume 20\n\nIn case you want to resume just a few fuzzers you may use selective resume. Let's say\nyou've had 20 afl instances running, killed all but the first one (the master instance) and now\nyou want to resume all slave instances without interrupting master:\n\n    $ afl-multicore -c target-multicore.conf resume number_of_jobs_to_resume,job_offset\n    $ afl-multicore -c target-multicore.conf resume 19,1\n\nThis `afl-multicore` invocation will resume 19 instances starting at offset 1. Of course other\nranges are possible too. However, when using an offset greater than `master_instances` (description\nbelow) only slave instances will be resumed!\n\nTarget settings and afl options are configured in a JSON configuration file.\nThe most simple configuration may look something like:\n\n```json\n{\n    \"input\": \"./in\",\n    \"output\": \"./out\",\n    \"target\": \"~/bin/target\",\n    \"cmdline\": \"--target-opt\"\n}\n```\n\nOf course a lot more settings can be configured, some of these settings are:\n\n* afl options: timeout, memory limit, dictionary, CPU affinity, ...\n* job options: session name, interactive mode\n* environment variables for interactive screen mode\n\nFor a complete list of options see `afl-multicore.conf.sample`. Their descriptions\nare documented in section `Configuration Settings` below.\n\nTo start four fuzzing instances simply do:\n\n    $ afl-multicore -c target.conf start 4\n\nNow, if you want to add two more instances because `afl-gotcpu` states you've\ngot some spare CPU cycles available, use the `add` command:\n\n    $ afl-multicore -c target.conf add 2\n\nInterrupted fuzzing jobs can be resumed the same way using the `resume` command.  \n**Note:** It is possible to *tell* `afl-multicore` to resume more jobs for a\nspecific target than were previously started. Obviously `afl-multicore` can\nresume just as many afl instances as it finds output directories for! Use the\n`add` command to start additional afl instances!\n\n`afl-fuzz` can be run using its `-f \u003cfile\u003e` argument to specify the location of\nthe generated sample. When using multiple `afl-fuzz` instances a single file\nobviously can't do the trick, because multiple fuzzers running in parallel would\nneed separate files to store their data. For that reason `afl-multicore` extends\nthe provided filename with the instance number similar to the session naming\nscheme: `cur_input` would be extended into `cur_input_000`, `cur_input_001` and\nso on. In order to use these files just use `%%` in the target command line\nspecification within the config file. `afl-multicore` will then do all the magic\nand use the correct files for the different instances of `afl-fuzz`.\n\nExample config:\n\n```json\n{\n    \"target\": \"/your/app/here\",\n    \"cmdline\": \"--some-target-opts --input-file %%\",\n      \"#\": \"^- translates to:\",\n      \"#\": \"--some-target-opts --input-file /path/to/cur_input_000\",\n      \"#\": \"--some-target-opts --input-file /path/to/cur_input_001\",\n      \"#\": \"...\",\n    \"file\": \"/path/to/cur_input\"\n}\n```\n\nReal life fuzzing experience showed that starting or resuming many afl-fuzz\ninstances at once can be problematic. Especially during initialization these\nfuzzers may heavily interfere with each other causing intermittent afl-fuzz\naborts. In case you are facing such a scenario you might want to give the delayed\nstartup feature (`-s \u003cdelay\u003e` option) a try! Chose the startup delay with caution\ndepending on your corpus size. For small corpora a few seconds should work well,\nfor corpora containing tens or hundreds of thousands of files much greater delays\n(minutes, hours or even days) are needed to have an effect.  \nIf you have no clue what to chose or you're simply lazy, try `auto`. This will\nestimate a delay based on the chosen afl timeout and the number of samples in the\ninput dir (for initial start ups) or in the queue dirs of the individual fuzzers\n(for resumes).\n\n    $ afl-multicore -c target.conf -s 120 resume 64\n    $ afl-multicore -c target.conf -s auto resume 64\n\n\n### Configuration settings\n\nAs already noted there are only four settings that are required in every config\nfile. These are `afl-fuzz` directory specifications `input` and `output`, the\npath to the target binary `target` and target command line arguments `cmdline`:\n\nIf you want to run `afl-multicore` on different `afl-fuzz` binaries you may\nspecify the fuzzer explicitly:\n\n```json\n\"fuzzer\": \"afl-fuzz-fast\"\n```\n\nMake sure the provided fuzzer binary is in your path! The default is to use `afl-fuzz`.   \n\nafl-fuzz directory specifications:\n\n```json\n\"input\": \"./in\",\n\"output\": \"./out\"\n```\n\nTarget binary and command line settings:\n\n```json\n\"target\": \"/usr/bin/target\",\n\"cmdline\": \"-a -b -c -d\"\n```\n\nLocation read by the fuzzed program. Valid options are:\n\n  * a file name\n  * `@@` (see afl-fuzz manual)\n\n```json\n\"file\": \"@@\"\n```\n\nTimeout in ms for each fuzzing run:\n\n```json\n\"timeout\": \"200+\"\n```\n\nMemory limit in MB for target processes. To avoid hiccups make sure to provide\nthe desired memory limit value as a string!\n\n```json\n\"mem_limit\": \"150\"\n```\n\nUse afl QEMU mode?\n\n```json\n\"qemu\": true\n```\n\nUse `afl_margs` to provide additional cmdline arguments for afl. These\narguments will directly be passed to afl! This way you may provide new,\nhacked or experimental cmdline args to `afl-fuzz`.\n\n```json\n\"afl_margs\": \"-T banner\"\n```\n\nSkip afl deterministic steps:\n\n```json\n\"dirty\": true\n```\n\nFuzz without instrumentation:\n\n```json\n\"dumb\": true\n```\n\nSpecify a fuzzing dictionary:\n\n```json\n\"dict\": \"dict/target.dict\"\n```\n\nProvide a name for the fuzzing session. Master outputs\nwill be written to `output/SESSION000`!\n\n```json\n\"session\": \"SESSION\"\n```\n\nThe optional `master_instances` configuration option controls how many master instances should be started:\n\n* `master_instances = 1` or omitted: run in default single-master mode\n* `master_instances \u003c= 0`: run in slave-only mode\n* `master_instances \u003e 1`: run in experimental multi-master mode\n\n```json\n\"master_instances\": 1\n```\n\nInteractive screen mode. Starts every afl instance in a separate\nscreen window. Run `afl-multicore` from inside screen!\n\n```json\n\"interactive\": true\n```\n\nEnvironment variables `afl-multicore` will set when using interactive screen mode.\n\n```json\n\"environment\": [\n    \"AFL_PERSISTENT=1\",\n    \"LD_PRELOAD=desock.so\"\n]\n```\n\n## afl-multikill\n\nAborts all `afl-fuzz` instances belonging to an active non-interactive `afl-multicore`\nsession. `afl-multicore` sessions that were started in `screen` mode can not be aborted!\n\nUsage example:\n\n    $ afl-multikill -S target_session\n\n\n## afl-stats\n\nPrints fuzzing statistics similar to `afl-whatsup -s` and optionally posts (tweets) them\nto Twitter. This is especially useful when fuzzing on multiple machines. Regularly ssh-ing\ninto all of your boxes to check `fuzzer_stats` quickly becomes a PITA...  \nAdditionally `afl-stats` may dump the current contents of `fuzzer_stats` into a database.\nSo upon later inspection you have historical stats information in one place for analysis.\nFor twitter setup instructions, please see\n[docs/INSTALL.md](https://github.com/rc0r/afl-utils/blob/master/docs/INSTALL.md)!\nScreenshots of sample tweets can be found in the final section of this document.\n\nUsage example:\n\n    $ afl-stats -c target-stats.conf -d stats.db -t\n\n\n## afl-sync\n\nUsing `afl-sync` you may distribute fuzzing corpora of multiple `afl-fuzz` instances\nacross node boundaries. It allows to backup, restore or synchronise `afl-fuzz` instance\ndirectories to, from or with a remote destination. Under the hood `afl-sync` uses\n`rsync` with enabled compression and tries to avoid unnecessary data transfers. During\na push operation `afl-sync` takes an `afl-fuzz` synchronisation directory and transfers\nall contained fuzzer directories to a remote location appending the `.sync` extension.\nWhen pulling `afl-sync` downloads all fuzzer directories from the remote location to\nthe synchronisation dir. Fuzzer instances already located in the local sync dir that\npreviously were used for pushing will not be downloaded! In order to download these\nfuzzer directories provide a clean sync dir.\nThe synchronisation operation simply issues a pull followed by push command.\nSpecific fuzzing jobs may be selected from a sync dir by providing their respective\nsession name (`-S session`). See `afl-multicore` for more info about session naming.\n\nUsage examples:\n\n    $ afl-sync push ./afl_sync_dir rc0r@remote.fuzzer_instance_repo.com:/repo/target/\n    $ afl-sync pull ./afl_sync_dir rc0r@remote.fuzzer_instance_repo.com:/repo/target/\n    $ afl-sync sync ./afl_sync_dir rc0r@remote.fuzzer_instance_repo.com:/repo/target/\n\n\n## afl-vcrash\n\n`afl-vcrash` verifies that afl-fuzz crash samples really lead to crashes in the target\nbinary and optionally removes these samples automatically.  \nNote: `afl-vcrash` functionality is incorporated into `afl-collect`. If `afl-collect` is\ninvoked with switch `-r`, it runs `afl-vcrash -qr` to quietly remove invalid samples from\nthe collected files.  \nTo enable parallel crash sample verification provide `-j` followed by the desired number\nof threads `afl-vcrash` will utilize. Depending on the target process you're fuzzing,\nrunning multiple threads in parallel can significantly improve verification speeds.\n\nUsage example:\n\n    $ afl-vcrash -r -j 8 ./dir_with_crashes -- /path/to/target --target-opt\n\n\n## Screenshots\n\n### afl-collect\n\nSample output:\n\n![afl-collect_sample](https://raw.githubusercontent.com/rc0r/afl-utils/master/.scrots/afl_collect_sample.png)\n\n### afl-sync\n\n![afl-sync_diagram](https://raw.githubusercontent.com/rc0r/afl-utils/master/.scrots/afl-sync-diagram.png)\n\n### afl-multicore\n\nSample output (normal mode):\n\n![afl-multicore_sample](https://raw.githubusercontent.com/rc0r/afl-utils/master/.scrots/afl_multicore_sample.png)\n\n### afl-stats\n\n![afl-stats_sample](https://raw.githubusercontent.com/rc0r/afl-utils/master/.scrots/afl_stats_sample.png)\n\n![afl-stats_tweet](https://raw.githubusercontent.com/rc0r/afl-utils/master/.scrots/afl_stats_tweet.png)\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frc0r%2Fafl-utils","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frc0r%2Fafl-utils","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frc0r%2Fafl-utils/lists"}