forked from p98n2ja4z/AFLplusplus
Compare commits
8 Commits
Author | SHA1 | Date |
---|---|---|
pqg5afj7f | 54cf7395a5 | 1 month ago |
p98n2ja4z | de1ce7bc50 | 1 month ago |
1LuB | 833075b5d9 | 1 month ago |
1LuB | 945de3a2c8 | 1 month ago |
p98n2ja4z | 2fd062c0b6 | 1 month ago |
p98n2ja4z | d65d488b97 | 1 month ago |
1LuB | 366233b009 | 1 month ago |
1LuB | dbc698415f | 1 month ago |
Binary file not shown.
Binary file not shown.
@ -0,0 +1,148 @@
|
|||||||
|
---
|
||||||
|
Language: Cpp
|
||||||
|
# BasedOnStyle: Google
|
||||||
|
AccessModifierOffset: -1
|
||||||
|
AlignAfterOpenBracket: Align
|
||||||
|
AlignConsecutiveAssignments: false
|
||||||
|
AlignConsecutiveDeclarations: true
|
||||||
|
AlignEscapedNewlines: Left
|
||||||
|
AlignOperands: true
|
||||||
|
AlignTrailingComments: true
|
||||||
|
AllowAllParametersOfDeclarationOnNextLine: true
|
||||||
|
AllowShortBlocksOnASingleLine: true
|
||||||
|
AllowShortCaseLabelsOnASingleLine: false
|
||||||
|
AllowShortFunctionsOnASingleLine: false
|
||||||
|
AllowShortIfStatementsOnASingleLine: true
|
||||||
|
AllowShortLoopsOnASingleLine: false
|
||||||
|
AlwaysBreakAfterDefinitionReturnType: None
|
||||||
|
AlwaysBreakAfterReturnType: None
|
||||||
|
AlwaysBreakBeforeMultilineStrings: true
|
||||||
|
AlwaysBreakTemplateDeclarations: Yes
|
||||||
|
BinPackArguments: true
|
||||||
|
BinPackParameters: true
|
||||||
|
BraceWrapping:
|
||||||
|
AfterClass: false
|
||||||
|
AfterControlStatement: false
|
||||||
|
AfterEnum: false
|
||||||
|
AfterFunction: false
|
||||||
|
AfterNamespace: false
|
||||||
|
AfterObjCDeclaration: false
|
||||||
|
AfterStruct: false
|
||||||
|
AfterUnion: false
|
||||||
|
AfterExternBlock: false
|
||||||
|
BeforeCatch: false
|
||||||
|
BeforeElse: false
|
||||||
|
IndentBraces: false
|
||||||
|
SplitEmptyFunction: true
|
||||||
|
SplitEmptyRecord: true
|
||||||
|
SplitEmptyNamespace: true
|
||||||
|
BreakBeforeBinaryOperators: None
|
||||||
|
BreakBeforeBraces: Attach
|
||||||
|
BreakBeforeInheritanceComma: false
|
||||||
|
BreakInheritanceList: BeforeColon
|
||||||
|
BreakBeforeTernaryOperators: true
|
||||||
|
BreakConstructorInitializersBeforeComma: false
|
||||||
|
BreakConstructorInitializers: BeforeColon
|
||||||
|
BreakAfterJavaFieldAnnotations: false
|
||||||
|
BreakStringLiterals: true
|
||||||
|
ColumnLimit: 80
|
||||||
|
CommentPragmas: '^ IWYU pragma:'
|
||||||
|
CompactNamespaces: false
|
||||||
|
ConstructorInitializerAllOnOneLineOrOnePerLine: true
|
||||||
|
ConstructorInitializerIndentWidth: 4
|
||||||
|
ContinuationIndentWidth: 4
|
||||||
|
Cpp11BracedListStyle: true
|
||||||
|
DerivePointerAlignment: false
|
||||||
|
DisableFormat: false
|
||||||
|
ExperimentalAutoDetectBinPacking: false
|
||||||
|
FixNamespaceComments: true
|
||||||
|
ForEachMacros:
|
||||||
|
- foreach
|
||||||
|
- Q_FOREACH
|
||||||
|
- BOOST_FOREACH
|
||||||
|
IncludeBlocks: Preserve
|
||||||
|
IncludeCategories:
|
||||||
|
- Regex: '^<ext/.*\.h>'
|
||||||
|
Priority: 2
|
||||||
|
- Regex: '^<.*\.h>'
|
||||||
|
Priority: 1
|
||||||
|
- Regex: '^<.*'
|
||||||
|
Priority: 2
|
||||||
|
- Regex: '.*'
|
||||||
|
Priority: 3
|
||||||
|
IncludeIsMainRegex: '([-_](test|unittest))?$'
|
||||||
|
IndentCaseLabels: true
|
||||||
|
IndentPPDirectives: BeforeHash
|
||||||
|
IndentWidth: 2
|
||||||
|
IndentWrappedFunctionNames: false
|
||||||
|
JavaScriptQuotes: Leave
|
||||||
|
JavaScriptWrapImports: true
|
||||||
|
KeepEmptyLinesAtTheStartOfBlocks: false
|
||||||
|
MacroBlockBegin: ''
|
||||||
|
MacroBlockEnd: ''
|
||||||
|
MaxEmptyLinesToKeep: 1
|
||||||
|
NamespaceIndentation: None
|
||||||
|
ObjCBinPackProtocolList: Never
|
||||||
|
ObjCBlockIndentWidth: 2
|
||||||
|
ObjCSpaceAfterProperty: false
|
||||||
|
ObjCSpaceBeforeProtocolList: true
|
||||||
|
PenaltyBreakAssignment: 2
|
||||||
|
PenaltyBreakBeforeFirstCallParameter: 1
|
||||||
|
PenaltyBreakComment: 300
|
||||||
|
PenaltyBreakFirstLessLess: 120
|
||||||
|
PenaltyBreakString: 1000
|
||||||
|
PenaltyBreakTemplateDeclaration: 10
|
||||||
|
PenaltyExcessCharacter: 1000000
|
||||||
|
PenaltyReturnTypeOnItsOwnLine: 200
|
||||||
|
PointerAlignment: Right
|
||||||
|
RawStringFormats:
|
||||||
|
- Language: Cpp
|
||||||
|
Delimiters:
|
||||||
|
- cc
|
||||||
|
- CC
|
||||||
|
- cpp
|
||||||
|
- Cpp
|
||||||
|
- CPP
|
||||||
|
- 'c++'
|
||||||
|
- 'C++'
|
||||||
|
CanonicalDelimiter: ''
|
||||||
|
BasedOnStyle: google
|
||||||
|
- Language: TextProto
|
||||||
|
Delimiters:
|
||||||
|
- pb
|
||||||
|
- PB
|
||||||
|
- proto
|
||||||
|
- PROTO
|
||||||
|
EnclosingFunctions:
|
||||||
|
- EqualsProto
|
||||||
|
- EquivToProto
|
||||||
|
- PARSE_PARTIAL_TEXT_PROTO
|
||||||
|
- PARSE_TEST_PROTO
|
||||||
|
- PARSE_TEXT_PROTO
|
||||||
|
- ParseTextOrDie
|
||||||
|
- ParseTextProtoOrDie
|
||||||
|
CanonicalDelimiter: ''
|
||||||
|
BasedOnStyle: google
|
||||||
|
ReflowComments: true
|
||||||
|
SortIncludes: false
|
||||||
|
SortUsingDeclarations: true
|
||||||
|
SpaceAfterCStyleCast: false
|
||||||
|
SpaceAfterTemplateKeyword: true
|
||||||
|
SpaceBeforeAssignmentOperators: true
|
||||||
|
SpaceBeforeCpp11BracedList: false
|
||||||
|
SpaceBeforeCtorInitializerColon: true
|
||||||
|
SpaceBeforeInheritanceColon: true
|
||||||
|
SpaceBeforeParens: ControlStatements
|
||||||
|
SpaceBeforeRangeBasedForLoopColon: true
|
||||||
|
SpaceInEmptyParentheses: false
|
||||||
|
SpacesBeforeTrailingComments: 2
|
||||||
|
SpacesInAngles: false
|
||||||
|
SpacesInContainerLiterals: true
|
||||||
|
SpacesInCStyleCastParentheses: false
|
||||||
|
SpacesInParentheses: false
|
||||||
|
SpacesInSquareBrackets: false
|
||||||
|
Standard: Auto
|
||||||
|
TabWidth: 8
|
||||||
|
UseTab: Never
|
||||||
|
...
|
||||||
|
|
@ -0,0 +1,159 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
#
|
||||||
|
# american fuzzy lop++ - custom code formatter
|
||||||
|
# --------------------------------------------
|
||||||
|
#
|
||||||
|
# Written and maintained by Andrea Fioraldi <andreafioraldi@gmail.com>
|
||||||
|
#
|
||||||
|
# Copyright 2015, 2016, 2017 Google Inc. All rights reserved.
|
||||||
|
# Copyright 2019-2023 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
|
||||||
|
#
|
||||||
|
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
# import re # TODO: for future use
|
||||||
|
import shutil
|
||||||
|
import importlib.metadata
|
||||||
|
|
||||||
|
# string_re = re.compile('(\\"(\\\\.|[^"\\\\])*\\")') # TODO: for future use
|
||||||
|
|
||||||
|
CURRENT_LLVM = os.getenv('LLVM_VERSION', 18)
|
||||||
|
CLANG_FORMAT_BIN = os.getenv("CLANG_FORMAT_BIN", "")
|
||||||
|
|
||||||
|
|
||||||
|
def check_clang_format_pip_version():
|
||||||
|
"""
|
||||||
|
Check if the correct version of clang-format is installed via pip.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
bool: True if the correct version of clang-format is installed,
|
||||||
|
False otherwise.
|
||||||
|
"""
|
||||||
|
# Check if clang-format is installed
|
||||||
|
if importlib.util.find_spec('clang_format'):
|
||||||
|
# Check if the installed version is the expected LLVM version
|
||||||
|
if importlib.metadata.version('clang-format')\
|
||||||
|
.startswith(str(CURRENT_LLVM)+'.'):
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
# Return False, because the clang-format version does not match
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
# If the 'clang_format' package isn't installed, return False
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
with open(".clang-format") as f:
|
||||||
|
fmt = f.read()
|
||||||
|
|
||||||
|
|
||||||
|
CLANG_FORMAT_PIP = check_clang_format_pip_version()
|
||||||
|
|
||||||
|
if shutil.which(CLANG_FORMAT_BIN) is None:
|
||||||
|
CLANG_FORMAT_BIN = f"clang-format-{CURRENT_LLVM}"
|
||||||
|
|
||||||
|
if shutil.which(CLANG_FORMAT_BIN) is None \
|
||||||
|
and CLANG_FORMAT_PIP is False:
|
||||||
|
print(f"[!] clang-format-{CURRENT_LLVM} is needed. Aborted.")
|
||||||
|
print(f"Run `pip3 install \"clang-format=={CURRENT_LLVM}.*\"` \
|
||||||
|
to install via pip.")
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
if CLANG_FORMAT_PIP:
|
||||||
|
CLANG_FORMAT_BIN = shutil.which("clang-format")
|
||||||
|
|
||||||
|
COLUMN_LIMIT = 80
|
||||||
|
for line in fmt.split("\n"):
|
||||||
|
line = line.split(":")
|
||||||
|
if line[0].strip() == "ColumnLimit":
|
||||||
|
COLUMN_LIMIT = int(line[1].strip())
|
||||||
|
|
||||||
|
|
||||||
|
def custom_format(filename):
|
||||||
|
p = subprocess.Popen([CLANG_FORMAT_BIN, filename], stdout=subprocess.PIPE)
|
||||||
|
src, _ = p.communicate()
|
||||||
|
src = str(src, "utf-8")
|
||||||
|
|
||||||
|
in_define = False
|
||||||
|
last_line = None
|
||||||
|
out = ""
|
||||||
|
|
||||||
|
for line in src.split("\n"):
|
||||||
|
if line.lstrip().startswith("#"):
|
||||||
|
if line[line.find("#") + 1:].lstrip().startswith("define"):
|
||||||
|
in_define = True
|
||||||
|
|
||||||
|
if (
|
||||||
|
"/*" in line
|
||||||
|
and not line.strip().startswith("/*")
|
||||||
|
and line.endswith("*/")
|
||||||
|
and len(line) < (COLUMN_LIMIT - 2)
|
||||||
|
):
|
||||||
|
cmt_start = line.rfind("/*")
|
||||||
|
line = (
|
||||||
|
line[:cmt_start]
|
||||||
|
+ " " * (COLUMN_LIMIT - 2 - len(line))
|
||||||
|
+ line[cmt_start:]
|
||||||
|
)
|
||||||
|
|
||||||
|
define_padding = 0
|
||||||
|
if last_line is not None and in_define and last_line.endswith("\\"):
|
||||||
|
last_line = last_line[:-1]
|
||||||
|
define_padding = max(0, len(last_line[last_line.rfind("\n") + 1:]))
|
||||||
|
|
||||||
|
if (
|
||||||
|
last_line is not None
|
||||||
|
and last_line.strip().endswith("{")
|
||||||
|
and line.strip() != ""
|
||||||
|
):
|
||||||
|
line = (" " * define_padding + "\\" if in_define else "") + "\n" + line
|
||||||
|
elif (
|
||||||
|
last_line is not None
|
||||||
|
and last_line.strip().startswith("}")
|
||||||
|
and line.strip() != ""
|
||||||
|
):
|
||||||
|
line = (" " * define_padding + "\\" if in_define else "") + "\n" + line
|
||||||
|
elif (
|
||||||
|
line.strip().startswith("}")
|
||||||
|
and last_line is not None
|
||||||
|
and last_line.strip() != ""
|
||||||
|
):
|
||||||
|
line = (" " * define_padding + "\\" if in_define else "") + "\n" + line
|
||||||
|
|
||||||
|
if not line.endswith("\\"):
|
||||||
|
in_define = False
|
||||||
|
|
||||||
|
out += line + "\n"
|
||||||
|
last_line = line
|
||||||
|
|
||||||
|
return out
|
||||||
|
|
||||||
|
|
||||||
|
args = sys.argv[1:]
|
||||||
|
if len(args) == 0:
|
||||||
|
print("Usage: ./format.py [-i] <filename>")
|
||||||
|
print()
|
||||||
|
print(" The -i option, if specified, let the script to modify in-place")
|
||||||
|
print(" the source files. By default the results are written to stdout.")
|
||||||
|
print()
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
in_place = False
|
||||||
|
if args[0] == "-i":
|
||||||
|
in_place = True
|
||||||
|
args = args[1:]
|
||||||
|
|
||||||
|
for filename in args:
|
||||||
|
code = custom_format(filename)
|
||||||
|
if in_place:
|
||||||
|
with open(filename, "w") as f:
|
||||||
|
f.write(code)
|
||||||
|
else:
|
||||||
|
print(code)
|
@ -0,0 +1,75 @@
|
|||||||
|
!/coresight_mode
|
||||||
|
*.dSYM
|
||||||
|
*.o
|
||||||
|
*.pyc
|
||||||
|
*.so
|
||||||
|
.sync_tmp
|
||||||
|
.test
|
||||||
|
.test2
|
||||||
|
.git
|
||||||
|
.dockerignore
|
||||||
|
.github
|
||||||
|
CITATION.cff
|
||||||
|
CONTRIBUTING.md
|
||||||
|
Changelog.md
|
||||||
|
Dockerfile
|
||||||
|
LICENSE
|
||||||
|
TODO.md
|
||||||
|
afl-analyze
|
||||||
|
afl-analyze.8
|
||||||
|
afl-as
|
||||||
|
afl-as.8
|
||||||
|
afl-clang
|
||||||
|
afl-clang-fast
|
||||||
|
afl-clang-fast.8
|
||||||
|
afl-clang-fast\+\+
|
||||||
|
afl-clang-fast\+\+.8
|
||||||
|
afl-clang-lto
|
||||||
|
afl-clang-lto.8
|
||||||
|
afl-clang-lto\+\+
|
||||||
|
afl-clang-lto\+\+.8
|
||||||
|
afl-clang\+\+
|
||||||
|
afl-cmin.8
|
||||||
|
afl-cmin.bash.8
|
||||||
|
afl-fuzz
|
||||||
|
afl-fuzz.8
|
||||||
|
afl-g\+\+
|
||||||
|
afl-g\+\+-fast
|
||||||
|
afl-g\+\+-fast.8
|
||||||
|
afl-gcc
|
||||||
|
afl-gcc-fast
|
||||||
|
afl-gcc-fast.8
|
||||||
|
afl-gcc.8
|
||||||
|
afl-gotcpu
|
||||||
|
afl-gotcpu.8
|
||||||
|
afl-ld
|
||||||
|
afl-ld-lto
|
||||||
|
afl-plot.8
|
||||||
|
afl-qemu-trace
|
||||||
|
afl-showmap
|
||||||
|
afl-showmap.8
|
||||||
|
afl-system-config.8
|
||||||
|
afl-tmin
|
||||||
|
afl-tmin.8
|
||||||
|
afl-whatsup.8
|
||||||
|
as
|
||||||
|
core*
|
||||||
|
examples/afl_frida/afl-frida
|
||||||
|
examples/afl_frida/frida-gum-example.c
|
||||||
|
examples/afl_frida/frida-gum.h
|
||||||
|
examples/afl_frida/libtestinstr.so
|
||||||
|
examples/afl_network_proxy/afl-network-client
|
||||||
|
examples/afl_network_proxy/afl-network-server
|
||||||
|
in
|
||||||
|
ld
|
||||||
|
out
|
||||||
|
qemu_mode/libcompcov/compcovtest
|
||||||
|
qemu_mode/qemu-*
|
||||||
|
test/unittests/unit_hash
|
||||||
|
test/unittests/unit_list
|
||||||
|
test/unittests/unit_maybe_alloc
|
||||||
|
test/unittests/unit_preallocable
|
||||||
|
test/unittests/unit_rand
|
||||||
|
unicorn_mode/samples/*/\.test-*
|
||||||
|
unicorn_mode/samples/*/output
|
||||||
|
unicorn_mode/unicornafl
|
@ -0,0 +1,13 @@
|
|||||||
|
# These are supported funding model platforms
|
||||||
|
|
||||||
|
# Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
|
||||||
|
github: AFLplusplus
|
||||||
|
patreon: # Replace with a single Patreon username
|
||||||
|
open_collective: AFLplusplusEU
|
||||||
|
ko_fi: # Replace with a single Ko-fi username
|
||||||
|
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
|
||||||
|
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
|
||||||
|
liberapay: # Replace with a single Liberapay username
|
||||||
|
issuehunt: # Replace with a single IssueHunt username
|
||||||
|
otechie: # Replace with a single Otechie username
|
||||||
|
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
|
@ -0,0 +1,32 @@
|
|||||||
|
---
|
||||||
|
name: Bug report
|
||||||
|
about: Create a report to help us improve
|
||||||
|
title: ''
|
||||||
|
labels: ''
|
||||||
|
assignees: ''
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**IMPORTANT**
|
||||||
|
1. You have verified that the issue to be present in the current `dev` branch.
|
||||||
|
2. Please supply the command line options and relevant environment variables,
|
||||||
|
e.g., a copy-paste of the contents of `out/default/fuzzer_setup`.
|
||||||
|
|
||||||
|
Thank you for making AFL++ better!
|
||||||
|
|
||||||
|
**Describe the bug**
|
||||||
|
A clear and concise description of what the bug is.
|
||||||
|
|
||||||
|
**To Reproduce**
|
||||||
|
Steps to reproduce the behavior:
|
||||||
|
1. ...
|
||||||
|
2. ...
|
||||||
|
|
||||||
|
**Expected behavior**
|
||||||
|
A clear and concise description of what you expected to happen.
|
||||||
|
|
||||||
|
**Screen output/Screenshots**
|
||||||
|
If applicable, add copy-paste of the screen output or screenshot that shows the issue. Please ensure the output is in **English** and not in Chinese, Russian, German, etc.
|
||||||
|
|
||||||
|
**Additional context**
|
||||||
|
Add any other context about the problem here.
|
@ -0,0 +1,20 @@
|
|||||||
|
---
|
||||||
|
name: Feature request
|
||||||
|
about: Suggest an idea for this project
|
||||||
|
title: ''
|
||||||
|
labels: ''
|
||||||
|
assignees: ''
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Is your feature request related to a problem? Please describe.**
|
||||||
|
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||||
|
|
||||||
|
**Describe the solution you'd like**
|
||||||
|
A clear and concise description of what you want to happen.
|
||||||
|
|
||||||
|
**Describe alternatives you've considered**
|
||||||
|
A clear and concise description of any alternative solutions or features you've considered.
|
||||||
|
|
||||||
|
**Additional context**
|
||||||
|
Add any other context or screenshots about the feature request here.
|
@ -0,0 +1,58 @@
|
|||||||
|
name: CI
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- stable
|
||||||
|
- dev
|
||||||
|
pull_request:
|
||||||
|
branches:
|
||||||
|
- dev # No need for stable-pull-request, as that equals dev-push
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
linux:
|
||||||
|
runs-on: "${{ matrix.os }}"
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
os: [ubuntu-22.04, ubuntu-20.04]
|
||||||
|
env:
|
||||||
|
AFL_SKIP_CPUFREQ: 1
|
||||||
|
AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES: 1
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
- name: update
|
||||||
|
run: sudo apt-get update && sudo apt-get upgrade -y
|
||||||
|
- name: debug
|
||||||
|
run: apt-cache search plugin-dev | grep gcc-; echo; apt-cache search clang-format- | grep clang-format-
|
||||||
|
- name: install packages
|
||||||
|
run: sudo apt-get install -y -m -f build-essential gcc-10 g++-10 git libtool libtool-bin automake flex bison libglib2.0-0 clang-12 llvm-12-dev libc++-dev findutils libcmocka-dev python3-dev python3-setuptools ninja-build python3-pip gcc-10-plugin-dev
|
||||||
|
- name: compiler installed
|
||||||
|
run: gcc -v; echo; clang -v
|
||||||
|
- name: install gcc plugin
|
||||||
|
run: sudo apt-get install -y -m -f --install-suggests $(readlink /usr/bin/gcc)-plugin-dev
|
||||||
|
- name: build afl++
|
||||||
|
run: export NO_NYX=1; export ASAN_BUILD=1; export LLVM_CONFIG=llvm-config-12; make ASAN_BUILD=1 NO_NYX=1 LLVM_CONFIG=llvm-config-12 distrib
|
||||||
|
- name: run tests
|
||||||
|
run: sudo -E ./afl-system-config; make tests
|
||||||
|
macos:
|
||||||
|
runs-on: macOS-latest
|
||||||
|
env:
|
||||||
|
AFL_MAP_SIZE: 65536
|
||||||
|
AFL_SKIP_CPUFREQ: 1
|
||||||
|
AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES: 1
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
- name: install
|
||||||
|
run: brew install make gcc llvm
|
||||||
|
# - name: fix install
|
||||||
|
# run: cd /usr/local/bin; ln -s gcc-11 gcc; ln -s g++-11 g++; which gcc; gcc -v
|
||||||
|
# - name: build
|
||||||
|
# run: export PATH=/usr/local/Cellar/llvm/*/":$PATH"; export CC=/usr/local/Cellar/llvm/*/bin/clang; export CXX="$CC"++; export LLVM_CONFIG=/usr/local/Cellar/llvm/*/bin/llvm-config; sudo -E ./afl-system-config; gmake ASAN_BUILD=1 afl-fuzz
|
||||||
|
- name: build
|
||||||
|
run: sudo -E ./afl-system-config; gmake ASAN_BUILD=1 afl-fuzz
|
||||||
|
# - name: frida
|
||||||
|
# run: export CC=/usr/local/Cellar/llvm/*/bin/clang; export CXX="$CC"++; cd frida_mode; gmake
|
||||||
|
# - name: run tests
|
||||||
|
# run: sudo -E ./afl-system-config; export CC=/usr/local/Cellar/llvm/*/bin/clang; export CXX="$CC"++; export PATH=/usr/local/Cellar/llvm/*/":/usr/local/bin:$PATH"; export LLVM_CONFIG=/usr/local/Cellar/llvm/*/bin/llvm-config; gmake tests
|
||||||
|
# - name: force frida test for MacOS
|
||||||
|
# run: export AFL_PATH=`pwd`; /usr/local/bin/gcc -o test-instr test-instr.c; mkdir in; echo > in/in; AFL_NO_UI=1 ./afl-fuzz -O -i in -o out -V 5 -- ./test-instr
|
@ -0,0 +1,33 @@
|
|||||||
|
name: Formatting
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- stable
|
||||||
|
- dev
|
||||||
|
pull_request:
|
||||||
|
branches:
|
||||||
|
- dev # No need for stable-pull-request, as that equals dev-push
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
code-format-check:
|
||||||
|
name: Check code format
|
||||||
|
if: ${{ 'false' == 'true' }} # Disable the job
|
||||||
|
runs-on: ubuntu-22.04
|
||||||
|
container: docker.io/aflplusplus/aflplusplus:dev
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
- name: Format
|
||||||
|
run: |
|
||||||
|
git config --global --add safe.directory /__w/AFLplusplus/AFLplusplus
|
||||||
|
apt-get update
|
||||||
|
apt-get install -y clang-format-${LLVM_VERSION}
|
||||||
|
make code-format
|
||||||
|
- name: Check if code needed formatting
|
||||||
|
run: |
|
||||||
|
git --no-pager -c color.ui=always diff HEAD
|
||||||
|
if ! git diff HEAD --quiet; then
|
||||||
|
echo "[!] Please run 'make code-format' and push its changes."
|
||||||
|
exit 1
|
||||||
|
fi
|
@ -0,0 +1,33 @@
|
|||||||
|
name: "CodeQL"
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- stable
|
||||||
|
- dev
|
||||||
|
pull_request:
|
||||||
|
branches:
|
||||||
|
- dev # No need for stable-pull-request, as that equals dev-push
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
analyze:
|
||||||
|
name: Analyze
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
container: # We use a previous image as it's expected to have all the dependencies
|
||||||
|
image: docker.io/aflplusplus/aflplusplus:dev
|
||||||
|
steps:
|
||||||
|
- name: Fix for using external repo in container build # https://github.com/actions/checkout/issues/760
|
||||||
|
run: git config --global --add safe.directory /__w/AFLplusplus/AFLplusplus
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
- name: Initialize CodeQL
|
||||||
|
uses: github/codeql-action/init@v2
|
||||||
|
with:
|
||||||
|
languages: cpp, python
|
||||||
|
- name: Build AFLplusplus # Rebuild because CodeQL needs to monitor the build process
|
||||||
|
env:
|
||||||
|
CC: gcc # These are symlinked to the version used in the container build
|
||||||
|
CXX: g++
|
||||||
|
run: make -i all # Best effort using -i
|
||||||
|
- name: Perform CodeQL Analysis
|
||||||
|
uses: github/codeql-action/analyze@v2
|
@ -0,0 +1,75 @@
|
|||||||
|
name: Container
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- stable
|
||||||
|
- dev
|
||||||
|
tags:
|
||||||
|
- "*"
|
||||||
|
pull_request:
|
||||||
|
branches:
|
||||||
|
- dev # No need for stable-pull-request, as that equals dev-push
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-and-test-amd64:
|
||||||
|
name: Test amd64 image
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
- name: Set up Docker Buildx
|
||||||
|
uses: docker/setup-buildx-action@v2
|
||||||
|
- name: Build amd64
|
||||||
|
uses: docker/build-push-action@v3
|
||||||
|
with:
|
||||||
|
context: .
|
||||||
|
tags: aflplusplus:test-amd64
|
||||||
|
load: true
|
||||||
|
cache-to: type=gha,mode=max
|
||||||
|
build-args: |
|
||||||
|
TEST_BUILD=1
|
||||||
|
- name: Test amd64
|
||||||
|
run: >
|
||||||
|
docker run --rm aflplusplus:test-amd64 bash -c "
|
||||||
|
apt-get update &&
|
||||||
|
apt-get install -y libcmocka-dev &&
|
||||||
|
make -i tests
|
||||||
|
"
|
||||||
|
|
||||||
|
push:
|
||||||
|
name: Push amd64 and arm64 images
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs:
|
||||||
|
- build-and-test-amd64
|
||||||
|
if: ${{ github.event_name == 'push' && github.repository == 'AFLplusplus/AFLplusplus' }}
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
- name: Set up QEMU
|
||||||
|
uses: docker/setup-qemu-action@v2
|
||||||
|
with:
|
||||||
|
platforms: arm64
|
||||||
|
- name: Set up Docker Buildx
|
||||||
|
uses: docker/setup-buildx-action@v2
|
||||||
|
- name: Login to docker.io
|
||||||
|
uses: docker/login-action@v2
|
||||||
|
with:
|
||||||
|
username: ${{ secrets.DOCKER_USERNAME }}
|
||||||
|
password: ${{ secrets.DOCKER_TOKEN }}
|
||||||
|
- name: Set tags to push
|
||||||
|
id: push-tags
|
||||||
|
run: |
|
||||||
|
PUSH_TAGS=docker.io/aflplusplus/aflplusplus:${GITHUB_REF_NAME}
|
||||||
|
if [ "${GITHUB_REF_NAME}" = "stable" ]; then
|
||||||
|
PUSH_TAGS=${PUSH_TAGS},docker.io/aflplusplus/aflplusplus:latest
|
||||||
|
fi
|
||||||
|
export PUSH_TAGS
|
||||||
|
echo "::set-output name=PUSH_TAGS::${PUSH_TAGS}"
|
||||||
|
- name: Push to docker.io registry
|
||||||
|
uses: docker/build-push-action@v3
|
||||||
|
with:
|
||||||
|
context: .
|
||||||
|
platforms: linux/amd64,linux/arm64
|
||||||
|
push: true
|
||||||
|
tags: ${{ steps.push-tags.outputs.PUSH_TAGS }}
|
||||||
|
cache-from: type=gha
|
@ -0,0 +1,33 @@
|
|||||||
|
name: Rust Custom Mutators
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- stable
|
||||||
|
- dev
|
||||||
|
pull_request:
|
||||||
|
branches:
|
||||||
|
- dev # No need for stable-pull-request, as that equals dev-push
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
test:
|
||||||
|
name: Test Rust Custom Mutator Support
|
||||||
|
runs-on: '${{ matrix.os }}'
|
||||||
|
defaults:
|
||||||
|
run:
|
||||||
|
working-directory: custom_mutators/rust
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
os: [ubuntu-22.04, ubuntu-20.04]
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
- name: Install Rust Toolchain
|
||||||
|
uses: actions-rs/toolchain@v1
|
||||||
|
with:
|
||||||
|
toolchain: stable
|
||||||
|
- name: Check Code Compiles
|
||||||
|
run: cargo check
|
||||||
|
- name: Run General Tests
|
||||||
|
run: cargo test
|
||||||
|
- name: Run Tests for afl_internals feature flag
|
||||||
|
run: cd custom_mutator && cargo test --features=afl_internals
|
@ -0,0 +1,116 @@
|
|||||||
|
!coresight_mode
|
||||||
|
!coresight_mode/coresight-trace
|
||||||
|
*.dSYM
|
||||||
|
*.o
|
||||||
|
*.o.tmp
|
||||||
|
*.pyc
|
||||||
|
*.so
|
||||||
|
*.swp
|
||||||
|
.DS_Store
|
||||||
|
.sync_tmp
|
||||||
|
.test
|
||||||
|
.test2
|
||||||
|
.vscode
|
||||||
|
afl-addseeds.8
|
||||||
|
afl-analyze
|
||||||
|
afl-analyze.8
|
||||||
|
afl-as
|
||||||
|
afl-as.8
|
||||||
|
afl-c++
|
||||||
|
afl-c++.8
|
||||||
|
afl-cc
|
||||||
|
afl-cc.8
|
||||||
|
afl-clang
|
||||||
|
afl-clang++
|
||||||
|
afl-clang-fast
|
||||||
|
afl-clang-fast++
|
||||||
|
afl-clang-fast++.8
|
||||||
|
afl-clang-fast.8
|
||||||
|
afl-clang-lto
|
||||||
|
afl-clang-lto++
|
||||||
|
afl-clang-lto++.8
|
||||||
|
afl-clang-lto.8
|
||||||
|
afl-cmin.8
|
||||||
|
afl-cmin.bash.8
|
||||||
|
afl-cs-proxy
|
||||||
|
afl-frida-trace.so
|
||||||
|
afl-fuzz
|
||||||
|
afl-fuzz.8
|
||||||
|
afl-g++
|
||||||
|
afl-g++.8
|
||||||
|
afl-gcc
|
||||||
|
afl-gcc.8
|
||||||
|
afl-gcc-fast
|
||||||
|
afl-gcc-fast.8
|
||||||
|
afl-g++-fast
|
||||||
|
afl-g++-fast.8
|
||||||
|
afl-gotcpu
|
||||||
|
afl-gotcpu.8
|
||||||
|
afl-ld
|
||||||
|
afl-ld-lto
|
||||||
|
afl-lto
|
||||||
|
afl-lto++
|
||||||
|
afl-lto++.8
|
||||||
|
afl-lto.8
|
||||||
|
afl-persistent-config.8
|
||||||
|
afl-plot.8
|
||||||
|
afl-qemu-trace
|
||||||
|
afl-showmap
|
||||||
|
afl-showmap.8
|
||||||
|
afl-system-config.8
|
||||||
|
afl-tmin
|
||||||
|
afl-tmin.8
|
||||||
|
afl-whatsup.8
|
||||||
|
a.out
|
||||||
|
as
|
||||||
|
compile_commands.json
|
||||||
|
core*
|
||||||
|
examples/afl_frida/afl-frida
|
||||||
|
examples/afl_frida/frida-gum-example.c
|
||||||
|
examples/afl_frida/frida-gum.h
|
||||||
|
examples/afl_frida/libtestinstr.so
|
||||||
|
examples/afl_network_proxy/afl-network-client
|
||||||
|
examples/afl_network_proxy/afl-network-server
|
||||||
|
examples/aflpp_driver/libAFLDriver.a
|
||||||
|
examples/aflpp_driver/libAFLQemuDriver.a
|
||||||
|
gmon.out
|
||||||
|
in
|
||||||
|
ld
|
||||||
|
libAFLDriver.a
|
||||||
|
libAFLQemuDriver.a
|
||||||
|
out
|
||||||
|
qemu_mode/libcompcov/compcovtest
|
||||||
|
qemu_mode/qemu-*
|
||||||
|
qemu_mode/qemuafl
|
||||||
|
test/.afl_performance
|
||||||
|
test-instr
|
||||||
|
test/output
|
||||||
|
test/test-c
|
||||||
|
test/test-cmplog
|
||||||
|
test/test-compcov
|
||||||
|
test/test-instr.ts
|
||||||
|
test/test-persistent
|
||||||
|
test/unittests/unit_hash
|
||||||
|
test/unittests/unit_list
|
||||||
|
test/unittests/unit_maybe_alloc
|
||||||
|
test/unittests/unit_preallocable
|
||||||
|
test/unittests/unit_rand
|
||||||
|
unicorn_mode/samples/*/output/
|
||||||
|
unicorn_mode/samples/*/\.test-*
|
||||||
|
utils/afl_network_proxy/afl-network-client
|
||||||
|
utils/afl_network_proxy/afl-network-server
|
||||||
|
utils/afl_proxy/afl-proxy
|
||||||
|
utils/bench/hash
|
||||||
|
utils/optimin/build
|
||||||
|
utils/optimin/optimin
|
||||||
|
utils/persistent_mode/persistent_demo
|
||||||
|
utils/persistent_mode/persistent_demo_new
|
||||||
|
utils/persistent_mode/persistent_demo_new_compat
|
||||||
|
utils/persistent_mode/test-instr
|
||||||
|
utils/replay_record/persistent_demo_replay
|
||||||
|
utils/replay_record/persistent_demo_replay_compat
|
||||||
|
utils/replay_record/persistent_demo_replay_argparse
|
||||||
|
utils/plot_ui/afl-plot-ui
|
||||||
|
vuln_prog
|
||||||
|
argv_fuzz_demo
|
||||||
|
argv_fuzz_persistent_demo
|
@ -0,0 +1,27 @@
|
|||||||
|
[submodule "unicorn_mode/unicornafl"]
|
||||||
|
path = unicorn_mode/unicornafl
|
||||||
|
url = https://github.com/AFLplusplus/unicornafl
|
||||||
|
[submodule "custom_mutators/grammar_mutator"]
|
||||||
|
path = custom_mutators/grammar_mutator/grammar_mutator
|
||||||
|
url = https://github.com/AFLplusplus/Grammar-Mutator
|
||||||
|
[submodule "qemu_mode/qemuafl"]
|
||||||
|
path = qemu_mode/qemuafl
|
||||||
|
url = https://github.com/AFLplusplus/qemuafl
|
||||||
|
[submodule "custom_mutators/gramatron/json-c"]
|
||||||
|
path = custom_mutators/gramatron/json-c
|
||||||
|
url = https://github.com/json-c/json-c
|
||||||
|
[submodule "coresight_mode/patchelf"]
|
||||||
|
path = coresight_mode/patchelf
|
||||||
|
url = https://github.com/NixOS/patchelf.git
|
||||||
|
[submodule "coresight_mode/coresight-trace"]
|
||||||
|
path = coresight_mode/coresight-trace
|
||||||
|
url = https://github.com/RICSecLab/coresight-trace.git
|
||||||
|
[submodule "nyx_mode/libnyx"]
|
||||||
|
path = nyx_mode/libnyx
|
||||||
|
url = https://github.com/nyx-fuzz/libnyx.git
|
||||||
|
[submodule "nyx_mode/packer"]
|
||||||
|
path = nyx_mode/packer
|
||||||
|
url = https://github.com/nyx-fuzz/packer.git
|
||||||
|
[submodule "nyx_mode/QEMU-Nyx"]
|
||||||
|
path = nyx_mode/QEMU-Nyx
|
||||||
|
url = https://github.com/nyx-fuzz/QEMU-Nyx
|
@ -0,0 +1,419 @@
|
|||||||
|
//
|
||||||
|
// NOTE: This file is outdated. None of the AFL++ team uses Android hence
|
||||||
|
// we need users to keep this updated.
|
||||||
|
// In the current state it will likely fail, please send fixes!
|
||||||
|
// Also, this should build frida_mode.
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
cc_defaults {
|
||||||
|
name: "afl-defaults",
|
||||||
|
|
||||||
|
local_include_dirs: [
|
||||||
|
"include",
|
||||||
|
"instrumentation",
|
||||||
|
],
|
||||||
|
|
||||||
|
cflags: [
|
||||||
|
"-flto=full",
|
||||||
|
"-funroll-loops",
|
||||||
|
"-Wno-pointer-sign",
|
||||||
|
"-Wno-pointer-arith",
|
||||||
|
"-Wno-sign-compare",
|
||||||
|
"-Wno-unused-parameter",
|
||||||
|
"-Wno-unused-function",
|
||||||
|
"-Wno-format",
|
||||||
|
"-Wno-user-defined-warnings",
|
||||||
|
"-DAFL_LLVM_USE_TRACE_PC=1",
|
||||||
|
"-DBIN_PATH=\"out/host/linux-x86/bin\"",
|
||||||
|
"-DDOC_PATH=\"out/host/linux-x86/shared/doc/afl\"",
|
||||||
|
"-D__USE_GNU",
|
||||||
|
"-DDEBUG_BUILD",
|
||||||
|
"-U_FORTIFY_SOURCE",
|
||||||
|
"-ggdb3",
|
||||||
|
"-g",
|
||||||
|
"-O0",
|
||||||
|
"-fno-omit-frame-pointer",
|
||||||
|
"-fPIC",
|
||||||
|
],
|
||||||
|
|
||||||
|
target: {
|
||||||
|
android_arm64: {
|
||||||
|
cflags: [
|
||||||
|
"-D__ANDROID__",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
android_arm: {
|
||||||
|
cflags: [
|
||||||
|
"-D__ANDROID__",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
android_x86_64: {
|
||||||
|
cflags: [
|
||||||
|
"-D__ANDROID__",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
android_x86: {
|
||||||
|
cflags: [
|
||||||
|
"-D__ANDROID__",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
cc_binary {
|
||||||
|
name: "afl-fuzz",
|
||||||
|
sanitize: {
|
||||||
|
never: true,
|
||||||
|
},
|
||||||
|
host_supported: true,
|
||||||
|
compile_multilib: "64",
|
||||||
|
|
||||||
|
defaults: [
|
||||||
|
"afl-defaults",
|
||||||
|
],
|
||||||
|
|
||||||
|
srcs: [
|
||||||
|
"src/afl-fuzz*.c",
|
||||||
|
"src/afl-common.c",
|
||||||
|
"src/afl-forkserver.c",
|
||||||
|
"src/afl-sharedmem.c",
|
||||||
|
"src/afl-forkserver.c",
|
||||||
|
"src/afl-performance.c",
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
cc_binary {
|
||||||
|
name: "afl-showmap",
|
||||||
|
static_executable: true,
|
||||||
|
host_supported: true,
|
||||||
|
|
||||||
|
defaults: [
|
||||||
|
"afl-defaults",
|
||||||
|
],
|
||||||
|
|
||||||
|
srcs: [
|
||||||
|
"src/afl-showmap.c",
|
||||||
|
"src/afl-common.c",
|
||||||
|
"src/afl-sharedmem.c",
|
||||||
|
"src/afl-forkserver.c",
|
||||||
|
"src/afl-performance.c",
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
cc_binary {
|
||||||
|
name: "afl-tmin",
|
||||||
|
static_executable: true,
|
||||||
|
host_supported: true,
|
||||||
|
|
||||||
|
defaults: [
|
||||||
|
"afl-defaults",
|
||||||
|
],
|
||||||
|
|
||||||
|
srcs: [
|
||||||
|
"src/afl-tmin.c",
|
||||||
|
"src/afl-common.c",
|
||||||
|
"src/afl-sharedmem.c",
|
||||||
|
"src/afl-forkserver.c",
|
||||||
|
"src/afl-performance.c",
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
cc_binary {
|
||||||
|
name: "afl-analyze",
|
||||||
|
static_executable: true,
|
||||||
|
host_supported: true,
|
||||||
|
|
||||||
|
defaults: [
|
||||||
|
"afl-defaults",
|
||||||
|
],
|
||||||
|
|
||||||
|
srcs: [
|
||||||
|
"src/afl-analyze.c",
|
||||||
|
"src/afl-common.c",
|
||||||
|
"src/afl-sharedmem.c",
|
||||||
|
"src/afl-performance.c",
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
cc_binary {
|
||||||
|
name: "afl-gotcpu",
|
||||||
|
static_executable: true,
|
||||||
|
host_supported: true,
|
||||||
|
|
||||||
|
defaults: [
|
||||||
|
"afl-defaults",
|
||||||
|
],
|
||||||
|
|
||||||
|
srcs: [
|
||||||
|
"src/afl-gotcpu.c",
|
||||||
|
"src/afl-common.c",
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
cc_binary_host {
|
||||||
|
name: "afl-cc",
|
||||||
|
static_executable: true,
|
||||||
|
|
||||||
|
defaults: [
|
||||||
|
"afl-defaults",
|
||||||
|
],
|
||||||
|
|
||||||
|
cflags: [
|
||||||
|
"-DAFL_PATH=\"out/host/linux-x86/lib64\"",
|
||||||
|
"-DAFL_CLANG_FLTO=\"-flto=full\"",
|
||||||
|
"-DUSE_BINDIR=1",
|
||||||
|
"-DLLVM_BINDIR=\"prebuilts/clang/host/linux-x86/clang-r383902b/bin\"",
|
||||||
|
"-DLLVM_LIBDIR=\"prebuilts/clang/host/linux-x86/clang-r383902b/lib64\"",
|
||||||
|
"-DCLANGPP_BIN=\"prebuilts/clang/host/linux-x86/clang-r383902b/bin/clang++\"",
|
||||||
|
"-DAFL_REAL_LD=\"prebuilts/clang/host/linux-x86/clang-r383902b/bin/ld.lld\"",
|
||||||
|
"-DLLVM_LTO=1",
|
||||||
|
"-DLLVM_MAJOR=11",
|
||||||
|
"-DLLVM_MINOR=2",
|
||||||
|
],
|
||||||
|
|
||||||
|
srcs: [
|
||||||
|
"src/afl-cc.c",
|
||||||
|
"src/afl-common.c",
|
||||||
|
],
|
||||||
|
|
||||||
|
symlinks: [
|
||||||
|
"afl-clang-fast",
|
||||||
|
"afl-clang-fast++",
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
cc_library_static {
|
||||||
|
name: "afl-compiler-rt",
|
||||||
|
compile_multilib: "64",
|
||||||
|
vendor_available: true,
|
||||||
|
host_supported: true,
|
||||||
|
recovery_available: true,
|
||||||
|
sdk_version: "9",
|
||||||
|
|
||||||
|
apex_available: [
|
||||||
|
"com.android.adbd",
|
||||||
|
"com.android.appsearch",
|
||||||
|
"com.android.art",
|
||||||
|
"com.android.bluetooth.updatable",
|
||||||
|
"com.android.cellbroadcast",
|
||||||
|
"com.android.conscrypt",
|
||||||
|
"com.android.extservices",
|
||||||
|
"com.android.cronet",
|
||||||
|
"com.android.neuralnetworks",
|
||||||
|
"com.android.media",
|
||||||
|
"com.android.media.swcodec",
|
||||||
|
"com.android.mediaprovider",
|
||||||
|
"com.android.permission",
|
||||||
|
"com.android.runtime",
|
||||||
|
"com.android.resolv",
|
||||||
|
"com.android.tethering",
|
||||||
|
"com.android.wifi",
|
||||||
|
"com.android.sdkext",
|
||||||
|
"com.android.os.statsd",
|
||||||
|
"//any",
|
||||||
|
],
|
||||||
|
|
||||||
|
defaults: [
|
||||||
|
"afl-defaults",
|
||||||
|
],
|
||||||
|
|
||||||
|
srcs: [
|
||||||
|
"instrumentation/afl-compiler-rt.o.c",
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
cc_library_headers {
|
||||||
|
name: "libafl_headers",
|
||||||
|
vendor_available: true,
|
||||||
|
host_supported: true,
|
||||||
|
|
||||||
|
export_include_dirs: [
|
||||||
|
"include",
|
||||||
|
"instrumentation",
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
cc_prebuilt_library_static {
|
||||||
|
name: "libfrida-gum",
|
||||||
|
compile_multilib: "64",
|
||||||
|
strip: {
|
||||||
|
none: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
srcs: [
|
||||||
|
"utils/afl_frida/android/libfrida-gum.a",
|
||||||
|
],
|
||||||
|
|
||||||
|
export_include_dirs: [
|
||||||
|
"utils/afl_frida/android",
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
cc_library_shared {
|
||||||
|
name: "libtestinstr",
|
||||||
|
|
||||||
|
srcs: [
|
||||||
|
"utils/afl_frida/libtestinstr.c",
|
||||||
|
],
|
||||||
|
|
||||||
|
cflags: [
|
||||||
|
"-O0",
|
||||||
|
"-fPIC",
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
cc_binary {
|
||||||
|
name: "afl-frida",
|
||||||
|
compile_multilib: "64",
|
||||||
|
|
||||||
|
defaults: [
|
||||||
|
"afl-defaults",
|
||||||
|
],
|
||||||
|
|
||||||
|
cflags: [
|
||||||
|
"-g",
|
||||||
|
"-O0",
|
||||||
|
"-Wno-format",
|
||||||
|
"-Wno-pointer-sign",
|
||||||
|
"-fpermissive",
|
||||||
|
"-fPIC",
|
||||||
|
],
|
||||||
|
|
||||||
|
static_libs: [
|
||||||
|
"afl-compiler-rt",
|
||||||
|
"libfrida-gum",
|
||||||
|
],
|
||||||
|
|
||||||
|
shared_libs: [
|
||||||
|
"libdl",
|
||||||
|
"liblog",
|
||||||
|
],
|
||||||
|
|
||||||
|
srcs: [
|
||||||
|
"utils/afl_frida/afl-frida.c",
|
||||||
|
],
|
||||||
|
|
||||||
|
local_include_dirs: [
|
||||||
|
"utils/afl_frida",
|
||||||
|
"utils/afl_frida/android",
|
||||||
|
],
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
cc_binary {
|
||||||
|
name: "afl-fuzz-32",
|
||||||
|
sanitize: {
|
||||||
|
never: true,
|
||||||
|
},
|
||||||
|
host_supported: true,
|
||||||
|
compile_multilib: "32",
|
||||||
|
|
||||||
|
defaults: [
|
||||||
|
"afl-defaults",
|
||||||
|
],
|
||||||
|
|
||||||
|
srcs: [
|
||||||
|
"src/afl-fuzz*.c",
|
||||||
|
"src/afl-common.c",
|
||||||
|
"src/afl-sharedmem.c",
|
||||||
|
"src/afl-forkserver.c",
|
||||||
|
"src/afl-performance.c",
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
cc_binary_host {
|
||||||
|
name: "afl-cc-32",
|
||||||
|
compile_multilib: "32",
|
||||||
|
static_executable: true,
|
||||||
|
|
||||||
|
defaults: [
|
||||||
|
"afl-defaults",
|
||||||
|
],
|
||||||
|
|
||||||
|
cflags: [
|
||||||
|
"-DAFL_PATH=\"out/host/linux-x86/lib64\"",
|
||||||
|
"-DAFL_CLANG_FLTO=\"-flto=full\"",
|
||||||
|
"-DUSE_BINDIR=1",
|
||||||
|
"-DLLVM_BINDIR=\"prebuilts/clang/host/linux-x86/clang-r383902b/bin\"",
|
||||||
|
"-DLLVM_LIBDIR=\"prebuilts/clang/host/linux-x86/clang-r383902b/lib64\"",
|
||||||
|
"-DCLANGPP_BIN=\"prebuilts/clang/host/linux-x86/clang-r383902b/bin/clang++\"",
|
||||||
|
"-DAFL_REAL_LD=\"prebuilts/clang/host/linux-x86/clang-r383902b/bin/ld.lld\"",
|
||||||
|
"-DLLVM_LTO=1",
|
||||||
|
"-DLLVM_MAJOR=11",
|
||||||
|
"-DLLVM_MINOR=2",
|
||||||
|
],
|
||||||
|
|
||||||
|
srcs: [
|
||||||
|
"src/afl-cc.c",
|
||||||
|
"src/afl-common.c",
|
||||||
|
],
|
||||||
|
|
||||||
|
symlinks: [
|
||||||
|
"afl-clang-fast-32",
|
||||||
|
"afl-clang-fast++-32",
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
cc_library_static {
|
||||||
|
name: "afl-compiler-rt-32",
|
||||||
|
compile_multilib: "32",
|
||||||
|
vendor_available: true,
|
||||||
|
host_supported: true,
|
||||||
|
recovery_available: true,
|
||||||
|
sdk_version: "9",
|
||||||
|
|
||||||
|
apex_available: [
|
||||||
|
"com.android.adbd",
|
||||||
|
"com.android.appsearch",
|
||||||
|
"com.android.art",
|
||||||
|
"com.android.bluetooth.updatable",
|
||||||
|
"com.android.cellbroadcast",
|
||||||
|
"com.android.conscrypt",
|
||||||
|
"com.android.extservices",
|
||||||
|
"com.android.cronet",
|
||||||
|
"com.android.neuralnetworks",
|
||||||
|
"com.android.media",
|
||||||
|
"com.android.media.swcodec",
|
||||||
|
"com.android.mediaprovider",
|
||||||
|
"com.android.permission",
|
||||||
|
"com.android.runtime",
|
||||||
|
"com.android.resolv",
|
||||||
|
"com.android.tethering",
|
||||||
|
"com.android.wifi",
|
||||||
|
"com.android.sdkext",
|
||||||
|
"com.android.os.statsd",
|
||||||
|
"//any",
|
||||||
|
],
|
||||||
|
|
||||||
|
defaults: [
|
||||||
|
"afl-defaults",
|
||||||
|
],
|
||||||
|
|
||||||
|
srcs: [
|
||||||
|
"instrumentation/afl-compiler-rt.o.c",
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
cc_prebuilt_library_static {
|
||||||
|
name: "libfrida-gum-32",
|
||||||
|
compile_multilib: "32",
|
||||||
|
strip: {
|
||||||
|
none: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
srcs: [
|
||||||
|
"utils/afl_frida/android/arm/libfrida-gum.a",
|
||||||
|
],
|
||||||
|
|
||||||
|
export_include_dirs: [
|
||||||
|
"utils/afl_frida/android/arm",
|
||||||
|
],
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
subdirs = [
|
||||||
|
"custom_mutators",
|
||||||
|
]
|
@ -0,0 +1,31 @@
|
|||||||
|
cff-version: 1.2.0
|
||||||
|
message: "If you use this software, please cite it as below."
|
||||||
|
authors:
|
||||||
|
- given-names: Marc
|
||||||
|
family-names: Heuse
|
||||||
|
email: mh@mh-sec.de
|
||||||
|
- given-names: Heiko
|
||||||
|
family-names: Eißfeldt
|
||||||
|
email: heiko.eissfeldt@hexco.de
|
||||||
|
- given-names: Andrea
|
||||||
|
family-names: Fioraldi
|
||||||
|
email: andreafioraldi@gmail.com
|
||||||
|
- given-names: Dominik
|
||||||
|
family-names: Maier
|
||||||
|
email: mail@dmnk.co
|
||||||
|
title: "AFL++"
|
||||||
|
version: 4.00c
|
||||||
|
type: software
|
||||||
|
date-released: 2022-01-26
|
||||||
|
url: "https://github.com/AFLplusplus/AFLplusplus"
|
||||||
|
keywords:
|
||||||
|
- fuzzing
|
||||||
|
- fuzzer
|
||||||
|
- fuzz-testing
|
||||||
|
- instrumentation
|
||||||
|
- afl-fuzz
|
||||||
|
- qemu
|
||||||
|
- llvm
|
||||||
|
- unicorn-emulator
|
||||||
|
- security
|
||||||
|
license: AGPL-3.0-or-later
|
@ -0,0 +1,60 @@
|
|||||||
|
# Contributing to AFL++
|
||||||
|
|
||||||
|
## How to submit a pull request
|
||||||
|
|
||||||
|
All contributions (pull requests) must be made against our `dev` branch.
|
||||||
|
|
||||||
|
Each modified source file, before merging, must be formatted.
|
||||||
|
|
||||||
|
```
|
||||||
|
make code-format
|
||||||
|
```
|
||||||
|
|
||||||
|
This should be fine if you modified one of the files already present in the
|
||||||
|
project, or added a file in a directory we already format, otherwise run:
|
||||||
|
|
||||||
|
```
|
||||||
|
./.custom-format.py -i file-that-you-have-created.c
|
||||||
|
```
|
||||||
|
|
||||||
|
Regarding the coding style, please follow the AFL style. No camel case at all
|
||||||
|
and use AFL's macros wherever possible (e.g., WARNF, FATAL, MAP_SIZE, ...).
|
||||||
|
|
||||||
|
Remember that AFL++ has to build and run on many platforms, so generalize your
|
||||||
|
Makefiles/GNUmakefile (or your patches to our pre-existing Makefiles) to be as
|
||||||
|
generic as possible.
|
||||||
|
|
||||||
|
## How to contribute to the docs
|
||||||
|
|
||||||
|
We welcome contributions to our docs.
|
||||||
|
|
||||||
|
Before creating a new file, please check if your content matches an existing
|
||||||
|
file in one the following folders:
|
||||||
|
|
||||||
|
* [docs/](docs/) (this is where you can find most of our docs content)
|
||||||
|
* [frida_mode/](frida_mode/)
|
||||||
|
* [instrumentation/](instrumentation/)
|
||||||
|
* [nyx_mode/](nyx_mode/)
|
||||||
|
* [qemu_mode/](qemu_mode/)
|
||||||
|
* [unicorn_mode/](unicorn_mode/)
|
||||||
|
|
||||||
|
When working on the docs, please keep the following guidelines in mind:
|
||||||
|
|
||||||
|
* Edit or create Markdown files and use Markdown markup.
|
||||||
|
* Do: fuzzing_gui_program.md
|
||||||
|
* Don't: fuzzing_gui_program.txt
|
||||||
|
* Use underscore in file names.
|
||||||
|
* Do: fuzzing_network_service.md
|
||||||
|
* Don't: fuzzing-network-service.md
|
||||||
|
* Use a maximum of 80 characters per line to make reading in a console easier.
|
||||||
|
* Make all pull requests against `dev`, see
|
||||||
|
[#how-to-submit-a-pull-request](#how-to-submit-a-pull-request).
|
||||||
|
|
||||||
|
And finally, here are some best practices for writing docs content:
|
||||||
|
|
||||||
|
* Use clear and simple language.
|
||||||
|
* Structure your content with headings and paragraphs.
|
||||||
|
* Use bulleted lists to present similar content in a way that makes it easy to
|
||||||
|
scan.
|
||||||
|
* Use numbered lists for procedures or prioritizing.
|
||||||
|
* Link to related content, for example, prerequisites or in-depth discussions.
|
@ -0,0 +1 @@
|
|||||||
|
docs/Changelog.md
|
@ -0,0 +1,97 @@
|
|||||||
|
#
|
||||||
|
# This Dockerfile for AFLplusplus uses Ubuntu 22.04 jammy and
|
||||||
|
# installs LLVM 14 for afl-clang-lto support.
|
||||||
|
#
|
||||||
|
# GCC 11 is used instead of 12 because genhtml for afl-cov doesn't like it.
|
||||||
|
#
|
||||||
|
|
||||||
|
FROM ubuntu:22.04 AS aflplusplus
|
||||||
|
LABEL "maintainer"="AFL++ team <afl@aflplus.plus>"
|
||||||
|
LABEL "about"="AFLplusplus container image"
|
||||||
|
|
||||||
|
### Comment out to enable these features
|
||||||
|
# Only available on specific ARM64 boards
|
||||||
|
ENV NO_CORESIGHT=1
|
||||||
|
# Possible but unlikely in a docker container
|
||||||
|
ENV NO_NYX=1
|
||||||
|
|
||||||
|
### Only change these if you know what you are doing:
|
||||||
|
# Current recommended LLVM version is 16
|
||||||
|
ENV LLVM_VERSION=16
|
||||||
|
# GCC 12 is producing compile errors for some targets so we stay at GCC 11
|
||||||
|
ENV GCC_VERSION=11
|
||||||
|
|
||||||
|
### No changes beyond the point unless you know what you are doing :)
|
||||||
|
|
||||||
|
ARG DEBIAN_FRONTEND=noninteractive
|
||||||
|
|
||||||
|
ENV NO_ARCH_OPT=1
|
||||||
|
ENV IS_DOCKER=1
|
||||||
|
|
||||||
|
RUN apt-get update && apt-get full-upgrade -y && \
|
||||||
|
apt-get install -y --no-install-recommends wget ca-certificates apt-utils && \
|
||||||
|
rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
RUN echo "deb [signed-by=/etc/apt/keyrings/llvm-snapshot.gpg.key] http://apt.llvm.org/jammy/ llvm-toolchain-jammy-${LLVM_VERSION} main" > /etc/apt/sources.list.d/llvm.list && \
|
||||||
|
wget -qO /etc/apt/keyrings/llvm-snapshot.gpg.key https://apt.llvm.org/llvm-snapshot.gpg.key
|
||||||
|
|
||||||
|
RUN apt-get update && \
|
||||||
|
apt-get -y install --no-install-recommends \
|
||||||
|
make cmake automake meson ninja-build bison flex \
|
||||||
|
git xz-utils bzip2 wget jupp nano bash-completion less vim joe ssh psmisc \
|
||||||
|
python3 python3-dev python3-pip python-is-python3 \
|
||||||
|
libtool libtool-bin libglib2.0-dev \
|
||||||
|
apt-transport-https gnupg dialog \
|
||||||
|
gnuplot-nox libpixman-1-dev bc \
|
||||||
|
gcc-${GCC_VERSION} g++-${GCC_VERSION} gcc-${GCC_VERSION}-plugin-dev gdb lcov \
|
||||||
|
clang-${LLVM_VERSION} clang-tools-${LLVM_VERSION} libc++1-${LLVM_VERSION} \
|
||||||
|
libc++-${LLVM_VERSION}-dev libc++abi1-${LLVM_VERSION} libc++abi-${LLVM_VERSION}-dev \
|
||||||
|
libclang1-${LLVM_VERSION} libclang-${LLVM_VERSION}-dev \
|
||||||
|
libclang-common-${LLVM_VERSION}-dev libclang-rt-${LLVM_VERSION}-dev libclang-cpp${LLVM_VERSION} \
|
||||||
|
libclang-cpp${LLVM_VERSION}-dev liblld-${LLVM_VERSION} \
|
||||||
|
liblld-${LLVM_VERSION}-dev liblldb-${LLVM_VERSION} liblldb-${LLVM_VERSION}-dev \
|
||||||
|
libllvm${LLVM_VERSION} libomp-${LLVM_VERSION}-dev libomp5-${LLVM_VERSION} \
|
||||||
|
lld-${LLVM_VERSION} lldb-${LLVM_VERSION} llvm-${LLVM_VERSION} \
|
||||||
|
llvm-${LLVM_VERSION}-dev llvm-${LLVM_VERSION}-runtime llvm-${LLVM_VERSION}-tools \
|
||||||
|
$([ "$(dpkg --print-architecture)" = "amd64" ] && echo gcc-${GCC_VERSION}-multilib gcc-multilib) \
|
||||||
|
$([ "$(dpkg --print-architecture)" = "arm64" ] && echo libcapstone-dev) && \
|
||||||
|
rm -rf /var/lib/apt/lists/*
|
||||||
|
# gcc-multilib is only used for -m32 support on x86
|
||||||
|
# libcapstone-dev is used for coresight_mode on arm64
|
||||||
|
|
||||||
|
RUN update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-${GCC_VERSION} 0 && \
|
||||||
|
update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-${GCC_VERSION} 0 && \
|
||||||
|
update-alternatives --install /usr/bin/clang clang /usr/bin/clang-${LLVM_VERSION} 0 && \
|
||||||
|
update-alternatives --install /usr/bin/clang++ clang++ /usr/bin/clang++-${LLVM_VERSION} 0
|
||||||
|
|
||||||
|
RUN wget -qO- https://sh.rustup.rs | CARGO_HOME=/etc/cargo sh -s -- -y -q --no-modify-path
|
||||||
|
ENV PATH=$PATH:/etc/cargo/bin
|
||||||
|
|
||||||
|
RUN apt clean -y
|
||||||
|
|
||||||
|
ENV LLVM_CONFIG=llvm-config-${LLVM_VERSION}
|
||||||
|
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 && \
|
||||||
|
(cd afl-cov && make install) && rm -rf afl-cov
|
||||||
|
|
||||||
|
WORKDIR /AFLplusplus
|
||||||
|
COPY . .
|
||||||
|
|
||||||
|
ARG CC=gcc-$GCC_VERSION
|
||||||
|
ARG CXX=g++-$GCC_VERSION
|
||||||
|
|
||||||
|
# Used in CI to prevent a 'make clean' which would remove the binaries to be tested
|
||||||
|
ARG TEST_BUILD
|
||||||
|
|
||||||
|
RUN sed -i.bak 's/^ -/ /g' GNUmakefile && \
|
||||||
|
make clean && make distrib && \
|
||||||
|
([ "${TEST_BUILD}" ] || (make install)) && \
|
||||||
|
mv GNUmakefile.bak GNUmakefile
|
||||||
|
|
||||||
|
RUN echo "set encoding=utf-8" > /root/.vimrc && \
|
||||||
|
echo ". /etc/bash_completion" >> ~/.bashrc && \
|
||||||
|
echo 'alias joe="joe --wordwrap --joe_state -nobackup"' >> ~/.bashrc && \
|
||||||
|
echo "export PS1='"'[AFL++ \h] \w \$ '"'" >> ~/.bashrc
|
@ -0,0 +1,848 @@
|
|||||||
|
#
|
||||||
|
# american fuzzy lop++ - makefile
|
||||||
|
# -----------------------------
|
||||||
|
#
|
||||||
|
# Originally written by Michal Zalewski
|
||||||
|
#
|
||||||
|
# Copyright 2013, 2014, 2015, 2016, 2017 Google Inc. 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:
|
||||||
|
#
|
||||||
|
# https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
|
||||||
|
# For Heiko:
|
||||||
|
#TEST_MMAP=1
|
||||||
|
# the hash character is treated differently in different make versions
|
||||||
|
# so use a variable for '#'
|
||||||
|
HASH=\#
|
||||||
|
|
||||||
|
PREFIX ?= /usr/local
|
||||||
|
BIN_PATH = $(PREFIX)/bin
|
||||||
|
HELPER_PATH = $(PREFIX)/lib/afl
|
||||||
|
DOC_PATH = $(PREFIX)/share/doc/afl
|
||||||
|
MISC_PATH = $(PREFIX)/share/afl
|
||||||
|
MAN_PATH = $(PREFIX)/share/man/man8
|
||||||
|
|
||||||
|
PROGNAME = afl
|
||||||
|
VERSION = $(shell grep '^$(HASH)define VERSION ' ../config.h | cut -d '"' -f2)
|
||||||
|
|
||||||
|
# PROGS intentionally omit afl-as, which gets installed elsewhere.
|
||||||
|
|
||||||
|
PROGS = afl-fuzz afl-showmap afl-tmin afl-gotcpu afl-analyze
|
||||||
|
SH_PROGS = afl-plot afl-cmin afl-cmin.bash afl-whatsup afl-addseeds afl-system-config afl-persistent-config afl-cc
|
||||||
|
MANPAGES=$(foreach p, $(PROGS) $(SH_PROGS), $(p).8) afl-as.8
|
||||||
|
ASAN_OPTIONS=detect_leaks=0
|
||||||
|
|
||||||
|
SYS = $(shell uname -s)
|
||||||
|
ARCH = $(shell uname -m)
|
||||||
|
|
||||||
|
$(info [*] Compiling AFL++ for OS $(SYS) on ARCH $(ARCH))
|
||||||
|
|
||||||
|
ifdef NO_SPLICING
|
||||||
|
override CFLAGS_OPT += -DNO_SPLICING
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifdef NO_UTF
|
||||||
|
override CFLAGS_OPT += -DFANCY_BOXES_NO_UTF
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifdef ASAN_BUILD
|
||||||
|
$(info Compiling ASAN version of binaries)
|
||||||
|
override CFLAGS += $(ASAN_CFLAGS)
|
||||||
|
override LDFLAGS += $(ASAN_LDFLAGS)
|
||||||
|
endif
|
||||||
|
ifdef UBSAN_BUILD
|
||||||
|
$(info Compiling UBSAN version of binaries)
|
||||||
|
override CFLAGS += -fsanitize=undefined -fno-omit-frame-pointer
|
||||||
|
override LDFLAGS += -fsanitize=undefined
|
||||||
|
endif
|
||||||
|
ifdef MSAN_BUILD
|
||||||
|
$(info Compiling MSAN version of binaries)
|
||||||
|
CC := clang
|
||||||
|
override CFLAGS += -fsanitize=memory -fno-omit-frame-pointer
|
||||||
|
override LDFLAGS += -fsanitize=memory
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifdef CODE_COVERAGE
|
||||||
|
override CFLAGS += -D__AFL_CODE_COVERAGE=1
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq "$(findstring android, $(shell $(CC) --version 2>/dev/null))" ""
|
||||||
|
ifeq "$(shell echo 'int main() {return 0; }' | $(CC) $(CFLAGS) -Werror -x c - -flto=full -o .test 2>/dev/null && echo 1 || echo 0 ; rm -f .test )" "1"
|
||||||
|
CFLAGS_FLTO ?= -flto=full
|
||||||
|
else
|
||||||
|
ifeq "$(shell echo 'int main() {return 0; }' | $(CC) $(CFLAGS) -Werror -x c - -flto=thin -o .test 2>/dev/null && echo 1 || echo 0 ; rm -f .test )" "1"
|
||||||
|
CFLAGS_FLTO ?= -flto=thin
|
||||||
|
else
|
||||||
|
ifeq "$(shell echo 'int main() {return 0; }' | $(CC) $(CFLAGS) -Werror -x c - -flto -o .test 2>/dev/null && echo 1 || echo 0 ; rm -f .test )" "1"
|
||||||
|
CFLAGS_FLTO ?= -flto
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifdef PERFORMANCE
|
||||||
|
SPECIAL_PERFORMANCE := -D_AFL_SPECIAL_PERFORMANCE
|
||||||
|
ifeq "$(SYS)" "Linux"
|
||||||
|
ifeq "$(shell grep avx2 /proc/cpuinfo)" ""
|
||||||
|
else
|
||||||
|
SPECIAL_PERFORMANCE += -mavx2 -D_HAVE_AVX2
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
ifeq "$(shell echo 'int main() {return 0; }' | $(CC) $(CFLAGS) -Werror -x c - -march=native -o .test 2>/dev/null && echo 1 || echo 0 ; rm -f .test )" "1"
|
||||||
|
HAVE_MARCHNATIVE = 1
|
||||||
|
SPECIAL_PERFORMANCE += -march=native
|
||||||
|
endif
|
||||||
|
$(info SPECIAL_PERFORMANCE=$(SPECIAL_PERFORMANCE))
|
||||||
|
else
|
||||||
|
SPECIAL_PERFORMANCE :=
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifneq "$(SYS)" "Darwin"
|
||||||
|
#ifeq "$(HAVE_MARCHNATIVE)" "1"
|
||||||
|
# SPECIAL_PERFORMANCE += -march=native
|
||||||
|
#endif
|
||||||
|
#ifndef DEBUG
|
||||||
|
# override CFLAGS_OPT += -D_FORTIFY_SOURCE=1
|
||||||
|
#endif
|
||||||
|
else
|
||||||
|
# On some odd MacOS system configurations, the Xcode sdk path is not set correctly
|
||||||
|
SDK_LD = -L$(shell xcrun --show-sdk-path)/usr/lib
|
||||||
|
override LDFLAGS += $(SDK_LD)
|
||||||
|
endif
|
||||||
|
|
||||||
|
COMPILER_TYPE=$(shell $(CC) --version|grep "Free Software Foundation")
|
||||||
|
ifneq "$(COMPILER_TYPE)" ""
|
||||||
|
#$(info gcc is being used)
|
||||||
|
override CFLAGS_OPT += -Wno-error=format-truncation -Wno-format-truncation
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq "$(SYS)" "SunOS"
|
||||||
|
override LDFLAGS = -lkstat -lrt -lsocket -lnsl
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifdef STATIC
|
||||||
|
$(info Compiling static version of binaries, disabling python though)
|
||||||
|
# Disable python for static compilation to simplify things
|
||||||
|
PYTHON_OK = 0
|
||||||
|
PYFLAGS=
|
||||||
|
PYTHON_INCLUDE = /
|
||||||
|
|
||||||
|
override CFLAGS_OPT += -static
|
||||||
|
override LDFLAGS += -lm -lpthread -lz -lutil
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifdef PROFILING
|
||||||
|
$(info Compiling with profiling information, for analysis: gprof ./afl-fuzz gmon.out > prof.txt)
|
||||||
|
override CFLAGS_OPT += -pg -DPROFILING=1
|
||||||
|
override LDFLAGS += -pg
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifdef INTROSPECTION
|
||||||
|
$(info Compiling with introspection documentation)
|
||||||
|
override CFLAGS_OPT += -DINTROSPECTION=1
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifneq "$(ARCH)" "x86_64"
|
||||||
|
ifneq "$(patsubst i%86,i386,$(ARCH))" "i386"
|
||||||
|
ifneq "$(ARCH)" "amd64"
|
||||||
|
ifneq "$(ARCH)" "i86pc"
|
||||||
|
AFL_NO_X86=1
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifdef DEBUG
|
||||||
|
$(info Compiling DEBUG version of binaries)
|
||||||
|
override CFLAGS += -ggdb3 -O0 -Wall -Wextra -Werror $(CFLAGS_OPT)
|
||||||
|
else
|
||||||
|
CFLAGS ?= -O2 $(CFLAGS_OPT) # -funroll-loops is slower on modern compilers
|
||||||
|
endif
|
||||||
|
|
||||||
|
override CFLAGS += -g -Wno-pointer-sign -Wno-variadic-macros -Wall -Wextra -Wno-pointer-arith \
|
||||||
|
-fPIC -I include/ -DAFL_PATH=\"$(HELPER_PATH)\" \
|
||||||
|
-DBIN_PATH=\"$(BIN_PATH)\" -DDOC_PATH=\"$(DOC_PATH)\"
|
||||||
|
# -fstack-protector
|
||||||
|
|
||||||
|
ifeq "$(SYS)" "FreeBSD"
|
||||||
|
override CFLAGS += -I /usr/local/include/
|
||||||
|
override LDFLAGS += -L /usr/local/lib/
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq "$(SYS)" "DragonFly"
|
||||||
|
override CFLAGS += -I /usr/local/include/
|
||||||
|
override LDFLAGS += -L /usr/local/lib/
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq "$(SYS)" "OpenBSD"
|
||||||
|
override CFLAGS += -I /usr/local/include/ -mno-retpoline
|
||||||
|
override LDFLAGS += -Wl,-z,notext -L /usr/local/lib/
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq "$(SYS)" "NetBSD"
|
||||||
|
override CFLAGS += -I /usr/pkg/include/
|
||||||
|
override LDFLAGS += -L /usr/pkg/lib/
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq "$(SYS)" "Haiku"
|
||||||
|
SHMAT_OK=0
|
||||||
|
override CFLAGS += -DUSEMMAP=1 -Wno-error=format
|
||||||
|
override LDFLAGS += -Wno-deprecated-declarations -lgnu -lnetwork
|
||||||
|
#SPECIAL_PERFORMANCE += -DUSEMMAP=1
|
||||||
|
endif
|
||||||
|
|
||||||
|
AFL_FUZZ_FILES = $(wildcard src/afl-fuzz*.c)
|
||||||
|
|
||||||
|
ifneq "$(shell command -v python3m 2>/dev/null)" ""
|
||||||
|
ifneq "$(shell command -v python3m-config 2>/dev/null)" ""
|
||||||
|
PYTHON_INCLUDE := $(shell python3m-config --includes)
|
||||||
|
PYTHON_VERSION := $(strip $(shell python3m --version 2>&1))
|
||||||
|
# Starting with python3.8, we need to pass the `embed` flag. Earlier versions didn't know this flag.
|
||||||
|
ifeq "$(shell python3m-config --embed --libs 2>/dev/null | grep -q lpython && echo 1 )" "1"
|
||||||
|
PYTHON_LIB := $(shell python3m-config --libs --embed --ldflags)
|
||||||
|
else
|
||||||
|
PYTHON_LIB := $(shell python3m-config --ldflags)
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq "$(PYTHON_INCLUDE)" ""
|
||||||
|
ifneq "$(shell command -v python3 2>/dev/null)" ""
|
||||||
|
ifneq "$(shell command -v python3-config 2>/dev/null)" ""
|
||||||
|
PYTHON_INCLUDE := $(shell python3-config --includes)
|
||||||
|
PYTHON_VERSION := $(strip $(shell python3 --version 2>&1))
|
||||||
|
# Starting with python3.8, we need to pass the `embed` flag. Earlier versions didn't know this flag.
|
||||||
|
ifeq "$(shell python3-config --embed --libs 2>/dev/null | grep -q lpython && echo 1 )" "1"
|
||||||
|
PYTHON_LIB := $(shell python3-config --libs --embed --ldflags)
|
||||||
|
else
|
||||||
|
PYTHON_LIB := $(shell python3-config --ldflags)
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq "$(PYTHON_INCLUDE)" ""
|
||||||
|
ifneq "$(shell command -v python 2>/dev/null)" ""
|
||||||
|
ifneq "$(shell command -v python-config 2>/dev/null)" ""
|
||||||
|
PYTHON_INCLUDE := $(shell python-config --includes)
|
||||||
|
PYTHON_LIB := $(shell python-config --ldflags)
|
||||||
|
PYTHON_VERSION := $(strip $(shell python --version 2>&1))
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
# Old Ubuntu and others dont have python/python3-config so we hardcode 3.7
|
||||||
|
ifeq "$(PYTHON_INCLUDE)" ""
|
||||||
|
ifneq "$(shell command -v python3.7 2>/dev/null)" ""
|
||||||
|
ifneq "$(shell command -v python3.7-config 2>/dev/null)" ""
|
||||||
|
PYTHON_INCLUDE := $(shell python3.7-config --includes)
|
||||||
|
PYTHON_LIB := $(shell python3.7-config --ldflags)
|
||||||
|
PYTHON_VERSION := $(strip $(shell python3.7 --version 2>&1))
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
# Old Ubuntu and others dont have python/python2-config so we hardcode 2.7
|
||||||
|
ifeq "$(PYTHON_INCLUDE)" ""
|
||||||
|
ifneq "$(shell command -v python2.7 2>/dev/null)" ""
|
||||||
|
ifneq "$(shell command -v python2.7-config 2>/dev/null)" ""
|
||||||
|
PYTHON_INCLUDE := $(shell python2.7-config --includes)
|
||||||
|
PYTHON_LIB := $(shell python2.7-config --ldflags)
|
||||||
|
PYTHON_VERSION := $(strip $(shell python2.7 --version 2>&1))
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifdef SOURCE_DATE_EPOCH
|
||||||
|
BUILD_DATE ?= $(shell date -u -d "@$(SOURCE_DATE_EPOCH)" "+%Y-%m-%d" 2>/dev/null || date -u -r "$(SOURCE_DATE_EPOCH)" "+%Y-%m-%d" 2>/dev/null || date -u "+%Y-%m-%d")
|
||||||
|
else
|
||||||
|
BUILD_DATE ?= $(shell date "+%Y-%m-%d")
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifneq "$(filter Linux GNU%,$(SYS))" ""
|
||||||
|
override LDFLAGS += -ldl -lrt -lm
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifneq "$(findstring FreeBSD, $(SYS))" ""
|
||||||
|
override CFLAGS += -pthread
|
||||||
|
override LDFLAGS += -lpthread -lm
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifneq "$(findstring NetBSD, $(SYS))" ""
|
||||||
|
override CFLAGS += -pthread
|
||||||
|
override LDFLAGS += -lpthread -lm
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifneq "$(findstring OpenBSD, $(SYS))" ""
|
||||||
|
override CFLAGS += -pthread
|
||||||
|
override LDFLAGS += -lpthread -lm
|
||||||
|
endif
|
||||||
|
|
||||||
|
COMM_HDR = include/alloc-inl.h include/config.h include/debug.h include/types.h
|
||||||
|
|
||||||
|
ifeq "$(shell echo '$(HASH)include <Python.h>@int main() {return 0; }' | tr @ '\n' | $(CC) $(CFLAGS) -x c - -o .test $(PYTHON_INCLUDE) $(LDFLAGS) $(PYTHON_LIB) 2>/dev/null && echo 1 || echo 0 ; rm -f .test )" "1"
|
||||||
|
PYTHON_OK=1
|
||||||
|
PYFLAGS=-DUSE_PYTHON $(PYTHON_INCLUDE) $(LDFLAGS) $(PYTHON_LIB) -DPYTHON_VERSION="\"$(PYTHON_VERSION)\""
|
||||||
|
else
|
||||||
|
PYTHON_OK=0
|
||||||
|
PYFLAGS=
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifdef NO_PYTHON
|
||||||
|
PYTHON_OK=0
|
||||||
|
PYFLAGS=
|
||||||
|
endif
|
||||||
|
|
||||||
|
IN_REPO=0
|
||||||
|
ifeq "$(shell command -v git >/dev/null && git status >/dev/null 2>&1 && echo 1 || echo 0)" "1"
|
||||||
|
IN_REPO=1
|
||||||
|
endif
|
||||||
|
ifeq "$(shell command -v svn >/dev/null && svn proplist . 2>/dev/null && echo 1 || echo 0)" "1"
|
||||||
|
IN_REPO=1
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq "$(shell echo 'int main() { return 0;}' | $(CC) $(CFLAGS) -fsanitize=address -x c - -o .test2 2>/dev/null && echo 1 || echo 0 ; rm -f .test2 )" "1"
|
||||||
|
ASAN_CFLAGS=-fsanitize=address -fstack-protector-all -fno-omit-frame-pointer -DASAN_BUILD
|
||||||
|
ASAN_LDFLAGS=-fsanitize=address -fstack-protector-all -fno-omit-frame-pointer
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq "$(shell echo '$(HASH)include <sys/ipc.h>@$(HASH)include <sys/shm.h>@int main() { int _id = shmget(IPC_PRIVATE, 65536, IPC_CREAT | IPC_EXCL | 0600); shmctl(_id, IPC_RMID, 0); return 0;}' | tr @ '\n' | $(CC) $(CFLAGS) -x c - -o .test2 2>/dev/null && echo 1 || echo 0 ; rm -f .test2 )" "1"
|
||||||
|
SHMAT_OK=1
|
||||||
|
else
|
||||||
|
SHMAT_OK=0
|
||||||
|
override CFLAGS+=-DUSEMMAP=1
|
||||||
|
LDFLAGS += -Wno-deprecated-declarations
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifdef TEST_MMAP
|
||||||
|
SHMAT_OK=0
|
||||||
|
override CFLAGS += -DUSEMMAP=1
|
||||||
|
LDFLAGS += -Wno-deprecated-declarations
|
||||||
|
endif
|
||||||
|
|
||||||
|
.PHONY: all
|
||||||
|
all: test_x86 test_shm test_python ready $(PROGS) afl-as llvm gcc_plugin test_build all_done
|
||||||
|
-$(MAKE) -C utils/aflpp_driver
|
||||||
|
@echo
|
||||||
|
@echo
|
||||||
|
@echo Build Summary:
|
||||||
|
@test -e afl-fuzz && echo "[+] afl-fuzz and supporting tools successfully built" || echo "[-] afl-fuzz could not be built, please set CC to a working compiler"
|
||||||
|
@test -e afl-llvm-pass.so && echo "[+] LLVM basic mode successfully built" || echo "[-] LLVM mode could not be built, please install at least llvm-11 and clang-11 or newer, see docs/INSTALL.md"
|
||||||
|
@test -e SanitizerCoveragePCGUARD.so && echo "[+] LLVM mode successfully built" || echo "[-] LLVM mode could not be built, please install at least llvm-13 and clang-13 or newer, see docs/INSTALL.md"
|
||||||
|
@test -e SanitizerCoverageLTO.so && echo "[+] LLVM LTO mode successfully built" || echo "[-] LLVM LTO mode could not be built, it is optional, if you want it, please install LLVM and LLD 11+. More information at instrumentation/README.lto.md on how to build it"
|
||||||
|
ifneq "$(SYS)" "Darwin"
|
||||||
|
@test -e afl-gcc-pass.so && echo "[+] gcc_mode successfully built" || echo "[-] gcc_mode could not be built, it is optional, install gcc-VERSION-plugin-dev to enable this"
|
||||||
|
endif
|
||||||
|
@echo
|
||||||
|
|
||||||
|
.PHONY: llvm
|
||||||
|
llvm:
|
||||||
|
-$(MAKE) -j$(nproc) -f GNUmakefile.llvm
|
||||||
|
@test -e afl-cc || { echo "[-] Compiling afl-cc failed. You seem not to have a working compiler." ; exit 1; }
|
||||||
|
|
||||||
|
.PHONY: gcc_plugin
|
||||||
|
gcc_plugin:
|
||||||
|
ifneq "$(SYS)" "Darwin"
|
||||||
|
-$(MAKE) -f GNUmakefile.gcc_plugin
|
||||||
|
endif
|
||||||
|
|
||||||
|
.PHONY: man
|
||||||
|
man: $(MANPAGES)
|
||||||
|
|
||||||
|
.PHONY: test
|
||||||
|
test: tests
|
||||||
|
|
||||||
|
.PHONY: tests
|
||||||
|
tests: source-only
|
||||||
|
@cd test ; ./test-all.sh
|
||||||
|
@rm -f test/errors
|
||||||
|
|
||||||
|
.PHONY: performance-tests
|
||||||
|
performance-tests: performance-test
|
||||||
|
.PHONY: test-performance
|
||||||
|
test-performance: performance-test
|
||||||
|
|
||||||
|
.PHONY: performance-test
|
||||||
|
performance-test: source-only
|
||||||
|
@cd test ; ./test-performance.sh
|
||||||
|
|
||||||
|
|
||||||
|
# hint: make targets are also listed in the top level README.md
|
||||||
|
.PHONY: help
|
||||||
|
help:
|
||||||
|
@echo "HELP --- the following make targets exist:"
|
||||||
|
@echo "=========================================="
|
||||||
|
@echo "all: the main AFL++ binaries and llvm/gcc instrumentation"
|
||||||
|
@echo "binary-only: everything for binary-only fuzzing: frida_mode, nyx_mode, qemu_mode, frida_mode, unicorn_mode, coresight_mode, libdislocator, libtokencap"
|
||||||
|
@echo "source-only: everything for source code fuzzing: nyx_mode, libdislocator, libtokencap"
|
||||||
|
@echo "distrib: everything (for both binary-only and source code fuzzing)"
|
||||||
|
@echo "man: creates simple man pages from the help option of the programs"
|
||||||
|
@echo "install: installs everything you have compiled with the build option above"
|
||||||
|
@echo "clean: cleans everything compiled (not downloads when on a checkout)"
|
||||||
|
@echo "deepclean: cleans everything including downloads"
|
||||||
|
@echo "uninstall: uninstall AFL++ from the system"
|
||||||
|
@echo "code-format: format the code, do this before you commit and send a PR please!"
|
||||||
|
@echo "tests: this runs the test framework. It is more catered for the developers, but if you run into problems this helps pinpointing the problem"
|
||||||
|
@echo "unit: perform unit tests (based on cmocka and GNU linker)"
|
||||||
|
@echo "document: creates afl-fuzz-document which will only do one run and save all manipulated inputs into out/queue/mutations"
|
||||||
|
@echo "help: shows these build options :-)"
|
||||||
|
@echo "=========================================="
|
||||||
|
@echo "Recommended: \"distrib\" or \"source-only\", then \"install\""
|
||||||
|
@echo
|
||||||
|
@echo Known build environment options:
|
||||||
|
@echo "=========================================="
|
||||||
|
@echo "PERFORMANCE - compile with performance options that make the binary not transferable to other systems. Recommended!"
|
||||||
|
@echo STATIC - compile AFL++ static
|
||||||
|
@echo "CODE_COVERAGE - compile the target for code coverage (see docs/instrumentation/README.llvm.md)"
|
||||||
|
@echo ASAN_BUILD - compiles AFL++ with memory sanitizer for debug purposes
|
||||||
|
@echo UBSAN_BUILD - compiles AFL++ tools with undefined behaviour sanitizer for debug purposes
|
||||||
|
@echo DEBUG - no optimization, -ggdb3, all warnings and -Werror
|
||||||
|
@echo LLVM_DEBUG - shows llvm deprecation warnings
|
||||||
|
@echo PROFILING - compile afl-fuzz with profiling information
|
||||||
|
@echo INTROSPECTION - compile afl-fuzz with mutation introspection
|
||||||
|
@echo NO_PYTHON - disable python support
|
||||||
|
@echo NO_SPLICING - disables splicing mutation in afl-fuzz, not recommended for normal fuzzing
|
||||||
|
@echo "NO_UTF - do not use UTF-8 for line rendering in status screen (fallback to G1 box drawing, of vanilla AFL)"
|
||||||
|
@echo NO_NYX - disable building nyx mode dependencies
|
||||||
|
@echo "NO_CORESIGHT - disable building coresight (arm64 only)"
|
||||||
|
@echo NO_UNICORN_ARM64 - disable building unicorn on arm64
|
||||||
|
@echo "WAFL_MODE - enable for WASM fuzzing with https://github.com/fgsect/WAFL"
|
||||||
|
@echo AFL_NO_X86 - if compiling on non-intel/amd platforms
|
||||||
|
@echo "LLVM_CONFIG - if your distro doesn't use the standard name for llvm-config (e.g., Debian)"
|
||||||
|
@echo "=========================================="
|
||||||
|
@echo e.g.: make LLVM_CONFIG=llvm-config-16
|
||||||
|
|
||||||
|
.PHONY: test_x86
|
||||||
|
ifndef AFL_NO_X86
|
||||||
|
test_x86:
|
||||||
|
@echo "[*] Checking for the default compiler cc..."
|
||||||
|
@type $(CC) >/dev/null || ( echo; echo "Oops, looks like there is no compiler '"$(CC)"' in your path."; echo; echo "Don't panic! You can restart with '"$(_)" CC=<yourCcompiler>'."; echo; exit 1 )
|
||||||
|
@echo "[*] Testing the PATH environment variable..."
|
||||||
|
@test "$${PATH}" != "$${PATH#.:}" && { echo "Please remove current directory '.' from PATH to avoid recursion of 'as', thanks!"; echo; exit 1; } || :
|
||||||
|
@echo "[*] Checking for the ability to compile x86 code..."
|
||||||
|
@echo 'int main() { __asm__("xorb %al, %al"); }' | $(CC) $(CFLAGS) $(LDFLAGS) -w -x c - -o .test1 || ( echo; echo "Oops, looks like your compiler can't generate x86 code."; echo; echo "Don't panic! You can use the LLVM or QEMU mode, but see docs/INSTALL first."; echo "(To ignore this error, set AFL_NO_X86=1 and try again.)"; echo; exit 1 )
|
||||||
|
@rm -f .test1
|
||||||
|
else
|
||||||
|
test_x86:
|
||||||
|
@echo "[!] Note: skipping x86 compilation checks (AFL_NO_X86 set)."
|
||||||
|
endif
|
||||||
|
|
||||||
|
.PHONY: test_shm
|
||||||
|
ifeq "$(SHMAT_OK)" "1"
|
||||||
|
test_shm:
|
||||||
|
@echo "[+] shmat seems to be working."
|
||||||
|
@rm -f .test2
|
||||||
|
else
|
||||||
|
test_shm:
|
||||||
|
@echo "[-] shmat seems not to be working, switching to mmap implementation"
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq "$(shell echo '$(HASH)include <zlib.h>@int main() {return 0; }' | tr @ '\n' | $(CC) $(CFLAGS) -Werror -x c - -lz -o .test 2>/dev/null && echo 1 || echo 0 ; rm -f .test )" "1"
|
||||||
|
override SPECIAL_PERFORMANCE += -DHAVE_ZLIB
|
||||||
|
override LDFLAGS += -lz
|
||||||
|
$(info [+] ZLIB detected)
|
||||||
|
else
|
||||||
|
$(info [!] Warning: no ZLIB detected)
|
||||||
|
endif
|
||||||
|
|
||||||
|
.PHONY: test_python
|
||||||
|
ifeq "$(PYTHON_OK)" "1"
|
||||||
|
test_python:
|
||||||
|
@rm -f .test 2> /dev/null
|
||||||
|
@echo "[+] $(PYTHON_VERSION) support seems to be working."
|
||||||
|
else
|
||||||
|
test_python:
|
||||||
|
@echo "[-] You seem to need to install the package python3-dev or python-dev (and perhaps python[3]-apt), but it is optional so we continue"
|
||||||
|
endif
|
||||||
|
|
||||||
|
.PHONY: ready
|
||||||
|
ready:
|
||||||
|
@echo "[+] Everything seems to be working, ready to compile. ($(shell $(CC) --version 2>&1|head -n 1))"
|
||||||
|
|
||||||
|
afl-as: src/afl-as.c include/afl-as.h $(COMM_HDR) | test_x86
|
||||||
|
$(CC) $(CFLAGS) src/$@.c -o $@ $(LDFLAGS)
|
||||||
|
@ln -sf afl-as as
|
||||||
|
|
||||||
|
src/afl-performance.o : $(COMM_HDR) src/afl-performance.c include/hash.h
|
||||||
|
$(CC) $(CFLAGS) $(CFLAGS_OPT) $(SPECIAL_PERFORMANCE) -Iinclude -c src/afl-performance.c -o src/afl-performance.o
|
||||||
|
|
||||||
|
src/afl-common.o : $(COMM_HDR) src/afl-common.c include/common.h
|
||||||
|
$(CC) $(CFLAGS) $(CFLAGS_FLTO) $(SPECIAL_PERFORMANCE) -c src/afl-common.c -o src/afl-common.o
|
||||||
|
|
||||||
|
src/afl-forkserver.o : $(COMM_HDR) src/afl-forkserver.c include/forkserver.h
|
||||||
|
$(CC) $(CFLAGS) $(CFLAGS_FLTO) $(SPECIAL_PERFORMANCE) -c src/afl-forkserver.c -o src/afl-forkserver.o
|
||||||
|
|
||||||
|
src/afl-sharedmem.o : $(COMM_HDR) src/afl-sharedmem.c include/sharedmem.h
|
||||||
|
$(CC) $(CFLAGS) $(CFLAGS_FLTO) $(SPECIAL_PERFORMANCE) -c src/afl-sharedmem.c -o src/afl-sharedmem.o
|
||||||
|
|
||||||
|
afl-fuzz: $(COMM_HDR) include/afl-fuzz.h $(AFL_FUZZ_FILES) src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o src/afl-performance.o | test_x86
|
||||||
|
$(CC) $(CFLAGS) $(COMPILE_STATIC) $(CFLAGS_FLTO) $(SPECIAL_PERFORMANCE) $(AFL_FUZZ_FILES) src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o src/afl-performance.o -o $@ $(PYFLAGS) $(LDFLAGS) -lm
|
||||||
|
|
||||||
|
afl-showmap: src/afl-showmap.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) $(SPECIAL_PERFORMANCE) src/$@.c src/afl-fuzz-mutators.c src/afl-fuzz-python.c src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o src/afl-performance.o -o $@ $(PYFLAGS) $(LDFLAGS)
|
||||||
|
|
||||||
|
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) $(SPECIAL_PERFORMANCE) 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 src/afl-forkserver.o $(COMM_HDR) | test_x86
|
||||||
|
$(CC) $(CFLAGS) $(COMPILE_STATIC) $(CFLAGS_FLTO) $(SPECIAL_PERFORMANCE) 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) $(SPECIAL_PERFORMANCE) src/$@.c src/afl-common.o -o $@ $(LDFLAGS)
|
||||||
|
|
||||||
|
.PHONY: document
|
||||||
|
document: afl-fuzz-document
|
||||||
|
|
||||||
|
# document all mutations and only do one run (use with only one input file!)
|
||||||
|
afl-fuzz-document: $(COMM_HDR) include/afl-fuzz.h $(AFL_FUZZ_FILES) src/afl-common.o src/afl-sharedmem.o src/afl-performance.o | test_x86
|
||||||
|
$(CC) -D_DEBUG=\"1\" -D_AFL_DOCUMENT_MUTATIONS $(CFLAGS) $(CFLAGS_FLTO) $(AFL_FUZZ_FILES) src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.c src/afl-performance.o -o afl-fuzz-document $(PYFLAGS) $(LDFLAGS)
|
||||||
|
|
||||||
|
test/unittests/unit_maybe_alloc.o : $(COMM_HDR) include/alloc-inl.h test/unittests/unit_maybe_alloc.c $(AFL_FUZZ_FILES)
|
||||||
|
@$(CC) $(CFLAGS) $(ASAN_CFLAGS) -c test/unittests/unit_maybe_alloc.c -o test/unittests/unit_maybe_alloc.o
|
||||||
|
|
||||||
|
unit_maybe_alloc: test/unittests/unit_maybe_alloc.o
|
||||||
|
@$(CC) $(CFLAGS) -Wl,--wrap=exit -Wl,--wrap=printf test/unittests/unit_maybe_alloc.o -o test/unittests/unit_maybe_alloc $(LDFLAGS) $(ASAN_LDFLAGS) -lcmocka
|
||||||
|
./test/unittests/unit_maybe_alloc
|
||||||
|
|
||||||
|
test/unittests/unit_hash.o : $(COMM_HDR) include/alloc-inl.h test/unittests/unit_hash.c $(AFL_FUZZ_FILES) src/afl-performance.o
|
||||||
|
@$(CC) $(CFLAGS) $(ASAN_CFLAGS) $(SPECIAL_PERFORMANCE) -c test/unittests/unit_hash.c -o test/unittests/unit_hash.o
|
||||||
|
|
||||||
|
unit_hash: test/unittests/unit_hash.o src/afl-performance.o
|
||||||
|
@$(CC) $(CFLAGS) $(SPECIAL_PERFORMANCE) -Wl,--wrap=exit -Wl,--wrap=printf $^ -o test/unittests/unit_hash $(LDFLAGS) $(ASAN_LDFLAGS) -lcmocka
|
||||||
|
./test/unittests/unit_hash
|
||||||
|
|
||||||
|
test/unittests/unit_rand.o : $(COMM_HDR) include/alloc-inl.h test/unittests/unit_rand.c $(AFL_FUZZ_FILES) src/afl-performance.o
|
||||||
|
@$(CC) $(CFLAGS) $(ASAN_CFLAGS) $(SPECIAL_PERFORMANCE) -c test/unittests/unit_rand.c -o test/unittests/unit_rand.o
|
||||||
|
|
||||||
|
unit_rand: test/unittests/unit_rand.o src/afl-common.o src/afl-performance.o
|
||||||
|
@$(CC) $(CFLAGS) $(ASAN_CFLAGS) $(SPECIAL_PERFORMANCE) -Wl,--wrap=exit -Wl,--wrap=printf $^ -o test/unittests/unit_rand $(LDFLAGS) $(ASAN_LDFLAGS) -lcmocka
|
||||||
|
./test/unittests/unit_rand
|
||||||
|
|
||||||
|
test/unittests/unit_list.o : $(COMM_HDR) include/list.h test/unittests/unit_list.c $(AFL_FUZZ_FILES)
|
||||||
|
@$(CC) $(CFLAGS) $(ASAN_CFLAGS) -c test/unittests/unit_list.c -o test/unittests/unit_list.o
|
||||||
|
|
||||||
|
unit_list: test/unittests/unit_list.o
|
||||||
|
@$(CC) $(CFLAGS) $(ASAN_CFLAGS) -Wl,--wrap=exit -Wl,--wrap=printf test/unittests/unit_list.o -o test/unittests/unit_list $(LDFLAGS) $(ASAN_LDFLAGS) -lcmocka
|
||||||
|
./test/unittests/unit_list
|
||||||
|
|
||||||
|
test/unittests/unit_preallocable.o : $(COMM_HDR) include/alloc-inl.h test/unittests/unit_preallocable.c $(AFL_FUZZ_FILES)
|
||||||
|
@$(CC) $(CFLAGS) $(ASAN_CFLAGS) -c test/unittests/unit_preallocable.c -o test/unittests/unit_preallocable.o
|
||||||
|
|
||||||
|
unit_preallocable: test/unittests/unit_preallocable.o
|
||||||
|
@$(CC) $(CFLAGS) $(ASAN_CFLAGS) -Wl,--wrap=exit -Wl,--wrap=printf test/unittests/unit_preallocable.o -o test/unittests/unit_preallocable $(LDFLAGS) $(ASAN_LDFLAGS) -lcmocka
|
||||||
|
./test/unittests/unit_preallocable
|
||||||
|
|
||||||
|
.PHONY: unit_clean
|
||||||
|
unit_clean:
|
||||||
|
@rm -f ./test/unittests/unit_preallocable ./test/unittests/unit_list ./test/unittests/unit_maybe_alloc test/unittests/*.o
|
||||||
|
|
||||||
|
.PHONY: unit
|
||||||
|
ifneq "$(SYS)" "Darwin"
|
||||||
|
unit: unit_maybe_alloc unit_preallocable unit_list unit_clean unit_rand unit_hash
|
||||||
|
else
|
||||||
|
unit:
|
||||||
|
@echo [-] unit tests are skipped on Darwin \(lacks GNU linker feature --wrap\)
|
||||||
|
endif
|
||||||
|
|
||||||
|
.PHONY: code-format
|
||||||
|
code-format:
|
||||||
|
./.custom-format.py -i src/*.c
|
||||||
|
./.custom-format.py -i include/*.h
|
||||||
|
./.custom-format.py -i instrumentation/*.h
|
||||||
|
./.custom-format.py -i instrumentation/*.cc
|
||||||
|
./.custom-format.py -i instrumentation/*.c
|
||||||
|
./.custom-format.py -i *.h
|
||||||
|
./.custom-format.py -i *.c
|
||||||
|
@#./.custom-format.py -i custom_mutators/*/*.c* # destroys libfuzzer :-(
|
||||||
|
@#./.custom-format.py -i custom_mutators/*/*.h # destroys honggfuzz :-(
|
||||||
|
./.custom-format.py -i utils/*/*.c*
|
||||||
|
./.custom-format.py -i utils/*/*.h
|
||||||
|
./.custom-format.py -i test/*.c
|
||||||
|
./.custom-format.py -i frida_mode/src/*.c
|
||||||
|
./.custom-format.py -i frida_mode/include/*.h
|
||||||
|
-./.custom-format.py -i frida_mode/src/*/*.c
|
||||||
|
./.custom-format.py -i qemu_mode/libcompcov/*.c
|
||||||
|
./.custom-format.py -i qemu_mode/libcompcov/*.cc
|
||||||
|
./.custom-format.py -i qemu_mode/libcompcov/*.h
|
||||||
|
./.custom-format.py -i qemu_mode/libqasan/*.c
|
||||||
|
./.custom-format.py -i qemu_mode/libqasan/*.h
|
||||||
|
|
||||||
|
|
||||||
|
.PHONY: test_build
|
||||||
|
ifndef AFL_NO_X86
|
||||||
|
test_build: afl-cc afl-gcc afl-as afl-showmap
|
||||||
|
@echo "[*] Testing the CC wrapper afl-cc and its instrumentation output..."
|
||||||
|
@unset AFL_MAP_SIZE AFL_USE_UBSAN AFL_USE_CFISAN AFL_USE_LSAN AFL_USE_ASAN AFL_USE_MSAN; ASAN_OPTIONS=detect_leaks=0 AFL_INST_RATIO=100 AFL_PATH=. ./afl-cc test-instr.c $(LDFLAGS) -o test-instr 2>&1 || (echo "Oops, afl-cc failed"; exit 1 )
|
||||||
|
-ASAN_OPTIONS=detect_leaks=0 ./afl-showmap -q -m none -o .test-instr0 ./test-instr < /dev/null
|
||||||
|
-echo 1 | ASAN_OPTIONS=detect_leaks=0 ./afl-showmap -m none -q -o .test-instr1 ./test-instr
|
||||||
|
@rm -f test-instr
|
||||||
|
@cmp -s .test-instr0 .test-instr1; DR="$$?"; rm -f .test-instr0 .test-instr1; if [ "$$DR" = "0" ]; then echo; echo "Oops, the instrumentation of afl-cc does not seem to be behaving correctly!"; echo; echo "Please post to https://github.com/AFLplusplus/AFLplusplus/issues to troubleshoot the issue."; echo; exit 1; fi
|
||||||
|
@echo
|
||||||
|
@echo "[+] All right, the instrumentation of afl-cc seems to be working!"
|
||||||
|
# @echo "[*] Testing the CC wrapper afl-gcc and its instrumentation output..."
|
||||||
|
# @unset AFL_MAP_SIZE AFL_USE_UBSAN AFL_USE_CFISAN AFL_USE_LSAN AFL_USE_ASAN AFL_USE_MSAN; AFL_CC=$(CC) ASAN_OPTIONS=detect_leaks=0 AFL_INST_RATIO=100 AFL_PATH=. ./afl-gcc test-instr.c -o test-instr 2>&1 || (echo "Oops, afl-gcc failed"; exit 1 )
|
||||||
|
# ASAN_OPTIONS=detect_leaks=0 ./afl-showmap -m none -q -o .test-instr0 ./test-instr < /dev/null
|
||||||
|
# echo 1 | ASAN_OPTIONS=detect_leaks=0 ./afl-showmap -m none -q -o .test-instr1 ./test-instr
|
||||||
|
# @rm -f test-instr
|
||||||
|
# @cmp -s .test-instr0 .test-instr1; DR="$$?"; rm -f .test-instr0 .test-instr1; if [ "$$DR" = "0" ]; then echo; echo "Oops, the instrumentation of afl-gcc does not seem to be behaving correctly!"; \
|
||||||
|
# gcc -v 2>&1 | grep -q -- --with-as= && ( echo; echo "Gcc is configured not to use an external assembler with the -B option." ) || \
|
||||||
|
# ( echo; echo "Please post to https://github.com/AFLplusplus/AFLplusplus/issues to troubleshoot the issue." ); echo; exit 0; fi
|
||||||
|
# @echo
|
||||||
|
# @echo "[+] All right, the instrumentation of afl-gcc seems to be working!"
|
||||||
|
else
|
||||||
|
test_build: afl-cc afl-as afl-showmap
|
||||||
|
@echo "[!] Note: skipping build tests (you may need to use LLVM or QEMU mode)."
|
||||||
|
endif
|
||||||
|
|
||||||
|
.PHONY: all_done
|
||||||
|
all_done: test_build
|
||||||
|
@test -e afl-cc && echo "[+] Main compiler 'afl-cc' successfully built!" || { echo "[-] Main compiler 'afl-cc' failed to build, set up a working build environment first!" ; exit 1 ; }
|
||||||
|
@test -e cmplog-instructions-pass.so && echo "[+] LLVM mode for 'afl-cc' successfully built!" || echo "[-] LLVM mode for 'afl-cc' failed to build, likely you either don't have llvm installed, or you need to set LLVM_CONFIG, to point to e.g. llvm-config-11. See instrumentation/README.llvm.md how to do this. Highly recommended!"
|
||||||
|
@test -e SanitizerCoverageLTO.so && echo "[+] LLVM LTO mode for 'afl-cc' successfully built!" || echo "[-] LLVM LTO mode for 'afl-cc' failed to build, this would need LLVM 11+, see instrumentation/README.lto.md how to build it"
|
||||||
|
@test -e afl-gcc-pass.so && echo "[+] gcc_plugin for 'afl-cc' successfully built!" || echo "[-] gcc_plugin for 'afl-cc' failed to build, unless you really need it that is fine - or read instrumentation/README.gcc_plugin.md how to build it"
|
||||||
|
@echo "[+] All done! Be sure to review the README.md - it's pretty short and useful."
|
||||||
|
@if [ "$(SYS)" = "Darwin" ]; then printf "\nWARNING: Fuzzing on MacOS X is slow because of the unusually high overhead of\nfork() on this OS. Consider using Linux or *BSD for fuzzing software not\nspecifically for MacOS.\n\n"; fi
|
||||||
|
@! tty <&1 >/dev/null || printf "\033[0;30mNOTE: If you can read this, your terminal probably uses white background.\nThis will make the UI hard to read. See docs/status_screen.md for advice.\033[0m\n" 2>/dev/null
|
||||||
|
|
||||||
|
.NOTPARALLEL: clean all
|
||||||
|
|
||||||
|
.PHONY: clean
|
||||||
|
clean:
|
||||||
|
rm -rf $(PROGS) afl-fuzz-document afl-as as afl-g++ afl-clang afl-clang++ *.o src/*.o *~ a.out core core.[1-9][0-9]* *.stackdump .test .test1 .test2 test-instr .test-instr0 .test-instr1 afl-cs-proxy afl-qemu-trace afl-gcc-fast afl-g++-fast ld *.so *.8 test/unittests/*.o test/unittests/unit_maybe_alloc test/unittests/preallocable .afl-* afl-gcc afl-g++ afl-clang afl-clang++ test/unittests/unit_hash test/unittests/unit_rand *.dSYM lib*.a
|
||||||
|
-$(MAKE) -f GNUmakefile.llvm clean
|
||||||
|
-$(MAKE) -f GNUmakefile.gcc_plugin clean
|
||||||
|
-$(MAKE) -C utils/libdislocator clean
|
||||||
|
-$(MAKE) -C utils/libtokencap clean
|
||||||
|
-$(MAKE) -C utils/aflpp_driver clean
|
||||||
|
-$(MAKE) -C utils/afl_network_proxy clean
|
||||||
|
-$(MAKE) -C utils/socket_fuzzing clean
|
||||||
|
-$(MAKE) -C utils/argv_fuzzing clean
|
||||||
|
-$(MAKE) -C utils/plot_ui clean
|
||||||
|
-$(MAKE) -C qemu_mode/unsigaction clean
|
||||||
|
-$(MAKE) -C qemu_mode/fastexit clean
|
||||||
|
-$(MAKE) -C qemu_mode/libcompcov clean
|
||||||
|
-$(MAKE) -C qemu_mode/libqasan clean
|
||||||
|
-$(MAKE) -C frida_mode clean
|
||||||
|
rm -rf nyx_mode/packer/linux_initramfs/init.cpio.gz nyx_mode/libnyx/libnyx/target/release/* nyx_mode/QEMU-Nyx/x86_64-softmmu/qemu-system-x86_64
|
||||||
|
ifeq "$(IN_REPO)" "1"
|
||||||
|
-test -e coresight_mode/coresight-trace/Makefile && $(MAKE) -C coresight_mode/coresight-trace clean || true
|
||||||
|
-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
|
||||||
|
-test -e nyx_mode/QEMU-Nyx/Makefile && $(MAKE) -C nyx_mode/QEMU-Nyx clean || true
|
||||||
|
else
|
||||||
|
rm -rf coresight_mode/coresight_trace
|
||||||
|
rm -rf qemu_mode/qemuafl
|
||||||
|
rm -rf unicorn_mode/unicornafl
|
||||||
|
endif
|
||||||
|
|
||||||
|
.PHONY: deepclean
|
||||||
|
deepclean: clean
|
||||||
|
rm -rf coresight_mode/coresight-trace
|
||||||
|
rm -rf unicorn_mode/unicornafl
|
||||||
|
rm -rf qemu_mode/qemuafl
|
||||||
|
rm -rf nyx_mode/libnyx nyx_mode/packer nyx_mode/QEMU-Nyx
|
||||||
|
ifeq "$(IN_REPO)" "1"
|
||||||
|
git checkout coresight_mode/coresight-trace
|
||||||
|
git checkout unicorn_mode/unicornafl
|
||||||
|
git checkout qemu_mode/qemuafl
|
||||||
|
git checkout nyx_mode/libnyx
|
||||||
|
git checkout nyx_mode/packer
|
||||||
|
git checkout nyx_mode/QEMU-Nyx
|
||||||
|
endif
|
||||||
|
|
||||||
|
.PHONY: distrib
|
||||||
|
distrib: all
|
||||||
|
-$(MAKE) -j$(nproc) -f GNUmakefile.llvm
|
||||||
|
ifneq "$(SYS)" "Darwin"
|
||||||
|
-$(MAKE) -f GNUmakefile.gcc_plugin
|
||||||
|
-$(MAKE) -C utils/libdislocator
|
||||||
|
-$(MAKE) -C utils/libtokencap
|
||||||
|
endif
|
||||||
|
-$(MAKE) -C utils/afl_network_proxy
|
||||||
|
-$(MAKE) -C utils/socket_fuzzing
|
||||||
|
-$(MAKE) -C utils/argv_fuzzing
|
||||||
|
# -$(MAKE) -C utils/plot_ui
|
||||||
|
-$(MAKE) -C frida_mode
|
||||||
|
ifneq "$(SYS)" "Darwin"
|
||||||
|
ifeq "$(ARCH)" "aarch64"
|
||||||
|
ifndef NO_CORESIGHT
|
||||||
|
-$(MAKE) -C coresight_mode
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
ifeq "$(SYS)" "Linux"
|
||||||
|
ifndef NO_NYX
|
||||||
|
-cd nyx_mode && ./build_nyx_support.sh
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
-cd qemu_mode && sh ./build_qemu_support.sh
|
||||||
|
ifeq "$(ARCH)" "aarch64"
|
||||||
|
ifndef NO_UNICORN_ARM64
|
||||||
|
-cd unicorn_mode && unset CFLAGS && sh ./build_unicorn_support.sh
|
||||||
|
endif
|
||||||
|
else
|
||||||
|
-cd unicorn_mode && unset CFLAGS && sh ./build_unicorn_support.sh
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
.PHONY: binary-only
|
||||||
|
binary-only: test_shm test_python ready $(PROGS)
|
||||||
|
ifneq "$(SYS)" "Darwin"
|
||||||
|
-$(MAKE) -C utils/libdislocator
|
||||||
|
-$(MAKE) -C utils/libtokencap
|
||||||
|
endif
|
||||||
|
-$(MAKE) -C utils/afl_network_proxy
|
||||||
|
-$(MAKE) -C utils/socket_fuzzing
|
||||||
|
-$(MAKE) -C utils/argv_fuzzing
|
||||||
|
# -$(MAKE) -C utils/plot_ui
|
||||||
|
-$(MAKE) -C frida_mode
|
||||||
|
ifneq "$(SYS)" "Darwin"
|
||||||
|
ifeq "$(ARCH)" "aarch64"
|
||||||
|
ifndef NO_CORESIGHT
|
||||||
|
-$(MAKE) -C coresight_mode
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
ifeq "$(SYS)" "Linux"
|
||||||
|
ifndef NO_NYX
|
||||||
|
-cd nyx_mode && ./build_nyx_support.sh
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
-cd qemu_mode && sh ./build_qemu_support.sh
|
||||||
|
ifeq "$(ARCH)" "aarch64"
|
||||||
|
ifndef NO_UNICORN_ARM64
|
||||||
|
-cd unicorn_mode && unset CFLAGS && sh ./build_unicorn_support.sh
|
||||||
|
endif
|
||||||
|
else
|
||||||
|
-cd unicorn_mode && unset CFLAGS && sh ./build_unicorn_support.sh
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
@echo
|
||||||
|
@echo
|
||||||
|
@echo Build Summary:
|
||||||
|
@test -e afl-fuzz && echo "[+] afl-fuzz and supporting tools successfully built" || echo "[-] afl-fuzz could not be built, please set CC to a working compiler"
|
||||||
|
ifneq "$(SYS)" "Darwin"
|
||||||
|
ifeq "$(ARCH)" "aarch64"
|
||||||
|
ifndef NO_CORESIGHT
|
||||||
|
@test -e afl-cs-proxy && echo "[+] coresight_mode successfully built" || echo "[-] coresight_mode could not be built, it is optional and experimental, see coresight_mode/README.md for what is needed"
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
ifeq "$(SYS)" "Linux"
|
||||||
|
ifndef NO_NYX
|
||||||
|
@test -e libnyx.so && echo "[+] nyx_mode successfully built" || echo "[-] nyx_mode could not be built, it is optional, see nyx_mode/README.md for what is needed"
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
@test -e afl-qemu-trace && echo "[+] qemu_mode successfully built" || echo "[-] qemu_mode could not be built, see docs/INSTALL.md for what is needed"
|
||||||
|
ifeq "$(ARCH)" "aarch64"
|
||||||
|
ifndef NO_UNICORN_ARM64
|
||||||
|
@test -e unicorn_mode/unicornafl/build_python/libunicornafl.so && echo "[+] unicorn_mode successfully built" || echo "[-] unicorn_mode could not be built, it is optional, see unicorn_mode/README.md for what is needed"
|
||||||
|
endif
|
||||||
|
else
|
||||||
|
@test -e unicorn_mode/unicornafl/build_python/libunicornafl.so && echo "[+] unicorn_mode successfully built" || echo "[-] unicorn_mode could not be built, it is optional, see unicorn_mode/README.md for what is needed"
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
@echo
|
||||||
|
|
||||||
|
.PHONY: source-only
|
||||||
|
source-only: all
|
||||||
|
-$(MAKE) -j$(nproc) -f GNUmakefile.llvm
|
||||||
|
ifneq "$(SYS)" "Darwin"
|
||||||
|
-$(MAKE) -f GNUmakefile.gcc_plugin
|
||||||
|
-$(MAKE) -C utils/libdislocator
|
||||||
|
-$(MAKE) -C utils/libtokencap
|
||||||
|
endif
|
||||||
|
# -$(MAKE) -C utils/plot_ui
|
||||||
|
ifeq "$(SYS)" "Linux"
|
||||||
|
ifndef NO_NYX
|
||||||
|
-cd nyx_mode && ./build_nyx_support.sh
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
@echo
|
||||||
|
@echo
|
||||||
|
@echo Build Summary:
|
||||||
|
@test -e afl-fuzz && echo "[+] afl-fuzz and supporting tools successfully built" || echo "[-] afl-fuzz could not be built, please set CC to a working compiler"
|
||||||
|
@test -e afl-llvm-pass.so && echo "[+] LLVM basic mode successfully built" || echo "[-] LLVM mode could not be built, please install at least llvm-11 and clang-11 or newer, see docs/INSTALL.md"
|
||||||
|
@test -e SanitizerCoveragePCGUARD.so && echo "[+] LLVM mode successfully built" || echo "[-] LLVM mode could not be built, please install at least llvm-13 and clang-13 or newer, see docs/INSTALL.md"
|
||||||
|
@test -e SanitizerCoverageLTO.so && echo "[+] LLVM LTO mode successfully built" || echo "[-] LLVM LTO mode could not be built, it is optional, if you want it, please install LLVM 11-14. More information at instrumentation/README.lto.md on how to build it"
|
||||||
|
ifneq "$(SYS)" "Darwin"
|
||||||
|
@test -e afl-gcc-pass.so && echo "[+] gcc_mode successfully built" || echo "[-] gcc_mode could not be built, it is optional, install gcc-VERSION-plugin-dev to enable this"
|
||||||
|
endif
|
||||||
|
ifeq "$(SYS)" "Linux"
|
||||||
|
ifndef NO_NYX
|
||||||
|
@test -e libnyx.so && echo "[+] nyx_mode successfully built" || echo "[-] nyx_mode could not be built, it is optional, see nyx_mode/README.md for what is needed"
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
@echo
|
||||||
|
|
||||||
|
%.8: %
|
||||||
|
@echo .TH $* 8 $(BUILD_DATE) "AFL++" > $@
|
||||||
|
@echo .SH NAME >> $@
|
||||||
|
@echo .B $* >> $@
|
||||||
|
@echo >> $@
|
||||||
|
@echo .SH SYNOPSIS >> $@
|
||||||
|
@./$* -h 2>&1 | head -n 3 | tail -n 1 | sed 's/^\.\///' >> $@
|
||||||
|
@echo >> $@
|
||||||
|
@echo .SH OPTIONS >> $@
|
||||||
|
@echo .nf >> $@
|
||||||
|
@./$* -hh 2>&1 | tail -n +4 >> $@
|
||||||
|
@echo >> $@
|
||||||
|
@echo .SH AUTHOR >> $@
|
||||||
|
@echo "AFL++ was written by Michal \"lcamtuf\" Zalewski and is maintained by Marc \"van Hauser\" Heuse <mh@mh-sec.de>, Dominik Maier <domenukk@gmail.com>, Andrea Fioraldi <andreafioraldi@gmail.com> and Heiko \"hexcoder-\" Eissfeldt <heiko.eissfeldt@hexco.de>" >> $@
|
||||||
|
@echo The homepage of AFL++ is: https://github.com/AFLplusplus/AFLplusplus >> $@
|
||||||
|
@echo >> $@
|
||||||
|
@echo .SH LICENSE >> $@
|
||||||
|
@echo Apache License Version 2.0, January 2004 >> $@
|
||||||
|
|
||||||
|
.PHONY: install
|
||||||
|
install: all $(MANPAGES)
|
||||||
|
@install -d -m 755 $${DESTDIR}$(BIN_PATH) $${DESTDIR}$(HELPER_PATH) $${DESTDIR}$(DOC_PATH) $${DESTDIR}$(MISC_PATH)
|
||||||
|
@rm -f $${DESTDIR}$(BIN_PATH)/afl-plot.sh
|
||||||
|
@rm -f $${DESTDIR}$(BIN_PATH)/afl-as
|
||||||
|
@rm -f $${DESTDIR}$(HELPER_PATH)/afl-llvm-rt.o $${DESTDIR}$(HELPER_PATH)/afl-llvm-rt-32.o $${DESTDIR}$(HELPER_PATH)/afl-llvm-rt-64.o $${DESTDIR}$(HELPER_PATH)/afl-gcc-rt.o
|
||||||
|
@for i in afl-llvm-dict2file.so afl-llvm-lto-instrumentlist.so afl-llvm-pass.so cmplog-instructions-pass.so cmplog-routines-pass.so cmplog-switches-pass.so compare-transform-pass.so libcompcov.so libdislocator.so libnyx.so libqasan.so libtokencap.so SanitizerCoverageLTO.so SanitizerCoveragePCGUARD.so split-compares-pass.so split-switches-pass.so injection-pass.so; do echo rm -fv $${DESTDIR}$(HELPER_PATH)/$${i}; done
|
||||||
|
install -m 755 $(PROGS) $(SH_PROGS) $${DESTDIR}$(BIN_PATH)
|
||||||
|
@if [ -f afl-qemu-trace ]; then install -m 755 afl-qemu-trace $${DESTDIR}$(BIN_PATH); fi
|
||||||
|
@if [ -f utils/plot_ui/afl-plot-ui ]; then install -m 755 utils/plot_ui/afl-plot-ui $${DESTDIR}$(BIN_PATH); fi
|
||||||
|
@if [ -f libdislocator.so ]; then set -e; install -m 755 libdislocator.so $${DESTDIR}$(HELPER_PATH); fi
|
||||||
|
@if [ -f libtokencap.so ]; then set -e; install -m 755 libtokencap.so $${DESTDIR}$(HELPER_PATH); fi
|
||||||
|
@if [ -f libcompcov.so ]; then set -e; install -m 755 libcompcov.so $${DESTDIR}$(HELPER_PATH); fi
|
||||||
|
@if [ -f libqasan.so ]; then set -e; install -m 755 libqasan.so $${DESTDIR}$(HELPER_PATH); fi
|
||||||
|
@if [ -f afl-fuzz-document ]; then set -e; install -m 755 afl-fuzz-document $${DESTDIR}$(BIN_PATH); fi
|
||||||
|
@if [ -f socketfuzz32.so -o -f socketfuzz64.so ]; then $(MAKE) -C utils/socket_fuzzing install; fi
|
||||||
|
@if [ -f argvfuzz32.so -o -f argvfuzz64.so ]; then $(MAKE) -C utils/argv_fuzzing install; fi
|
||||||
|
@if [ -f afl-frida-trace.so ]; then install -m 755 afl-frida-trace.so $${DESTDIR}$(HELPER_PATH); fi
|
||||||
|
@if [ -f libnyx.so ]; then install -m 755 libnyx.so $${DESTDIR}$(HELPER_PATH); fi
|
||||||
|
@if [ -f utils/afl_network_proxy/afl-network-server ]; then $(MAKE) -C utils/afl_network_proxy install; fi
|
||||||
|
@if [ -f utils/aflpp_driver/libAFLDriver.a ]; then set -e; install -m 644 utils/aflpp_driver/libAFLDriver.a $${DESTDIR}$(HELPER_PATH); fi
|
||||||
|
@if [ -f utils/aflpp_driver/libAFLQemuDriver.a ]; then set -e; install -m 644 utils/aflpp_driver/libAFLQemuDriver.a $${DESTDIR}$(HELPER_PATH); fi
|
||||||
|
-$(MAKE) -f GNUmakefile.llvm install
|
||||||
|
ifneq "$(SYS)" "Darwin"
|
||||||
|
-$(MAKE) -f GNUmakefile.gcc_plugin install
|
||||||
|
endif
|
||||||
|
ln -sf afl-cc $${DESTDIR}$(BIN_PATH)/afl-gcc
|
||||||
|
ln -sf afl-cc $${DESTDIR}$(BIN_PATH)/afl-g++
|
||||||
|
ln -sf afl-cc $${DESTDIR}$(BIN_PATH)/afl-clang
|
||||||
|
ln -sf afl-cc $${DESTDIR}$(BIN_PATH)/afl-clang++
|
||||||
|
@mkdir -m 0755 -p ${DESTDIR}$(MAN_PATH)
|
||||||
|
install -m0644 *.8 ${DESTDIR}$(MAN_PATH)
|
||||||
|
install -m 755 afl-as $${DESTDIR}$(HELPER_PATH)
|
||||||
|
ln -sf afl-as $${DESTDIR}$(HELPER_PATH)/as
|
||||||
|
install -m 644 docs/*.md $${DESTDIR}$(DOC_PATH)
|
||||||
|
cp -r testcases/ $${DESTDIR}$(MISC_PATH)
|
||||||
|
cp -r dictionaries/ $${DESTDIR}$(MISC_PATH)
|
||||||
|
cp injections.dic $${DESTDIR}$(MISC_PATH)
|
||||||
|
|
||||||
|
.PHONY: uninstall
|
||||||
|
uninstall:
|
||||||
|
-cd $${DESTDIR}$(BIN_PATH) && rm -f $(PROGS) $(SH_PROGS) afl-cs-proxy afl-qemu-trace afl-plot-ui afl-fuzz-document afl-network-client afl-network-server afl-g* afl-plot.sh afl-as afl-ld-lto afl-c* afl-lto*
|
||||||
|
-cd $${DESTDIR}$(HELPER_PATH) && rm -f afl-g*.*o afl-llvm-*.*o afl-compiler-*.*o libdislocator.so libtokencap.so libcompcov.so libqasan.so afl-frida-trace.so libnyx.so socketfuzz*.so argvfuzz*.so libAFLDriver.a libAFLQemuDriver.a as afl-as SanitizerCoverage*.so compare-transform-pass.so cmplog-*-pass.so split-*-pass.so dynamic_list.txt injections.dic
|
||||||
|
-rm -rf $${DESTDIR}$(MISC_PATH)/testcases $${DESTDIR}$(MISC_PATH)/dictionaries
|
||||||
|
-sh -c "ls docs/*.md | sed 's|^docs/|$${DESTDIR}$(DOC_PATH)/|' | xargs rm -f"
|
||||||
|
-cd $${DESTDIR}$(MAN_PATH) && rm -f $(MANPAGES)
|
||||||
|
-rmdir $${DESTDIR}$(BIN_PATH) 2>/dev/null
|
||||||
|
-rmdir $${DESTDIR}$(HELPER_PATH) 2>/dev/null
|
||||||
|
-rmdir $${DESTDIR}$(MISC_PATH) 2>/dev/null
|
||||||
|
-rmdir $${DESTDIR}$(DOC_PATH) 2>/dev/null
|
||||||
|
-rmdir $${DESTDIR}$(MAN_PATH) 2>/dev/null
|
@ -0,0 +1,212 @@
|
|||||||
|
#
|
||||||
|
# american fuzzy lop++ - GCC plugin instrumentation
|
||||||
|
# -----------------------------------------------
|
||||||
|
#
|
||||||
|
# Written by Austin Seipp <aseipp@pobox.com> and
|
||||||
|
# Laszlo Szekeres <lszekeres@google.com> and
|
||||||
|
# Michal Zalewski and
|
||||||
|
# Heiko Eißfeldt <heiko@hexco.de>
|
||||||
|
#
|
||||||
|
# GCC integration design is based on the LLVM design, which comes
|
||||||
|
# from Laszlo Szekeres.
|
||||||
|
#
|
||||||
|
# Copyright 2015 Google Inc. All rights reserved.
|
||||||
|
# Copyright 2019-2024 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:
|
||||||
|
#
|
||||||
|
# https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
#TEST_MMAP=1
|
||||||
|
PREFIX ?= /usr/local
|
||||||
|
HELPER_PATH ?= $(PREFIX)/lib/afl
|
||||||
|
BIN_PATH ?= $(PREFIX)/bin
|
||||||
|
DOC_PATH ?= $(PREFIX)/share/doc/afl
|
||||||
|
MAN_PATH ?= $(PREFIX)/share/man/man8
|
||||||
|
|
||||||
|
VERSION = $(shell grep '^$(HASH)define VERSION ' ./config.h | cut -d '"' -f2)
|
||||||
|
|
||||||
|
CFLAGS ?= -O3 -g -funroll-loops
|
||||||
|
# -D_FORTIFY_SOURCE=1
|
||||||
|
CFLAGS_SAFE := -Wall -Iinclude -Wno-pointer-sign \
|
||||||
|
-DAFL_PATH=\"$(HELPER_PATH)\" -DBIN_PATH=\"$(BIN_PATH)\" \
|
||||||
|
-DGCC_VERSION=\"$(GCCVER)\" -DGCC_BINDIR=\"$(GCCBINDIR)\" \
|
||||||
|
-Wno-unused-function
|
||||||
|
override CFLAGS += $(CFLAGS_SAFE)
|
||||||
|
|
||||||
|
CXXFLAGS ?= -O3 -g -funroll-loops
|
||||||
|
# -D_FORTIFY_SOURCE=1
|
||||||
|
CXXEFLAGS := $(CXXFLAGS) $(CPPFLAGS) -Wall -std=c++11
|
||||||
|
|
||||||
|
CC ?= gcc
|
||||||
|
CXX ?= g++
|
||||||
|
|
||||||
|
SYS = $(shell uname -s)
|
||||||
|
|
||||||
|
ifeq "clang" "$(CC)"
|
||||||
|
CC = gcc
|
||||||
|
CXX = g++
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq "clang++" "$(CXX)"
|
||||||
|
CC = gcc
|
||||||
|
CXX = g++
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq "$(findstring Foundation,$(shell $(CC) --version))" ""
|
||||||
|
CC = gcc
|
||||||
|
CXX = g++
|
||||||
|
endif
|
||||||
|
|
||||||
|
PLUGIN_BASE = "$(shell $(CC) -print-file-name=plugin)"
|
||||||
|
PLUGIN_FLAGS = -fPIC -fno-rtti -fno-exceptions -I$(PLUGIN_BASE)/include -I$(PLUGIN_BASE)
|
||||||
|
HASH=\#
|
||||||
|
|
||||||
|
GCCVER = $(shell $(CC) --version 2>/dev/null | awk 'NR == 1 {print $$NF}')
|
||||||
|
GCCBINDIR = $(shell dirname `command -v $(CC)` 2>/dev/null )
|
||||||
|
|
||||||
|
ifeq "$(shell echo '$(HASH)include <sys/ipc.h>@$(HASH)include <sys/shm.h>@int main() { int _id = shmget(IPC_PRIVATE, 65536, IPC_CREAT | IPC_EXCL | 0600); shmctl(_id, IPC_RMID, 0); return 0;}' | tr @ '\n' | $(CC) -x c - -o .test2 2>/dev/null && echo 1 || echo 0 ; rm -f .test2 )" "1"
|
||||||
|
SHMAT_OK=1
|
||||||
|
else
|
||||||
|
SHMAT_OK=0
|
||||||
|
override CFLAGS_SAFE += -DUSEMMAP=1
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq "$(TEST_MMAP)" "1"
|
||||||
|
SHMAT_OK=0
|
||||||
|
override CFLAGS_SAFE += -DUSEMMAP=1
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifneq "$(SYS)" "Haiku"
|
||||||
|
ifneq "$(SYS)" "OpenBSD"
|
||||||
|
LDFLAGS += -lrt
|
||||||
|
endif
|
||||||
|
else
|
||||||
|
CFLAGS_SAFE += -DUSEMMAP=1
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq "$(SYS)" "OpenBSD"
|
||||||
|
CC = egcc
|
||||||
|
CXX = eg++
|
||||||
|
PLUGIN_FLAGS += -I/usr/local/include
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq "$(SYS)" "DragonFly"
|
||||||
|
PLUGIN_FLAGS += -I/usr/local/include
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq "$(SYS)" "SunOS"
|
||||||
|
PLUGIN_FLAGS += -I/usr/include/gmp
|
||||||
|
endif
|
||||||
|
|
||||||
|
|
||||||
|
PASSES = ./afl-gcc-pass.so ./afl-gcc-cmplog-pass.so ./afl-gcc-cmptrs-pass.so
|
||||||
|
|
||||||
|
PROGS = $(PASSES) ./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
|
||||||
|
|
||||||
|
.PHONY: test_shm
|
||||||
|
ifeq "$(SHMAT_OK)" "1"
|
||||||
|
test_shm:
|
||||||
|
@echo "[+] shmat seems to be working."
|
||||||
|
@rm -f .test2
|
||||||
|
else
|
||||||
|
test_shm:
|
||||||
|
@echo "[-] shmat seems not to be working, switching to mmap implementation"
|
||||||
|
endif
|
||||||
|
|
||||||
|
.PHONY: test_deps
|
||||||
|
test_deps:
|
||||||
|
@echo "[*] Checking for working '$(CC)'..."
|
||||||
|
@command -v $(CC) >/dev/null 2>&1 || ( echo "[-] Oops, can't find '$(CC)'. Make sure that it's in your \$$PATH (or set \$$CC and \$$CXX)."; exit 1 )
|
||||||
|
# @echo "[*] Checking for gcc for plugin support..."
|
||||||
|
# @$(CC) -v 2>&1 | grep -q -- --enable-plugin || ( echo "[-] Oops, this gcc has not been configured with plugin support."; exit 1 )
|
||||||
|
@echo "[*] Checking for gcc plugin development header files..."
|
||||||
|
@test -d `$(CC) -print-file-name=plugin`/include || ( echo "[-] Oops, can't find gcc header files. Be sure to install 'gcc-X-plugin-dev'."; exit 1 )
|
||||||
|
@echo "[*] Checking for './afl-showmap'..."
|
||||||
|
@test -f ./afl-showmap || ( echo "[-] Oops, can't find './afl-showmap'. Be sure to compile AFL first."; exit 1 )
|
||||||
|
@echo "[+] All set and ready to build."
|
||||||
|
|
||||||
|
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!"; 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!"; else echo "failed (that's fine)"; fi
|
||||||
|
|
||||||
|
$(PASSES): instrumentation/afl-gcc-common.h
|
||||||
|
|
||||||
|
./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
|
||||||
|
ln -sf afl-cc afl-g++-fast
|
||||||
|
ln -sf afl-cc.8 afl-gcc-fast.8
|
||||||
|
ln -sf afl-cc.8 afl-g++-fast.8
|
||||||
|
|
||||||
|
./afl-gcc-cmplog-pass.so: instrumentation/afl-gcc-cmplog-pass.so.cc | test_deps
|
||||||
|
$(CXX) $(CXXEFLAGS) $(PLUGIN_FLAGS) -shared $< -o $@
|
||||||
|
|
||||||
|
./afl-gcc-cmptrs-pass.so: instrumentation/afl-gcc-cmptrs-pass.so.cc | test_deps
|
||||||
|
$(CXX) $(CXXEFLAGS) $(PLUGIN_FLAGS) -shared $< -o $@
|
||||||
|
|
||||||
|
.PHONY: test_build
|
||||||
|
test_build: $(PROGS)
|
||||||
|
@echo "[*] Testing the CC wrapper and instrumentation output..."
|
||||||
|
unset AFL_USE_ASAN AFL_USE_MSAN; ASAN_OPTIONS=detect_leaks=0 AFL_QUIET=1 AFL_INST_RATIO=100 AFL_PATH=. AFL_CC=$(CC) ./afl-gcc-fast $(CFLAGS) $(CPPFLAGS) ./test-instr.c -o test-instr $(LDFLAGS)
|
||||||
|
ASAN_OPTIONS=detect_leaks=0 ./afl-showmap -m none -q -o .test-instr0 ./test-instr </dev/null
|
||||||
|
echo 1 | ASAN_OPTIONS=detect_leaks=0 ./afl-showmap -m none -q -o .test-instr1 ./test-instr
|
||||||
|
@rm -f test-instr
|
||||||
|
@cmp -s .test-instr0 .test-instr1; DR="$$?"; rm -f .test-instr0 .test-instr1; if [ "$$DR" = "0" ]; then echo; echo "Oops, the instrumentation does not seem to be behaving correctly!"; echo; echo "Please post to https://github.com/AFLplusplus/AFLplusplus/issues to troubleshoot the issue."; echo; exit 1; fi
|
||||||
|
@echo "[+] All right, the instrumentation seems to be working!"
|
||||||
|
|
||||||
|
.PHONY: all_done
|
||||||
|
all_done: test_build
|
||||||
|
@echo "[+] All done! You can now use './afl-gcc-fast' to compile programs."
|
||||||
|
|
||||||
|
.NOTPARALLEL: clean
|
||||||
|
|
||||||
|
%.8: %
|
||||||
|
@echo .TH $* 8 `date "+%Y-%m-%d"` "AFL++" > ./$@
|
||||||
|
@echo .SH NAME >> ./$@
|
||||||
|
@echo .B $* >> ./$@
|
||||||
|
@echo >> ./$@
|
||||||
|
@echo .SH SYNOPSIS >> ./$@
|
||||||
|
@./$* -h 2>&1 | head -n 3 | tail -n 1 | sed 's/^\.\///' >> ./$@
|
||||||
|
@echo >> ./$@
|
||||||
|
@echo .SH OPTIONS >> ./$@
|
||||||
|
@echo .nf >> ./$@
|
||||||
|
@./$* -h 2>&1 | tail -n +4 >> ./$@
|
||||||
|
@echo >> ./$@
|
||||||
|
@echo .SH AUTHOR >> ./$@
|
||||||
|
@echo "AFL++ was written by Michal \"lcamtuf\" Zalewski and is maintained by Marc \"van Hauser\" Heuse <mh@mh-sec.de>, Dominik Maier <domenukk@gmail.com>, Andrea Fioraldi <andreafioraldi@gmail.com> and Heiko \"hexcoder-\" Eissfeldt <heiko.eissfeldt@hexco.de>" >> ./$@
|
||||||
|
@echo The homepage of AFL++ is: https://github.com/AFLplusplus/AFLplusplus >> ./$@
|
||||||
|
@echo >> ./$@
|
||||||
|
@echo .SH LICENSE >> ./$@
|
||||||
|
@echo Apache License Version 2.0, January 2004 >> ./$@
|
||||||
|
ln -sf afl-cc.8 ./afl-g++-fast.8
|
||||||
|
|
||||||
|
.PHONY: install
|
||||||
|
install: all
|
||||||
|
ln -sf afl-cc $${DESTDIR}$(BIN_PATH)/afl-gcc-fast
|
||||||
|
ln -sf afl-c++ $${DESTDIR}$(BIN_PATH)/afl-g++-fast
|
||||||
|
ln -sf afl-compiler-rt.o $${DESTDIR}$(HELPER_PATH)/afl-gcc-rt.o
|
||||||
|
install -m 755 ./afl-gcc-pass.so $${DESTDIR}$(HELPER_PATH)
|
||||||
|
install -m 755 ./afl-gcc-cmplog-pass.so $${DESTDIR}$(HELPER_PATH)
|
||||||
|
install -m 755 ./afl-gcc-cmptrs-pass.so $${DESTDIR}$(HELPER_PATH)
|
||||||
|
install -m 644 -T instrumentation/README.gcc_plugin.md $${DESTDIR}$(DOC_PATH)/README.gcc_plugin.md
|
||||||
|
|
||||||
|
.PHONY: clean
|
||||||
|
clean:
|
||||||
|
rm -f *.o *.so *~ a.out core core.[1-9][0-9]* test-instr .test-instr0 .test-instr1 .test2
|
||||||
|
rm -f $(PROGS) afl-common.o ./afl-g++-fast ./afl-g*-fast.8 instrumentation/*.o
|
@ -0,0 +1,575 @@
|
|||||||
|
# american fuzzy lop++ - LLVM instrumentation
|
||||||
|
# -----------------------------------------
|
||||||
|
#
|
||||||
|
# Written by Laszlo Szekeres <lszekeres@google.com> and
|
||||||
|
# Michal Zalewski
|
||||||
|
#
|
||||||
|
# LLVM integration design comes from Laszlo Szekeres.
|
||||||
|
#
|
||||||
|
# Copyright 2015, 2016 Google Inc. 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:
|
||||||
|
#
|
||||||
|
# https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
|
||||||
|
# For Heiko:
|
||||||
|
#TEST_MMAP=1
|
||||||
|
HASH=\#
|
||||||
|
|
||||||
|
PREFIX ?= /usr/local
|
||||||
|
HELPER_PATH ?= $(PREFIX)/lib/afl
|
||||||
|
BIN_PATH ?= $(PREFIX)/bin
|
||||||
|
DOC_PATH ?= $(PREFIX)/share/doc/afl
|
||||||
|
MISC_PATH ?= $(PREFIX)/share/afl
|
||||||
|
MAN_PATH ?= $(PREFIX)/share/man/man8
|
||||||
|
|
||||||
|
BUILD_DATE ?= $(shell date -u -d "@$(SOURCE_DATE_EPOCH)" "+%Y-%m-%d" 2>/dev/null || date -u -r "$(SOURCE_DATE_EPOCH)" "+%Y-%m-%d" 2>/dev/null || date -u "+%Y-%m-%d")
|
||||||
|
|
||||||
|
VERSION = $(shell grep '^$(HASH)define VERSION ' ./config.h | cut -d '"' -f2)
|
||||||
|
|
||||||
|
SYS = $(shell uname -s)
|
||||||
|
|
||||||
|
override LLVM_TOO_NEW_DEFAULT := 18
|
||||||
|
override LLVM_TOO_OLD_DEFAULT := 13
|
||||||
|
|
||||||
|
ifeq "$(SYS)" "OpenBSD"
|
||||||
|
LLVM_CONFIG ?= $(BIN_PATH)/llvm-config
|
||||||
|
HAS_OPT = $(shell test -x $(BIN_PATH)/opt && echo 0 || echo 1)
|
||||||
|
ifeq "$(HAS_OPT)" "1"
|
||||||
|
$(warning llvm_mode needs a complete llvm installation (versions 6.0 up to 13) -> e.g. "pkg_add llvm-7.0.1p9")
|
||||||
|
endif
|
||||||
|
else
|
||||||
|
# Small function to use Bash to detect the latest available clang and clang++ binaries, if using them by that name fails
|
||||||
|
override _CLANG_VERSIONS_TO_TEST := $(patsubst %,-%,$(shell seq $(LLVM_TOO_NEW_DEFAULT) -1 $(LLVM_TOO_OLD_DEFAULT)))
|
||||||
|
detect_newest=$(shell for v in "" $(_CLANG_VERSIONS_TO_TEST); do test -n "$$(command -v -- $1$$v)" && { echo "$1$$v"; break; }; done)
|
||||||
|
LLVM_CONFIG ?= $(call detect_newest,llvm-config)
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifneq "$(LLVM_CONFIG)" ""
|
||||||
|
override LLVM_RAW_VER := $(shell $(LLVM_CONFIG) --version 2>/dev/null)
|
||||||
|
LLVMVER := $(subst svn,,$(subst git,,$(LLVM_RAW_VER)))
|
||||||
|
|
||||||
|
LLVM_BINDIR := $(shell $(LLVM_CONFIG) --bindir 2>/dev/null)
|
||||||
|
LLVM_LIBDIR := $(shell $(LLVM_CONFIG) --libdir 2>/dev/null)
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifneq "$(LLVMVER)" ""
|
||||||
|
LLVM_MAJOR := $(firstword $(subst ., ,$(LLVMVER)))
|
||||||
|
LLVM_MINOR := $(firstword $(subst ., ,$(subst $(LLVM_MAJOR).,,$(LLVMVER))))
|
||||||
|
LLVM_TOO_NEW := $(shell test $(LLVM_MAJOR) -gt $(LLVM_TOO_NEW_DEFAULT) && echo 1 || echo 0)
|
||||||
|
LLVM_TOO_OLD := $(shell test $(LLVM_MAJOR) -lt $(LLVM_TOO_OLD_DEFAULT) && echo 1 || echo 0)
|
||||||
|
LLVM_NEW_API := $(shell test $(LLVM_MAJOR) -ge 10 && echo 1 || echo 0)
|
||||||
|
LLVM_NEWER_API := $(shell test $(LLVM_MAJOR) -ge 16 && echo 1 || echo 0)
|
||||||
|
LLVM_13_OK := $(shell test $(LLVM_MAJOR) -ge 13 && echo 1 || echo 0)
|
||||||
|
LLVM_HAVE_LTO := $(shell test $(LLVM_MAJOR) -ge 12 && echo 1 || echo 0)
|
||||||
|
endif
|
||||||
|
|
||||||
|
LLVM_STDCXX := gnu++11
|
||||||
|
LLVM_LTO := 0
|
||||||
|
LLVM_UNSUPPORTED := $(shell echo "$(LLVMVER)" | grep -E -q '^[0-2]\.|^3\.[0-8]\.' && echo 1 || echo 0)
|
||||||
|
# Uncomment to see the values assigned above
|
||||||
|
# $(foreach var,LLVM_CONFIG LLVMVER LLVM_MAJOR LLVM_MINOR LLVM_TOO_NEW LLVM_TOO_OLD LLVM_TOO_NEW_DEFAULT LLVM_TOO_OLD_DEFAULT LLVM_NEW_API LLVM_NEWER_API LLVM_13_OK LLVM_HAVE_LTO LLVM_BINDIR LLVM_LIBDIR LLVM_STDCXX LLVM_APPLE_XCODE LLVM_LTO LLVM_UNSUPPORTED,$(warning $(var) = $($(var))))
|
||||||
|
|
||||||
|
ifeq "$(LLVMVER)" ""
|
||||||
|
$(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 3.8 onwards)
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq "$(LLVM_TOO_NEW)" "1"
|
||||||
|
$(warning you are using an in-development llvm version - this might break llvm_mode!)
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq "$(LLVM_TOO_OLD)" "1"
|
||||||
|
$(warning you are using an outdated LLVM version! Please use at least LLVM 13 or newer!)
|
||||||
|
$(shell sleep 2)
|
||||||
|
endif
|
||||||
|
|
||||||
|
# No switching the meaning of LLVM_TOO_OLD
|
||||||
|
LLVM_TOO_OLD=1
|
||||||
|
|
||||||
|
ifeq "$(LLVM_MAJOR)" "9"
|
||||||
|
$(info [+] llvm_mode detected llvm 9, enabling neverZero implementation)
|
||||||
|
LLVM_TOO_OLD=0
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq "$(LLVM_NEW_API)" "1"
|
||||||
|
$(info [+] llvm_mode detected llvm 10+, enabling neverZero implementation and c++14)
|
||||||
|
LLVM_STDCXX = c++14
|
||||||
|
LLVM_TOO_OLD=0
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq "$(LLVM_NEWER_API)" "1"
|
||||||
|
$(info [+] llvm_mode detected llvm 16+, enabling c++17)
|
||||||
|
LLVM_STDCXX = c++17
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq "$(LLVM_HAVE_LTO)" "1"
|
||||||
|
$(info [+] llvm_mode detected llvm 12+, enabling afl-lto LTO implementation)
|
||||||
|
LLVM_LTO = 1
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq "$(LLVM_LTO)" "0"
|
||||||
|
$(info [+] llvm_mode detected llvm < 12, afl-lto LTO will not be build.)
|
||||||
|
endif
|
||||||
|
|
||||||
|
# We were using llvm-config --bindir to get the location of clang, but
|
||||||
|
# this seems to be busted on some distros, so using the one in $PATH is
|
||||||
|
# probably better.
|
||||||
|
|
||||||
|
CC = $(LLVM_BINDIR)/clang
|
||||||
|
CXX = $(LLVM_BINDIR)/clang++
|
||||||
|
|
||||||
|
LLVM_APPLE_XCODE := $(shell $(CC) -v 2>&1 | grep -q Apple && echo 1 || echo 0)
|
||||||
|
ifeq "$(LLVM_APPLE_XCODE)" "1"
|
||||||
|
$(warning llvm_mode will not compile with Xcode clang...)
|
||||||
|
endif
|
||||||
|
|
||||||
|
# llvm-config --bindir may not providing a valid path, so ...
|
||||||
|
ifeq "$(shell test -e $(CC) || echo 1 )" "1"
|
||||||
|
# however we must ensure that this is not a "CC=gcc make"
|
||||||
|
ifeq "$(shell command -v $(CC) 2> /dev/null)" ""
|
||||||
|
# we do not have a valid CC variable so we try alternatives
|
||||||
|
ifeq "$(shell test -e '$(BIN_DIR)/clang' && echo 1)" "1"
|
||||||
|
# we found one in the local install directory, lets use these
|
||||||
|
CC = $(BIN_DIR)/clang
|
||||||
|
else
|
||||||
|
# hope for the best
|
||||||
|
$(warning we have trouble finding clang - llvm-config is not helping us)
|
||||||
|
CC = clang
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
# llvm-config --bindir may not providing a valid path, so ...
|
||||||
|
ifeq "$(shell test -e $(CXX) || echo 1 )" "1"
|
||||||
|
# however we must ensure that this is not a "CXX=g++ make"
|
||||||
|
ifeq "$(shell command -v $(CXX) 2> /dev/null)" ""
|
||||||
|
# we do not have a valid CXX variable so we try alternatives
|
||||||
|
ifeq "$(shell test -e '$(BIN_DIR)/clang++' && echo 1)" "1"
|
||||||
|
# we found one in the local install directory, lets use these
|
||||||
|
CXX = $(BIN_DIR)/clang++
|
||||||
|
else
|
||||||
|
# hope for the best
|
||||||
|
$(warning we have trouble finding clang++ - llvm-config is not helping us)
|
||||||
|
CXX = clang++
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
# sanity check.
|
||||||
|
# Are versions of clang --version and llvm-config --version equal?
|
||||||
|
CLANGVER = $(shell $(CC) --version | sed -E -ne '/^.*version\ (1?[0-9]\.[0-9]\.[0-9]).*/s//\1/p')
|
||||||
|
|
||||||
|
# I disable this because it does not make sense with what we did before (marc)
|
||||||
|
# We did exactly set these 26 lines above with these values, and it would break
|
||||||
|
# "CC=gcc make" etc. usages
|
||||||
|
ifeq "$(findstring clang, $(shell $(CC) --version 2>/dev/null))" ""
|
||||||
|
CC_SAVE := $(LLVM_BINDIR)/clang
|
||||||
|
else
|
||||||
|
CC_SAVE := $(CC)
|
||||||
|
endif
|
||||||
|
ifeq "$(findstring clang, $(shell $(CXX) --version 2>/dev/null))" ""
|
||||||
|
CXX_SAVE := $(LLVM_BINDIR)/clang++
|
||||||
|
else
|
||||||
|
CXX_SAVE := $(CXX)
|
||||||
|
endif
|
||||||
|
|
||||||
|
CLANG_BIN := $(CC_SAVE)
|
||||||
|
CLANGPP_BIN := $(CXX_SAVE)
|
||||||
|
|
||||||
|
ifeq "$(CC_SAVE)" "$(LLVM_BINDIR)/clang"
|
||||||
|
USE_BINDIR = 1
|
||||||
|
else
|
||||||
|
ifeq "$(CXX_SAVE)" "$(LLVM_BINDIR)/clang++"
|
||||||
|
USE_BINDIR = 1
|
||||||
|
else
|
||||||
|
USE_BINDIR = 0
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
# On old platform we cannot compile with clang because std++ libraries are too
|
||||||
|
# old. For these we need to use gcc/g++, so if we find REAL_CC and REAL_CXX
|
||||||
|
# variable we override the compiler variables here
|
||||||
|
ifneq "$(REAL_CC)" ""
|
||||||
|
CC = $(REAL_CC)
|
||||||
|
endif
|
||||||
|
ifneq "$(REAL_CXX)" ""
|
||||||
|
CXX = $(REAL_CXX)
|
||||||
|
endif
|
||||||
|
|
||||||
|
#
|
||||||
|
# Now it can happen that CC points to clang - but there is no clang on the
|
||||||
|
# system. Then we fall back to cc
|
||||||
|
#
|
||||||
|
ifeq "$(shell command -v $(CC) 2>/dev/null)" ""
|
||||||
|
CC = cc
|
||||||
|
endif
|
||||||
|
ifeq "$(shell command -v $(CXX) 2>/dev/null)" ""
|
||||||
|
CXX = c++
|
||||||
|
endif
|
||||||
|
|
||||||
|
|
||||||
|
# After we set CC/CXX we can start makefile magic tests
|
||||||
|
|
||||||
|
#ifeq "$(shell echo 'int main() {return 0; }' | $(CC) -x c - -march=native -o .test 2>/dev/null && echo 1 || echo 0 ; rm -f .test )" "1"
|
||||||
|
# CFLAGS_OPT = -march=native
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ifeq "$(shell echo 'int main() {return 0; }' | $(CLANG_BIN) -x c - -flto=full -o .test 2>/dev/null && echo 1 || echo 0 ; rm -f .test )" "1"
|
||||||
|
AFL_CLANG_FLTO ?= -flto=full
|
||||||
|
else
|
||||||
|
ifeq "$(shell echo 'int main() {return 0; }' | $(CLANG_BIN) -x c - -flto=thin -o .test 2>/dev/null && echo 1 || echo 0 ; rm -f .test )" "1"
|
||||||
|
AFL_CLANG_FLTO ?= -flto=thin
|
||||||
|
else
|
||||||
|
ifeq "$(shell echo 'int main() {return 0; }' | $(CLANG_BIN) -x c - -flto -o .test 2>/dev/null && echo 1 || echo 0 ; rm -f .test )" "1"
|
||||||
|
AFL_CLANG_FLTO ?= -flto
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq "$(LLVM_LTO)" "1"
|
||||||
|
ifneq "$(AFL_CLANG_FLTO)" ""
|
||||||
|
ifeq "$(AFL_REAL_LD)" ""
|
||||||
|
ifneq "$(shell readlink $(LLVM_BINDIR)/ld.lld 2>&1)" ""
|
||||||
|
AFL_REAL_LD = $(LLVM_BINDIR)/ld.lld
|
||||||
|
else ifneq "$(shell command -v ld.lld 2>/dev/null)" ""
|
||||||
|
AFL_REAL_LD = $(shell command -v ld.lld)
|
||||||
|
TMP_LDLDD_VERSION = $(shell $(AFL_REAL_LD) --version | awk '{ print $$2 }')
|
||||||
|
ifeq "$(LLVMVER)" "$(TMP_LDLDD_VERSION)"
|
||||||
|
$(warning ld.lld found in a weird location ($(AFL_REAL_LD)), but its the same version as LLVM so we will allow it)
|
||||||
|
else
|
||||||
|
$(warning ld.lld found in a weird location ($(AFL_REAL_LD)) and its of a different version than LLMV ($(TMP_LDLDD_VERSION) vs. $(LLVMVER)) - cannot enable LTO mode)
|
||||||
|
AFL_REAL_LD=
|
||||||
|
LLVM_LTO = 0
|
||||||
|
endif
|
||||||
|
undefine TMP_LDLDD_VERSION
|
||||||
|
else
|
||||||
|
$(warning ld.lld not found, cannot enable LTO mode)
|
||||||
|
LLVM_LTO = 0
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
else
|
||||||
|
$(warning clang option -flto is not working - maybe LLVMgold.so not found - cannot enable LTO mode)
|
||||||
|
LLVM_LTO = 0
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
AFL_CLANG_FUSELD=
|
||||||
|
ifeq "$(LLVM_LTO)" "1"
|
||||||
|
ifeq "$(shell echo 'int main() {return 0; }' | $(CLANG_BIN) -x c - -fuse-ld=$$(command -v ld) -o .test 2>/dev/null && echo 1 || echo 0 ; rm -f .test )" "1"
|
||||||
|
AFL_CLANG_FUSELD=1
|
||||||
|
ifeq "$(shell echo 'int main() {return 0; }' | $(CLANG_BIN) -x c - -fuse-ld=ld.lld --ld-path=$(AFL_REAL_LD) -o .test 2>/dev/null && echo 1 || echo 0 ; rm -f .test )" "1"
|
||||||
|
AFL_CLANG_LDPATH=1
|
||||||
|
endif
|
||||||
|
else
|
||||||
|
$(warning -fuse-ld is not working, cannot enable LTO mode)
|
||||||
|
LLVM_LTO = 0
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq "$(shell echo 'int main() {return 0; }' | $(CLANG_BIN) -x c - -fdebug-prefix-map=$(CURDIR)=llvm_mode -o .test 2>/dev/null && echo 1 || echo 0 ; rm -f .test )" "1"
|
||||||
|
AFL_CLANG_DEBUG_PREFIX = -fdebug-prefix-map="$(CURDIR)=llvm_mode"
|
||||||
|
else
|
||||||
|
AFL_CLANG_DEBUG_PREFIX =
|
||||||
|
endif
|
||||||
|
|
||||||
|
CFLAGS ?= -O3 -funroll-loops -fPIC
|
||||||
|
# -D_FORTIFY_SOURCE=1
|
||||||
|
CFLAGS_SAFE := -Wall -g -Wno-cast-qual -Wno-variadic-macros -Wno-pointer-sign \
|
||||||
|
-I ./include/ -I ./instrumentation/ \
|
||||||
|
-DAFL_PATH=\"$(HELPER_PATH)\" -DBIN_PATH=\"$(BIN_PATH)\" \
|
||||||
|
-DLLVM_BINDIR=\"$(LLVM_BINDIR)\" -DVERSION=\"$(VERSION)\" \
|
||||||
|
-DLLVM_LIBDIR=\"$(LLVM_LIBDIR)\" -DLLVM_VERSION=\"$(LLVMVER)\" \
|
||||||
|
-DAFL_CLANG_FLTO=\"$(AFL_CLANG_FLTO)\" -DAFL_REAL_LD=\"$(AFL_REAL_LD)\" \
|
||||||
|
-DAFL_CLANG_LDPATH=\"$(AFL_CLANG_LDPATH)\" -DAFL_CLANG_FUSELD=\"$(AFL_CLANG_FUSELD)\" \
|
||||||
|
-DCLANG_BIN=\"$(CLANG_BIN)\" -DCLANGPP_BIN=\"$(CLANGPP_BIN)\" -DUSE_BINDIR=$(USE_BINDIR) \
|
||||||
|
-Wno-unused-function $(AFL_CLANG_DEBUG_PREFIX)
|
||||||
|
ifndef LLVM_DEBUG
|
||||||
|
CFLAGS_SAFE += -Wno-deprecated
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifdef CODE_COVERAGE
|
||||||
|
override CFLAGS_SAFE += -D__AFL_CODE_COVERAGE=1
|
||||||
|
override LDFLAGS += -ldl
|
||||||
|
endif
|
||||||
|
|
||||||
|
override CFLAGS += $(CFLAGS_SAFE)
|
||||||
|
|
||||||
|
ifdef AFL_TRACE_PC
|
||||||
|
$(info Compile option AFL_TRACE_PC is deprecated, just set AFL_LLVM_INSTRUMENT=PCGUARD to activate when compiling targets )
|
||||||
|
endif
|
||||||
|
|
||||||
|
CXXFLAGS ?= -O3 -funroll-loops -fPIC
|
||||||
|
# -D_FORTIFY_SOURCE=1
|
||||||
|
override CXXFLAGS += -Wall -g -I ./include/ \
|
||||||
|
-DVERSION=\"$(VERSION)\" -Wno-variadic-macros -Wno-deprecated-copy-with-dtor \
|
||||||
|
-DLLVM_MINOR=$(LLVM_MINOR) -DLLVM_MAJOR=$(LLVM_MAJOR)
|
||||||
|
|
||||||
|
ifneq "$(shell $(LLVM_CONFIG) --includedir) 2> /dev/null" ""
|
||||||
|
CLANG_CFL = -I$(shell $(LLVM_CONFIG) --includedir)
|
||||||
|
endif
|
||||||
|
ifneq "$(LLVM_CONFIG)" ""
|
||||||
|
CLANG_CFL += -I$(shell dirname $(LLVM_CONFIG))/../include
|
||||||
|
endif
|
||||||
|
CLANG_CPPFL = $$($(LLVM_CONFIG) --cxxflags) -fno-rtti -fno-exceptions -fPIC $(CXXFLAGS) $(CPPFLAGS) -Wno-deprecated-declarations
|
||||||
|
CLANG_LFL = $$($(LLVM_CONFIG) --ldflags) $(LDFLAGS)
|
||||||
|
|
||||||
|
# wasm fuzzing: disable thread-local storage and unset LLVM debug flag
|
||||||
|
ifdef WAFL_MODE
|
||||||
|
$(info Compiling libraries for use with WAVM)
|
||||||
|
CLANG_CPPFL += -DNDEBUG -DNO_TLS
|
||||||
|
endif
|
||||||
|
|
||||||
|
# User teor2345 reports that this is required to make things work on MacOS X.
|
||||||
|
ifeq "$(SYS)" "Darwin"
|
||||||
|
CLANG_LFL += -Wl,-undefined,dynamic_lookup
|
||||||
|
override LLVM_HAVE_LTO := 0
|
||||||
|
override LLVM_LTO := 0
|
||||||
|
else
|
||||||
|
CLANG_CPPFL += -Wl,-znodelete
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq "$(SYS)" "OpenBSD"
|
||||||
|
CLANG_LFL += $$($(LLVM_CONFIG) --libdir)/libLLVM.so
|
||||||
|
CLANG_CPPFL += -mno-retpoline
|
||||||
|
CFLAGS += -mno-retpoline
|
||||||
|
# Needed for unwind symbols
|
||||||
|
LDFLAGS += -lc++abi -lpthread
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq "$(shell echo '$(HASH)include <sys/ipc.h>@$(HASH)include <sys/shm.h>@int main() { int _id = shmget(IPC_PRIVATE, 65536, IPC_CREAT | IPC_EXCL | 0600); shmctl(_id, IPC_RMID, 0); return 0;}' | tr @ '\n' | $(CC) -x c - -o .test2 2>/dev/null && echo 1 || echo 0 ; rm -f .test2 )" "1"
|
||||||
|
SHMAT_OK=1
|
||||||
|
else
|
||||||
|
SHMAT_OK=0
|
||||||
|
CFLAGS_SAFE += -DUSEMMAP=1
|
||||||
|
LDFLAGS += -Wno-deprecated-declarations
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq "$(TEST_MMAP)" "1"
|
||||||
|
SHMAT_OK=0
|
||||||
|
CFLAGS_SAFE += -DUSEMMAP=1
|
||||||
|
LDFLAGS += -Wno-deprecated-declarations
|
||||||
|
endif
|
||||||
|
|
||||||
|
PROGS_ALWAYS = ./afl-cc ./afl-compiler-rt.o ./afl-compiler-rt-32.o ./afl-compiler-rt-64.o
|
||||||
|
PROGS = $(PROGS_ALWAYS) ./afl-llvm-pass.so ./SanitizerCoveragePCGUARD.so ./split-compares-pass.so ./split-switches-pass.so ./cmplog-routines-pass.so ./cmplog-instructions-pass.so ./cmplog-switches-pass.so ./afl-llvm-dict2file.so ./compare-transform-pass.so ./afl-ld-lto ./afl-llvm-lto-instrumentlist.so ./SanitizerCoverageLTO.so ./injection-pass.so
|
||||||
|
|
||||||
|
# If prerequisites are not given, warn, do not build anything, and exit with code 0
|
||||||
|
ifeq "$(LLVMVER)" ""
|
||||||
|
NO_BUILD = 1
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifneq "$(LLVM_UNSUPPORTED)$(LLVM_APPLE_XCODE)" "00"
|
||||||
|
NO_BUILD = 1
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq "$(NO_BUILD)" "1"
|
||||||
|
TARGETS = test_shm $(PROGS_ALWAYS) afl-cc.8
|
||||||
|
else
|
||||||
|
TARGETS = test_shm test_deps $(PROGS) afl-cc.8 test_build all_done
|
||||||
|
endif
|
||||||
|
|
||||||
|
LLVM_MIN_4_0_1 = $(shell awk 'function tonum(ver, a) {split(ver,a,"."); return a[1]*1000000+a[2]*1000+a[3]} BEGIN { exit tonum(ARGV[1]) >= tonum(ARGV[2]) }' $(LLVMVER) 4.0.1; echo $$?)
|
||||||
|
|
||||||
|
.PHONY: all
|
||||||
|
all: $(TARGETS)
|
||||||
|
|
||||||
|
.PHONY: test_shm
|
||||||
|
ifeq "$(SHMAT_OK)" "1"
|
||||||
|
test_shm:
|
||||||
|
@echo "[+] shmat seems to be working."
|
||||||
|
@rm -f .test2
|
||||||
|
else
|
||||||
|
test_shm:
|
||||||
|
@echo "[-] shmat seems not to be working, switching to mmap implementation"
|
||||||
|
endif
|
||||||
|
|
||||||
|
.PHONY: no_build
|
||||||
|
no_build:
|
||||||
|
@printf "%b\\n" "\\033[0;31mPrerequisites are not met, skipping build llvm_mode\\033[0m"
|
||||||
|
|
||||||
|
.PHONY: test_deps
|
||||||
|
test_deps:
|
||||||
|
@echo "[*] Checking for working 'llvm-config'..."
|
||||||
|
ifneq "$(LLVM_APPLE_XCODE)" "1"
|
||||||
|
@type $(LLVM_CONFIG) >/dev/null 2>&1 || ( echo "[-] Oops, can't find 'llvm-config'. Install clang or set \$$LLVM_CONFIG or \$$PATH beforehand."; echo " (Sometimes, the binary will be named llvm-config-11 or something like that.)"; exit 1 )
|
||||||
|
endif
|
||||||
|
@echo "[*] Checking for working '$(CC)'..."
|
||||||
|
@type $(CC) >/dev/null 2>&1 || ( echo "[-] Oops, can't find '$(CC)'. Make sure that it's in your \$$PATH (or set \$$CC and \$$CXX)."; exit 1 )
|
||||||
|
@echo "[*] Checking for matching versions of '$(CC)' and '$(LLVM_CONFIG)'"
|
||||||
|
ifneq "$(CLANGVER)" "$(LLVMVER)"
|
||||||
|
@echo "[!] WARNING: we have llvm-config version $(LLVMVER) and a clang version $(CLANGVER)"
|
||||||
|
else
|
||||||
|
@echo "[*] We have llvm-config version $(LLVMVER) with a clang version $(CLANGVER), good."
|
||||||
|
endif
|
||||||
|
@echo "[*] Checking for './afl-showmap'..."
|
||||||
|
@test -f ./afl-showmap || ( echo "[-] Oops, can't find './afl-showmap'. Be sure to compile AFL first."; exit 1 )
|
||||||
|
@echo "[+] All set and ready to build."
|
||||||
|
|
||||||
|
instrumentation/afl-common.o: ./src/afl-common.c
|
||||||
|
$(CC) $(CFLAGS) $(CPPFLAGS) -c $< -o $@ $(LDFLAGS)
|
||||||
|
|
||||||
|
./afl-cc: src/afl-cc.c instrumentation/afl-common.o
|
||||||
|
$(CC) $(CLANG_CFL) $(CFLAGS) $(CPPFLAGS) $< instrumentation/afl-common.o -o $@ -DLLVM_MINOR=$(LLVM_MINOR) -DLLVM_MAJOR=$(LLVM_MAJOR) $(LDFLAGS) -DCFLAGS_OPT=\"$(CFLAGS_OPT)\" -lm
|
||||||
|
@ln -sf afl-cc ./afl-c++
|
||||||
|
@ln -sf afl-cc ./afl-gcc
|
||||||
|
@ln -sf afl-cc ./afl-g++
|
||||||
|
@ln -sf afl-cc ./afl-clang
|
||||||
|
@ln -sf afl-cc ./afl-clang++
|
||||||
|
@ln -sf afl-cc ./afl-clang-fast
|
||||||
|
@ln -sf afl-cc ./afl-clang-fast++
|
||||||
|
ifneq "$(AFL_CLANG_FLTO)" ""
|
||||||
|
ifeq "$(LLVM_LTO)" "1"
|
||||||
|
@ln -sf afl-cc ./afl-clang-lto
|
||||||
|
@ln -sf afl-cc ./afl-clang-lto++
|
||||||
|
@ln -sf afl-cc ./afl-lto
|
||||||
|
@ln -sf afl-cc ./afl-lto++
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
instrumentation/afl-llvm-common.o: instrumentation/afl-llvm-common.cc instrumentation/afl-llvm-common.h
|
||||||
|
$(CXX) $(CFLAGS) $(CPPFLAGS) $$($(LLVM_CONFIG) --cxxflags) -fno-rtti -fPIC -std=$(LLVM_STDCXX) -c $< -o $@
|
||||||
|
|
||||||
|
./afl-llvm-pass.so: instrumentation/afl-llvm-pass.so.cc instrumentation/afl-llvm-common.o | test_deps
|
||||||
|
ifeq "$(LLVM_MIN_4_0_1)" "0"
|
||||||
|
$(info [!] N-gram branch coverage instrumentation is not available for llvm version $(LLVMVER))
|
||||||
|
endif
|
||||||
|
$(CXX) $(CLANG_CPPFL) -Wdeprecated -fno-rtti -fPIC -std=$(LLVM_STDCXX) -shared $< -o $@ $(CLANG_LFL) instrumentation/afl-llvm-common.o
|
||||||
|
|
||||||
|
./SanitizerCoveragePCGUARD.so: instrumentation/SanitizerCoveragePCGUARD.so.cc instrumentation/afl-llvm-common.o | test_deps
|
||||||
|
ifeq "$(LLVM_13_OK)" "1"
|
||||||
|
-$(CXX) $(CLANG_CPPFL) -fno-rtti -fPIC -std=$(LLVM_STDCXX) -shared $< -o $@ $(CLANG_LFL) -Wno-deprecated-copy-dtor -Wdeprecated instrumentation/afl-llvm-common.o
|
||||||
|
endif
|
||||||
|
|
||||||
|
./afl-llvm-lto-instrumentlist.so: instrumentation/afl-llvm-lto-instrumentlist.so.cc instrumentation/afl-llvm-common.o
|
||||||
|
ifeq "$(LLVM_LTO)" "1"
|
||||||
|
$(CXX) $(CLANG_CPPFL) -fno-rtti -fPIC -std=$(LLVM_STDCXX) -shared $< -o $@ $(CLANG_LFL) instrumentation/afl-llvm-common.o
|
||||||
|
endif
|
||||||
|
|
||||||
|
./afl-ld-lto: src/afl-ld-lto.c
|
||||||
|
ifeq "$(LLVM_LTO)" "1"
|
||||||
|
$(CC) $(CFLAGS) $(CPPFLAGS) $< -o $@
|
||||||
|
endif
|
||||||
|
|
||||||
|
./SanitizerCoverageLTO.so: instrumentation/SanitizerCoverageLTO.so.cc instrumentation/afl-llvm-common.o
|
||||||
|
ifeq "$(LLVM_LTO)" "1"
|
||||||
|
$(CXX) $(CLANG_CPPFL) -Wno-writable-strings -fno-rtti -fPIC -std=$(LLVM_STDCXX) -shared $< -o $@ $(CLANG_LFL) instrumentation/afl-llvm-common.o
|
||||||
|
$(CLANG_BIN) $(CFLAGS_SAFE) $(CPPFLAGS) -Wno-unused-result -O0 $(AFL_CLANG_FLTO) -fPIC -c instrumentation/afl-llvm-rt-lto.o.c -o ./afl-llvm-rt-lto.o
|
||||||
|
@$(CLANG_BIN) $(CFLAGS_SAFE) $(CPPFLAGS) -Wno-unused-result -O0 $(AFL_CLANG_FLTO) -m64 -fPIC -c instrumentation/afl-llvm-rt-lto.o.c -o ./afl-llvm-rt-lto-64.o 2>/dev/null; if [ "$$?" = "0" ]; then : ; fi
|
||||||
|
@$(CLANG_BIN) $(CFLAGS_SAFE) $(CPPFLAGS) -Wno-unused-result -O0 $(AFL_CLANG_FLTO) -m32 -fPIC -c instrumentation/afl-llvm-rt-lto.o.c -o ./afl-llvm-rt-lto-32.o 2>/dev/null; if [ "$$?" = "0" ]; then : ; fi
|
||||||
|
endif
|
||||||
|
|
||||||
|
# laf
|
||||||
|
./split-switches-pass.so: instrumentation/split-switches-pass.so.cc instrumentation/afl-llvm-common.o | test_deps
|
||||||
|
$(CXX) $(CLANG_CPPFL) -shared $< -o $@ $(CLANG_LFL) instrumentation/afl-llvm-common.o
|
||||||
|
./compare-transform-pass.so: instrumentation/compare-transform-pass.so.cc instrumentation/afl-llvm-common.o | test_deps
|
||||||
|
$(CXX) $(CLANG_CPPFL) -shared $< -o $@ $(CLANG_LFL) instrumentation/afl-llvm-common.o
|
||||||
|
./split-compares-pass.so: instrumentation/split-compares-pass.so.cc instrumentation/afl-llvm-common.o | test_deps
|
||||||
|
$(CXX) $(CLANG_CPPFL) -shared $< -o $@ $(CLANG_LFL) instrumentation/afl-llvm-common.o
|
||||||
|
# /laf
|
||||||
|
|
||||||
|
./cmplog-routines-pass.so: instrumentation/cmplog-routines-pass.cc instrumentation/afl-llvm-common.o | test_deps
|
||||||
|
$(CXX) $(CLANG_CPPFL) -shared $< -o $@ $(CLANG_LFL) instrumentation/afl-llvm-common.o
|
||||||
|
|
||||||
|
./cmplog-instructions-pass.so: instrumentation/cmplog-instructions-pass.cc instrumentation/afl-llvm-common.o | test_deps
|
||||||
|
$(CXX) $(CLANG_CPPFL) -shared $< -o $@ $(CLANG_LFL) instrumentation/afl-llvm-common.o
|
||||||
|
|
||||||
|
./cmplog-switches-pass.so: instrumentation/cmplog-switches-pass.cc instrumentation/afl-llvm-common.o | test_deps
|
||||||
|
$(CXX) $(CLANG_CPPFL) -shared $< -o $@ $(CLANG_LFL) instrumentation/afl-llvm-common.o
|
||||||
|
|
||||||
|
afl-llvm-dict2file.so: instrumentation/afl-llvm-dict2file.so.cc instrumentation/afl-llvm-common.o | test_deps
|
||||||
|
$(CXX) $(CLANG_CPPFL) -shared $< -o $@ $(CLANG_LFL) instrumentation/afl-llvm-common.o
|
||||||
|
|
||||||
|
./injection-pass.so: instrumentation/injection-pass.cc instrumentation/afl-llvm-common.o | test_deps
|
||||||
|
$(CXX) $(CLANG_CPPFL) -shared $< -o $@ $(CLANG_LFL) instrumentation/afl-llvm-common.o
|
||||||
|
|
||||||
|
.PHONY: document
|
||||||
|
document:
|
||||||
|
$(CLANG_BIN) -D_AFL_DOCUMENT_MUTATIONS $(CFLAGS_SAFE) $(CPPFLAGS) $(CLANG_CFL) -O3 -Wno-unused-result -fPIC -c instrumentation/afl-compiler-rt.o.c -o ./afl-compiler-rt.o
|
||||||
|
@$(CLANG_BIN) -D_AFL_DOCUMENT_MUTATIONS $(CFLAGS_SAFE) $(CPPFLAGS) $(CLANG_CFL) -O3 -Wno-unused-result -m32 -fPIC -c instrumentation/afl-compiler-rt.o.c -o ./afl-compiler-rt-32.o 2>/dev/null; if [ "$$?" = "0" ]; then echo "success!"; else echo "failed (that's fine)"; fi
|
||||||
|
@$(CLANG_BIN) -D_AFL_DOCUMENT_MUTATIONS $(CFLAGS_SAFE) $(CPPFLAGS) $(CLANG_CFL) -O3 -Wno-unused-result -m64 -fPIC -c instrumentation/afl-compiler-rt.o.c -o ./afl-compiler-rt-64.o 2>/dev/null; if [ "$$?" = "0" ]; then echo "success!"; else echo "failed (that's fine)"; fi
|
||||||
|
|
||||||
|
./afl-compiler-rt.o: instrumentation/afl-compiler-rt.o.c
|
||||||
|
$(CC) $(CLANG_CFL) $(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) $(CLANG_CFL) $(CFLAGS_SAFE) $(CPPFLAGS) -O3 -Wno-unused-result -m32 -fPIC -c $< -o $@ 2>/dev/null; if [ "$$?" = "0" ]; then echo "success!"; 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) $(CLANG_CFL) $(CFLAGS_SAFE) $(CPPFLAGS) -O3 -Wno-unused-result -m64 -fPIC -c $< -o $@ 2>/dev/null; if [ "$$?" = "0" ]; then echo "success!"; else echo "failed (that's fine)"; fi
|
||||||
|
|
||||||
|
.PHONY: test_build
|
||||||
|
test_build: $(PROGS)
|
||||||
|
@echo "[*] Testing the CC wrapper and instrumentation output..."
|
||||||
|
unset AFL_USE_ASAN AFL_USE_MSAN AFL_INST_RATIO; ASAN_OPTIONS=detect_leaks=0 AFL_QUIET=1 AFL_PATH=. AFL_LLVM_LAF_ALL=1 ./afl-cc $(CFLAGS) $(CPPFLAGS) ./test-instr.c -o test-instr $(LDFLAGS)
|
||||||
|
ASAN_OPTIONS=detect_leaks=0 ./afl-showmap -m none -q -o .test-instr0 ./test-instr < /dev/null
|
||||||
|
echo 1 | ASAN_OPTIONS=detect_leaks=0 ./afl-showmap -m none -q -o .test-instr1 ./test-instr
|
||||||
|
@rm -f test-instr
|
||||||
|
@cmp -s .test-instr0 .test-instr1; DR="$$?"; rm -f .test-instr0 .test-instr1; if [ "$$DR" = "0" ]; then echo; echo "Oops, the instrumentation does not seem to be behaving correctly!"; echo; echo "Please post to https://github.com/AFLplusplus/AFLplusplus/issues to troubleshoot the issue."; echo; exit 1; fi
|
||||||
|
@echo "[+] All right, the instrumentation seems to be working!"
|
||||||
|
|
||||||
|
.PHONY: all_done
|
||||||
|
all_done: test_build
|
||||||
|
@echo "[+] All done! You can now use './afl-cc' to compile programs."
|
||||||
|
|
||||||
|
.NOTPARALLEL: clean
|
||||||
|
|
||||||
|
.PHONY: install
|
||||||
|
install: all
|
||||||
|
@install -d -m 755 $${DESTDIR}$(BIN_PATH) $${DESTDIR}$(HELPER_PATH) $${DESTDIR}$(DOC_PATH) $${DESTDIR}$(MISC_PATH)
|
||||||
|
@if [ -f ./afl-cc ]; then set -e; install -m 755 ./afl-cc $${DESTDIR}$(BIN_PATH); ln -sf afl-cc $${DESTDIR}$(BIN_PATH)/afl-c++; fi
|
||||||
|
@rm -f $${DESTDIR}$(HELPER_PATH)/afl-llvm-rt*.o $${DESTDIR}$(HELPER_PATH)/afl-gcc-rt*.o
|
||||||
|
@if [ -f ./afl-compiler-rt.o ]; then set -e; install -m 755 ./afl-compiler-rt.o $${DESTDIR}$(HELPER_PATH); fi
|
||||||
|
@if [ -f ./afl-lto ]; then set -e; ln -sf afl-cc $${DESTDIR}$(BIN_PATH)/afl-lto; ln -sf afl-cc $${DESTDIR}$(BIN_PATH)/afl-lto++; ln -sf afl-cc $${DESTDIR}$(BIN_PATH)/afl-clang-lto; ln -sf afl-cc $${DESTDIR}$(BIN_PATH)/afl-clang-lto++; install -m 755 ./afl-llvm-rt-lto*.o ./afl-llvm-lto-instrumentlist.so $${DESTDIR}$(HELPER_PATH); fi
|
||||||
|
@if [ -f ./afl-ld-lto ]; then set -e; install -m 755 ./afl-ld-lto $${DESTDIR}$(BIN_PATH); fi
|
||||||
|
@if [ -f ./afl-compiler-rt-32.o ]; then set -e; install -m 755 ./afl-compiler-rt-32.o $${DESTDIR}$(HELPER_PATH); fi
|
||||||
|
@if [ -f ./afl-compiler-rt-64.o ]; then set -e; install -m 755 ./afl-compiler-rt-64.o $${DESTDIR}$(HELPER_PATH); fi
|
||||||
|
@if [ -f ./compare-transform-pass.so ]; then set -e; install -m 755 ./*.so $${DESTDIR}$(HELPER_PATH); fi
|
||||||
|
@if [ -f ./compare-transform-pass.so ]; then set -e; ln -sf afl-cc $${DESTDIR}$(BIN_PATH)/afl-clang-fast ; ln -sf ./afl-c++ $${DESTDIR}$(BIN_PATH)/afl-clang-fast++ ; ln -sf afl-cc $${DESTDIR}$(BIN_PATH)/afl-clang ; ln -sf ./afl-c++ $${DESTDIR}$(BIN_PATH)/afl-clang++ ; fi
|
||||||
|
@if [ -f ./SanitizerCoverageLTO.so ]; then set -e; ln -sf afl-cc $${DESTDIR}$(BIN_PATH)/afl-clang-lto ; ln -sf ./afl-c++ $${DESTDIR}$(BIN_PATH)/afl-clang-lto++ ; fi
|
||||||
|
set -e; install -m 644 ./dynamic_list.txt $${DESTDIR}$(HELPER_PATH)
|
||||||
|
install -m 644 instrumentation/README.*.md $${DESTDIR}$(DOC_PATH)/
|
||||||
|
|
||||||
|
%.8: %
|
||||||
|
@echo .TH $* 8 $(BUILD_DATE) "AFL++" > ./$@
|
||||||
|
@echo .SH NAME >> ./$@
|
||||||
|
@printf "%s" ".B $* \- " >> ./$@
|
||||||
|
@./$* -h 2>&1 | head -n 1 | sed -e "s/$$(printf '\e')[^m]*m//g" >> ./$@
|
||||||
|
@echo .B $* >> ./$@
|
||||||
|
@echo >> ./$@
|
||||||
|
@echo .SH SYNOPSIS >> ./$@
|
||||||
|
@./$* -h 2>&1 | head -n 3 | tail -n 1 | sed 's/^\.\///' >> ./$@
|
||||||
|
@echo >> ./$@
|
||||||
|
@echo .SH OPTIONS >> ./$@
|
||||||
|
@echo .nf >> ./$@
|
||||||
|
@./$* -h 2>&1 | tail -n +4 >> ./$@
|
||||||
|
@echo >> ./$@
|
||||||
|
@echo .SH AUTHOR >> ./$@
|
||||||
|
@echo "AFL++ was written by Michal \"lcamtuf\" Zalewski and is maintained by Marc \"van Hauser\" Heuse <mh@mh-sec.de>, Dominik Maier <domenukk@gmail.com>, Andrea Fioraldi <andreafioraldi@gmail.com> and Heiko \"hexcoder-\" Eissfeldt <heiko.eissfeldt@hexco.de>" >> ./$@
|
||||||
|
@echo The homepage of AFL++ is: https://github.com/AFLplusplus/AFLplusplus >> ./$@
|
||||||
|
@echo >> ./$@
|
||||||
|
@echo .SH LICENSE >> ./$@
|
||||||
|
@echo Apache License Version 2.0, January 2004 >> ./$@
|
||||||
|
@ln -sf afl-cc.8 ./afl-c++.8
|
||||||
|
@ln -sf afl-cc.8 ./afl-clang-fast.8
|
||||||
|
@ln -sf afl-cc.8 ./afl-clang-fast++.8
|
||||||
|
ifneq "$(AFL_CLANG_FLTO)" ""
|
||||||
|
ifeq "$(LLVM_LTO)" "1"
|
||||||
|
@ln -sf afl-cc.8 ./afl-clang-lto.8
|
||||||
|
@ln -sf afl-cc.8 ./afl-clang-lto++.8
|
||||||
|
@ln -sf afl-cc.8 ./afl-lto.8
|
||||||
|
@ln -sf afl-cc.8 ./afl-lto++.8
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
.PHONY: clean
|
||||||
|
clean:
|
||||||
|
rm -f *.o *.so *~ a.out core core.[1-9][0-9]* .test2 test-instr .test-instr0 .test-instr1 *.dwo
|
||||||
|
rm -f $(PROGS) afl-common.o ./afl-c++ ./afl-lto ./afl-lto++ ./afl-clang-lto* ./afl-clang-fast* ./afl-clang*.8 ./ld ./afl-ld ./afl-compiler-rt*.o ./afl-llvm-rt*.o instrumentation/*.o
|
@ -0,0 +1,201 @@
|
|||||||
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
|
1. Definitions.
|
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by
|
||||||
|
the copyright owner that is granting the License.
|
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all
|
||||||
|
other entities that control, are controlled by, or are under common
|
||||||
|
control with that entity. For the purposes of this definition,
|
||||||
|
"control" means (i) the power, direct or indirect, to cause the
|
||||||
|
direction or management of such entity, whether by contract or
|
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity
|
||||||
|
exercising permissions granted by this License.
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications,
|
||||||
|
including but not limited to software source code, documentation
|
||||||
|
source, and configuration files.
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical
|
||||||
|
transformation or translation of a Source form, including but
|
||||||
|
not limited to compiled object code, generated documentation,
|
||||||
|
and conversions to other media types.
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or
|
||||||
|
Object form, made available under the License, as indicated by a
|
||||||
|
copyright notice that is included in or attached to the work
|
||||||
|
(an example is provided in the Appendix below).
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object
|
||||||
|
form, that is based on (or derived from) the Work and for which the
|
||||||
|
editorial revisions, annotations, elaborations, or other modifications
|
||||||
|
represent, as a whole, an original work of authorship. For the purposes
|
||||||
|
of this License, Derivative Works shall not include works that remain
|
||||||
|
separable from, or merely link (or bind by name) to the interfaces of,
|
||||||
|
the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including
|
||||||
|
the original version of the Work and any modifications or additions
|
||||||
|
to that Work or Derivative Works thereof, that is intentionally
|
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of
|
||||||
|
the copyright owner. For the purposes of this definition, "submitted"
|
||||||
|
means any form of electronic, verbal, or written communication sent
|
||||||
|
to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems,
|
||||||
|
and issue tracking systems that are managed by, or on behalf of, the
|
||||||
|
Licensor for the purpose of discussing and improving the Work, but
|
||||||
|
excluding communication that is conspicuously marked or otherwise
|
||||||
|
designated in writing by the copyright owner as "Not a Contribution."
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
|
on behalf of whom a Contribution has been received by Licensor and
|
||||||
|
subsequently incorporated within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
copyright license to reproduce, prepare Derivative Works of,
|
||||||
|
publicly display, publicly perform, sublicense, and distribute the
|
||||||
|
Work and such Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
(except as stated in this section) patent license to make, have made,
|
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||||
|
where such license applies only to those patent claims licensable
|
||||||
|
by such Contributor that are necessarily infringed by their
|
||||||
|
Contribution(s) alone or by combination of their Contribution(s)
|
||||||
|
with the Work to which such Contribution(s) was submitted. If You
|
||||||
|
institute patent litigation against any entity (including a
|
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||||
|
or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses
|
||||||
|
granted to You under this License for that Work shall terminate
|
||||||
|
as of the date such litigation is filed.
|
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the
|
||||||
|
Work or Derivative Works thereof in any medium, with or without
|
||||||
|
modifications, and in Source or Object form, provided that You
|
||||||
|
meet the following conditions:
|
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or
|
||||||
|
Derivative Works a copy of this License; and
|
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices
|
||||||
|
stating that You changed the files; and
|
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works
|
||||||
|
that You distribute, all copyright, patent, trademark, and
|
||||||
|
attribution notices from the Source form of the Work,
|
||||||
|
excluding those notices that do not pertain to any part of
|
||||||
|
the Derivative Works; and
|
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its
|
||||||
|
distribution, then any Derivative Works that You distribute must
|
||||||
|
include a readable copy of the attribution notices contained
|
||||||
|
within such NOTICE file, excluding those notices that do not
|
||||||
|
pertain to any part of the Derivative Works, in at least one
|
||||||
|
of the following places: within a NOTICE text file distributed
|
||||||
|
as part of the Derivative Works; within the Source form or
|
||||||
|
documentation, if provided along with the Derivative Works; or,
|
||||||
|
within a display generated by the Derivative Works, if and
|
||||||
|
wherever such third-party notices normally appear. The contents
|
||||||
|
of the NOTICE file are for informational purposes only and
|
||||||
|
do not modify the License. You may add Your own attribution
|
||||||
|
notices within Derivative Works that You distribute, alongside
|
||||||
|
or as an addendum to the NOTICE text from the Work, provided
|
||||||
|
that such additional attribution notices cannot be construed
|
||||||
|
as modifying the License.
|
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and
|
||||||
|
may provide additional or different license terms and conditions
|
||||||
|
for use, reproduction, or distribution of Your modifications, or
|
||||||
|
for any such Derivative Works as a whole, provided Your use,
|
||||||
|
reproduction, and distribution of the Work otherwise complies with
|
||||||
|
the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||||
|
any Contribution intentionally submitted for inclusion in the Work
|
||||||
|
by You to the Licensor shall be under the terms and conditions of
|
||||||
|
this License, without any additional terms or conditions.
|
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify
|
||||||
|
the terms of any separate license agreement you may have executed
|
||||||
|
with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade
|
||||||
|
names, trademarks, service marks, or product names of the Licensor,
|
||||||
|
except as required for reasonable and customary use in describing the
|
||||||
|
origin of the Work and reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||||
|
agreed to in writing, Licensor provides the Work (and each
|
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
implied, including, without limitation, any warranties or conditions
|
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
appropriateness of using or redistributing the Work and assume any
|
||||||
|
risks associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory,
|
||||||
|
whether in tort (including negligence), contract, or otherwise,
|
||||||
|
unless required by applicable law (such as deliberate and grossly
|
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
|
liable to You for damages, including any direct, indirect, special,
|
||||||
|
incidental, or consequential damages of any character arising as a
|
||||||
|
result of this License or out of the use or inability to use the
|
||||||
|
Work (including but not limited to damages for loss of goodwill,
|
||||||
|
work stoppage, computer failure or malfunction, or any and all
|
||||||
|
other commercial damages or losses), even if such Contributor
|
||||||
|
has been advised of the possibility of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing
|
||||||
|
the Work or Derivative Works thereof, You may choose to offer,
|
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||||
|
or other liability obligations and/or rights consistent with this
|
||||||
|
License. However, in accepting such obligations, You may act only
|
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf
|
||||||
|
of any other Contributor, and only if You agree to indemnify,
|
||||||
|
defend, and hold each Contributor harmless for any liability
|
||||||
|
incurred by, or claims asserted against, such Contributor by reason
|
||||||
|
of your accepting any such warranty or additional liability.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
APPENDIX: How to apply the Apache License to your work.
|
||||||
|
|
||||||
|
To apply the Apache License to your work, attach the following
|
||||||
|
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||||
|
replaced with your own identifying information. (Don't include
|
||||||
|
the brackets!) The text should be enclosed in the appropriate
|
||||||
|
comment syntax for the file format. We also recommend that a
|
||||||
|
file or class name and description of purpose be included on the
|
||||||
|
same "printed page" as the copyright notice for easier
|
||||||
|
identification within third-party archives.
|
||||||
|
|
||||||
|
Copyright [yyyy] [name of copyright owner]
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
@ -0,0 +1,42 @@
|
|||||||
|
all:
|
||||||
|
@echo trying to use GNU make...
|
||||||
|
@gmake all || echo please install GNUmake
|
||||||
|
|
||||||
|
source-only:
|
||||||
|
@gmake source-only
|
||||||
|
|
||||||
|
binary-only:
|
||||||
|
@gmake binary-only
|
||||||
|
|
||||||
|
distrib:
|
||||||
|
@gmake distrib
|
||||||
|
|
||||||
|
man:
|
||||||
|
@gmake man
|
||||||
|
|
||||||
|
install:
|
||||||
|
@gmake install
|
||||||
|
|
||||||
|
document:
|
||||||
|
@gmake document
|
||||||
|
|
||||||
|
deepclean:
|
||||||
|
@gmake deepclean
|
||||||
|
|
||||||
|
code-format:
|
||||||
|
@gmake code-format
|
||||||
|
|
||||||
|
help:
|
||||||
|
@gmake help
|
||||||
|
|
||||||
|
tests:
|
||||||
|
@gmake tests
|
||||||
|
|
||||||
|
unit:
|
||||||
|
@gmake unit
|
||||||
|
|
||||||
|
unit_clean:
|
||||||
|
@gmake unit_clean
|
||||||
|
|
||||||
|
clean:
|
||||||
|
@gmake clean
|
@ -0,0 +1,260 @@
|
|||||||
|
# American Fuzzy Lop plus plus (AFL++)
|
||||||
|
|
||||||
|
<img align="right" src="https://raw.githubusercontent.com/AFLplusplus/Website/main/static/aflpp_bg.svg" alt="AFL++ logo" width="250" height="250">
|
||||||
|
|
||||||
|
Release version: [4.21c](https://github.com/AFLplusplus/AFLplusplus/releases)
|
||||||
|
|
||||||
|
GitHub version: 4.22a
|
||||||
|
|
||||||
|
Repository:
|
||||||
|
[https://github.com/AFLplusplus/AFLplusplus](https://github.com/AFLplusplus/AFLplusplus)
|
||||||
|
|
||||||
|
AFL++ is maintained by:
|
||||||
|
|
||||||
|
* Marc "van Hauser" Heuse <mh@mh-sec.de>
|
||||||
|
* Dominik Maier <mail@dmnk.co>
|
||||||
|
* Andrea Fioraldi <andreafioraldi@gmail.com>
|
||||||
|
* Heiko "hexcoder-" Eissfeldt <heiko.eissfeldt@hexco.de>
|
||||||
|
* frida_mode is maintained by @Worksbutnottested
|
||||||
|
* Documentation: Jana Aydinbas <jana.aydinbas@gmail.com>
|
||||||
|
|
||||||
|
Originally developed by Michal "lcamtuf" Zalewski.
|
||||||
|
|
||||||
|
AFL++ is a superior fork to Google's AFL - more speed, more and better
|
||||||
|
mutations, more and better instrumentation, custom module support, etc.
|
||||||
|
|
||||||
|
You are free to copy, modify, and distribute AFL++ with attribution under the
|
||||||
|
terms of the Apache-2.0 License. See the [LICENSE](LICENSE) for details.
|
||||||
|
|
||||||
|
## Getting started
|
||||||
|
|
||||||
|
Here is some information to get you started:
|
||||||
|
|
||||||
|
* For an overview of the AFL++ documentation and a very helpful graphical guide,
|
||||||
|
please visit [docs/README.md](docs/README.md).
|
||||||
|
* To get you started with tutorials, go to
|
||||||
|
[docs/tutorials.md](docs/tutorials.md).
|
||||||
|
* For releases, see the
|
||||||
|
[Releases tab](https://github.com/AFLplusplus/AFLplusplus/releases) and
|
||||||
|
[branches](#branches). The best branches to use are, however, `stable` or
|
||||||
|
`dev` - depending on your risk appetite. Also take a look at the list of
|
||||||
|
[important changes in AFL++](docs/important_changes.md) and the list of
|
||||||
|
[features](docs/features.md).
|
||||||
|
* If you want to use AFL++ for your academic work, check the
|
||||||
|
[papers page](https://aflplus.plus/papers/) on the website.
|
||||||
|
* To cite our work, look at the [Cite](#cite) section.
|
||||||
|
* For comparisons, use the fuzzbench `aflplusplus` setup, or use
|
||||||
|
`afl-clang-fast` with `AFL_LLVM_CMPLOG=1`. You can find the `aflplusplus`
|
||||||
|
default configuration on Google's
|
||||||
|
[fuzzbench](https://github.com/google/fuzzbench/tree/master/fuzzers/aflplusplus).
|
||||||
|
|
||||||
|
## Building and installing AFL++
|
||||||
|
|
||||||
|
To have AFL++ easily available with everything compiled, pull the image directly
|
||||||
|
from the Docker Hub (available for both x86_64 and arm64):
|
||||||
|
|
||||||
|
```shell
|
||||||
|
docker pull aflplusplus/aflplusplus
|
||||||
|
docker run -ti -v /location/of/your/target:/src aflplusplus/aflplusplus
|
||||||
|
```
|
||||||
|
|
||||||
|
This image is automatically published when a push to the stable branch happens
|
||||||
|
(see [branches](#branches)). If you use the command above, you will find your
|
||||||
|
target source code in `/src` in the container.
|
||||||
|
|
||||||
|
Note: you can also pull `aflplusplus/aflplusplus:dev` which is the most current
|
||||||
|
development state of AFL++.
|
||||||
|
|
||||||
|
To build AFL++ yourself - *which we recommend* - continue at
|
||||||
|
[docs/INSTALL.md](docs/INSTALL.md).
|
||||||
|
|
||||||
|
## Quick start: Fuzzing with AFL++
|
||||||
|
|
||||||
|
*NOTE: Before you start, please read about the
|
||||||
|
[common sense risks of fuzzing](docs/fuzzing_in_depth.md#0-common-sense-risks).*
|
||||||
|
|
||||||
|
This is a quick start for fuzzing targets with the source code available. To
|
||||||
|
read about the process in detail, see
|
||||||
|
[docs/fuzzing_in_depth.md](docs/fuzzing_in_depth.md).
|
||||||
|
|
||||||
|
To learn about fuzzing other targets, see:
|
||||||
|
* Binary-only targets:
|
||||||
|
[docs/fuzzing_binary-only_targets.md](docs/fuzzing_binary-only_targets.md)
|
||||||
|
* Network services:
|
||||||
|
[docs/best_practices.md#fuzzing-a-network-service](docs/best_practices.md#fuzzing-a-network-service)
|
||||||
|
* GUI programs:
|
||||||
|
[docs/best_practices.md#fuzzing-a-gui-program](docs/best_practices.md#fuzzing-a-gui-program)
|
||||||
|
|
||||||
|
Step-by-step quick start:
|
||||||
|
|
||||||
|
1. Compile the program or library to be fuzzed using `afl-cc`. A common way to
|
||||||
|
do this would be:
|
||||||
|
|
||||||
|
```
|
||||||
|
CC=/path/to/afl-cc CXX=/path/to/afl-c++ ./configure --disable-shared
|
||||||
|
make clean all
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Get a small but valid input file that makes sense to the program. When
|
||||||
|
fuzzing verbose syntax (SQL, HTTP, etc.), create a dictionary as described in
|
||||||
|
[dictionaries/README.md](dictionaries/README.md), too.
|
||||||
|
|
||||||
|
3. If the program reads from stdin, run `afl-fuzz` like so:
|
||||||
|
|
||||||
|
```
|
||||||
|
./afl-fuzz -i seeds_dir -o output_dir -- \
|
||||||
|
/path/to/tested/program [...program's cmdline...]
|
||||||
|
```
|
||||||
|
|
||||||
|
To add a dictionary, add `-x /path/to/dictionary.txt` to afl-fuzz.
|
||||||
|
|
||||||
|
If the program takes input from a file, you can put `@@` in the program's
|
||||||
|
command line; AFL++ will put an auto-generated file name in there for you.
|
||||||
|
|
||||||
|
4. Investigate anything shown in red in the fuzzer UI by promptly consulting
|
||||||
|
[docs/afl-fuzz_approach.md#understanding-the-status-screen](docs/afl-fuzz_approach.md#understanding-the-status-screen).
|
||||||
|
|
||||||
|
5. You will find found crashes and hangs in the subdirectories `crashes/` and
|
||||||
|
`hangs/` in the `-o output_dir` directory. You can replay the crashes by
|
||||||
|
feeding them to the target, e.g. if your target is using stdin:
|
||||||
|
|
||||||
|
```
|
||||||
|
cat output_dir/crashes/id:000000,* | /path/to/tested/program [...program's cmdline...]
|
||||||
|
```
|
||||||
|
|
||||||
|
You can generate cores or use gdb directly to follow up the crashes.
|
||||||
|
|
||||||
|
6. We cannot stress this enough - if you want to fuzz effectively, read the
|
||||||
|
[docs/fuzzing_in_depth.md](docs/fuzzing_in_depth.md) document!
|
||||||
|
|
||||||
|
## Contact
|
||||||
|
|
||||||
|
Questions? Concerns? Bug reports?
|
||||||
|
|
||||||
|
* The contributors can be reached via (e.g., by creating an issue):
|
||||||
|
[https://github.com/AFLplusplus/AFLplusplus](https://github.com/AFLplusplus/AFLplusplus).
|
||||||
|
* Take a look at our [FAQ](docs/FAQ.md). If you find an interesting or important
|
||||||
|
question missing, submit it via
|
||||||
|
[https://github.com/AFLplusplus/AFLplusplus/discussions](https://github.com/AFLplusplus/AFLplusplus/discussions).
|
||||||
|
* Best: join the [Awesome Fuzzing](https://discord.gg/gCraWct) Discord server.
|
||||||
|
* There is a (not really used) mailing list for the AFL/AFL++ project
|
||||||
|
([browse archive](https://groups.google.com/group/afl-users)). To compare
|
||||||
|
notes with other users or to get notified about major new features, send an
|
||||||
|
email to <afl-users+subscribe@googlegroups.com>, but note that this is not
|
||||||
|
managed by us.
|
||||||
|
|
||||||
|
## Branches
|
||||||
|
|
||||||
|
The following branches exist:
|
||||||
|
|
||||||
|
* [release](https://github.com/AFLplusplus/AFLplusplus/tree/release): the latest
|
||||||
|
release
|
||||||
|
* [stable/trunk](https://github.com/AFLplusplus/AFLplusplus/): stable state of
|
||||||
|
AFL++ - it is synced from dev from time to time when we are satisfied with its
|
||||||
|
stability
|
||||||
|
* [dev](https://github.com/AFLplusplus/AFLplusplus/tree/dev): development state
|
||||||
|
of AFL++ - bleeding edge and you might catch a checkout which does not compile
|
||||||
|
or has a bug. **We only accept PRs (pull requests) for the 'dev' branch!**
|
||||||
|
* (any other): experimental branches to work on specific features or testing new
|
||||||
|
functionality or changes.
|
||||||
|
|
||||||
|
## Help wanted
|
||||||
|
|
||||||
|
We have several [ideas](docs/ideas.md) we would like to see in AFL++ to make it
|
||||||
|
even better. However, we already work on so many things that we do not have the
|
||||||
|
time for all the big ideas.
|
||||||
|
|
||||||
|
This can be your way to support and contribute to AFL++ - extend it to do
|
||||||
|
something cool.
|
||||||
|
|
||||||
|
For everyone who wants to contribute (and send pull requests), please read our
|
||||||
|
[contributing guidelines](CONTRIBUTING.md) before you submit.
|
||||||
|
|
||||||
|
## Special thanks
|
||||||
|
|
||||||
|
Many of the improvements to the original AFL and AFL++ wouldn't be possible
|
||||||
|
without feedback, bug reports, or patches from our contributors.
|
||||||
|
|
||||||
|
Thank you! (For people sending pull requests - please add yourself to this list
|
||||||
|
:-)
|
||||||
|
|
||||||
|
<details>
|
||||||
|
|
||||||
|
<summary>List of contributors</summary>
|
||||||
|
|
||||||
|
```
|
||||||
|
Jann Horn Hanno Boeck
|
||||||
|
Felix Groebert Jakub Wilk
|
||||||
|
Richard W. M. Jones Alexander Cherepanov
|
||||||
|
Tom Ritter Hovik Manucharyan
|
||||||
|
Sebastian Roschke Eberhard Mattes
|
||||||
|
Padraig Brady Ben Laurie
|
||||||
|
@dronesec Luca Barbato
|
||||||
|
Tobias Ospelt Thomas Jarosch
|
||||||
|
Martin Carpenter Mudge Zatko
|
||||||
|
Joe Zbiciak Ryan Govostes
|
||||||
|
Michael Rash William Robinet
|
||||||
|
Jonathan Gray Filipe Cabecinhas
|
||||||
|
Nico Weber Jodie Cunningham
|
||||||
|
Andrew Griffiths Parker Thompson
|
||||||
|
Jonathan Neuschaefer Tyler Nighswander
|
||||||
|
Ben Nagy Samir Aguiar
|
||||||
|
Aidan Thornton Aleksandar Nikolich
|
||||||
|
Sam Hakim Laszlo Szekeres
|
||||||
|
David A. Wheeler Turo Lamminen
|
||||||
|
Andreas Stieger Richard Godbee
|
||||||
|
Louis Dassy teor2345
|
||||||
|
Alex Moneger Dmitry Vyukov
|
||||||
|
Keegan McAllister Kostya Serebryany
|
||||||
|
Richo Healey Martijn Bogaard
|
||||||
|
rc0r Jonathan Foote
|
||||||
|
Christian Holler Dominique Pelle
|
||||||
|
Jacek Wielemborek Leo Barnes
|
||||||
|
Jeremy Barnes Jeff Trull
|
||||||
|
Guillaume Endignoux ilovezfs
|
||||||
|
Daniel Godas-Lopez Franjo Ivancic
|
||||||
|
Austin Seipp Daniel Komaromy
|
||||||
|
Daniel Binderman Jonathan Metzman
|
||||||
|
Vegard Nossum Jan Kneschke
|
||||||
|
Kurt Roeckx Marcel Boehme
|
||||||
|
Van-Thuan Pham Abhik Roychoudhury
|
||||||
|
Joshua J. Drake Toby Hutton
|
||||||
|
Rene Freingruber Sergey Davidoff
|
||||||
|
Sami Liedes Craig Young
|
||||||
|
Andrzej Jackowski Daniel Hodson
|
||||||
|
Nathan Voss Dominik Maier
|
||||||
|
Andrea Biondo Vincent Le Garrec
|
||||||
|
Khaled Yakdan Kuang-che Wu
|
||||||
|
Josephine Calliotte Konrad Welc
|
||||||
|
Thomas Rooijakkers David Carlier
|
||||||
|
Ruben ten Hove Joey Jiao
|
||||||
|
fuzzah @intrigus-lgtm
|
||||||
|
Yaakov Saxon Sergej Schumilo
|
||||||
|
```
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
## Cite
|
||||||
|
|
||||||
|
If you use AFL++ in scientific work, consider citing
|
||||||
|
[our paper](https://www.usenix.org/conference/woot20/presentation/fioraldi)
|
||||||
|
presented at WOOT'20:
|
||||||
|
|
||||||
|
Andrea Fioraldi, Dominik Maier, Heiko Eißfeldt, and Marc Heuse. “AFL++: Combining incremental steps of fuzzing research”. In 14th USENIX Workshop on Offensive Technologies (WOOT 20). USENIX Association, Aug. 2020.
|
||||||
|
|
||||||
|
<details>
|
||||||
|
|
||||||
|
<summary>BibTeX</summary>
|
||||||
|
|
||||||
|
```bibtex
|
||||||
|
@inproceedings {AFLplusplus-Woot20,
|
||||||
|
author = {Andrea Fioraldi and Dominik Maier and Heiko Ei{\ss}feldt and Marc Heuse},
|
||||||
|
title = {{AFL++}: Combining Incremental Steps of Fuzzing Research},
|
||||||
|
booktitle = {14th {USENIX} Workshop on Offensive Technologies ({WOOT} 20)},
|
||||||
|
year = {2020},
|
||||||
|
publisher = {{USENIX} Association},
|
||||||
|
month = aug,
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
</details>
|
@ -0,0 +1,50 @@
|
|||||||
|
# TODO list for AFL++
|
||||||
|
|
||||||
|
## Must
|
||||||
|
|
||||||
|
- ijon support?
|
||||||
|
- check for null ptr for xml/curl/g_ string transform functions
|
||||||
|
- hardened_usercopy=0 page_alloc.shuffle=0
|
||||||
|
- add value_profile but only enable after 15 minutes without finds
|
||||||
|
- cmplog max items env?
|
||||||
|
- adapt MOpt to new mutation engine
|
||||||
|
- Update afl->pending_not_fuzzed for MOpt
|
||||||
|
- cmplog rtn sanity check on fixed length? currently we ignore the length
|
||||||
|
- afl-showmap -f support
|
||||||
|
- afl-fuzz multicore wrapper script
|
||||||
|
- when trimming then perform crash detection
|
||||||
|
|
||||||
|
|
||||||
|
## Should
|
||||||
|
|
||||||
|
- afl-crash-analysis
|
||||||
|
- cmplog: add loop count resolving (byte -> loop cnt change, calc special values)
|
||||||
|
- support persistent and deferred fork server in afl-showmap?
|
||||||
|
- better autodetection of shifting runtime timeout values
|
||||||
|
- afl-plot to support multiple plot_data
|
||||||
|
- parallel builds for source-only targets
|
||||||
|
- get rid of check_binary, replace with more forkserver communication
|
||||||
|
- first fuzzer should be a main automatically? not sure.
|
||||||
|
|
||||||
|
## Maybe
|
||||||
|
|
||||||
|
- forkserver tells afl-fuzz if cmplog is supported and if so enable
|
||||||
|
it by default, with AFL_CMPLOG_NO=1 (?) set to skip?
|
||||||
|
- afl_custom_splice()
|
||||||
|
- cmdline option from-to range for mutations
|
||||||
|
|
||||||
|
## Further down the road
|
||||||
|
|
||||||
|
QEMU mode/FRIDA mode:
|
||||||
|
- non colliding instrumentation
|
||||||
|
- rename qemu specific envs to AFL_QEMU (AFL_ENTRYPOINT, AFL_CODE_START/END,
|
||||||
|
AFL_COMPCOV_LEVEL?)
|
||||||
|
- add AFL_QEMU_EXITPOINT (maybe multiple?)
|
||||||
|
|
||||||
|
## Ideas
|
||||||
|
|
||||||
|
- LTO/sancov: write current edge to prev_loc and use that information when
|
||||||
|
using cmplog or __sanitizer_cov_trace_cmp*. maybe we can deduct by follow up
|
||||||
|
edge numbers that both following cmp paths have been found and then disable
|
||||||
|
working on this edge id -> cmplog_intelligence branch
|
||||||
|
- use cmplog colorization taint result for havoc locations?
|
@ -0,0 +1,54 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
test -z "$1" -o "$1" = "-h" -o "$1" = "--help" && {
|
||||||
|
echo Syntax: afl-addseeds -o afl-out-dir [-i seed_file_or_dir] seed_file_or_seed_dir seed_file_or_seed_dir ...
|
||||||
|
echo
|
||||||
|
echo Options:
|
||||||
|
echo " -o afl-out-dir the output directory being used in the fuzzing campaign"
|
||||||
|
echo " -i seed_file_or_dir file or directory of files to add"
|
||||||
|
echo
|
||||||
|
echo Adds new seeds to an existing AFL++ fuzzing campaign.
|
||||||
|
exit 0
|
||||||
|
}
|
||||||
|
|
||||||
|
for TOOL in find ls; do
|
||||||
|
X=`which $TOOL`
|
||||||
|
test -n "$X" || { echo "Error: required tool '$TOOL' not found."; exit 1; }
|
||||||
|
done
|
||||||
|
|
||||||
|
TEST=`printf %06d 123 2>/dev/null`
|
||||||
|
test "$TEST" = "000123" || { echo "Error: required tool 'printf' not found."; exit 1; }
|
||||||
|
|
||||||
|
OUT=
|
||||||
|
NEXT=
|
||||||
|
for i in $*; do
|
||||||
|
test -n "$NEXT" && { OUT=$i ; NEXT=""; }
|
||||||
|
test "$i" = "-o" && { NEXT=1; }
|
||||||
|
done
|
||||||
|
|
||||||
|
test -d "$OUT" || { echo Error: $OUT is not an existing directory; exit 1; }
|
||||||
|
OK=`ls $OUT/*/fuzzer_stats 2>/dev/null`
|
||||||
|
test -n "$OK" || { echo "Error: $OUT is not an 'afl-fuzz -o ... ' output directory" ; exit 1; }
|
||||||
|
|
||||||
|
OUTDIR=$OUT/addseeds/queue
|
||||||
|
mkdir -p "$OUTDIR" 2>/dev/null
|
||||||
|
test -d "$OUTDIR" || { echo Error: could not create $OUTDIR ; exit 1 ; }
|
||||||
|
|
||||||
|
echo Adding seeds ...
|
||||||
|
NEXTID=0
|
||||||
|
for i in $*; do
|
||||||
|
test -z "$i" -o "$i" = "$OUT" -o "$i" = "-i" -o "$i" = "-o" || {
|
||||||
|
find "$i" -type f | while read FILE; do
|
||||||
|
N=xxx
|
||||||
|
while [ -n "$N" ]; do
|
||||||
|
ID=$NEXTID
|
||||||
|
N=`ls "$OUTDIR/id:$(printf %06d $ID),"* 2>/dev/null`
|
||||||
|
NEXTID=$(($NEXTID + 1))
|
||||||
|
done
|
||||||
|
FN=`echo "$FILE" | sed 's/.*\///'`
|
||||||
|
cp -v "$FILE" "$OUTDIR/id:$(printf %06d $ID),time:0,execs:0,orig:$FN"
|
||||||
|
done
|
||||||
|
}
|
||||||
|
done
|
||||||
|
|
||||||
|
echo Done.
|
@ -0,0 +1,689 @@
|
|||||||
|
#!/usr/bin/env sh
|
||||||
|
SYS=$(uname -s)
|
||||||
|
test "$SYS" = "Darwin" && {
|
||||||
|
echo Error: afl-cmin does not work on Apple currently. please use afl-cmin.bash instead.
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
export AFL_QUIET=1
|
||||||
|
export ASAN_OPTIONS=detect_leaks=0
|
||||||
|
THISPATH=`dirname ${0}`
|
||||||
|
export PATH="${THISPATH}:$PATH"
|
||||||
|
awk -f - -- ${@+"$@"} <<'EOF'
|
||||||
|
#!/usr/bin/awk -f
|
||||||
|
# awk script to minimize a test corpus of input files
|
||||||
|
#
|
||||||
|
# based on afl-cmin bash script written by Michal Zalewski
|
||||||
|
# rewritten by Heiko Eissfeldt (hexcoder-)
|
||||||
|
# tested with:
|
||||||
|
# gnu awk (x86 Linux)
|
||||||
|
# bsd awk (x86 *BSD)
|
||||||
|
# mawk (arm32 raspbian)
|
||||||
|
#
|
||||||
|
# uses getopt.awk package from Arnold Robbins
|
||||||
|
#
|
||||||
|
# external tools used by this script:
|
||||||
|
# test
|
||||||
|
# grep
|
||||||
|
# rm
|
||||||
|
# mkdir
|
||||||
|
# ln
|
||||||
|
# cp
|
||||||
|
# pwd
|
||||||
|
# type
|
||||||
|
# cd
|
||||||
|
# find
|
||||||
|
# stat
|
||||||
|
# sort
|
||||||
|
# cut
|
||||||
|
# and afl-showmap from this project :-)
|
||||||
|
|
||||||
|
# getopt.awk --- Do C library getopt(3) function in awk
|
||||||
|
|
||||||
|
# External variables:
|
||||||
|
# Optind -- index in ARGV of first nonoption argument
|
||||||
|
# Optarg -- string value of argument to current option
|
||||||
|
# Opterr -- if nonzero, print our own diagnostic
|
||||||
|
# Optopt -- current option letter
|
||||||
|
|
||||||
|
# Returns:
|
||||||
|
# -1 at end of options
|
||||||
|
# "?" for unrecognized option
|
||||||
|
# <c> a character representing the current option
|
||||||
|
|
||||||
|
# Private Data:
|
||||||
|
# _opti -- index in multiflag option, e.g., -abc
|
||||||
|
|
||||||
|
function getopt(argc, argv, options, thisopt, i)
|
||||||
|
{
|
||||||
|
if (length(options) == 0) # no options given
|
||||||
|
return -1
|
||||||
|
|
||||||
|
if (argv[Optind] == "--") { # all done
|
||||||
|
Optind++
|
||||||
|
_opti = 0
|
||||||
|
return -1
|
||||||
|
} else if (argv[Optind] !~ /^-[^:\t ]/) {
|
||||||
|
_opti = 0
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
if (_opti == 0)
|
||||||
|
_opti = 2
|
||||||
|
thisopt = substr(argv[Optind], _opti, 1)
|
||||||
|
Optopt = thisopt
|
||||||
|
i = index(options, thisopt)
|
||||||
|
if (i == 0) {
|
||||||
|
if (Opterr)
|
||||||
|
printf("%c -- invalid option\n", thisopt) > "/dev/stderr"
|
||||||
|
if (_opti >= length(argv[Optind])) {
|
||||||
|
Optind++
|
||||||
|
_opti = 0
|
||||||
|
} else
|
||||||
|
_opti++
|
||||||
|
return "?"
|
||||||
|
}
|
||||||
|
if (substr(options, i + 1, 1) == ":") {
|
||||||
|
# get option argument
|
||||||
|
if (length(substr(argv[Optind], _opti + 1)) > 0)
|
||||||
|
Optarg = substr(argv[Optind], _opti + 1)
|
||||||
|
else
|
||||||
|
Optarg = argv[++Optind]
|
||||||
|
_opti = 0
|
||||||
|
} else
|
||||||
|
Optarg = ""
|
||||||
|
if (_opti == 0 || _opti >= length(argv[Optind])) {
|
||||||
|
Optind++
|
||||||
|
_opti = 0
|
||||||
|
} else
|
||||||
|
_opti++
|
||||||
|
return thisopt
|
||||||
|
}
|
||||||
|
|
||||||
|
function usage() {
|
||||||
|
print \
|
||||||
|
"afl-cmin [ options ] -- /path/to/target_app [ ... ]\n" \
|
||||||
|
"\n" \
|
||||||
|
"Required parameters:\n" \
|
||||||
|
" -i dir - input directory with starting corpus\n" \
|
||||||
|
" -o dir - output directory for minimized files\n" \
|
||||||
|
"\n" \
|
||||||
|
"Execution control settings:\n" \
|
||||||
|
" -T tasks - how many parallel tasks to run (default: 1, all=nproc)\n" \
|
||||||
|
" -f file - location read by the fuzzed program (default: stdin)\n" \
|
||||||
|
" -m megs - memory limit for child process ("mem_limit" MB)\n" \
|
||||||
|
" -t msec - run time limit for child process (default: 5000)\n" \
|
||||||
|
" -O - use binary-only instrumentation (FRIDA mode)\n" \
|
||||||
|
" -Q - use binary-only instrumentation (QEMU mode)\n" \
|
||||||
|
" -U - use unicorn-based instrumentation (unicorn mode)\n" \
|
||||||
|
" -X - use Nyx mode\n" \
|
||||||
|
"\n" \
|
||||||
|
"Minimization settings:\n" \
|
||||||
|
" -A - allow crashes and timeouts (not recommended)\n" \
|
||||||
|
" -C - keep crashing inputs, reject everything else\n" \
|
||||||
|
" -e - solve for edge coverage only, ignore hit counts\n" \
|
||||||
|
"\n" \
|
||||||
|
"For additional tips, please consult README.md\n" \
|
||||||
|
"\n" \
|
||||||
|
"Environment variables used:\n" \
|
||||||
|
"AFL_CRASH_EXITCODE: optional child exit code to be interpreted as crash\n" \
|
||||||
|
"AFL_FORKSRV_INIT_TMOUT: time the fuzzer waits for the forkserver to come up\n" \
|
||||||
|
"AFL_KEEP_TRACES: leave the temporary <out_dir>/.traces directory\n" \
|
||||||
|
"AFL_KILL_SIGNAL: Signal delivered to child processes on timeout (default: SIGKILL)\n" \
|
||||||
|
"AFL_FORK_SERVER_KILL_SIGNAL: Signal delivered to fork server processes on\n" \
|
||||||
|
" termination (default: SIGTERM). If this is not set and AFL_KILL_SIGNAL is\n" \
|
||||||
|
" set, this will be set to the same value as AFL_KILL_SIGNAL.\n" \
|
||||||
|
"AFL_NO_FORKSRV: run target via execve instead of using the forkserver\n" \
|
||||||
|
"AFL_CMIN_ALLOW_ANY: write tuples for crashing inputs also\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 afl instrumentation checks for target binary\n"
|
||||||
|
"AFL_CUSTOM_MUTATOR_LIBRARY: custom mutator library (post_process and send)\n"
|
||||||
|
"AFL_PYTHON_MODULE: custom mutator library (post_process and send)\n"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
function exists_and_is_executable(binarypath) {
|
||||||
|
return 0 == system("test -f "binarypath" -a -x "binarypath)
|
||||||
|
}
|
||||||
|
|
||||||
|
BEGIN {
|
||||||
|
if (0 != system( "test -t 1")) {
|
||||||
|
redirected = 1
|
||||||
|
} else {
|
||||||
|
redirected = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
print "corpus minimization tool for AFL++ (awk version)\n"
|
||||||
|
|
||||||
|
# defaults
|
||||||
|
extra_par = ""
|
||||||
|
AFL_CMIN_CRASHES_ONLY = ""
|
||||||
|
AFL_CMIN_ALLOW_ANY = ""
|
||||||
|
|
||||||
|
# process options
|
||||||
|
Opterr = 1 # default is to diagnose
|
||||||
|
Optind = 1 # skip ARGV[0]
|
||||||
|
while ((_go_c = getopt(ARGC, ARGV, "hi:o:f:m:t:eACOQUXYT:?")) != -1) {
|
||||||
|
if (_go_c == "i") {
|
||||||
|
if (!Optarg) usage()
|
||||||
|
if (in_dir) { print "Option "_go_c" is only allowed once" > "/dev/stderr"}
|
||||||
|
in_dir = Optarg
|
||||||
|
continue
|
||||||
|
} else
|
||||||
|
if (_go_c == "T") {
|
||||||
|
if (!Optarg) usage()
|
||||||
|
if (threads) { print "Option "_go_c" is only allowed once" > "/dev/stderr"}
|
||||||
|
threads = Optarg
|
||||||
|
continue
|
||||||
|
} else
|
||||||
|
if (_go_c == "o") {
|
||||||
|
if (!Optarg) usage()
|
||||||
|
if (out_dir) { print "Option "_go_c" is only allowed once" > "/dev/stderr"}
|
||||||
|
out_dir = Optarg
|
||||||
|
continue
|
||||||
|
} else
|
||||||
|
if (_go_c == "f") {
|
||||||
|
if (!Optarg) usage()
|
||||||
|
if (stdin_file) { print "Option "_go_c" is only allowed once" > "/dev/stderr"}
|
||||||
|
stdin_file = Optarg
|
||||||
|
continue
|
||||||
|
} else
|
||||||
|
if (_go_c == "m") {
|
||||||
|
if (!Optarg) usage()
|
||||||
|
if (mem_limit) { print "Option "_go_c" is only allowed once" > "/dev/stderr"}
|
||||||
|
mem_limit = Optarg
|
||||||
|
mem_limit_given = 1
|
||||||
|
continue
|
||||||
|
} else
|
||||||
|
if (_go_c == "t") {
|
||||||
|
if (!Optarg) usage()
|
||||||
|
if (timeout) { print "Option "_go_c" is only allowed once" > "/dev/stderr"}
|
||||||
|
timeout = Optarg
|
||||||
|
continue
|
||||||
|
} else
|
||||||
|
if (_go_c == "C") {
|
||||||
|
AFL_CMIN_CRASHES_ONLY = "AFL_CMIN_CRASHES_ONLY=1 "
|
||||||
|
continue
|
||||||
|
} else
|
||||||
|
if (_go_c == "A") {
|
||||||
|
AFL_CMIN_ALLOW_ANY = "AFL_CMIN_ALLOW_ANY=1 "
|
||||||
|
continue
|
||||||
|
} else
|
||||||
|
if (_go_c == "e") {
|
||||||
|
extra_par = extra_par " -e"
|
||||||
|
continue
|
||||||
|
} else
|
||||||
|
if (_go_c == "O") {
|
||||||
|
if (frida_mode) { print "Option "_go_c" is only allowed once" > "/dev/stderr"}
|
||||||
|
extra_par = extra_par " -O"
|
||||||
|
frida_mode = 1
|
||||||
|
continue
|
||||||
|
} else
|
||||||
|
if (_go_c == "Q") {
|
||||||
|
if (qemu_mode) { print "Option "_go_c" is only allowed once" > "/dev/stderr"}
|
||||||
|
extra_par = extra_par " -Q"
|
||||||
|
qemu_mode = 1
|
||||||
|
continue
|
||||||
|
} else
|
||||||
|
if (_go_c == "U") {
|
||||||
|
if (unicorn_mode) { print "Option "_go_c" is only allowed once" > "/dev/stderr"}
|
||||||
|
extra_par = extra_par " -U"
|
||||||
|
unicorn_mode = 1
|
||||||
|
continue
|
||||||
|
} else
|
||||||
|
if (_go_c == "X" || _go_c == "Y") {
|
||||||
|
if (nyx_mode) { print "Option "_go_c" is only allowed once" > "/dev/stderr"}
|
||||||
|
extra_par = extra_par " -X"
|
||||||
|
nyx_mode = 1
|
||||||
|
continue
|
||||||
|
} else
|
||||||
|
if (_go_c == "?") {
|
||||||
|
exit 1
|
||||||
|
} else
|
||||||
|
usage()
|
||||||
|
} # while options
|
||||||
|
|
||||||
|
if (!mem_limit) mem_limit = "none"
|
||||||
|
if (!timeout) timeout = "5000"
|
||||||
|
|
||||||
|
# get program args
|
||||||
|
i = 0
|
||||||
|
prog_args_string = ""
|
||||||
|
for (; Optind < ARGC; Optind++) {
|
||||||
|
prog_args[i++] = ARGV[Optind]
|
||||||
|
if (i > 1)
|
||||||
|
prog_args_string = prog_args_string" '"ARGV[Optind]"'"
|
||||||
|
}
|
||||||
|
|
||||||
|
# sanity checks
|
||||||
|
if (!prog_args[0] || !in_dir || !out_dir) usage()
|
||||||
|
|
||||||
|
target_bin = prog_args[0]
|
||||||
|
|
||||||
|
# Do a sanity check to discourage the use of /tmp, since we can't really
|
||||||
|
# handle this safely from an awk script.
|
||||||
|
|
||||||
|
if (!ENVIRON["AFL_ALLOW_TMP"]) {
|
||||||
|
dirlist[0] = in_dir
|
||||||
|
dirlist[1] = target_bin
|
||||||
|
dirlist[2] = out_dir
|
||||||
|
dirlist[3] = stdin_file
|
||||||
|
"pwd" | getline dirlist[4] # current directory
|
||||||
|
for (dirind in dirlist) {
|
||||||
|
dir = dirlist[dirind]
|
||||||
|
if (dir ~ /^(\/var)?\/tmp/) {
|
||||||
|
print "[-] Warning: do not use this script in /tmp or /var/tmp for security reasons." > "/dev/stderr"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
delete dirlist
|
||||||
|
}
|
||||||
|
|
||||||
|
if (threads && stdin_file) {
|
||||||
|
print "[-] Error: -T and -f cannot be used together." > "/dev/stderr"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!threads && !stdin_file && !nyx_mode) {
|
||||||
|
print "[*] Are you aware of the '-T all' parallelize option that improves the speed for large/slow corpuses?"
|
||||||
|
}
|
||||||
|
|
||||||
|
# If @@ is specified, but there's no -f, let's come up with a temporary input
|
||||||
|
# file name.
|
||||||
|
|
||||||
|
trace_dir = out_dir "/.traces"
|
||||||
|
|
||||||
|
if (!stdin_file) {
|
||||||
|
found_atat = 0
|
||||||
|
for (prog_args_ind in prog_args) {
|
||||||
|
if (match(prog_args[prog_args_ind], "@@") != 0) {
|
||||||
|
found_atat = 1
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (found_atat) {
|
||||||
|
stdin_file = trace_dir "/.cur_input"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check for obvious errors.
|
||||||
|
|
||||||
|
if (mem_limit && mem_limit != "none" && mem_limit < 5) {
|
||||||
|
print "[-] Error: dangerously low memory limit." > "/dev/stderr"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
if (timeout && timeout != "none" && timeout < 10) {
|
||||||
|
print "[-] Error: dangerously low timeout." > "/dev/stderr"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (!nyx_mode && target_bin && !exists_and_is_executable(target_bin)) {
|
||||||
|
|
||||||
|
cmd = "command -v "target_bin" 2>/dev/null"
|
||||||
|
cmd | getline tnew
|
||||||
|
close(cmd)
|
||||||
|
if (!tnew || !exists_and_is_executable(tnew)) {
|
||||||
|
print "[-] Error: binary '"target_bin"' not found or not executable." > "/dev/stderr"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
target_bin = tnew
|
||||||
|
}
|
||||||
|
|
||||||
|
if (0 == system ( "grep -aq AFL_DUMP_MAP_SIZE " target_bin )) {
|
||||||
|
echo "[!] Trying to obtain the map size of the target ..."
|
||||||
|
get_map_size = "AFL_DUMP_MAP_SIZE=1 " target_bin
|
||||||
|
get_map_size | getline mapsize
|
||||||
|
close(get_map_size)
|
||||||
|
if (mapsize && mapsize > 65535 && mapsize < 100000000) {
|
||||||
|
AFL_MAP_SIZE = "AFL_MAP_SIZE="mapsize" "
|
||||||
|
print "[+] Setting "AFL_MAP_SIZE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ENVIRON["AFL_SKIP_BIN_CHECK"] && !qemu_mode && !frida_mode && !unicorn_mode && !nyx_mode) {
|
||||||
|
if (0 != system( "grep -q __AFL_SHM_ID "target_bin )) {
|
||||||
|
print "[-] Error: binary '"target_bin"' doesn't appear to be instrumented." > "/dev/stderr"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (0 != system( "test -d "in_dir )) {
|
||||||
|
print "[-] Error: directory '"in_dir"' not found." > "/dev/stderr"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
#if (0 == system( "test -d "in_dir"/default" )) {
|
||||||
|
# in_dir = in_dir "/default"
|
||||||
|
#}
|
||||||
|
#
|
||||||
|
#if (0 == system( "test -d "in_dir"/queue" )) {
|
||||||
|
# in_dir = in_dir "/queue"
|
||||||
|
#}
|
||||||
|
|
||||||
|
system("rm -rf "trace_dir" 2>/dev/null");
|
||||||
|
system("rm "out_dir"/id[:_]* 2>/dev/null")
|
||||||
|
|
||||||
|
cmd = "ls "out_dir"/* 2>/dev/null | wc -l"
|
||||||
|
cmd | getline noofentries
|
||||||
|
close(cmd)
|
||||||
|
if (0 == system( "test -d "out_dir" -a "noofentries" -gt 0" )) {
|
||||||
|
print "[-] Error: directory '"out_dir"' exists and is not empty - delete it first." > "/dev/stderr"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
if (threads) {
|
||||||
|
cmd = "nproc"
|
||||||
|
cmd | getline nproc
|
||||||
|
close(cmd)
|
||||||
|
if (threads == "all") {
|
||||||
|
threads = nproc
|
||||||
|
} else {
|
||||||
|
if (!(threads > 1 && threads <= nproc)) {
|
||||||
|
print "[-] Error: -T option must be between 1 and "nproc" or \"all\"." > "/dev/stderr"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check for the more efficient way to copy files...
|
||||||
|
if (0 != system("mkdir -p -m 0700 "trace_dir)) {
|
||||||
|
print "[-] Error: Cannot create directory "trace_dir > "/dev/stderr"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stdin_file) {
|
||||||
|
# truncate input file
|
||||||
|
printf "" > stdin_file
|
||||||
|
close(stdin_file)
|
||||||
|
}
|
||||||
|
|
||||||
|
# First we look in PATH
|
||||||
|
if (0 == system("command -v afl-showmap >/dev/null 2>&1")) {
|
||||||
|
cmd = "command -v afl-showmap 2>/dev/null"
|
||||||
|
cmd | getline showmap
|
||||||
|
close(cmd)
|
||||||
|
} else {
|
||||||
|
# then we look in the current directory
|
||||||
|
if (0 == system("test -x ./afl-showmap")) {
|
||||||
|
showmap = "./afl-showmap"
|
||||||
|
} else {
|
||||||
|
if (ENVIRON["AFL_PATH"]) {
|
||||||
|
showmap = ENVIRON["AFL_PATH"] "/afl-showmap"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!showmap || 0 != system("test -x "showmap )) {
|
||||||
|
print "[-] Error: can't find 'afl-showmap' - please set AFL_PATH." > "/dev/stderr"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# get list of input filenames sorted by size
|
||||||
|
i = 0
|
||||||
|
# yuck, gnu stat is option incompatible to bsd stat
|
||||||
|
# we use a heuristic to differentiate between
|
||||||
|
# GNU stat and other stats
|
||||||
|
cmd = "stat --version 2>/dev/null"
|
||||||
|
cmd | getline statversion
|
||||||
|
close(cmd)
|
||||||
|
if (statversion ~ /GNU coreutils/ || statversion ~ /BusyBox/) {
|
||||||
|
stat_format = "-c '%s %n'" # GNU
|
||||||
|
} else {
|
||||||
|
stat_format = "-f '%z %N'" # *BSD, MacOS
|
||||||
|
}
|
||||||
|
cmdline = "(cd "in_dir" && find . \\( ! -name \".*\" -a -type d \\) -o -type f -exec stat "stat_format" \\{\\} + | sort -k1n -k2r) | grep -Ev '^0'"
|
||||||
|
#cmdline = "ls "in_dir" | (cd "in_dir" && xargs stat "stat_format" 2>/dev/null) | sort -k1n -k2r"
|
||||||
|
#cmdline = "(cd "in_dir" && stat "stat_format" *) | sort -k1n -k2r"
|
||||||
|
#cmdline = "(cd "in_dir" && ls | xargs stat "stat_format" ) | sort -k1n -k2r"
|
||||||
|
while (cmdline | getline) {
|
||||||
|
sub(/^[0-9]+ (\.\/)?/,"",$0)
|
||||||
|
infilesSmallToBigFull[i] = $0
|
||||||
|
sub(/.*\//, "", $0)
|
||||||
|
infilesSmallToBig[i] = $0
|
||||||
|
infilesSmallToBigMap[infilesSmallToBig[i]] = infilesSmallToBigFull[i]
|
||||||
|
infilesSmallToBigFullMap[infilesSmallToBigFull[i]] = infilesSmallToBig[i]
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
close(cmdline)
|
||||||
|
in_count = i
|
||||||
|
|
||||||
|
first_file = infilesSmallToBigFull[0]
|
||||||
|
|
||||||
|
#if (0 == system("test -d ""\""in_dir"/"first_file"\"")) {
|
||||||
|
# print "[-] Error: The input directory is empty or contains subdirectories - please fix." > "/dev/stderr"
|
||||||
|
# exit 1
|
||||||
|
#}
|
||||||
|
|
||||||
|
system(">\""in_dir"/.afl-cmin.test\"")
|
||||||
|
if (0 == system("ln \""in_dir"/.afl-cmin.test\" "trace_dir"/.link_test")) {
|
||||||
|
cp_tool = "ln"
|
||||||
|
} else {
|
||||||
|
cp_tool = "cp"
|
||||||
|
}
|
||||||
|
system("rm -f \""in_dir"/.afl-cmin.test\"")
|
||||||
|
|
||||||
|
if (!ENVIRON["AFL_SKIP_BIN_CHECK"]) {
|
||||||
|
# Make sure that we can actually get anything out of afl-showmap before we
|
||||||
|
# waste too much time.
|
||||||
|
|
||||||
|
print "[*] Testing the target binary..."
|
||||||
|
|
||||||
|
if (!stdin_file) {
|
||||||
|
system(AFL_MAP_SIZE "AFL_CMIN_ALLOW_ANY=1 "AFL_CMIN_CRASHES_ONLY"\""showmap"\" -m "mem_limit" -t "timeout" -o \""trace_dir"/.run_test\" -Z "extra_par" -- \""target_bin"\" "prog_args_string" <\""in_dir"/"first_file"\"")
|
||||||
|
} else {
|
||||||
|
system("cp \""in_dir"/"first_file"\" "stdin_file)
|
||||||
|
system(AFL_MAP_SIZE "AFL_CMIN_ALLOW_ANY=1 "AFL_CMIN_CRASHES_ONLY"\""showmap"\" -m "mem_limit" -t "timeout" -o \""trace_dir"/.run_test\" -Z "extra_par" -H \""stdin_file"\" -- \""target_bin"\" "prog_args_string" </dev/null")
|
||||||
|
}
|
||||||
|
|
||||||
|
first_count = 0
|
||||||
|
|
||||||
|
runtest = trace_dir"/.run_test"
|
||||||
|
while ((getline < runtest) > 0) {
|
||||||
|
++first_count
|
||||||
|
}
|
||||||
|
close(runtest)
|
||||||
|
|
||||||
|
if (first_count) {
|
||||||
|
print "[+] OK, "first_count" tuples recorded."
|
||||||
|
} else {
|
||||||
|
print "[-] Error: no instrumentation output detected (perhaps crash or timeout)." > "/dev/stderr"
|
||||||
|
if (!ENVIRON["AFL_KEEP_TRACES"]) {
|
||||||
|
system("rm -rf "trace_dir" 2>/dev/null")
|
||||||
|
}
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (in_count < threads) {
|
||||||
|
threads = in_count
|
||||||
|
print "[!] WARNING: less inputs than threads, reducing threads to "threads" and likely the overhead of threading makes things slower..."
|
||||||
|
}
|
||||||
|
|
||||||
|
# Let's roll!
|
||||||
|
|
||||||
|
#############################
|
||||||
|
# STEP 1: Collecting traces #
|
||||||
|
#############################
|
||||||
|
|
||||||
|
if (threads) {
|
||||||
|
|
||||||
|
inputsperfile = int(in_count / threads)
|
||||||
|
if (in_count % threads) {
|
||||||
|
inputsperfile++;
|
||||||
|
}
|
||||||
|
|
||||||
|
cnt = 0;
|
||||||
|
tmpfile=out_dir "/.filelist"
|
||||||
|
for (instance = 1; instance < threads; instance++) {
|
||||||
|
for (i = 0; i < inputsperfile; i++) {
|
||||||
|
print in_dir"/"infilesSmallToBigFull[cnt] >> tmpfile"."instance
|
||||||
|
cnt++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (; cnt < in_count; cnt++) {
|
||||||
|
print in_dir"/"infilesSmallToBigFull[cnt] >> tmpfile"."threads
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
print "[*] Obtaining traces for "in_count" input files in '"in_dir"'."
|
||||||
|
|
||||||
|
cur = 0;
|
||||||
|
|
||||||
|
if (threads > 1) {
|
||||||
|
|
||||||
|
print "[*] Creating " threads " parallel tasks with about " inputsperfile " items each."
|
||||||
|
for (i = 1; i <= threads; i++) {
|
||||||
|
|
||||||
|
if (!stdin_file) {
|
||||||
|
# print " { "AFL_MAP_SIZE AFL_CMIN_ALLOW_ANY AFL_CMIN_CRASHES_ONLY"\""showmap"\" -m "mem_limit" -t "timeout" -o \""trace_dir"\" -Z "extra_par" -I \""tmpfile"."i"\" -- \""target_bin"\" "prog_args_string"; > "tmpfile"."i".done ; } &"
|
||||||
|
retval = system(" { "AFL_MAP_SIZE AFL_CMIN_ALLOW_ANY AFL_CMIN_CRASHES_ONLY"\""showmap"\" -m "mem_limit" -t "timeout" -o \""trace_dir"\" -Z "extra_par" -I \""tmpfile"."i"\" -- \""target_bin"\" "prog_args_string"; > "tmpfile"."i".done ; } &")
|
||||||
|
} else {
|
||||||
|
stdin_file=tmpfile"."i".stdin"
|
||||||
|
# print " { "AFL_MAP_SIZE AFL_CMIN_ALLOW_ANY AFL_CMIN_CRASHES_ONLY"\""showmap"\" -m "mem_limit" -t "timeout" -o \""trace_dir"\" -Z "extra_par" -I \""tmpfile"."i"\" -H \""stdin_file"\" -- \""target_bin"\" "prog_args_string" </dev/null; > "tmpfile"."i".done ; } &"
|
||||||
|
retval = system(" { "AFL_MAP_SIZE AFL_CMIN_ALLOW_ANY AFL_CMIN_CRASHES_ONLY"\""showmap"\" -m "mem_limit" -t "timeout" -o \""trace_dir"\" -Z "extra_par" -I \""tmpfile"."i"\" -H \""stdin_file"\" -- \""target_bin"\" "prog_args_string" </dev/null; > "tmpfile"."i".done ; } &")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
print "[*] Waiting for parallel tasks to complete ..."
|
||||||
|
# wait for all processes to finish
|
||||||
|
ok=0
|
||||||
|
while (ok < threads) {
|
||||||
|
ok=0
|
||||||
|
for (i = 1; i <= threads; i++) {
|
||||||
|
if (system("test -f "tmpfile"."i".done") == 0) {
|
||||||
|
ok++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
print "[*] Done!"
|
||||||
|
system("rm -f "tmpfile"*")
|
||||||
|
} else {
|
||||||
|
if (!stdin_file) {
|
||||||
|
print " Processing "in_count" files (forkserver mode)..."
|
||||||
|
# print AFL_CMIN_CRASHES_ONLY"\""showmap"\" -m "mem_limit" -t "timeout" -o \""trace_dir"\" -Z "extra_par" -i \""in_dir"\" -- \""target_bin"\" "prog_args_string
|
||||||
|
retval = system(AFL_MAP_SIZE AFL_CMIN_ALLOW_ANY AFL_CMIN_CRASHES_ONLY"\""showmap"\" -m "mem_limit" -t "timeout" -o \""trace_dir"\" -Z "extra_par" -i \""in_dir"\" -- \""target_bin"\" "prog_args_string)
|
||||||
|
} else {
|
||||||
|
print " Processing "in_count" files (forkserver mode)..."
|
||||||
|
# print AFL_CMIN_CRASHES_ONLY"\""showmap"\" -m "mem_limit" -t "timeout" -o \""trace_dir"\" -Z "extra_par" -i \""in_dir"\" -H \""stdin_file"\" -- \""target_bin"\" "prog_args_string" </dev/null"
|
||||||
|
retval = system(AFL_MAP_SIZE AFL_CMIN_ALLOW_ANY AFL_CMIN_CRASHES_ONLY"\""showmap"\" -m "mem_limit" -t "timeout" -o \""trace_dir"\" -Z "extra_par" -i \""in_dir"\" -H \""stdin_file"\" -- \""target_bin"\" "prog_args_string" </dev/null")
|
||||||
|
}
|
||||||
|
|
||||||
|
if (retval && (!AFL_CMIN_CRASHES_ONLY && !AFL_CMIN_ALLOW_ANY)) {
|
||||||
|
print "[!] Exit code "retval" != 0 received from afl-showmap (this means a crashing or timeout input is likely present), terminating..."
|
||||||
|
|
||||||
|
if (!ENVIRON["AFL_KEEP_TRACES"]) {
|
||||||
|
system("rm -rf "trace_dir" 2>/dev/null")
|
||||||
|
system("rmdir "out_dir)
|
||||||
|
}
|
||||||
|
exit retval
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#######################################################
|
||||||
|
# STEP 2: register smallest input file for each tuple #
|
||||||
|
# STEP 3: copy that file (at most once) #
|
||||||
|
#######################################################
|
||||||
|
|
||||||
|
print "[*] Processing traces for input files in '"in_dir"'."
|
||||||
|
|
||||||
|
cur = 0
|
||||||
|
out_count = 0
|
||||||
|
tuple_count = 0
|
||||||
|
|
||||||
|
# from rare to frequent new tuples
|
||||||
|
# get the best (smallest) file for it
|
||||||
|
# and copy it
|
||||||
|
while (cur < in_count) {
|
||||||
|
fn = infilesSmallToBig[cur]
|
||||||
|
++cur
|
||||||
|
if (redirected == 0) { printf "\r Processing file "cur"/"in_count }
|
||||||
|
else { print " Processing file "cur"/"in_count }
|
||||||
|
# create path for the trace file from afl-showmap
|
||||||
|
tracefile_path = trace_dir"/"fn
|
||||||
|
# ensure the file size is not zero
|
||||||
|
cmd = "du -b \""tracefile_path"\""
|
||||||
|
# "ls -l \""tracefile_path"\""
|
||||||
|
cmd | getline output
|
||||||
|
close(cmd)
|
||||||
|
split(output, result, "\t")
|
||||||
|
if (result[1] == 0) {
|
||||||
|
print "[!] WARNING: file "fn" is crashing the target, ignoring..."
|
||||||
|
}
|
||||||
|
# gather all keys, and count them
|
||||||
|
while ((getline line < tracefile_path) > 0) {
|
||||||
|
key = line
|
||||||
|
if (!(key in key_count)) {
|
||||||
|
++tuple_count
|
||||||
|
}
|
||||||
|
++key_count[key]
|
||||||
|
if (! (key in best_file)) {
|
||||||
|
# this is the best file for this key
|
||||||
|
best_file[key] = fn
|
||||||
|
#printf "BEST_FILE[%d]=\"%s\"\n",key,fn | "sort -t'[' -k2 > "trace_dir"/.candidate_script"
|
||||||
|
}
|
||||||
|
#printf "%d %s\n",key,fn > trace_dir"/.candidate_list"
|
||||||
|
}
|
||||||
|
close(tracefile_path)
|
||||||
|
}
|
||||||
|
print ""
|
||||||
|
|
||||||
|
# sort keys
|
||||||
|
sortedKeys = trace_dir"/.all_uniq"
|
||||||
|
sortKeysCmd = "sort -k1n > "sortedKeys
|
||||||
|
for (key in key_count) {
|
||||||
|
printf "%7d %s\n",key_count[key],key | sortKeysCmd
|
||||||
|
}
|
||||||
|
close(sortKeysCmd)
|
||||||
|
|
||||||
|
# iterate over keys from rare to frequent and
|
||||||
|
# copy best file
|
||||||
|
while ((getline < sortedKeys) > 0) {
|
||||||
|
|
||||||
|
# split
|
||||||
|
nrFields = split($0, field, / +/)
|
||||||
|
#print nrFields" Felder: '"field[0]"', '"field[1]"', '"field[2]"', '"field[3]"'"
|
||||||
|
key = field[nrFields]
|
||||||
|
|
||||||
|
++tcnt;
|
||||||
|
if (redirected == 0) { printf "\r Processing tuple "tcnt"/"tuple_count" with count "key_count[key]"..." }
|
||||||
|
else { print " Processing tuple "tcnt"/"tuple_count" with count "key_count[key]"..." }
|
||||||
|
|
||||||
|
if (key in keyAlreadyKnown) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
fn = best_file[key]
|
||||||
|
# gather all tuples from the best file for this key
|
||||||
|
tracedfn = trace_dir"/"fn
|
||||||
|
while ((getline < tracedfn) > 0) {
|
||||||
|
keyAlreadyKnown[$0] = ""
|
||||||
|
}
|
||||||
|
close(tracedfn)
|
||||||
|
|
||||||
|
# copy file unless already done
|
||||||
|
if (! (fn in file_already_copied)) {
|
||||||
|
realfile = infilesSmallToBigMap[fn]
|
||||||
|
system(cp_tool" \""in_dir"/"realfile"\" \""out_dir"/"fn"\"")
|
||||||
|
file_already_copied[fn] = ""
|
||||||
|
++out_count
|
||||||
|
#printf "tuple nr %d (%d cnt=%d) -> %s\n",tcnt,key,key_count[key],fn > trace_dir"/.log"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
close(sortedKeys)
|
||||||
|
print ""
|
||||||
|
print "[+] Found "tuple_count" unique tuples across "in_count" files."
|
||||||
|
|
||||||
|
if (out_count == 1) {
|
||||||
|
print "[!] WARNING: All test cases had the same traces, check syntax!"
|
||||||
|
}
|
||||||
|
print "[+] Narrowed down to "out_count" files, saved in '"out_dir"'."
|
||||||
|
|
||||||
|
if (!ENVIRON["AFL_KEEP_TRACES"]) {
|
||||||
|
system("rm -rf "trace_dir" 2>/dev/null")
|
||||||
|
}
|
||||||
|
|
||||||
|
exit 0
|
||||||
|
}
|
||||||
|
EOF
|
@ -0,0 +1,630 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
#
|
||||||
|
# american fuzzy lop++ - corpus minimization tool
|
||||||
|
# ---------------------------------------------
|
||||||
|
#
|
||||||
|
# Originally written by Michal Zalewski
|
||||||
|
#
|
||||||
|
# Copyright 2014, 2015 Google Inc. All rights reserved.
|
||||||
|
#
|
||||||
|
# Copyright 2019-2024 AFLplusplus
|
||||||
|
#
|
||||||
|
# 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:
|
||||||
|
#
|
||||||
|
# https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# This tool tries to find the smallest subset of files in the input directory
|
||||||
|
# that still trigger the full range of instrumentation data points seen in
|
||||||
|
# the starting corpus. This has two uses:
|
||||||
|
#
|
||||||
|
# - Screening large corpora of input files before using them as a seed for
|
||||||
|
# afl-fuzz. The tool will remove functionally redundant files and likely
|
||||||
|
# leave you with a much smaller set.
|
||||||
|
#
|
||||||
|
# (In this case, you probably also want to consider running afl-tmin on
|
||||||
|
# the individual files later on to reduce their size.)
|
||||||
|
#
|
||||||
|
# - Minimizing the corpus generated organically by afl-fuzz, perhaps when
|
||||||
|
# planning to feed it to more resource-intensive tools. The tool achieves
|
||||||
|
# this by removing all entries that used to trigger unique behaviors in the
|
||||||
|
# past, but have been made obsolete by later finds.
|
||||||
|
#
|
||||||
|
# Note that the tool doesn't modify the files themselves. For that, you want
|
||||||
|
# afl-tmin.
|
||||||
|
#
|
||||||
|
# This script must use bash because other shells may have hardcoded limits on
|
||||||
|
# array sizes.
|
||||||
|
#
|
||||||
|
|
||||||
|
echo "corpus minimization tool for afl-fuzz"
|
||||||
|
echo
|
||||||
|
|
||||||
|
#########
|
||||||
|
# SETUP #
|
||||||
|
#########
|
||||||
|
|
||||||
|
# Process command-line options...
|
||||||
|
|
||||||
|
MEM_LIMIT=none
|
||||||
|
TIMEOUT=5000
|
||||||
|
|
||||||
|
unset IN_DIR OUT_DIR STDIN_FILE EXTRA_PAR MEM_LIMIT_GIVEN F_ARG \
|
||||||
|
AFL_CMIN_CRASHES_ONLY AFL_CMIN_ALLOW_ANY QEMU_MODE UNICORN_MODE T_ARG
|
||||||
|
|
||||||
|
export AFL_QUIET=1
|
||||||
|
|
||||||
|
while getopts "+i:o:f:m:t:T:eOQUAChXY" opt; do
|
||||||
|
|
||||||
|
case "$opt" in
|
||||||
|
|
||||||
|
"h")
|
||||||
|
;;
|
||||||
|
|
||||||
|
"i")
|
||||||
|
IN_DIR="$OPTARG"
|
||||||
|
;;
|
||||||
|
|
||||||
|
"o")
|
||||||
|
OUT_DIR="$OPTARG"
|
||||||
|
;;
|
||||||
|
"f")
|
||||||
|
STDIN_FILE="$OPTARG"
|
||||||
|
F_ARG=1
|
||||||
|
;;
|
||||||
|
"m")
|
||||||
|
MEM_LIMIT="$OPTARG"
|
||||||
|
MEM_LIMIT_GIVEN=1
|
||||||
|
;;
|
||||||
|
"t")
|
||||||
|
TIMEOUT="$OPTARG"
|
||||||
|
;;
|
||||||
|
"e")
|
||||||
|
EXTRA_PAR="$EXTRA_PAR -e"
|
||||||
|
;;
|
||||||
|
"A")
|
||||||
|
export AFL_CMIN_ALLOW_ANY=1
|
||||||
|
;;
|
||||||
|
"C")
|
||||||
|
export AFL_CMIN_CRASHES_ONLY=1
|
||||||
|
;;
|
||||||
|
"O")
|
||||||
|
EXTRA_PAR="$EXTRA_PAR -O"
|
||||||
|
FRIDA_MODE=1
|
||||||
|
;;
|
||||||
|
"Q")
|
||||||
|
EXTRA_PAR="$EXTRA_PAR -Q"
|
||||||
|
QEMU_MODE=1
|
||||||
|
;;
|
||||||
|
"Y")
|
||||||
|
EXTRA_PAR="$EXTRA_PAR -X"
|
||||||
|
NYX_MODE=1
|
||||||
|
;;
|
||||||
|
"X")
|
||||||
|
EXTRA_PAR="$EXTRA_PAR -X"
|
||||||
|
NYX_MODE=1
|
||||||
|
;;
|
||||||
|
"U")
|
||||||
|
EXTRA_PAR="$EXTRA_PAR -U"
|
||||||
|
UNICORN_MODE=1
|
||||||
|
;;
|
||||||
|
"T")
|
||||||
|
T_ARG="$OPTARG"
|
||||||
|
;;
|
||||||
|
"?")
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
|
||||||
|
esac
|
||||||
|
|
||||||
|
done
|
||||||
|
|
||||||
|
shift $((OPTIND-1))
|
||||||
|
|
||||||
|
TARGET_BIN="$1"
|
||||||
|
|
||||||
|
if [ "$TARGET_BIN" = "" -o "$IN_DIR" = "" -o "$OUT_DIR" = "" ]; then
|
||||||
|
|
||||||
|
cat 1>&2 <<_EOF_
|
||||||
|
Usage: $0 [ options ] -- /path/to/target_app [ ... ]
|
||||||
|
|
||||||
|
Required parameters:
|
||||||
|
|
||||||
|
-i dir - input directory with the starting corpus
|
||||||
|
-o dir - output directory for minimized files
|
||||||
|
|
||||||
|
Execution control settings:
|
||||||
|
|
||||||
|
-T tasks - how many parallel processes to create (default=1, "all"=nproc)
|
||||||
|
-f file - location read by the fuzzed program (default: stdin)
|
||||||
|
-m megs - memory limit for child process (default=$MEM_LIMIT MB)
|
||||||
|
-t msec - run time limit for child process (default: 5000ms)
|
||||||
|
-O - use binary-only instrumentation (FRIDA mode)
|
||||||
|
-Q - use binary-only instrumentation (QEMU mode)
|
||||||
|
-U - use unicorn-based instrumentation (Unicorn mode)
|
||||||
|
-X - use Nyx mode
|
||||||
|
|
||||||
|
Minimization settings:
|
||||||
|
|
||||||
|
-A - allow crashing and timeout inputs
|
||||||
|
-C - keep crashing inputs, reject everything else
|
||||||
|
-e - solve for edge coverage only, ignore hit counts
|
||||||
|
|
||||||
|
For additional tips, please consult README.md.
|
||||||
|
This script cannot read filenames that end with a space ' '.
|
||||||
|
|
||||||
|
Environment variables used:
|
||||||
|
AFL_KEEP_TRACES: leave the temporary <out_dir>\.traces directory
|
||||||
|
AFL_NO_FORKSRV: run target via execve instead of using the forkserver
|
||||||
|
AFL_PATH: last resort location to find the afl-showmap binary
|
||||||
|
AFL_SKIP_BIN_CHECK: skip check for target binary
|
||||||
|
AFL_CUSTOM_MUTATOR_LIBRARY: custom mutator library (post_process and send)
|
||||||
|
AFL_PYTHON_MODULE: custom mutator library (post_process and send)
|
||||||
|
_EOF_
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Do a sanity check to discourage the use of /tmp, since we can't really
|
||||||
|
# handle this safely from a shell script.
|
||||||
|
|
||||||
|
if [ "$AFL_ALLOW_TMP" = "" ]; then
|
||||||
|
|
||||||
|
echo "$IN_DIR" | grep -qE '^(/var)?/tmp/'
|
||||||
|
T1="$?"
|
||||||
|
|
||||||
|
echo "$TARGET_BIN" | grep -qE '^(/var)?/tmp/'
|
||||||
|
T2="$?"
|
||||||
|
|
||||||
|
echo "$OUT_DIR" | grep -qE '^(/var)?/tmp/'
|
||||||
|
T3="$?"
|
||||||
|
|
||||||
|
echo "$STDIN_FILE" | grep -qE '^(/var)?/tmp/'
|
||||||
|
T4="$?"
|
||||||
|
|
||||||
|
echo "$PWD" | grep -qE '^(/var)?/tmp/'
|
||||||
|
T5="$?"
|
||||||
|
|
||||||
|
if [ "$T1" = "0" -o "$T2" = "0" -o "$T3" = "0" -o "$T4" = "0" -o "$T5" = "0" ]; then
|
||||||
|
echo "[-] Warning: do not use this script in /tmp or /var/tmp for security reasons." 1>&2
|
||||||
|
fi
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
# If @@ is specified, but there's no -f, let's come up with a temporary input
|
||||||
|
# file name.
|
||||||
|
|
||||||
|
TRACE_DIR="$OUT_DIR/.traces"
|
||||||
|
|
||||||
|
if [ "$STDIN_FILE" = "" ]; then
|
||||||
|
|
||||||
|
if echo "$*" | grep -qF '@@'; then
|
||||||
|
STDIN_FILE="$TRACE_DIR/.cur_input"
|
||||||
|
fi
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check for obvious errors.
|
||||||
|
|
||||||
|
if [ ! "$T_ARG" = "" -a -n "$F_ARG" -a ! "$NYX_MODE" == 1 ]; then
|
||||||
|
echo "[-] Error: -T and -f can not be used together." 1>&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! "$MEM_LIMIT" = "none" ]; then
|
||||||
|
|
||||||
|
if [ "$MEM_LIMIT" -lt "5" ]; then
|
||||||
|
echo "[-] Error: dangerously low memory limit." 1>&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! "$TIMEOUT" = "none" ]; then
|
||||||
|
|
||||||
|
if [ "$TIMEOUT" -lt "10" ]; then
|
||||||
|
echo "[-] Error: dangerously low timeout." 1>&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$NYX_MODE" = "" ]; then
|
||||||
|
if [ ! -f "$TARGET_BIN" -o ! -x "$TARGET_BIN" ]; then
|
||||||
|
|
||||||
|
TNEW="`which "$TARGET_BIN" 2>/dev/null`"
|
||||||
|
|
||||||
|
if [ ! -f "$TNEW" -o ! -x "$TNEW" ]; then
|
||||||
|
echo "[-] Error: binary '$TARGET_BIN' not found or not executable." 1>&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
TARGET_BIN="$TNEW"
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
grep -aq AFL_DUMP_MAP_SIZE "$TARGET_BIN" && {
|
||||||
|
echo "[!] Trying to obtain the map size of the target ..."
|
||||||
|
MAPSIZE=`AFL_DUMP_MAP_SIZE=1 "./$TARGET_BIN" 2>/dev/null`
|
||||||
|
test -n "$MAPSIZE" && {
|
||||||
|
export AFL_MAP_SIZE=$MAPSIZE
|
||||||
|
echo "[+] Setting AFL_MAP_SIZE=$MAPSIZE"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if [ "$AFL_SKIP_BIN_CHECK" = "" -a "$QEMU_MODE" = "" -a "$FRIDA_MODE" = "" -a "$UNICORN_MODE" = "" -a "$NYX_MODE" = "" ]; then
|
||||||
|
|
||||||
|
if ! grep -qF "__AFL_SHM_ID" "$TARGET_BIN"; then
|
||||||
|
echo "[-] Error: binary '$TARGET_BIN' doesn't appear to be instrumented." 1>&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -d "$IN_DIR" ]; then
|
||||||
|
echo "[-] Error: directory '$IN_DIR' not found." 1>&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
test -d "$IN_DIR/default" && IN_DIR="$IN_DIR/default"
|
||||||
|
test -d "$IN_DIR/queue" && IN_DIR="$IN_DIR/queue"
|
||||||
|
|
||||||
|
find "$OUT_DIR" -name 'id[:_]*' -maxdepth 1 -exec rm -- {} \; 2>/dev/null
|
||||||
|
rm -rf "$TRACE_DIR" 2>/dev/null
|
||||||
|
|
||||||
|
rmdir "$OUT_DIR" 2>/dev/null
|
||||||
|
|
||||||
|
if [ -d "$OUT_DIR" ]; then
|
||||||
|
echo "[-] Error: directory '$OUT_DIR' exists and is not empty - delete it first." 1>&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir -m 700 -p "$TRACE_DIR" || exit 1
|
||||||
|
|
||||||
|
if [ ! "$STDIN_FILE" = "" ]; then
|
||||||
|
rm -f "$STDIN_FILE" || exit 1
|
||||||
|
touch "$STDIN_FILE" || exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
SHOWMAP=`command -v afl-showmap 2>/dev/null`
|
||||||
|
|
||||||
|
if [ -z "$SHOWMAP" ]; then
|
||||||
|
TMP="${0%/afl-cmin.bash}/afl-showmap"
|
||||||
|
if [ -x "$TMP" ]; then
|
||||||
|
SHOWMAP=$TMP
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$SHOWMAP" -a -x "./afl-showmap" ]; then
|
||||||
|
SHOWMAP="./afl-showmap"
|
||||||
|
else
|
||||||
|
if [ -n "$AFL_PATH" ]; then
|
||||||
|
SHOWMAP="$AFL_PATH/afl-showmap"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -x "$SHOWMAP" ]; then
|
||||||
|
echo "[-] Error: can't find 'afl-showmap' - please set AFL_PATH." 1>&2
|
||||||
|
rm -rf "$TRACE_DIR"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
THREADS=
|
||||||
|
if [ ! "$T_ARG" = "" ]; then
|
||||||
|
if [ "$T_ARG" = "all" ]; then
|
||||||
|
THREADS=$(nproc)
|
||||||
|
else
|
||||||
|
if [ "$T_ARG" -gt 1 -a "$T_ARG" -le "$(nproc)" ]; then
|
||||||
|
THREADS=$T_ARG
|
||||||
|
else
|
||||||
|
echo "[-] Error: -T parameter must between 2 and $(nproc) or \"all\"." 1>&2
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
if [ -z "$F_ARG" ]; then
|
||||||
|
echo "[*] Are you aware of the '-T all' parallelize option that massively improves the speed?"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
IN_COUNT=$((`ls -- "$IN_DIR" 2>/dev/null | wc -l`))
|
||||||
|
|
||||||
|
if [ "$IN_COUNT" = "0" ]; then
|
||||||
|
echo "[-] Hmm, no inputs in the target directory. Nothing to be done."
|
||||||
|
rm -rf "$TRACE_DIR"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "[*] Are you aware that afl-cmin is faster than this afl-cmin.bash script?"
|
||||||
|
echo "[+] Found $IN_COUNT files for minimizing."
|
||||||
|
|
||||||
|
if [ -n "$THREADS" ]; then
|
||||||
|
if [ "$IN_COUNT" -lt "$THREADS" ]; then
|
||||||
|
THREADS=$IN_COUNT
|
||||||
|
echo "[!] WARNING: less inputs than threads, reducing threads to $THREADS and likely the overhead of threading makes things slower..."
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
FIRST_FILE=`ls "$IN_DIR" | head -1`
|
||||||
|
|
||||||
|
# Make sure that we're not dealing with a directory.
|
||||||
|
|
||||||
|
if [ -d "$IN_DIR/$FIRST_FILE" ]; then
|
||||||
|
echo "[-] Error: The target directory contains subdirectories - please fix." 1>&2
|
||||||
|
rm -rf "$TRACE_DIR"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check for the more efficient way to copy files...
|
||||||
|
|
||||||
|
if ln "$IN_DIR/$FIRST_FILE" "$TRACE_DIR/.link_test" 2>/dev/null; then
|
||||||
|
CP_TOOL=ln
|
||||||
|
else
|
||||||
|
CP_TOOL=cp
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Make sure that we can actually get anything out of afl-showmap before we
|
||||||
|
# waste too much time.
|
||||||
|
|
||||||
|
echo "[*] Testing the target binary..."
|
||||||
|
|
||||||
|
if [ "$STDIN_FILE" = "" ]; then
|
||||||
|
|
||||||
|
AFL_CMIN_ALLOW_ANY=1 "$SHOWMAP" -m "$MEM_LIMIT" -t "$TIMEOUT" -o "$TRACE_DIR/.run_test" -Z $EXTRA_PAR -- "$@" <"$IN_DIR/$FIRST_FILE"
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
cp "$IN_DIR/$FIRST_FILE" "$STDIN_FILE"
|
||||||
|
AFL_CMIN_ALLOW_ANY=1 "$SHOWMAP" -m "$MEM_LIMIT" -t "$TIMEOUT" -o "$TRACE_DIR/.run_test" -Z $EXTRA_PAR -H "$STDIN_FILE" -- "$@" </dev/null
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
FIRST_COUNT=$((`grep -c . "$TRACE_DIR/.run_test"`))
|
||||||
|
|
||||||
|
if [ "$FIRST_COUNT" -gt "0" ]; then
|
||||||
|
|
||||||
|
echo "[+] OK, $FIRST_COUNT tuples recorded."
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
echo "[-] Error: no instrumentation output detected (perhaps crash or timeout)." 1>&2
|
||||||
|
test "$AFL_KEEP_TRACES" = "" && rm -rf "$TRACE_DIR"
|
||||||
|
exit 1
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
TMPFILE=$OUT_DIR/.list.$$
|
||||||
|
if [ ! "$THREADS" = "" ]; then
|
||||||
|
ls -- "$IN_DIR" > $TMPFILE 2>/dev/null
|
||||||
|
IN_COUNT=$(cat $TMPFILE | wc -l)
|
||||||
|
SPLIT=$(($IN_COUNT / $THREADS))
|
||||||
|
if [ "$(($IN_COUNT % $THREADS))" -gt 0 ]; then
|
||||||
|
SPLIT=$(($SPLIT + 1))
|
||||||
|
fi
|
||||||
|
echo "[+] Splitting workload into $THREADS tasks with $SPLIT items on average each."
|
||||||
|
split -l $SPLIT $TMPFILE $TMPFILE.
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Let's roll!
|
||||||
|
|
||||||
|
#############################
|
||||||
|
# STEP 1: COLLECTING TRACES #
|
||||||
|
#############################
|
||||||
|
|
||||||
|
echo "[*] Obtaining traces for input files in '$IN_DIR'..."
|
||||||
|
|
||||||
|
if [ "$THREADS" = "" ]; then
|
||||||
|
(
|
||||||
|
|
||||||
|
CUR=0
|
||||||
|
|
||||||
|
if [ "$STDIN_FILE" = "" ]; then
|
||||||
|
|
||||||
|
ls "$IN_DIR" | while read -r fn; do
|
||||||
|
|
||||||
|
if [ -s "$IN_DIR/$fn" ]; then
|
||||||
|
|
||||||
|
CUR=$((CUR+1))
|
||||||
|
printf "\\r Processing file $CUR/$IN_COUNT... "
|
||||||
|
|
||||||
|
"$SHOWMAP" -m "$MEM_LIMIT" -t "$TIMEOUT" -o "$TRACE_DIR/$fn" -Z $EXTRA_PAR -- "$@" <"$IN_DIR/$fn"
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
done
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
ls "$IN_DIR" | while read -r fn; do
|
||||||
|
|
||||||
|
if [ -s "$IN_DIR/$fn" ]; then
|
||||||
|
|
||||||
|
CUR=$((CUR+1))
|
||||||
|
printf "\\r Processing file $CUR/$IN_COUNT... "
|
||||||
|
|
||||||
|
cp "$IN_DIR/$fn" "$STDIN_FILE"
|
||||||
|
"$SHOWMAP" -m "$MEM_LIMIT" -t "$TIMEOUT" -o "$TRACE_DIR/$fn" -Z $EXTRA_PAR -H "$STDIN_FILE" -- "$@" </dev/null
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
done
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
PIDS=
|
||||||
|
CNT=0
|
||||||
|
for inputs in $(ls ${TMPFILE}.*); do
|
||||||
|
|
||||||
|
(
|
||||||
|
|
||||||
|
if [ "$STDIN_FILE" = "" ]; then
|
||||||
|
|
||||||
|
cat $inputs | while read -r fn; do
|
||||||
|
|
||||||
|
if [ -s "$IN_DIR/$fn" ]; then
|
||||||
|
|
||||||
|
"$SHOWMAP" -m "$MEM_LIMIT" -t "$TIMEOUT" -o "$TRACE_DIR/$fn" -Z $EXTRA_PAR -- "$@" <"$IN_DIR/$fn"
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
done
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
if [ -s "$IN_DIR/$fn" ]; then
|
||||||
|
STDIN_FILE="$inputs.$$"
|
||||||
|
cat $inputs | while read -r fn; do
|
||||||
|
|
||||||
|
cp "$IN_DIR/$fn" "$STDIN_FILE"
|
||||||
|
"$SHOWMAP" -m "$MEM_LIMIT" -t "$TIMEOUT" -o "$TRACE_DIR/$fn" -Z $EXTRA_PAR -H "$STDIN_FILE" -- "$@" </dev/null
|
||||||
|
|
||||||
|
done
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
) &
|
||||||
|
|
||||||
|
PIDS="$PIDS $!"
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "[+] Waiting for running tasks IDs:$PIDS"
|
||||||
|
wait
|
||||||
|
echo "[+] all $THREADS running tasks completed."
|
||||||
|
rm -f ${TMPFILE}*
|
||||||
|
|
||||||
|
#echo trace dir files: $(ls $TRACE_DIR/*|wc -l)
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
##########################
|
||||||
|
# STEP 2: SORTING TUPLES #
|
||||||
|
##########################
|
||||||
|
|
||||||
|
# With this out of the way, we sort all tuples by popularity across all
|
||||||
|
# datasets. The reasoning here is that we won't be able to avoid the files
|
||||||
|
# that trigger unique tuples anyway, so we will want to start with them and
|
||||||
|
# see what's left.
|
||||||
|
|
||||||
|
echo "[*] Sorting trace sets (this may take a while)..."
|
||||||
|
|
||||||
|
ls "$IN_DIR" | sed "s#^#$TRACE_DIR/#" | tr '\n' '\0' | xargs -0 -n 1 cat | \
|
||||||
|
sort | uniq -c | sort -k 1,1 -n >"$TRACE_DIR/.all_uniq"
|
||||||
|
|
||||||
|
TUPLE_COUNT=$((`grep -c . "$TRACE_DIR/.all_uniq"`))
|
||||||
|
|
||||||
|
echo "[+] Found $TUPLE_COUNT unique tuples across $IN_COUNT files."
|
||||||
|
|
||||||
|
#####################################
|
||||||
|
# STEP 3: SELECTING CANDIDATE FILES #
|
||||||
|
#####################################
|
||||||
|
|
||||||
|
# The next step is to find the best candidate for each tuple. The "best"
|
||||||
|
# part is understood simply as the smallest input that includes a particular
|
||||||
|
# tuple in its trace. Empirical evidence suggests that this produces smaller
|
||||||
|
# datasets than more involved algorithms that could be still pulled off in
|
||||||
|
# a shell script.
|
||||||
|
|
||||||
|
echo "[*] Finding best candidates for each tuple..."
|
||||||
|
|
||||||
|
CUR=0
|
||||||
|
|
||||||
|
ls -rS "$IN_DIR" | while read -r fn; do
|
||||||
|
|
||||||
|
CUR=$((CUR+1))
|
||||||
|
printf "\\r Processing file $CUR/$IN_COUNT... "
|
||||||
|
|
||||||
|
sed "s#\$# $fn#" "$TRACE_DIR/$fn" >>"$TRACE_DIR/.candidate_list"
|
||||||
|
|
||||||
|
test -s "$TRACE_DIR/$fn" || echo Warning: $fn is ignored because of crashing the target
|
||||||
|
|
||||||
|
done
|
||||||
|
|
||||||
|
echo
|
||||||
|
|
||||||
|
##############################
|
||||||
|
# STEP 4: LOADING CANDIDATES #
|
||||||
|
##############################
|
||||||
|
|
||||||
|
# At this point, we have a file of tuple-file pairs, sorted by file size
|
||||||
|
# in ascending order (as a consequence of ls -rS). By doing sort keyed
|
||||||
|
# only by tuple (-k 1,1) and configured to output only the first line for
|
||||||
|
# every key (-s -u), we end up with the smallest file for each tuple.
|
||||||
|
|
||||||
|
echo "[*] Sorting candidate list (be patient)..."
|
||||||
|
|
||||||
|
sort -k1,1 -s -u "$TRACE_DIR/.candidate_list" | \
|
||||||
|
sed 's/^/BEST_FILE[/;s/ /]="/;s/$/"/' >"$TRACE_DIR/.candidate_script"
|
||||||
|
|
||||||
|
if [ ! -s "$TRACE_DIR/.candidate_script" ]; then
|
||||||
|
echo "[-] Error: no traces obtained from test cases, check syntax!" 1>&2
|
||||||
|
test "$AFL_KEEP_TRACES" = "" && rm -rf "$TRACE_DIR"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# The sed command converted the sorted list to a shell script that populates
|
||||||
|
# BEST_FILE[tuple]="fname". Let's load that!
|
||||||
|
|
||||||
|
. "$TRACE_DIR/.candidate_script"
|
||||||
|
|
||||||
|
##########################
|
||||||
|
# STEP 5: WRITING OUTPUT #
|
||||||
|
##########################
|
||||||
|
|
||||||
|
# The final trick is to grab the top pick for each tuple, unless said tuple is
|
||||||
|
# already set due to the inclusion of an earlier candidate; and then put all
|
||||||
|
# tuples associated with the newly-added file to the "already have" list. The
|
||||||
|
# loop works from least popular tuples and toward the most common ones.
|
||||||
|
|
||||||
|
echo "[*] Processing candidates and writing output files..."
|
||||||
|
|
||||||
|
CUR=0
|
||||||
|
|
||||||
|
touch "$TRACE_DIR/.already_have"
|
||||||
|
|
||||||
|
while read -r cnt tuple; do
|
||||||
|
|
||||||
|
CUR=$((CUR+1))
|
||||||
|
printf "\\r Processing tuple $CUR/$TUPLE_COUNT with count $cnt... "
|
||||||
|
|
||||||
|
# If we already have this tuple, skip it.
|
||||||
|
|
||||||
|
grep -q "^$tuple\$" "$TRACE_DIR/.already_have" && continue
|
||||||
|
|
||||||
|
FN=${BEST_FILE[tuple]}
|
||||||
|
|
||||||
|
# echo "tuple nr $CUR ($tuple cnt=$cnt) -> $FN" >> "$TRACE_DIR/.log"
|
||||||
|
$CP_TOOL "$IN_DIR/$FN" "$OUT_DIR/$FN"
|
||||||
|
|
||||||
|
if [ "$((CUR % 5))" = "0" ]; then
|
||||||
|
sort -u "$TRACE_DIR/$FN" "$TRACE_DIR/.already_have" >"$TRACE_DIR/.tmp"
|
||||||
|
mv -f "$TRACE_DIR/.tmp" "$TRACE_DIR/.already_have"
|
||||||
|
else
|
||||||
|
cat "$TRACE_DIR/$FN" >>"$TRACE_DIR/.already_have"
|
||||||
|
fi
|
||||||
|
|
||||||
|
done <"$TRACE_DIR/.all_uniq"
|
||||||
|
|
||||||
|
echo
|
||||||
|
|
||||||
|
OUT_COUNT=`ls -- "$OUT_DIR" | wc -l`
|
||||||
|
|
||||||
|
if [ "$OUT_COUNT" = "1" ]; then
|
||||||
|
echo "[!] WARNING: All test cases had the same traces, check syntax!"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "[+] Narrowed down to $OUT_COUNT files, saved in '$OUT_DIR'."
|
||||||
|
echo
|
||||||
|
|
||||||
|
test "$AFL_KEEP_TRACES" = "" && rm -rf "$TRACE_DIR"
|
||||||
|
|
||||||
|
exit 0
|
@ -0,0 +1,155 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# written by jhertz
|
||||||
|
#
|
||||||
|
|
||||||
|
test "$1" = "-h" -o "$1" = "-hh" -o "$1" = "--help" && {
|
||||||
|
echo 'afl-persistent-config'
|
||||||
|
echo
|
||||||
|
echo $0
|
||||||
|
echo
|
||||||
|
echo afl-persistent-config has no command line options
|
||||||
|
echo
|
||||||
|
echo afl-persistent-config permanently reconfigures the system to a high performance fuzzing state.
|
||||||
|
echo "WARNING: this reduces the security of the system!"
|
||||||
|
echo
|
||||||
|
echo Note that there is also afl-system-config which sets additional runtime
|
||||||
|
echo configuration options.
|
||||||
|
exit 0
|
||||||
|
}
|
||||||
|
|
||||||
|
if [ $# -ne 0 ]; then
|
||||||
|
echo "ERROR: Unknown option(s): $@"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo "WARNING: This scripts makes permanent configuration changes to the system to"
|
||||||
|
echo " increase the performance for fuzzing. As a result, the system also"
|
||||||
|
echo " becomes less secure against attacks! If you use this script, setup"
|
||||||
|
echo " strong firewall rules and only make SSH available as a network"
|
||||||
|
echo " service!"
|
||||||
|
echo
|
||||||
|
echo -n "Type \"YES\" to continue: "
|
||||||
|
read ANSWER
|
||||||
|
if [[ "$ANSWER" != "YES" ]]; then
|
||||||
|
echo Input was not YES, aborting ...
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo
|
||||||
|
PLATFORM=`uname -s`
|
||||||
|
ARCH=`uname -m`
|
||||||
|
|
||||||
|
# check that we're on Mac
|
||||||
|
if [[ "$PLATFORM" = "Darwin" ]] ; then
|
||||||
|
|
||||||
|
# check if UID == 0
|
||||||
|
if [[ "$EUID" -ne 0 ]]; then
|
||||||
|
echo "You need to be root to do this. E.g. use \"sudo\""
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# check if SIP is disabled
|
||||||
|
if [[ ! $(csrutil status | grep "disabled") ]]; then
|
||||||
|
echo "SIP needs to be disabled. Restart and press Command-R at reboot, Utilities => Terminal => enter \"csrutil disable\""
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Checks passed."
|
||||||
|
|
||||||
|
echo "Installing /Library/LaunchDaemons/shm_setup.plist"
|
||||||
|
|
||||||
|
cat << EOF > /Library/LaunchDaemons/shm_setup.plist
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>Label</key>
|
||||||
|
<string>shmemsetup</string>
|
||||||
|
<key>UserName</key>
|
||||||
|
<string>root</string>
|
||||||
|
<key>GroupName</key>
|
||||||
|
<string>wheel</string>
|
||||||
|
<key>ProgramArguments</key>
|
||||||
|
<array>
|
||||||
|
<string>/usr/sbin/sysctl</string>
|
||||||
|
<string>-w</string>
|
||||||
|
<string>kern.sysv.shmmax=524288000</string>
|
||||||
|
<string>kern.sysv.shmmin=1</string>
|
||||||
|
<string>kern.sysv.shmmni=128</string>
|
||||||
|
<string>kern.sysv.shmseg=48</string>
|
||||||
|
<string>kern.sysv.shmall=131072000</string>
|
||||||
|
</array>
|
||||||
|
<key>KeepAlive</key>
|
||||||
|
<false/>
|
||||||
|
<key>RunAtLoad</key>
|
||||||
|
<true/>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
|
EOF
|
||||||
|
|
||||||
|
if [[ "$ARCH" = "x86_64" ]]; then
|
||||||
|
echo "Disabling ASLR system wide"
|
||||||
|
nvram boot-args="no_aslr=1"
|
||||||
|
else
|
||||||
|
echo NOTICE: on ARM64 we do not know currently how to disable system wide ASLR, please report if you know how.
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo "Reboot and enjoy your fuzzing"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$PLATFORM" = "Linux" ]] ; then
|
||||||
|
|
||||||
|
# check if UID == 0
|
||||||
|
if [[ "$EUID" -ne 0 ]]; then
|
||||||
|
echo "You need to be root to do this. E.g. use \"sudo\""
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Checks passed."
|
||||||
|
|
||||||
|
test -d /etc/sysctl.d || echo Error: /etc/sysctl.d directory not found, cannot install shmem config
|
||||||
|
test -d /etc/sysctl.d -a '!' -e /etc/sysctl.d/99-fuzzing.conf && {
|
||||||
|
echo "Installing /etc/sysctl.d/99-fuzzing.conf"
|
||||||
|
cat << EOF > /etc/sysctl.d/99-fuzzing.conf
|
||||||
|
kernel.core_uses_pid=0
|
||||||
|
kernel.core_pattern=core
|
||||||
|
kernel.randomize_va_space=0
|
||||||
|
kernel.sched_child_runs_first=1
|
||||||
|
kernel.sched_autogroup_enabled=1
|
||||||
|
kernel.sched_migration_cost_ns=50000000
|
||||||
|
kernel.sched_latency_ns=250000000
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
grub_try_disable_mitigation () {
|
||||||
|
KEY="$1"
|
||||||
|
if ! grep -E "^$KEY=" /etc/default/grub | grep -E -q 'noibrs pcid nopti'; then
|
||||||
|
echo "Configuring performance boot options"
|
||||||
|
LINE=`grep -E "^$KEY=" /etc/default/grub | sed "s/^$KEY=//" | tr -d '"'`
|
||||||
|
OPTIONS="$LINE ibpb=off ibrs=off kpti=off l1tf=off spec_rstack_overflow=off mds=off no_stf_barrier noibpb noibrs pcid nopti nospec_store_bypass_disable nospectre_v1 nospectre_v2 pcid=on pti=off spec_store_bypass_disable=off spectre_v2=off stf_barrier=off srbds=off noexec=off noexec32=off tsx=on tsx=on tsx_async_abort=off mitigations=off audit=0 hardened_usercopy=off ssbd=force-off"
|
||||||
|
echo Setting boot options in /etc/default/grub to $KEY=\"$OPTIONS\"
|
||||||
|
sed -i "s|^$KEY=.*|$KEY=\"$OPTIONS\"|" /etc/default/grub
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if grep -E -q '^GRUB_CMDLINE_LINUX=' /etc/default/grub || grep -E -q '^GRUB_CMDLINE_LINUX_DEFAULT=' /etc/default/grub; then
|
||||||
|
grub_try_disable_mitigation "GRUB_CMDLINE_LINUX_DEFAULT"
|
||||||
|
# We also overwrite GRUB_CMDLINE_LINUX because some distributions already overwrite GRUB_CMDLINE_LINUX_DEFAULT
|
||||||
|
grub_try_disable_mitigation "GRUB_CMDLINE_LINUX"
|
||||||
|
else
|
||||||
|
echo "Error: /etc/default/grub with GRUB_CMDLINE_LINUX is not present, cannot set boot options"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo "Reboot and enjoy your fuzzing"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
echo "Error: Unknown platform \"$PLATFORM\", currently supported are Linux and MacOS."
|
||||||
|
exit 1
|
@ -0,0 +1,337 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
#
|
||||||
|
# american fuzzy lop++ - Advanced Persistent Graphing
|
||||||
|
# -------------------------------------------------
|
||||||
|
#
|
||||||
|
# Originally written by Michal Zalewski
|
||||||
|
# Based on a design & prototype by Michael Rash.
|
||||||
|
#
|
||||||
|
# Copyright 2014, 2015 Google Inc. 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:
|
||||||
|
#
|
||||||
|
# https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
|
||||||
|
get_abs_path() {
|
||||||
|
echo $(cd "`dirname "$1"`" && pwd)/"`basename "$1"`"
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "progress plotting utility for afl-fuzz by Michal Zalewski"
|
||||||
|
echo
|
||||||
|
|
||||||
|
GRAPHICAL="0"
|
||||||
|
|
||||||
|
if [ "$1" = "-g" ] || [ "$1" = "--graphical" ]; then
|
||||||
|
GRAPHICAL="1"
|
||||||
|
shift
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$#" != "2" ]; then
|
||||||
|
|
||||||
|
cat 1>&2 <<_EOF_
|
||||||
|
$0 [ -g | --graphical ] afl_state_dir graph_output_dir
|
||||||
|
|
||||||
|
This program generates gnuplot images from afl-fuzz output data.
|
||||||
|
|
||||||
|
Usage:
|
||||||
|
|
||||||
|
afl_state_dir should point to an existing state directory for any
|
||||||
|
active or stopped instance of afl-fuzz
|
||||||
|
graph_output_dir should point to an empty directory where this
|
||||||
|
tool can write the resulting plots to
|
||||||
|
-g, --graphical (optional) display the plots in a graphical window
|
||||||
|
(you should have built afl-plot-ui to use this option)
|
||||||
|
|
||||||
|
The program will put index.html and three PNG images in the output directory;
|
||||||
|
you should be able to view it with any web browser of your choice.
|
||||||
|
_EOF_
|
||||||
|
|
||||||
|
exit 1
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
inputdir=`get_abs_path "$1"`
|
||||||
|
outputdir=`get_abs_path "$2"`
|
||||||
|
|
||||||
|
#if [ "$AFL_ALLOW_TMP" = "" ]; then
|
||||||
|
#
|
||||||
|
# echo "$inputdir" | grep -qE '^(/var)?/tmp/'
|
||||||
|
# T1="$?"
|
||||||
|
#
|
||||||
|
# echo "$outputdir" | grep -qE '^(/var)?/tmp/'
|
||||||
|
# T2="$?"
|
||||||
|
#
|
||||||
|
# if [ "$T1" = "0" -o "$T2" = "0" ]; then
|
||||||
|
#
|
||||||
|
# echo "[-] Error: this script shouldn't be used with shared /tmp directories." 1>&2
|
||||||
|
# exit 1
|
||||||
|
#
|
||||||
|
# fi
|
||||||
|
#
|
||||||
|
#fi
|
||||||
|
|
||||||
|
if [ ! -f "$inputdir/plot_data" ]; then
|
||||||
|
|
||||||
|
if [ -f "$inputdir/default/plot_data" ]; then
|
||||||
|
|
||||||
|
echo "[-] Error: input directory is not valid (missing 'plot_data'), likely you mean $inputdir/default?" 1>&2
|
||||||
|
exit 1
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
echo "[-] Error: input directory is not valid (missing 'plot_data')." 1>&2
|
||||||
|
exit 1
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
LINES=`cat "$inputdir/plot_data" | wc -l`
|
||||||
|
|
||||||
|
if [ "$LINES" -lt 3 ]; then
|
||||||
|
|
||||||
|
echo "[-] Error: plot_data carries too little data, let it run longer." 1>&2
|
||||||
|
exit 1
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
BANNER="`cat "$inputdir/fuzzer_stats" 2> /dev/null | grep '^afl_banner ' | cut -d: -f2- | cut -b2-`"
|
||||||
|
|
||||||
|
test "$BANNER" = "" && BANNER="(none)"
|
||||||
|
|
||||||
|
GNUPLOT=`command -v gnuplot 2>/dev/null`
|
||||||
|
|
||||||
|
if [ "$GNUPLOT" = "" ]; then
|
||||||
|
|
||||||
|
echo "[-] Error: can't find 'gnuplot' in your \$PATH." 1>&2
|
||||||
|
exit 1
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir "$outputdir" 2>/dev/null
|
||||||
|
|
||||||
|
if [ ! -d "$outputdir" ]; then
|
||||||
|
|
||||||
|
echo "[-] Error: unable to create the output directory - pick another location." 1>&2
|
||||||
|
exit 1
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
rm -f "$outputdir/high_freq.png" "$outputdir/low_freq.png" "$outputdir/exec_speed.png" "$outputdir/edges.png"
|
||||||
|
mv -f "$outputdir/index.html" "$outputdir/index.html.orig" 2>/dev/null
|
||||||
|
|
||||||
|
GNUPLOT_SETUP="
|
||||||
|
#set xdata time
|
||||||
|
#set timefmt '%s'
|
||||||
|
#set format x \"%b %d\n%H:%M\"
|
||||||
|
set tics font 'small'
|
||||||
|
unset mxtics
|
||||||
|
unset mytics
|
||||||
|
|
||||||
|
set grid xtics linetype 0 linecolor rgb '#e0e0e0'
|
||||||
|
set grid ytics linetype 0 linecolor rgb '#e0e0e0'
|
||||||
|
set border linecolor rgb '#50c0f0'
|
||||||
|
set tics textcolor rgb '#000000'
|
||||||
|
set key outside
|
||||||
|
|
||||||
|
set autoscale xfixmin
|
||||||
|
set autoscale xfixmax
|
||||||
|
|
||||||
|
set xlabel \"relative time in seconds\" font \"small\"
|
||||||
|
"
|
||||||
|
|
||||||
|
PLOT_HF="
|
||||||
|
set terminal png truecolor enhanced size 1000,300 butt
|
||||||
|
set output '$outputdir/high_freq.png'
|
||||||
|
|
||||||
|
$GNUPLOT_SETUP
|
||||||
|
|
||||||
|
plot '$inputdir/plot_data' using 1:4 with filledcurve x1 title 'corpus count' linecolor rgb '#000000' fillstyle transparent solid 0.2 noborder, \\
|
||||||
|
'' using 1:3 with filledcurve x1 title 'current item' linecolor rgb '#f0f0f0' fillstyle transparent solid 0.5 noborder, \\
|
||||||
|
'' using 1:5 with lines title 'pending items' linecolor rgb '#0090ff' linewidth 3, \\
|
||||||
|
'' using 1:6 with lines title 'pending favs' linecolor rgb '#c00080' linewidth 3, \\
|
||||||
|
'' using 1:2 with lines title 'cycles done' linecolor rgb '#c000f0' linewidth 3
|
||||||
|
"
|
||||||
|
|
||||||
|
PLOT_LF="
|
||||||
|
set terminal png truecolor enhanced size 1000,200 butt
|
||||||
|
set output '$outputdir/low_freq.png'
|
||||||
|
|
||||||
|
$GNUPLOT_SETUP
|
||||||
|
|
||||||
|
plot '$inputdir/plot_data' using 1:8 with filledcurve x1 title '' linecolor rgb '#c00080' fillstyle transparent solid 0.2 noborder, \\
|
||||||
|
'' using 1:8 with lines title ' uniq crashes' linecolor rgb '#c00080' linewidth 3, \\
|
||||||
|
'' using 1:9 with lines title 'uniq hangs' linecolor rgb '#c000f0' linewidth 3, \\
|
||||||
|
'' using 1:10 with lines title 'levels' linecolor rgb '#0090ff' linewidth 3
|
||||||
|
"
|
||||||
|
|
||||||
|
PLOT_ES="
|
||||||
|
set terminal png truecolor enhanced size 1000,200 butt
|
||||||
|
set output '$outputdir/exec_speed.png'
|
||||||
|
|
||||||
|
$GNUPLOT_SETUP
|
||||||
|
|
||||||
|
plot '$inputdir/plot_data' using 1:11 with filledcurve x1 title '' linecolor rgb '#0090ff' fillstyle transparent solid 0.2 noborder, \\
|
||||||
|
'$inputdir/plot_data' using 1:11 with lines title ' execs/sec' linecolor rgb '#0090ff' linewidth 3 smooth bezier;
|
||||||
|
"
|
||||||
|
|
||||||
|
PLOT_EG="
|
||||||
|
set terminal png truecolor enhanced size 1000,300 butt
|
||||||
|
set output '$outputdir/edges.png'
|
||||||
|
|
||||||
|
$GNUPLOT_SETUP
|
||||||
|
|
||||||
|
plot '$inputdir/plot_data' using 1:13 with lines title ' edges' linecolor rgb '#0090ff' linewidth 3
|
||||||
|
"
|
||||||
|
|
||||||
|
if [ "$#" = "2" ] && [ "$GRAPHICAL" = "1" ]; then
|
||||||
|
|
||||||
|
afl-plot-ui -h > /dev/null 2>&1
|
||||||
|
|
||||||
|
if [ "$?" != "0" ]; then
|
||||||
|
|
||||||
|
cat 1>&2 <<_EOF_
|
||||||
|
You do not seem to have the afl-plot-ui utility installed. If you have installed afl-plot-ui, make sure the afl-plot-ui executable is in your PATH.
|
||||||
|
If you are still facing any problems, please open an issue at https://github.com/AFLplusplus/AFLplusplus/issues.
|
||||||
|
|
||||||
|
No plots have been generated. Please rerun without the "-g" or "--graphical" flag to generate the plots.
|
||||||
|
_EOF_
|
||||||
|
|
||||||
|
exit 1
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
rm -rf "$outputdir/.tmp"
|
||||||
|
mkdir -p "$outputdir/.tmp"
|
||||||
|
mkfifo "$outputdir/.tmp/win_ids" || exit 1
|
||||||
|
|
||||||
|
afl-plot-ui > "$outputdir/.tmp/win_ids" &
|
||||||
|
W_IDS=$(cat "$outputdir/.tmp/win_ids")
|
||||||
|
|
||||||
|
rm -rf "$outputdir/.tmp"
|
||||||
|
|
||||||
|
W_ID1=$(echo "$W_IDS" | head -n 1)
|
||||||
|
W_ID2=$(echo "$W_IDS" | head -n 2 | tail -n 1)
|
||||||
|
W_ID3=$(echo "$W_IDS" | head -n 3 | tail -n 1)
|
||||||
|
W_ID4=$(echo "$W_IDS" | tail -n 1)
|
||||||
|
|
||||||
|
echo "[*] Generating plots..."
|
||||||
|
|
||||||
|
(
|
||||||
|
|
||||||
|
cat << _EOF_
|
||||||
|
|
||||||
|
$PLOT_HF
|
||||||
|
set term x11 window "$W_ID3"
|
||||||
|
set output
|
||||||
|
replot
|
||||||
|
pause mouse close
|
||||||
|
|
||||||
|
_EOF_
|
||||||
|
|
||||||
|
) | gnuplot 2> /dev/null &
|
||||||
|
|
||||||
|
(
|
||||||
|
|
||||||
|
cat << _EOF_
|
||||||
|
|
||||||
|
$PLOT_LF
|
||||||
|
set term x11 window "$W_ID4"
|
||||||
|
set output
|
||||||
|
replot
|
||||||
|
pause mouse close
|
||||||
|
|
||||||
|
_EOF_
|
||||||
|
|
||||||
|
) | gnuplot 2> /dev/null &
|
||||||
|
|
||||||
|
(
|
||||||
|
|
||||||
|
cat << _EOF_
|
||||||
|
|
||||||
|
$PLOT_ES
|
||||||
|
set term x11 window "$W_ID2"
|
||||||
|
set output
|
||||||
|
replot
|
||||||
|
pause mouse close
|
||||||
|
|
||||||
|
_EOF_
|
||||||
|
|
||||||
|
) | gnuplot 2> /dev/null &
|
||||||
|
|
||||||
|
(
|
||||||
|
|
||||||
|
cat << _EOF_
|
||||||
|
|
||||||
|
$PLOT_EG
|
||||||
|
set term x11 window "$W_ID1"
|
||||||
|
set output
|
||||||
|
replot
|
||||||
|
pause mouse close
|
||||||
|
|
||||||
|
_EOF_
|
||||||
|
|
||||||
|
) | gnuplot 2> /dev/null &
|
||||||
|
|
||||||
|
sleep 1
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
echo "[*] Generating plots..."
|
||||||
|
|
||||||
|
(
|
||||||
|
|
||||||
|
cat << _EOF_
|
||||||
|
|
||||||
|
$PLOT_HF
|
||||||
|
|
||||||
|
$PLOT_LF
|
||||||
|
|
||||||
|
$PLOT_ES
|
||||||
|
|
||||||
|
$PLOT_EG
|
||||||
|
|
||||||
|
_EOF_
|
||||||
|
|
||||||
|
) | gnuplot || echo "Note: if you see errors concerning 'unknown or ambiguous terminal type' then you need to use a gnuplot that has png support compiled in."
|
||||||
|
|
||||||
|
echo "[?] You can also use -g flag to view the plots in an GUI window, and interact with the plots (if you have built afl-plot-ui). Run \"afl-plot -h\" to know more."
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -s "$outputdir/exec_speed.png" ]; then
|
||||||
|
|
||||||
|
echo "[-] Error: something went wrong! Perhaps you have an ancient version of gnuplot?" 1>&2
|
||||||
|
exit 1
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "[*] Generating index.html..."
|
||||||
|
|
||||||
|
cat >"$outputdir/index.html" <<_EOF_
|
||||||
|
<table style="font-family: 'Trebuchet MS', 'Tahoma', 'Arial', 'Helvetica'">
|
||||||
|
<tr><td style="width: 18ex"><b>Banner:</b></td><td>$BANNER</td></tr>
|
||||||
|
<tr><td><b>Directory:</b></td><td>$inputdir</td></tr>
|
||||||
|
<tr><td><b>Generated on:</b></td><td>`date`</td></tr>
|
||||||
|
</table>
|
||||||
|
<p>
|
||||||
|
<img src="edges.png" width=1000 height=300>
|
||||||
|
<img src="high_freq.png" width=1000 height=300><p>
|
||||||
|
<img src="low_freq.png" width=1000 height=200><p>
|
||||||
|
<img src="exec_speed.png" width=1000 height=200>
|
||||||
|
|
||||||
|
_EOF_
|
||||||
|
|
||||||
|
# Make it easy to remotely view results when outputting directly to a directory
|
||||||
|
# served by Apache or other HTTP daemon. Since the plots aren't horribly
|
||||||
|
# sensitive, this seems like a reasonable trade-off.
|
||||||
|
|
||||||
|
chmod 755 "$outputdir"
|
||||||
|
chmod 644 "$outputdir/high_freq.png" "$outputdir/low_freq.png" "$outputdir/exec_speed.png" "$outputdir/edges.png" "$outputdir/index.html"
|
||||||
|
|
||||||
|
echo "[+] All done - enjoy your charts!"
|
||||||
|
|
||||||
|
exit 0
|
@ -0,0 +1,143 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
test "$1" = "-h" -o "$1" = "-hh" -o "$1" = "--help" && {
|
||||||
|
echo 'afl-system-config by Marc Heuse <mh@mh-sec.de>'
|
||||||
|
echo
|
||||||
|
echo $0
|
||||||
|
echo
|
||||||
|
echo afl-system-config has no command line options
|
||||||
|
echo
|
||||||
|
echo afl-system-config reconfigures the system to a high performance fuzzing state.
|
||||||
|
echo "WARNING: this reduces the security of the system!"
|
||||||
|
echo
|
||||||
|
echo Note that there is also afl-persistent-config which sets additional permanent
|
||||||
|
echo configuration options.
|
||||||
|
exit 0
|
||||||
|
}
|
||||||
|
if [ $# -ne 0 ]; then
|
||||||
|
echo "ERROR: Unknown option(s): $@"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
DONE=
|
||||||
|
PLATFORM=`uname -s`
|
||||||
|
echo This reconfigures the system to have a better fuzzing performance.
|
||||||
|
echo "WARNING: this reduces the security of the system!"
|
||||||
|
echo
|
||||||
|
if [ '!' "$EUID" = 0 ] && [ '!' `id -u` = 0 ] ; then
|
||||||
|
echo "Warning: you need to be root to run this!"
|
||||||
|
sleep 1
|
||||||
|
# we do not exit as other mechanisms exist that allows to do this than
|
||||||
|
# being root. let the errors speak for themselves.
|
||||||
|
fi
|
||||||
|
sleep 1
|
||||||
|
if [ "$PLATFORM" = "Linux" ] ; then
|
||||||
|
{
|
||||||
|
sysctl -w kernel.core_uses_pid=0
|
||||||
|
# Arch Linux requires core_pattern to be empty :(
|
||||||
|
test -e /etc/arch-release && sysctl -w kernel.core_pattern=
|
||||||
|
test -e /etc/arch-release || sysctl -w kernel.core_pattern=core
|
||||||
|
sysctl -w kernel.randomize_va_space=0
|
||||||
|
sysctl -w kernel.sched_child_runs_first=1
|
||||||
|
sysctl -w kernel.sched_autogroup_enabled=1
|
||||||
|
sysctl -w kernel.sched_migration_cost_ns=50000000 2>/dev/null
|
||||||
|
sysctl -w kernel.sched_latency_ns=250000000 2>/dev/null
|
||||||
|
echo never > /sys/kernel/mm/transparent_hugepage/enabled
|
||||||
|
test -e /sys/devices/system/cpu/cpufreq/scaling_governor && echo performance | tee /sys/devices/system/cpu/cpufreq/scaling_governor
|
||||||
|
test -e /sys/devices/system/cpu/cpufreq/policy0/scaling_governor && echo performance | tee /sys/devices/system/cpu/cpufreq/policy*/scaling_governor
|
||||||
|
test -e /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor && echo performance | tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor
|
||||||
|
test -e /sys/devices/system/cpu/intel_pstate/no_turbo && echo 0 > /sys/devices/system/cpu/intel_pstate/no_turbo
|
||||||
|
test -e /sys/devices/system/cpu/cpufreq/boost && echo 1 > /sys/devices/system/cpu/cpufreq/boost
|
||||||
|
test -e /sys/devices/system/cpu/intel_pstate/max_perf_pct && echo 100 > /sys/devices/system/cpu/intel_pstate/max_perf_pct
|
||||||
|
test -n "$(which auditctl)" && auditctl -a never,task >/dev/null 2>&1
|
||||||
|
} > /dev/null
|
||||||
|
echo Settings applied.
|
||||||
|
echo
|
||||||
|
dmesg | grep -E -q 'noibrs pcid nopti' || {
|
||||||
|
echo It is recommended to boot the kernel with lots of security off - if you are running a machine that is in a secured network - so set this:
|
||||||
|
echo ' /etc/default/grub:GRUB_CMDLINE_LINUX_DEFAULT="ibpb=off ibrs=off kpti=0 l1tf=off mds=off mitigations=off no_stf_barrier noibpb noibrs pcid nopti nospec_store_bypass_disable nospectre_v1 nospectre_v2 pcid=on pti=off spec_store_bypass_disable=off spectre_v2=off stf_barrier=off srbds=off noexec=off noexec32=off tsx=on tsx_async_abort=off arm64.nopauth audit=0 hardened_usercopy=off ssbd=force-off"'
|
||||||
|
echo
|
||||||
|
}
|
||||||
|
echo If you run fuzzing instances in docker, run them with \"--security-opt seccomp=unconfined\" for more speed.
|
||||||
|
echo
|
||||||
|
DONE=1
|
||||||
|
fi
|
||||||
|
if [ "$PLATFORM" = "FreeBSD" ] ; then
|
||||||
|
{
|
||||||
|
sysctl kern.elf32.aslr.enable=0
|
||||||
|
sysctl kern.elf64.aslr.enable=0
|
||||||
|
} > /dev/null
|
||||||
|
echo Settings applied.
|
||||||
|
echo
|
||||||
|
cat <<EOF
|
||||||
|
In order to suppress core file generation during fuzzing it is recommended to set
|
||||||
|
me:\\
|
||||||
|
:coredumpsize=0:
|
||||||
|
in the ~/.login_conf file for the user used for fuzzing.
|
||||||
|
EOF
|
||||||
|
echo It is recommended to boot the kernel with lots of security off - if you are running a machine that is in a secured network - so set this:
|
||||||
|
echo ' sysctl hw.ibrs_disable=1'
|
||||||
|
echo 'Setting kern.pmap.pg_ps_enabled=0 into /boot/loader.conf might be helpful too.'
|
||||||
|
echo
|
||||||
|
DONE=1
|
||||||
|
fi
|
||||||
|
if [ "$PLATFORM" = "OpenBSD" ] ; then
|
||||||
|
doas sysctl vm.malloc_conf=
|
||||||
|
echo 'Freecheck on allocation in particular can be detrimental to performance.'
|
||||||
|
echo 'Also we might not want necessarily to abort at any allocation failure.'
|
||||||
|
echo 'System security features cannot be disabled on OpenBSD.'
|
||||||
|
echo
|
||||||
|
DONE=1
|
||||||
|
fi
|
||||||
|
if [ "$PLATFORM" = "DragonFly" ] ; then
|
||||||
|
#/sbin/sysctl kern.corefile=/dev/null
|
||||||
|
#echo Settings applied.
|
||||||
|
cat <<EOF
|
||||||
|
In order to suppress core file generation during fuzzing it is recommended to set
|
||||||
|
me:\\
|
||||||
|
:coredumpsize=0:
|
||||||
|
in the ~/.login_conf file for the user used for fuzzing.
|
||||||
|
EOF
|
||||||
|
echo
|
||||||
|
DONE=1
|
||||||
|
fi
|
||||||
|
if [ "$PLATFORM" = "NetBSD" ] ; then
|
||||||
|
{
|
||||||
|
/sbin/sysctl -w security.models.extensions.user_set_cpu_affinity=1
|
||||||
|
} > /dev/null
|
||||||
|
echo Settings applied.
|
||||||
|
echo
|
||||||
|
DONE=1
|
||||||
|
fi
|
||||||
|
if [ "$PLATFORM" = "Darwin" ] ; then
|
||||||
|
sysctl kern.sysv.shmmax=524288000
|
||||||
|
sysctl kern.sysv.shmmin=1
|
||||||
|
sysctl kern.sysv.shmseg=48
|
||||||
|
sysctl kern.sysv.shmall=131072000
|
||||||
|
echo Settings applied.
|
||||||
|
echo
|
||||||
|
if $(launchctl list 2>/dev/null | grep -q '\.ReportCrash\>') ; then
|
||||||
|
echo
|
||||||
|
echo Unloading the default crash reporter
|
||||||
|
SL=/System/Library; PL=com.apple.ReportCrash
|
||||||
|
sudo -u "$SUDO_USER" launchctl unload -w ${SL}/LaunchAgents/${PL}.plist
|
||||||
|
launchctl unload -w ${SL}/LaunchDaemons/${PL}.Root.plist
|
||||||
|
echo
|
||||||
|
fi
|
||||||
|
echo It is recommended to disable System Integrity Protection for increased performance.
|
||||||
|
echo See: https://developer.apple.com/documentation/security/disabling_and_enabling_system_integrity_protection
|
||||||
|
echo
|
||||||
|
DONE=1
|
||||||
|
fi
|
||||||
|
if [ "$PLATFORM" = "Haiku" ] ; then
|
||||||
|
DEBUG_SERVER_DIR=~/config/settings/system/debug_server
|
||||||
|
[ ! -d ${DEBUG_SERVER_DIR} ] && mkdir -p ${DEBUG_SERVER_DIR}
|
||||||
|
SETTINGS=${DEBUG_SERVER_DIR}/settings
|
||||||
|
[ -r ${SETTINGS} ] && grep -qE "default_action\s+kill" ${SETTINGS} && { echo "Nothing to do"; } || { \
|
||||||
|
echo We change the debug_server default_action from user to silently kill; \
|
||||||
|
[ ! -r ${SETTINGS} ] && echo "default_action kill" >${SETTINGS} || { mv ${SETTINGS} s.tmp; sed -e "s/default_action\s\s*user/default_action kill/" s.tmp > ${SETTINGS}; rm s.tmp; }; \
|
||||||
|
echo Settings applied.; echo; \
|
||||||
|
}
|
||||||
|
DONE=1
|
||||||
|
fi
|
||||||
|
test -z "$DONE" && echo Error: Unknown platform: $PLATFORM
|
||||||
|
exit 0
|
@ -0,0 +1,452 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
#
|
||||||
|
# american fuzzy lop++ - status check tool
|
||||||
|
# ----------------------------------------
|
||||||
|
#
|
||||||
|
# Originally written by Michal Zalewski
|
||||||
|
#
|
||||||
|
# Copyright 2015 Google Inc. All rights reserved.
|
||||||
|
# Copyright 2019-2024 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:
|
||||||
|
#
|
||||||
|
# https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# This tool summarizes the status of any locally-running synchronized
|
||||||
|
# instances of afl-fuzz.
|
||||||
|
#
|
||||||
|
|
||||||
|
test "$1" = "-h" -o "$1" = "-hh" && {
|
||||||
|
echo "$0 status check tool for afl-fuzz by Michal Zalewski"
|
||||||
|
echo
|
||||||
|
echo "Usage: $0 [-s] [-d] afl_output_directory"
|
||||||
|
echo
|
||||||
|
echo Options:
|
||||||
|
echo " -d - include dead fuzzer stats"
|
||||||
|
echo " -m - just show minimal stats"
|
||||||
|
echo " -n - no color output"
|
||||||
|
echo " -s - skip details and output summary results only"
|
||||||
|
echo
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
unset MINIMAL_ONLY
|
||||||
|
unset NO_COLOR
|
||||||
|
unset PROCESS_DEAD
|
||||||
|
unset SUMMARY_ONLY
|
||||||
|
unset RED
|
||||||
|
unset GREEN
|
||||||
|
unset YELLOW
|
||||||
|
unset BLUE
|
||||||
|
unset NC
|
||||||
|
unset RESET
|
||||||
|
|
||||||
|
if [ -z "$TERM" ]; then export TERM=vt220; fi
|
||||||
|
|
||||||
|
while [ "$1" = "-d" -o "$1" = "-m" -o "$1" = "-n" -o "$1" = "-s" ]; do
|
||||||
|
|
||||||
|
if [ "$1" = "-d" ]; then
|
||||||
|
PROCESS_DEAD=1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$1" = "-m" ]; then
|
||||||
|
MINIMAL_ONLY=1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$1" = "-n" ]; then
|
||||||
|
NO_COLOR=1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$1" = "-s" ]; then
|
||||||
|
SUMMARY_ONLY=1
|
||||||
|
fi
|
||||||
|
|
||||||
|
shift
|
||||||
|
|
||||||
|
done
|
||||||
|
|
||||||
|
DIR="$1"
|
||||||
|
|
||||||
|
if [ "$DIR" = "" -o "$DIR" = "-h" -o "$DIR" = "--help" ]; then
|
||||||
|
|
||||||
|
echo "$0 status check tool for afl-fuzz by Michal Zalewski" 1>&2
|
||||||
|
echo 1>&2
|
||||||
|
echo "Usage: $0 [-d] [-m] [-n] [-s] afl_output_directory" 1>&2
|
||||||
|
echo 1>&2
|
||||||
|
echo Options: 1>&2
|
||||||
|
echo " -d - include dead fuzzer stats" 1>&2
|
||||||
|
echo " -m - just show minimal stats" 1>&2
|
||||||
|
echo " -n - no color output" 1>&2
|
||||||
|
echo " -s - skip details and output summary results only" 1>&2
|
||||||
|
echo 1>&2
|
||||||
|
exit 1
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$MINIMAL_ONLY" ]; then
|
||||||
|
echo "$0 status check tool for afl-fuzz by Michal Zalewski"
|
||||||
|
echo
|
||||||
|
fi
|
||||||
|
|
||||||
|
cd "$DIR" || exit 1
|
||||||
|
|
||||||
|
if [ -d queue ]; then
|
||||||
|
|
||||||
|
echo "[-] Error: parameter is an individual output directory, not a sync dir." 1>&2
|
||||||
|
exit 1
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
BC=`which bc 2>/dev/null`
|
||||||
|
FUSER=`which fuser 2>/dev/null`
|
||||||
|
|
||||||
|
if [ -z "$NO_COLOR" ]; then
|
||||||
|
RED=`tput setaf 9 1 1 2>/dev/null`
|
||||||
|
GREEN=`tput setaf 2 1 1 2>/dev/null`
|
||||||
|
BLUE=`tput setaf 4 1 1 2>/dev/null`
|
||||||
|
YELLOW=`tput setaf 11 1 1 2>/dev/null`
|
||||||
|
NC=`tput sgr0`
|
||||||
|
RESET="$NC"
|
||||||
|
fi
|
||||||
|
|
||||||
|
PLATFORM=`uname -s`
|
||||||
|
#if [ "$PLATFORM" = "Linux" ] ; then
|
||||||
|
# CUR_TIME=`cat /proc/uptime | awk '{printf "%.0f\n", $1}'`
|
||||||
|
#else
|
||||||
|
# This will lead to inacurate results but will prevent the script from breaking on platforms other than Linux
|
||||||
|
CUR_TIME=`date +%s`
|
||||||
|
#fi
|
||||||
|
|
||||||
|
TMP=`mktemp -t .afl-whatsup-XXXXXXXX` || TMP=`mktemp -p /data/local/tmp .afl-whatsup-XXXXXXXX` || TMP=`mktemp -p /data/local/tmp .afl-whatsup-XXXXXXXX` || exit 1
|
||||||
|
trap "rm -f $TMP" 1 2 3 13 15
|
||||||
|
|
||||||
|
ALIVE_CNT=0
|
||||||
|
DEAD_CNT=0
|
||||||
|
START_CNT=0
|
||||||
|
|
||||||
|
TOTAL_TIME=0
|
||||||
|
TOTAL_EXECS=0
|
||||||
|
TOTAL_EPS=0
|
||||||
|
TOTAL_EPLM=0
|
||||||
|
TOTAL_CRASHES=0
|
||||||
|
TOTAL_HANGS=0
|
||||||
|
TOTAL_PFAV=0
|
||||||
|
TOTAL_PENDING=0
|
||||||
|
TOTAL_COVERAGE=
|
||||||
|
|
||||||
|
# Time since last find / crash / hang, formatted as string
|
||||||
|
FMT_TIME="0 days 0 hours"
|
||||||
|
FMT_FIND="${RED}none seen yet${NC}"
|
||||||
|
FMT_CRASH="none seen yet"
|
||||||
|
FMT_HANG="none seen yet"
|
||||||
|
|
||||||
|
if [ "$SUMMARY_ONLY" = "" ]; then
|
||||||
|
|
||||||
|
echo "Individual fuzzers"
|
||||||
|
echo "=================="
|
||||||
|
echo
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
fmt_duration()
|
||||||
|
{
|
||||||
|
DUR_STRING=
|
||||||
|
if [ $1 -le 0 ]; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
local duration=$((CUR_TIME - $1))
|
||||||
|
local days=$((duration / 60 / 60 / 24))
|
||||||
|
local hours=$(((duration / 60 / 60) % 24))
|
||||||
|
local minutes=$(((duration / 60) % 60))
|
||||||
|
local seconds=$((duration % 60))
|
||||||
|
|
||||||
|
if [ $duration -le 0 ]; then
|
||||||
|
DUR_STRING="0 seconds"
|
||||||
|
elif [ $duration -eq 1 ]; then
|
||||||
|
DUR_STRING="1 second"
|
||||||
|
elif [ $days -gt 0 ]; then
|
||||||
|
DUR_STRING="$days days, $hours hours"
|
||||||
|
elif [ $hours -gt 0 ]; then
|
||||||
|
DUR_STRING="$hours hours, $minutes minutes"
|
||||||
|
elif [ $minutes -gt 0 ]; then
|
||||||
|
DUR_STRING="$minutes minutes, $seconds seconds"
|
||||||
|
else
|
||||||
|
DUR_STRING="$seconds seconds"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
FIRST=true
|
||||||
|
TOTAL_WCOP=
|
||||||
|
TOTAL_LAST_FIND=0
|
||||||
|
|
||||||
|
for j in `find . -maxdepth 2 -iname fuzzer_setup | sort`; do
|
||||||
|
|
||||||
|
DIR=$(dirname "$j")
|
||||||
|
i=$DIR/fuzzer_stats
|
||||||
|
|
||||||
|
if [ -f "$i" ]; then
|
||||||
|
|
||||||
|
IS_STARTING=
|
||||||
|
IS_DEAD=
|
||||||
|
sed 's/^command_line.*$/_skip:1/;s/[ ]*:[ ]*/="/;s/$/"/' "$i" >"$TMP"
|
||||||
|
. "$TMP"
|
||||||
|
DIRECTORY=$DIR
|
||||||
|
DIR=${DIR##*/}
|
||||||
|
RUN_UNIX=$run_time
|
||||||
|
RUN_DAYS=$((RUN_UNIX / 60 / 60 / 24))
|
||||||
|
RUN_HRS=$(((RUN_UNIX / 60 / 60) % 24))
|
||||||
|
COVERAGE=$(echo $bitmap_cvg|tr -d %)
|
||||||
|
if [ -n "$TOTAL_COVERAGE" -a -n "$COVERAGE" -a -n "$BC" ]; then
|
||||||
|
if [ "$(echo "$TOTAL_COVERAGE < $COVERAGE" | bc)" -eq 1 ]; then
|
||||||
|
TOTAL_COVERAGE=$COVERAGE
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
if [ -z "$TOTAL_COVERAGE" ]; then TOTAL_COVERAGE=$COVERAGE ; fi
|
||||||
|
|
||||||
|
test -n "$cycles_wo_finds" && {
|
||||||
|
test -z "$FIRST" && TOTAL_WCOP="${TOTAL_WCOP}/"
|
||||||
|
TOTAL_WCOP="${TOTAL_WCOP}${cycles_wo_finds}"
|
||||||
|
FIRST=
|
||||||
|
}
|
||||||
|
|
||||||
|
if [ "$SUMMARY_ONLY" = "" ]; then
|
||||||
|
|
||||||
|
echo ">>> $afl_banner instance: $DIR ($RUN_DAYS days, $RUN_HRS hrs) fuzzer PID: $fuzzer_pid <<<"
|
||||||
|
echo
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! kill -0 "$fuzzer_pid" 2>/dev/null; then
|
||||||
|
|
||||||
|
if [ -e "$i" ] && [ -e "$j" ] && [ -n "$FUSER" ]; then
|
||||||
|
|
||||||
|
if [ "$i" -ot "$j" ]; then
|
||||||
|
|
||||||
|
# fuzzer_setup is newer than fuzzer_stats, maybe the instance is starting?
|
||||||
|
TMP_PID=`fuser -v "$DIRECTORY" 2>&1 | grep afl-fuzz`
|
||||||
|
|
||||||
|
if [ -n "$TMP_PID" ]; then
|
||||||
|
|
||||||
|
if [ "$SUMMARY_ONLY" = "" ]; then
|
||||||
|
|
||||||
|
echo " Instance is still starting up, skipping."
|
||||||
|
echo
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
START_CNT=$((START_CNT + 1))
|
||||||
|
last_find=0
|
||||||
|
IS_STARTING=1
|
||||||
|
|
||||||
|
if [ "$PROCESS_DEAD" = "" ]; then
|
||||||
|
|
||||||
|
continue
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$IS_STARTING" ]; then
|
||||||
|
|
||||||
|
if [ "$SUMMARY_ONLY" = "" ]; then
|
||||||
|
|
||||||
|
echo " Instance is dead or running remotely, skipping."
|
||||||
|
echo
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
DEAD_CNT=$((DEAD_CNT + 1))
|
||||||
|
IS_DEAD=1
|
||||||
|
last_find=0
|
||||||
|
|
||||||
|
if [ "$PROCESS_DEAD" = "" ]; then
|
||||||
|
|
||||||
|
continue
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
ALIVE_CNT=$((ALIVE_CNT + 1))
|
||||||
|
|
||||||
|
EXEC_SEC=0
|
||||||
|
EXEC_MIN=0
|
||||||
|
test -z "$RUN_UNIX" -o "$RUN_UNIX" = 0 || EXEC_SEC=$((execs_done / RUN_UNIX))
|
||||||
|
PATH_PERC=$((cur_item * 100 / corpus_count))
|
||||||
|
|
||||||
|
test "$IS_DEAD" = 1 || EXEC_MIN=$(echo $execs_ps_last_min|sed 's/\..*//')
|
||||||
|
|
||||||
|
TOTAL_TIME=$((TOTAL_TIME + RUN_UNIX))
|
||||||
|
TOTAL_EPS=$((TOTAL_EPS + EXEC_SEC))
|
||||||
|
TOTAL_EPLM=$((TOTAL_EPLM + EXEC_MIN))
|
||||||
|
TOTAL_EXECS=$((TOTAL_EXECS + execs_done))
|
||||||
|
TOTAL_CRASHES=$((TOTAL_CRASHES + saved_crashes))
|
||||||
|
TOTAL_HANGS=$((TOTAL_HANGS + saved_hangs))
|
||||||
|
TOTAL_PENDING=$((TOTAL_PENDING + pending_total))
|
||||||
|
TOTAL_PFAV=$((TOTAL_PFAV + pending_favs))
|
||||||
|
|
||||||
|
if [ "$last_find" -gt "$TOTAL_LAST_FIND" ]; then
|
||||||
|
TOTAL_LAST_FIND=$last_find
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$SUMMARY_ONLY" = "" ]; then
|
||||||
|
|
||||||
|
# Warnings in red
|
||||||
|
TIMEOUT_PERC=$((exec_timeout * 100 / execs_done))
|
||||||
|
if [ $TIMEOUT_PERC -ge 10 ]; then
|
||||||
|
echo " ${RED}timeout_ratio $TIMEOUT_PERC%${NC}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ $EXEC_SEC -eq 0 ]; then
|
||||||
|
echo " ${YELLOW}no data yet, 0 execs/sec${NC}"
|
||||||
|
elif [ $EXEC_SEC -lt 100 ]; then
|
||||||
|
echo " ${RED}slow execution, $EXEC_SEC execs/sec${NC}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
fmt_duration $last_find && FMT_FIND=$DUR_STRING
|
||||||
|
fmt_duration $last_crash && FMT_CRASH=$DUR_STRING
|
||||||
|
fmt_duration $last_hang && FMT_HANG=$DUR_STRING
|
||||||
|
FMT_CWOP="not available"
|
||||||
|
test -n "$cycles_wo_finds" && {
|
||||||
|
test "$cycles_wo_finds" = 0 && FMT_CWOP="$cycles_wo_finds"
|
||||||
|
test "$cycles_wo_finds" -gt 10 && FMT_CWOP="${YELLOW}$cycles_wo_finds${NC}"
|
||||||
|
test "$cycles_wo_finds" -gt 50 && FMT_CWOP="${RED}$cycles_wo_finds${NC}"
|
||||||
|
}
|
||||||
|
|
||||||
|
echo " last_find : $FMT_FIND"
|
||||||
|
echo " last_crash : $FMT_CRASH"
|
||||||
|
if [ -z "$MINIMAL_ONLY" ]; then
|
||||||
|
echo " last_hang : $FMT_HANG"
|
||||||
|
echo " cycles_wo_finds : $FMT_CWOP"
|
||||||
|
fi
|
||||||
|
echo " coverage : $COVERAGE%"
|
||||||
|
|
||||||
|
if [ -z "$MINIMAL_ONLY" ]; then
|
||||||
|
|
||||||
|
CPU_USAGE=$(ps aux | grep -w $fuzzer_pid | grep -v grep | awk '{print $3}')
|
||||||
|
MEM_USAGE=$(ps aux | grep -w $fuzzer_pid | grep -v grep | awk '{print $4}')
|
||||||
|
|
||||||
|
echo " cpu usage $CPU_USAGE%, memory usage $MEM_USAGE%"
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo " cycles $((cycles_done + 1)), lifetime speed $EXEC_SEC execs/sec, items $cur_item/$corpus_count (${PATH_PERC}%)"
|
||||||
|
|
||||||
|
if [ "$saved_crashes" = "0" ]; then
|
||||||
|
echo " pending $pending_favs/$pending_total, coverage $bitmap_cvg, no crashes yet"
|
||||||
|
else
|
||||||
|
echo " pending $pending_favs/$pending_total, coverage $bitmap_cvg, crashes saved $saved_crashes (!)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
if [ ! -e "$i" -a -e "$j" ]; then
|
||||||
|
|
||||||
|
if [ '!' "$PROCESS_DEAD" = "" ]; then
|
||||||
|
ALIVE_CNT=$((ALIVE_CNT + 1))
|
||||||
|
fi
|
||||||
|
START_CNT=$((START_CNT + 1))
|
||||||
|
last_find=0
|
||||||
|
IS_STARTING=1
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
done
|
||||||
|
|
||||||
|
# Formatting for total time, time since last find, crash, and hang
|
||||||
|
fmt_duration $((CUR_TIME - TOTAL_TIME)) && FMT_TIME=$DUR_STRING
|
||||||
|
# Formatting for total execution
|
||||||
|
FMT_EXECS="0 millions"
|
||||||
|
EXECS_MILLION=$((TOTAL_EXECS / 1000 / 1000))
|
||||||
|
EXECS_THOUSAND=$((TOTAL_EXECS / 1000 % 1000))
|
||||||
|
if [ $EXECS_MILLION -gt 9 ]; then
|
||||||
|
FMT_EXECS="$EXECS_MILLION millions"
|
||||||
|
elif [ $EXECS_MILLION -gt 0 ]; then
|
||||||
|
FMT_EXECS="$EXECS_MILLION millions, $EXECS_THOUSAND thousands"
|
||||||
|
else
|
||||||
|
FMT_EXECS="$EXECS_THOUSAND thousands"
|
||||||
|
fi
|
||||||
|
|
||||||
|
rm -f "$TMP"
|
||||||
|
|
||||||
|
TOTAL_DAYS=$((TOTAL_TIME / 60 / 60 / 24))
|
||||||
|
TOTAL_HRS=$(((TOTAL_TIME / 60 / 60) % 24))
|
||||||
|
|
||||||
|
test -z "$TOTAL_WCOP" && TOTAL_WCOP="not available"
|
||||||
|
fmt_duration $TOTAL_LAST_FIND && TOTAL_LAST_FIND=$DUR_STRING
|
||||||
|
|
||||||
|
test "$TOTAL_TIME" = "0" && TOTAL_TIME=1
|
||||||
|
|
||||||
|
if [ "$PROCESS_DEAD" = "" ]; then
|
||||||
|
|
||||||
|
TXT="excluded from stats"
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
TXT="included in stats"
|
||||||
|
ALIVE_CNT=$(($ALIVE_CNT - $DEAD_CNT - $START_CNT))
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Summary stats"
|
||||||
|
echo "============="
|
||||||
|
if [ -z "$SUMMARY_ONLY" -o -z "$MINIMAL_ONLY" ]; then
|
||||||
|
echo
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo " Fuzzers alive : $ALIVE_CNT"
|
||||||
|
|
||||||
|
if [ ! "$START_CNT" = "0" ]; then
|
||||||
|
echo " Starting up : $START_CNT ($TXT)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! "$DEAD_CNT" = "0" ]; then
|
||||||
|
echo " Dead or remote : $DEAD_CNT ($TXT)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo " Total run time : $FMT_TIME"
|
||||||
|
if [ -z "$MINIMAL_ONLY" ]; then
|
||||||
|
echo " Total execs : $FMT_EXECS"
|
||||||
|
echo " Cumulative speed : $TOTAL_EPS execs/sec"
|
||||||
|
if [ "$ALIVE_CNT" -gt "0" ]; then
|
||||||
|
echo " Total average speed : $((TOTAL_EPS / ALIVE_CNT)) execs/sec"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
if [ "$ALIVE_CNT" -gt "0" ]; then
|
||||||
|
echo "Current average speed : $TOTAL_EPLM execs/sec"
|
||||||
|
fi
|
||||||
|
if [ -z "$MINIMAL_ONLY" ]; then
|
||||||
|
echo " Pending items : $TOTAL_PFAV faves, $TOTAL_PENDING total"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$ALIVE_CNT" -gt "1" -o -n "$MINIMAL_ONLY" ]; then
|
||||||
|
if [ "$ALIVE_CNT" -gt "0" ]; then
|
||||||
|
echo " Pending per fuzzer : $((TOTAL_PFAV/ALIVE_CNT)) faves, $((TOTAL_PENDING/ALIVE_CNT)) total (on average)"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo " Coverage reached : ${TOTAL_COVERAGE}%"
|
||||||
|
echo " Crashes saved : $TOTAL_CRASHES"
|
||||||
|
if [ -z "$MINIMAL_ONLY" ]; then
|
||||||
|
echo " Hangs saved : $TOTAL_HANGS"
|
||||||
|
echo " Cycles without finds : $TOTAL_WCOP"
|
||||||
|
fi
|
||||||
|
echo " Time without finds : $TOTAL_LAST_FIND"
|
||||||
|
echo
|
||||||
|
|
||||||
|
exit 0
|
@ -0,0 +1,80 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import pefile
|
||||||
|
import shutil
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
if len(sys.argv) < 2:
|
||||||
|
print("[afl-wine-trace] usage: ./afl-wine-trace binary [args...]\n")
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
if os.getenv("AFL_PATH"):
|
||||||
|
my_dir = os.getenv("AFL_PATH")
|
||||||
|
else:
|
||||||
|
my_dir = os.path.dirname(os.path.abspath(__file__))
|
||||||
|
|
||||||
|
os.environ["WINELOADERNOEXEC"] = "1"
|
||||||
|
|
||||||
|
pe = pefile.PE(sys.argv[1])
|
||||||
|
|
||||||
|
if "AFL_ENTRYPOINT" not in os.environ:
|
||||||
|
os.environ["AFL_ENTRYPOINT"] = "0x%x" % (pe.OPTIONAL_HEADER.ImageBase + pe.OPTIONAL_HEADER.AddressOfEntryPoint)
|
||||||
|
if not os.getenv("AFL_INST_LIBS"):
|
||||||
|
if "AFL_CODE_START" not in os.environ:
|
||||||
|
os.environ["AFL_CODE_START"] = "0x%x" % (pe.OPTIONAL_HEADER.ImageBase + pe.OPTIONAL_HEADER.BaseOfCode)
|
||||||
|
if "AFL_CODE_END" not in os.environ:
|
||||||
|
os.environ["AFL_CODE_END"] = "0x%x" % (pe.OPTIONAL_HEADER.ImageBase + pe.OPTIONAL_HEADER.BaseOfCode + pe.OPTIONAL_HEADER.SizeOfCode)
|
||||||
|
|
||||||
|
if pe.FILE_HEADER.Machine == pefile.MACHINE_TYPE["IMAGE_FILE_MACHINE_AMD64"] or pe.FILE_HEADER.Machine == pefile.MACHINE_TYPE["IMAGE_FILE_MACHINE_IA64"]:
|
||||||
|
os.environ["QEMU_SET_ENV"] = "LD_PRELOAD=" + os.path.join(my_dir, "qemu_mode/unsigaction/unsigaction64.so") + ",WINEARCH=win64"
|
||||||
|
else:
|
||||||
|
os.environ["QEMU_SET_ENV"] = "LD_PRELOAD=" + os.path.join(my_dir, "qemu_mode/unsigaction/unsigaction32.so") + ",WINEARCH=win32"
|
||||||
|
|
||||||
|
if os.getenv("WINECOV_QEMU_PATH"):
|
||||||
|
qemu_path = os.getenv("WINECOV_QEMU_PATH")
|
||||||
|
elif os.path.exists(os.path.join(my_dir, "afl-qemu-trace")):
|
||||||
|
qemu_path = os.path.join(my_dir, "afl-qemu-trace")
|
||||||
|
else:
|
||||||
|
qemu_path = "qemu-"
|
||||||
|
if pe.FILE_HEADER.Machine == pefile.MACHINE_TYPE["IMAGE_FILE_MACHINE_AMD64"] or pe.FILE_HEADER.Machine == pefile.MACHINE_TYPE["IMAGE_FILE_MACHINE_IA64"]:
|
||||||
|
qemu_path += "x86_64"
|
||||||
|
elif pe.FILE_HEADER.Machine == pefile.MACHINE_TYPE["IMAGE_FILE_MACHINE_I386"]:
|
||||||
|
qemu_path += "i386"
|
||||||
|
else:
|
||||||
|
print ("[afl-wine-trace] unsuppoted architecture\n")
|
||||||
|
exit(1)
|
||||||
|
qemu_path = shutil.which(qemu_path)
|
||||||
|
|
||||||
|
wine_path = None
|
||||||
|
if os.getenv("AFL_WINE_PATH"):
|
||||||
|
wine_path = os.getenv("AFL_WINE_PATH")
|
||||||
|
else:
|
||||||
|
if not wine_path and shutil.which("wine"):
|
||||||
|
wine_path = shutil.which("wine")
|
||||||
|
if not wine_path and os.path.exists("/usr/bin/wine"):
|
||||||
|
wine_path = "/usr/bin/wine"
|
||||||
|
if not wine_path and os.path.exists("/usr/lib/wine/wine"):
|
||||||
|
wine_path = "/usr/lib/wine/wine"
|
||||||
|
if pe.FILE_HEADER.Machine == pefile.MACHINE_TYPE["IMAGE_FILE_MACHINE_AMD64"] or pe.FILE_HEADER.Machine == pefile.MACHINE_TYPE["IMAGE_FILE_MACHINE_IA64"]:
|
||||||
|
wine_path += "64"
|
||||||
|
elif pe.FILE_HEADER.Machine == pefile.MACHINE_TYPE["IMAGE_FILE_MACHINE_I386"]:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
print ("[afl-wine-trace] unsopported architecture\n")
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
argv = sys.argv[1:]
|
||||||
|
for i in range(len(argv)):
|
||||||
|
if ".cur_input" in argv[i]:
|
||||||
|
# Get the Wine translated path using the winepath tool
|
||||||
|
arg_translated = subprocess.run([os.path.join(os.path.dirname(wine_path), "winepath"), "--windows", argv[i]], universal_newlines=True, stdout=subprocess.PIPE).stdout
|
||||||
|
# Remove the spurious LF at the end of the path
|
||||||
|
if len(arg_translated) > 0 and arg_translated[-1] == '\n':
|
||||||
|
arg_translated = arg_translated[:-1]
|
||||||
|
argv[i] = arg_translated
|
||||||
|
break
|
||||||
|
|
||||||
|
print("[afl-wine-trace] exec:", " ".join([qemu_path, wine_path] + argv))
|
||||||
|
os.execve(qemu_path, [qemu_path, wine_path] + argv, os.environ)
|
@ -0,0 +1,14 @@
|
|||||||
|
|CPU | MHz | threads | singlecore | multicore | afl-*-config |
|
||||||
|
|----------------------------------------------------|-------|---------|------------|-----------|--------------|
|
||||||
|
|Raspberry Pi 5 | 2400 | 4 | 25786 | 101114 | both |
|
||||||
|
|AMD EPYC 7282 16-Core Processor | 3194 | 32 | 87199 | 769001 | both |
|
||||||
|
|AMD Ryzen 5 PRO 4650G with Radeon Graphics | 3700 | 12 | 95356 | 704840 | both |
|
||||||
|
|Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz | 4995 | 16 | 120064 | 1168943 | both |
|
||||||
|
|12th Gen Intel(R) Core(TM) i7-1270P | 4761 | 16 | 149778 | 641219 | both |
|
||||||
|
|AMD Ryzen 9 5950X 16-Core Processor | 4792 | 32 | 161690 | 2339763 | both |
|
||||||
|
|Apple Mac Studio M2 Ultra 2023, Linux VM guest | 3500 | 16 | 163570 | 1157465 | both |
|
||||||
|
|AMD Ryzen 9 6900HS with Radeon Graphics | 4676 | 16 | 62860 | 614404 | system |
|
||||||
|
|AMD Ryzen 9 6900HS with Radeon Graphics | 4745 | 16 | 135501 | 991133 | both |
|
||||||
|
|AMD Ryzen 9 7950X3D 16-Core Processor | 5400 | 32 | 71566 | 1566279 | system |
|
||||||
|
|AMD Ryzen 9 7950X3D 16-Core Processor | 5478 | 32 | 161960 | 2173959 | both |
|
||||||
|
|Ampere Altra Q80-30 | 0 | 80 | 54477 | 1604482 | system |
|
@ -0,0 +1,59 @@
|
|||||||
|
# American Fuzzy Lop plus plus (AFL++)
|
||||||
|
|
||||||
|
## benchmarking
|
||||||
|
|
||||||
|
This directory contains benchmarking tools that allow you to compare one machine
|
||||||
|
with another in terms of raw ability to execute a fuzzing target repeatedly.
|
||||||
|
|
||||||
|
To achieve this, we use a sample program ("test-instr.c") where each path is
|
||||||
|
equally likely, supply it a single seed, and tell AFL to exit after one run of
|
||||||
|
deterministic mutations against that seed.
|
||||||
|
|
||||||
|
**Note that this is not a real-world scenario!**
|
||||||
|
Because the target does basically nothing this is rather a stress test on
|
||||||
|
Kernel I/O / context switching.
|
||||||
|
For this reason you will not see a difference if you run the multicore test
|
||||||
|
with 20 or 40 threads - or even see the performance decline the more threads
|
||||||
|
(`-f` parameter) you use. In a real-world scenario you can expect to gain
|
||||||
|
exec/s until 40-60 threads (if you have that many available on your CPU).
|
||||||
|
|
||||||
|
Usage example:
|
||||||
|
|
||||||
|
```
|
||||||
|
cd aflplusplus/benchmark
|
||||||
|
python3 benchmark.py
|
||||||
|
[*] Ready, starting benchmark...
|
||||||
|
[*] Compiling the test-instr-persist-shmem fuzzing harness for the benchmark to use.
|
||||||
|
[*] singlecore test-instr-persist-shmem run 1 of 2, execs/s: 124883.62
|
||||||
|
[*] singlecore test-instr-persist-shmem run 2 of 2, execs/s: 126704.93
|
||||||
|
[*] Average execs/sec for this test across all runs was: 125794.28
|
||||||
|
[*] Using 16 fuzzers for multicore fuzzing (use --fuzzers to override).
|
||||||
|
[*] multicore test-instr-persist-shmem run 1 of 2, execs/s: 1179822.66
|
||||||
|
[*] multicore test-instr-persist-shmem run 2 of 2, execs/s: 1175584.09
|
||||||
|
[*] Average execs/sec for this test across all runs was: 1177703.38
|
||||||
|
[*] Results have been written to the benchmark-results.jsonl file.
|
||||||
|
[*] Results have been written to the COMPARISON.md file.
|
||||||
|
```
|
||||||
|
|
||||||
|
By default, the script will use a number of parallel fuzzers equal to your
|
||||||
|
available CPUs/threads (change with `--fuzzers`), and will perform each test
|
||||||
|
three times and average the result (change with `--runs`).
|
||||||
|
|
||||||
|
The script will use multicore fuzzing instead of singlecore by default (change
|
||||||
|
with `--mode singlecore`) and use a persistent-mode shared memory harness for
|
||||||
|
optimal speed (change with `--target test-instr`).
|
||||||
|
|
||||||
|
Feel free to submit the resulting line for your CPU added to the COMPARISON.md
|
||||||
|
and benchmark-results.jsonl files back to AFL++ in a pull request.
|
||||||
|
|
||||||
|
Each run writes results to [benchmark-results.jsonl](benchmark-results.jsonl)
|
||||||
|
in [JSON Lines](https://jsonlines.org/) format, ready to be pulled in to other
|
||||||
|
tools such as [jq -cs](https://jqlang.github.io/jq/) or
|
||||||
|
[pandas](https://pandas.pydata.org/) for analysis.
|
||||||
|
|
||||||
|
## Data analysis
|
||||||
|
|
||||||
|
There is sample data in [benchmark-results.jsonl](benchmark-results.jsonl), and
|
||||||
|
a Jupyter notebook for exploring the results and suggesting their meaning at
|
||||||
|
[benchmark.ipynb](benchmark.ipynb).
|
||||||
|
|
@ -0,0 +1,424 @@
|
|||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4788.77, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr": {"singlecore": {"execs_per_sec": 9845.64, "execs_total": 98545, "fuzzers_used": 1}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4989.281, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"singlecore": {"execs_per_sec": 125682.73, "execs_total": 1257330, "fuzzers_used": 1}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4799.415, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 120293.77, "execs_total": 1203058, "fuzzers_used": 1}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4703.293, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 231429.96, "execs_total": 2314531, "fuzzers_used": 2}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4800.375, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 346759.33, "execs_total": 3468290, "fuzzers_used": 3}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4915.27, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 455340.06, "execs_total": 4554427, "fuzzers_used": 4}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4701.051, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 568405.15, "execs_total": 5685076, "fuzzers_used": 5}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4704.999, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 678030.96, "execs_total": 6781781, "fuzzers_used": 6}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4800.438, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 782585.04, "execs_total": 7827974, "fuzzers_used": 7}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4794.851, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 893618.35, "execs_total": 8938405, "fuzzers_used": 8}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4998.383, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 956026.15, "execs_total": 9562791, "fuzzers_used": 9}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4997.352, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 984942.13, "execs_total": 9853724, "fuzzers_used": 10}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4987.681, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 1016758.62, "execs_total": 10172892, "fuzzers_used": 11}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4998.196, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 1053087.9, "execs_total": 10536439, "fuzzers_used": 12}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4995.211, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 1085797.87, "execs_total": 10865305, "fuzzers_used": 13}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4997.577, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 1110640.2, "execs_total": 11114033, "fuzzers_used": 14}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4799.955, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 1138984.22, "execs_total": 11397389, "fuzzers_used": 15}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4997.247, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 1168943.19, "execs_total": 11699439, "fuzzers_used": 16}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4994.207, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 1135093.91, "execs_total": 11360219, "fuzzers_used": 17}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4994.47, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 1160430.45, "execs_total": 11614570, "fuzzers_used": 18}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4991.188, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 1155769.97, "execs_total": 11569540, "fuzzers_used": 19}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4997.63, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 1150156.26, "execs_total": 11509407, "fuzzers_used": 20}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4998.227, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 1136873.58, "execs_total": 11377110, "fuzzers_used": 21}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4998.317, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 1112404.25, "execs_total": 11134086, "fuzzers_used": 22}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 5000.851, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 1143131.72, "execs_total": 11440024, "fuzzers_used": 23}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4998.261, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 1143931.38, "execs_total": 11448786, "fuzzers_used": 24}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4997.259, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 1102090.61, "execs_total": 11028561, "fuzzers_used": 25}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4998.149, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 1116518.7, "execs_total": 11172681, "fuzzers_used": 26}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4801.01, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 1099224.19, "execs_total": 11000537, "fuzzers_used": 27}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4998.448, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 1114945.37, "execs_total": 11158802, "fuzzers_used": 28}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4997.663, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 1110889.91, "execs_total": 11118113, "fuzzers_used": 29}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4997.741, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 1058548.28, "execs_total": 10595540, "fuzzers_used": 30}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4998.852, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 1119804.85, "execs_total": 11208645, "fuzzers_used": 31}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4998.417, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 1118828.99, "execs_total": 11197813, "fuzzers_used": 32}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 5000.682, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 1093426.61, "execs_total": 10942324, "fuzzers_used": 33}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4998.248, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 1108123.59, "execs_total": 11090315, "fuzzers_used": 34}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4998.053, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 1041486.52, "execs_total": 10422413, "fuzzers_used": 35}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4998.299, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 1092395.61, "execs_total": 10932107, "fuzzers_used": 36}}}}
|
||||||
|
{"config": {"afl_persistent_config": false, "afl_system_config": false, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4996.081, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr": {"singlecore": {"execs_per_sec": 8278.64, "execs_total": 82894, "fuzzers_used": 1}}}}
|
||||||
|
{"config": {"afl_persistent_config": false, "afl_system_config": false, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4994.118, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 90641.62, "execs_total": 906960, "fuzzers_used": 1}}}}
|
||||||
|
{"config": {"afl_persistent_config": false, "afl_system_config": false, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4996.588, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 178184.19, "execs_total": 1782109, "fuzzers_used": 2}}}}
|
||||||
|
{"config": {"afl_persistent_config": false, "afl_system_config": false, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4996.204, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 262652.86, "execs_total": 2627228, "fuzzers_used": 3}}}}
|
||||||
|
{"config": {"afl_persistent_config": false, "afl_system_config": false, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4996.829, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 339119.32, "execs_total": 3391956, "fuzzers_used": 4}}}}
|
||||||
|
{"config": {"afl_persistent_config": false, "afl_system_config": false, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4997.205, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 420239.94, "execs_total": 4202989, "fuzzers_used": 5}}}}
|
||||||
|
{"config": {"afl_persistent_config": false, "afl_system_config": false, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4997.0, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 498062.02, "execs_total": 4981367, "fuzzers_used": 6}}}}
|
||||||
|
{"config": {"afl_persistent_config": false, "afl_system_config": false, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 5000.407, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 578495.44, "execs_total": 5786691, "fuzzers_used": 7}}}}
|
||||||
|
{"config": {"afl_persistent_config": false, "afl_system_config": false, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 5002.997, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 661836.22, "execs_total": 6620265, "fuzzers_used": 8}}}}
|
||||||
|
{"config": {"afl_persistent_config": false, "afl_system_config": false, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4996.952, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 684808.49, "execs_total": 6850000, "fuzzers_used": 9}}}}
|
||||||
|
{"config": {"afl_persistent_config": false, "afl_system_config": false, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4996.99, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 707094.65, "execs_total": 7074048, "fuzzers_used": 10}}}}
|
||||||
|
{"config": {"afl_persistent_config": false, "afl_system_config": false, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4998.003, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 732106.17, "execs_total": 7325352, "fuzzers_used": 11}}}}
|
||||||
|
{"config": {"afl_persistent_config": false, "afl_system_config": false, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4998.488, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 752910.17, "execs_total": 7533775, "fuzzers_used": 12}}}}
|
||||||
|
{"config": {"afl_persistent_config": false, "afl_system_config": false, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 5003.679, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 776179.85, "execs_total": 7767507, "fuzzers_used": 13}}}}
|
||||||
|
{"config": {"afl_persistent_config": false, "afl_system_config": false, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4995.45, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 797520.58, "execs_total": 7981534, "fuzzers_used": 14}}}}
|
||||||
|
{"config": {"afl_persistent_config": false, "afl_system_config": false, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4997.313, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 822235.41, "execs_total": 8228941, "fuzzers_used": 15}}}}
|
||||||
|
{"config": {"afl_persistent_config": false, "afl_system_config": false, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4996.723, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 843897.51, "execs_total": 8445693, "fuzzers_used": 16}}}}
|
||||||
|
{"config": {"afl_persistent_config": false, "afl_system_config": false, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4996.488, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 843177.15, "execs_total": 8438493, "fuzzers_used": 17}}}}
|
||||||
|
{"config": {"afl_persistent_config": false, "afl_system_config": false, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4997.299, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 844779.09, "execs_total": 8456834, "fuzzers_used": 18}}}}
|
||||||
|
{"config": {"afl_persistent_config": false, "afl_system_config": false, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4996.662, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 846060.74, "execs_total": 8465728, "fuzzers_used": 19}}}}
|
||||||
|
{"config": {"afl_persistent_config": false, "afl_system_config": false, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4996.922, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 847556.23, "execs_total": 8482537, "fuzzers_used": 20}}}}
|
||||||
|
{"config": {"afl_persistent_config": false, "afl_system_config": false, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4997.098, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 844022.97, "execs_total": 8447616, "fuzzers_used": 21}}}}
|
||||||
|
{"config": {"afl_persistent_config": false, "afl_system_config": false, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4996.352, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 845818.7, "execs_total": 8464237, "fuzzers_used": 22}}}}
|
||||||
|
{"config": {"afl_persistent_config": false, "afl_system_config": false, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4995.457, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 844118.27, "execs_total": 8448858, "fuzzers_used": 23}}}}
|
||||||
|
{"config": {"afl_persistent_config": false, "afl_system_config": false, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4997.019, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 837189.02, "execs_total": 8379746, "fuzzers_used": 24}}}}
|
||||||
|
{"config": {"afl_persistent_config": false, "afl_system_config": false, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4995.513, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 834712.31, "execs_total": 8354719, "fuzzers_used": 25}}}}
|
||||||
|
{"config": {"afl_persistent_config": false, "afl_system_config": false, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4996.891, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 836344.12, "execs_total": 8370166, "fuzzers_used": 26}}}}
|
||||||
|
{"config": {"afl_persistent_config": false, "afl_system_config": false, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4996.494, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 827784.91, "execs_total": 8283782, "fuzzers_used": 27}}}}
|
||||||
|
{"config": {"afl_persistent_config": false, "afl_system_config": false, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4996.761, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 828641.27, "execs_total": 8293602, "fuzzers_used": 28}}}}
|
||||||
|
{"config": {"afl_persistent_config": false, "afl_system_config": false, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4997.115, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 826123.67, "execs_total": 8268211, "fuzzers_used": 29}}}}
|
||||||
|
{"config": {"afl_persistent_config": false, "afl_system_config": false, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4993.515, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 817765.77, "execs_total": 8184720, "fuzzers_used": 30}}}}
|
||||||
|
{"config": {"afl_persistent_config": false, "afl_system_config": false, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4996.555, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 816556.66, "execs_total": 8171816, "fuzzers_used": 31}}}}
|
||||||
|
{"config": {"afl_persistent_config": false, "afl_system_config": false, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4996.999, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 812661.77, "execs_total": 8132767, "fuzzers_used": 32}}}}
|
||||||
|
{"config": {"afl_persistent_config": false, "afl_system_config": false, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4995.561, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 805352.16, "execs_total": 8060482, "fuzzers_used": 33}}}}
|
||||||
|
{"config": {"afl_persistent_config": false, "afl_system_config": false, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4996.938, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 815888.26, "execs_total": 8164454, "fuzzers_used": 34}}}}
|
||||||
|
{"config": {"afl_persistent_config": false, "afl_system_config": false, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4996.951, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 812348.56, "execs_total": 8129441, "fuzzers_used": 35}}}}
|
||||||
|
{"config": {"afl_persistent_config": false, "afl_system_config": false, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4999.444, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 817278.03, "execs_total": 8178918, "fuzzers_used": 36}}}}
|
||||||
|
{"config": {"afl_persistent_config": false, "afl_system_config": true, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4996.133, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 91247.98, "execs_total": 912571, "fuzzers_used": 1}}}}
|
||||||
|
{"config": {"afl_persistent_config": false, "afl_system_config": true, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4997.029, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 177503.74, "execs_total": 1775569, "fuzzers_used": 2}}}}
|
||||||
|
{"config": {"afl_persistent_config": false, "afl_system_config": true, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4996.516, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 263559.94, "execs_total": 2635863, "fuzzers_used": 3}}}}
|
||||||
|
{"config": {"afl_persistent_config": false, "afl_system_config": true, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4996.946, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 339880.84, "execs_total": 3399660, "fuzzers_used": 4}}}}
|
||||||
|
{"config": {"afl_persistent_config": false, "afl_system_config": true, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4997.539, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 418569.46, "execs_total": 4186780, "fuzzers_used": 5}}}}
|
||||||
|
{"config": {"afl_persistent_config": false, "afl_system_config": true, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4995.53, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 496208.2, "execs_total": 4962992, "fuzzers_used": 6}}}}
|
||||||
|
{"config": {"afl_persistent_config": false, "afl_system_config": true, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4998.015, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 580870.62, "execs_total": 5809953, "fuzzers_used": 7}}}}
|
||||||
|
{"config": {"afl_persistent_config": false, "afl_system_config": true, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4998.662, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 662910.24, "execs_total": 6631172, "fuzzers_used": 8}}}}
|
||||||
|
{"config": {"afl_persistent_config": false, "afl_system_config": true, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4996.8, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 683654.43, "execs_total": 6838092, "fuzzers_used": 9}}}}
|
||||||
|
{"config": {"afl_persistent_config": false, "afl_system_config": true, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4996.849, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 707555.71, "execs_total": 7078261, "fuzzers_used": 10}}}}
|
||||||
|
{"config": {"afl_persistent_config": false, "afl_system_config": true, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 5007.628, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 732211.35, "execs_total": 7325661, "fuzzers_used": 11}}}}
|
||||||
|
{"config": {"afl_persistent_config": false, "afl_system_config": true, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4981.601, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 756121.92, "execs_total": 7565074, "fuzzers_used": 12}}}}
|
||||||
|
{"config": {"afl_persistent_config": false, "afl_system_config": true, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4996.041, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 774101.97, "execs_total": 7745053, "fuzzers_used": 13}}}}
|
||||||
|
{"config": {"afl_persistent_config": false, "afl_system_config": true, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 5004.554, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 796439.54, "execs_total": 7972225, "fuzzers_used": 14}}}}
|
||||||
|
{"config": {"afl_persistent_config": false, "afl_system_config": true, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4996.433, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 822652.36, "execs_total": 8232836, "fuzzers_used": 15}}}}
|
||||||
|
{"config": {"afl_persistent_config": false, "afl_system_config": true, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4996.063, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 846458.67, "execs_total": 8473949, "fuzzers_used": 16}}}}
|
||||||
|
{"config": {"afl_persistent_config": false, "afl_system_config": true, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4996.85, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 847285.31, "execs_total": 8479183, "fuzzers_used": 17}}}}
|
||||||
|
{"config": {"afl_persistent_config": false, "afl_system_config": true, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4996.627, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 847278.34, "execs_total": 8481577, "fuzzers_used": 18}}}}
|
||||||
|
{"config": {"afl_persistent_config": false, "afl_system_config": true, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 5002.007, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 849345.2, "execs_total": 8500890, "fuzzers_used": 19}}}}
|
||||||
|
{"config": {"afl_persistent_config": false, "afl_system_config": true, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4998.497, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 848498.04, "execs_total": 8491840, "fuzzers_used": 20}}}}
|
||||||
|
{"config": {"afl_persistent_config": false, "afl_system_config": true, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4997.084, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 848737.28, "execs_total": 8494747, "fuzzers_used": 21}}}}
|
||||||
|
{"config": {"afl_persistent_config": false, "afl_system_config": true, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4995.872, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 847610.49, "execs_total": 8484864, "fuzzers_used": 22}}}}
|
||||||
|
{"config": {"afl_persistent_config": false, "afl_system_config": true, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4997.036, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 846329.82, "execs_total": 8471670, "fuzzers_used": 23}}}}
|
||||||
|
{"config": {"afl_persistent_config": false, "afl_system_config": true, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4995.731, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 839140.26, "execs_total": 8397496, "fuzzers_used": 24}}}}
|
||||||
|
{"config": {"afl_persistent_config": false, "afl_system_config": true, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4988.743, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 843648.98, "execs_total": 8444091, "fuzzers_used": 25}}}}
|
||||||
|
{"config": {"afl_persistent_config": false, "afl_system_config": true, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 5004.084, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 835215.19, "execs_total": 8359949, "fuzzers_used": 26}}}}
|
||||||
|
{"config": {"afl_persistent_config": false, "afl_system_config": true, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4998.828, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 833416.5, "execs_total": 8340275, "fuzzers_used": 27}}}}
|
||||||
|
{"config": {"afl_persistent_config": false, "afl_system_config": true, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4995.795, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 826512.71, "execs_total": 8272574, "fuzzers_used": 28}}}}
|
||||||
|
{"config": {"afl_persistent_config": false, "afl_system_config": true, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4997.022, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 828656.04, "execs_total": 8292856, "fuzzers_used": 29}}}}
|
||||||
|
{"config": {"afl_persistent_config": false, "afl_system_config": true, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4996.939, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 823292.55, "execs_total": 8239885, "fuzzers_used": 30}}}}
|
||||||
|
{"config": {"afl_persistent_config": false, "afl_system_config": true, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4995.233, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 824657.95, "execs_total": 8252812, "fuzzers_used": 31}}}}
|
||||||
|
{"config": {"afl_persistent_config": false, "afl_system_config": true, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4995.909, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 817807.44, "execs_total": 8183838, "fuzzers_used": 32}}}}
|
||||||
|
{"config": {"afl_persistent_config": false, "afl_system_config": true, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4995.834, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 815344.89, "execs_total": 8160193, "fuzzers_used": 33}}}}
|
||||||
|
{"config": {"afl_persistent_config": false, "afl_system_config": true, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4997.968, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 814327.97, "execs_total": 8149984, "fuzzers_used": 34}}}}
|
||||||
|
{"config": {"afl_persistent_config": false, "afl_system_config": true, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4996.625, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 819612.64, "execs_total": 8202605, "fuzzers_used": 35}}}}
|
||||||
|
{"config": {"afl_persistent_config": false, "afl_system_config": true, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4998.404, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 813155.19, "execs_total": 8137546, "fuzzers_used": 36}}}}
|
||||||
|
{"config": {"afl_persistent_config": false, "afl_system_config": true, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 5001.911, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr": {"singlecore": {"execs_per_sec": 8391.52, "execs_total": 83932, "fuzzers_used": 1}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": false, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4980.444, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr": {"singlecore": {"execs_per_sec": 10754.79, "execs_total": 107720, "fuzzers_used": 1}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": false, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 5000.011, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 126201.28, "execs_total": 1262139, "fuzzers_used": 1}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": false, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4993.941, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 245701.79, "execs_total": 2457750, "fuzzers_used": 2}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": false, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4983.297, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 361167.18, "execs_total": 3612273, "fuzzers_used": 3}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": false, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4994.008, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 475221.97, "execs_total": 4752815, "fuzzers_used": 4}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": false, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4996.977, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 586393.43, "execs_total": 5865460, "fuzzers_used": 5}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": false, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4996.97, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 690946.36, "execs_total": 6910846, "fuzzers_used": 6}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": false, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4997.017, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 801029.31, "execs_total": 8011774, "fuzzers_used": 7}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": false, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4998.617, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 913876.89, "execs_total": 9140715, "fuzzers_used": 8}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": false, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4996.997, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 946293.38, "execs_total": 9464848, "fuzzers_used": 9}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": false, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4996.162, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 980031.45, "execs_total": 9803628, "fuzzers_used": 10}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": false, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4994.223, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 1015241.63, "execs_total": 10157948, "fuzzers_used": 11}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": false, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4994.761, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 1042290.69, "execs_total": 10427527, "fuzzers_used": 12}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": false, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4996.045, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 1073567.99, "execs_total": 10739590, "fuzzers_used": 13}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": false, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4995.484, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 1119312.88, "execs_total": 11199130, "fuzzers_used": 14}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": false, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4994.729, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 1156363.75, "execs_total": 11573213, "fuzzers_used": 15}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": false, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4996.146, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 1183713.3, "execs_total": 11848245, "fuzzers_used": 16}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": false, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4997.048, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 1187603.56, "execs_total": 11886825, "fuzzers_used": 17}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": false, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4986.845, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 1190369.21, "execs_total": 11914954, "fuzzers_used": 18}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": false, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4985.364, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 1188828.6, "execs_total": 11902947, "fuzzers_used": 19}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": false, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4996.108, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 1187617.46, "execs_total": 11887934, "fuzzers_used": 20}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": false, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4997.754, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 1188490.16, "execs_total": 11894967, "fuzzers_used": 21}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": false, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4996.129, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 1184138.92, "execs_total": 11850653, "fuzzers_used": 22}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": false, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4997.048, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 1189374.23, "execs_total": 11903803, "fuzzers_used": 23}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": false, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4996.261, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 1178947.43, "execs_total": 11800850, "fuzzers_used": 24}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": false, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4997.422, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 1173540.28, "execs_total": 11743120, "fuzzers_used": 25}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": false, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4996.909, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 1168471.78, "execs_total": 11696401, "fuzzers_used": 26}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": false, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4966.966, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 1169320.61, "execs_total": 11703900, "fuzzers_used": 27}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": false, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4997.207, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 1165434.17, "execs_total": 11661131, "fuzzers_used": 28}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": false, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4999.554, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 1161113.26, "execs_total": 11619771, "fuzzers_used": 29}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": false, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4994.822, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 1155066.44, "execs_total": 11560147, "fuzzers_used": 30}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": false, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4997.061, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 1145196.35, "execs_total": 11461349, "fuzzers_used": 31}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": false, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4996.006, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 1151794.28, "execs_total": 11526764, "fuzzers_used": 32}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": false, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4995.939, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 1151652.84, "execs_total": 11526720, "fuzzers_used": 33}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": false, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4997.002, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 1153215.56, "execs_total": 11539780, "fuzzers_used": 34}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": false, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4996.456, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 1146882.5, "execs_total": 11478112, "fuzzers_used": 35}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": false, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4996.183, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 1155253.95, "execs_total": 11561694, "fuzzers_used": 36}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4848.974, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr": {"multicore": {"execs_per_sec": 10714.79, "execs_total": 107180, "fuzzers_used": 1}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4998.353, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr": {"multicore": {"execs_per_sec": 20493.07, "execs_total": 205279, "fuzzers_used": 2}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4998.198, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr": {"multicore": {"execs_per_sec": 29660.06, "execs_total": 297006, "fuzzers_used": 3}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4998.015, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr": {"multicore": {"execs_per_sec": 37875.57, "execs_total": 379078, "fuzzers_used": 4}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4996.975, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr": {"multicore": {"execs_per_sec": 46326.75, "execs_total": 463731, "fuzzers_used": 5}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4998.579, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr": {"multicore": {"execs_per_sec": 54595.48, "execs_total": 546283, "fuzzers_used": 6}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4983.814, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr": {"multicore": {"execs_per_sec": 62720.98, "execs_total": 628151, "fuzzers_used": 7}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4997.617, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr": {"multicore": {"execs_per_sec": 70777.99, "execs_total": 708505, "fuzzers_used": 8}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4998.286, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr": {"multicore": {"execs_per_sec": 74236.02, "execs_total": 743157, "fuzzers_used": 9}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4799.516, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr": {"multicore": {"execs_per_sec": 78134.94, "execs_total": 782272, "fuzzers_used": 10}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4911.536, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr": {"multicore": {"execs_per_sec": 81886.33, "execs_total": 819649, "fuzzers_used": 11}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4996.199, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr": {"multicore": {"execs_per_sec": 85923.44, "execs_total": 860033, "fuzzers_used": 12}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4997.447, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr": {"multicore": {"execs_per_sec": 89696.95, "execs_total": 897746, "fuzzers_used": 13}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4998.496, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr": {"multicore": {"execs_per_sec": 93540.52, "execs_total": 936217, "fuzzers_used": 14}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4997.936, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr": {"multicore": {"execs_per_sec": 97641.51, "execs_total": 977546, "fuzzers_used": 15}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4991.829, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr": {"multicore": {"execs_per_sec": 101692.65, "execs_total": 1017683, "fuzzers_used": 16}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4998.489, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr": {"multicore": {"execs_per_sec": 101236.75, "execs_total": 1013188, "fuzzers_used": 17}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4998.352, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr": {"multicore": {"execs_per_sec": 101006.28, "execs_total": 1011004, "fuzzers_used": 18}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4999.894, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr": {"multicore": {"execs_per_sec": 99952.26, "execs_total": 1000431, "fuzzers_used": 19}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4942.12, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr": {"multicore": {"execs_per_sec": 99798.64, "execs_total": 998795, "fuzzers_used": 20}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4997.686, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr": {"multicore": {"execs_per_sec": 99018.86, "execs_total": 991012, "fuzzers_used": 21}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4998.308, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr": {"multicore": {"execs_per_sec": 98600.87, "execs_total": 986643, "fuzzers_used": 22}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4997.683, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr": {"multicore": {"execs_per_sec": 98634.02, "execs_total": 987082, "fuzzers_used": 23}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4998.457, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr": {"multicore": {"execs_per_sec": 98352.9, "execs_total": 984071, "fuzzers_used": 24}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4997.733, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr": {"multicore": {"execs_per_sec": 98118.63, "execs_total": 981865, "fuzzers_used": 25}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4994.474, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr": {"multicore": {"execs_per_sec": 97752.45, "execs_total": 978192, "fuzzers_used": 26}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4853.378, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr": {"multicore": {"execs_per_sec": 97864.07, "execs_total": 979334, "fuzzers_used": 27}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4997.484, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr": {"multicore": {"execs_per_sec": 97821.8, "execs_total": 978814, "fuzzers_used": 28}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4996.738, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr": {"multicore": {"execs_per_sec": 97564.87, "execs_total": 976335, "fuzzers_used": 29}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4997.341, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr": {"multicore": {"execs_per_sec": 98508.1, "execs_total": 985853, "fuzzers_used": 30}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4998.773, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr": {"multicore": {"execs_per_sec": 98238.96, "execs_total": 983062, "fuzzers_used": 31}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4998.037, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr": {"multicore": {"execs_per_sec": 98363.93, "execs_total": 984411, "fuzzers_used": 32}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4998.448, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr": {"multicore": {"execs_per_sec": 96758.69, "execs_total": 968157, "fuzzers_used": 33}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4998.238, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr": {"multicore": {"execs_per_sec": 96327.0, "execs_total": 964046, "fuzzers_used": 34}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4997.619, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr": {"multicore": {"execs_per_sec": 95913.98, "execs_total": 959817, "fuzzers_used": 35}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "i9-9900k, 16GB DDR4-3000, Arch Linux", "compiler": "clang version 16.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4998.076, "cpu_model": "Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz", "cpu_threads": 16}, "targets": {"test-instr": {"multicore": {"execs_per_sec": 95871.39, "execs_total": 959318, "fuzzers_used": 36}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "Apple Mac Studio M2 Ultra 2023, Linux VM guest, 16 threads assigned to VM", "compiler": "Ubuntu clang version 16.0.6", "target_arch": "aarch64-unknown-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3500.0, "cpu_model": "Apple Mac Studio M2 Ultra 2023", "cpu_threads": 16}, "targets": {"test-instr": {"singlecore": {"execs_per_sec": 5741.89, "execs_total": 57505, "fuzzers_used": 1}}, "test-instr-persist-shmem": {"singlecore": {"execs_per_sec": 163570.34, "execs_total": 1635867, "fuzzers_used": 1}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "Apple Mac Studio M2 Ultra 2023, Linux VM guest, 16 threads assigned to VM", "compiler": "Ubuntu clang version 16.0.6", "target_arch": "aarch64-unknown-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3500.0, "cpu_model": "Apple Mac Studio M2 Ultra 2023", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 164224.43, "execs_total": 1642737, "fuzzers_used": 1}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "Apple Mac Studio M2 Ultra 2023, Linux VM guest, 16 threads assigned to VM", "compiler": "Ubuntu clang version 16.0.6", "target_arch": "aarch64-unknown-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3500.0, "cpu_model": "Apple Mac Studio M2 Ultra 2023", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 167222.58, "execs_total": 1672393, "fuzzers_used": 1}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "Apple Mac Studio M2 Ultra 2023, Linux VM guest, 16 threads assigned to VM", "compiler": "Ubuntu clang version 16.0.6", "target_arch": "aarch64-unknown-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3500.0, "cpu_model": "Apple Mac Studio M2 Ultra 2023", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 306547.24, "execs_total": 3065934, "fuzzers_used": 2}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "Apple Mac Studio M2 Ultra 2023, Linux VM guest, 16 threads assigned to VM", "compiler": "Ubuntu clang version 16.0.6", "target_arch": "aarch64-unknown-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3500.0, "cpu_model": "Apple Mac Studio M2 Ultra 2023", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 436010.2, "execs_total": 4360827, "fuzzers_used": 3}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "Apple Mac Studio M2 Ultra 2023, Linux VM guest, 16 threads assigned to VM", "compiler": "Ubuntu clang version 16.0.6", "target_arch": "aarch64-unknown-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3500.0, "cpu_model": "Apple Mac Studio M2 Ultra 2023", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 536415.92, "execs_total": 5365101, "fuzzers_used": 4}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "Apple Mac Studio M2 Ultra 2023, Linux VM guest, 16 threads assigned to VM", "compiler": "Ubuntu clang version 16.0.6", "target_arch": "aarch64-unknown-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3500.0, "cpu_model": "Apple Mac Studio M2 Ultra 2023", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 622104.43, "execs_total": 6222784, "fuzzers_used": 5}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "Apple Mac Studio M2 Ultra 2023, Linux VM guest, 16 threads assigned to VM", "compiler": "Ubuntu clang version 16.0.6", "target_arch": "aarch64-unknown-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3500.0, "cpu_model": "Apple Mac Studio M2 Ultra 2023", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 729436.2, "execs_total": 7295214, "fuzzers_used": 6}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "Apple Mac Studio M2 Ultra 2023, Linux VM guest, 16 threads assigned to VM", "compiler": "Ubuntu clang version 16.0.6", "target_arch": "aarch64-unknown-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3500.0, "cpu_model": "Apple Mac Studio M2 Ultra 2023", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 820258.88, "execs_total": 8203409, "fuzzers_used": 7}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "Apple Mac Studio M2 Ultra 2023, Linux VM guest, 16 threads assigned to VM", "compiler": "Ubuntu clang version 16.0.6", "target_arch": "aarch64-unknown-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3500.0, "cpu_model": "Apple Mac Studio M2 Ultra 2023", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 884746.31, "execs_total": 8848458, "fuzzers_used": 8}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "Apple Mac Studio M2 Ultra 2023, Linux VM guest, 16 threads assigned to VM", "compiler": "Ubuntu clang version 16.0.6", "target_arch": "aarch64-unknown-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3500.0, "cpu_model": "Apple Mac Studio M2 Ultra 2023", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 947308.55, "execs_total": 9474351, "fuzzers_used": 9}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "Apple Mac Studio M2 Ultra 2023, Linux VM guest, 16 threads assigned to VM", "compiler": "Ubuntu clang version 16.0.6", "target_arch": "aarch64-unknown-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3500.0, "cpu_model": "Apple Mac Studio M2 Ultra 2023", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 985953.62, "execs_total": 9860922, "fuzzers_used": 10}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "Apple Mac Studio M2 Ultra 2023, Linux VM guest, 16 threads assigned to VM", "compiler": "Ubuntu clang version 16.0.6", "target_arch": "aarch64-unknown-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3500.0, "cpu_model": "Apple Mac Studio M2 Ultra 2023", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 1009716.71, "execs_total": 10098454, "fuzzers_used": 11}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "Apple Mac Studio M2 Ultra 2023, Linux VM guest, 16 threads assigned to VM", "compiler": "Ubuntu clang version 16.0.6", "target_arch": "aarch64-unknown-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3500.0, "cpu_model": "Apple Mac Studio M2 Ultra 2023", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 1041437.1, "execs_total": 10415844, "fuzzers_used": 12}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "Apple Mac Studio M2 Ultra 2023, Linux VM guest, 16 threads assigned to VM", "compiler": "Ubuntu clang version 16.0.6", "target_arch": "aarch64-unknown-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3500.0, "cpu_model": "Apple Mac Studio M2 Ultra 2023", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 1068180.17, "execs_total": 10683116, "fuzzers_used": 13}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "Apple Mac Studio M2 Ultra 2023, Linux VM guest, 16 threads assigned to VM", "compiler": "Ubuntu clang version 16.0.6", "target_arch": "aarch64-unknown-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3500.0, "cpu_model": "Apple Mac Studio M2 Ultra 2023", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 1108873.82, "execs_total": 11089926, "fuzzers_used": 14}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "Apple Mac Studio M2 Ultra 2023, Linux VM guest, 16 threads assigned to VM", "compiler": "Ubuntu clang version 16.0.6", "target_arch": "aarch64-unknown-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3500.0, "cpu_model": "Apple Mac Studio M2 Ultra 2023", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 1134135.0, "execs_total": 11354464, "fuzzers_used": 15}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "Apple Mac Studio M2 Ultra 2023, Linux VM guest, 16 threads assigned to VM", "compiler": "Ubuntu clang version 16.0.6", "target_arch": "aarch64-unknown-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3500.0, "cpu_model": "Apple Mac Studio M2 Ultra 2023", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 1157465.79, "execs_total": 11582583, "fuzzers_used": 16}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "Apple Mac Studio M2 Ultra 2023, Linux VM guest, 16 threads assigned to VM", "compiler": "Ubuntu clang version 16.0.6", "target_arch": "aarch64-unknown-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3500.0, "cpu_model": "Apple Mac Studio M2 Ultra 2023", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 1122785.14, "execs_total": 11235138, "fuzzers_used": 17}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "Apple Mac Studio M2 Ultra 2023, Linux VM guest, 16 threads assigned to VM", "compiler": "Ubuntu clang version 16.0.6", "target_arch": "aarch64-unknown-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3500.0, "cpu_model": "Apple Mac Studio M2 Ultra 2023", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 1094132.3, "execs_total": 10950326, "fuzzers_used": 18}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "Apple Mac Studio M2 Ultra 2023, Linux VM guest, 16 threads assigned to VM", "compiler": "Ubuntu clang version 16.0.6", "target_arch": "aarch64-unknown-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3500.0, "cpu_model": "Apple Mac Studio M2 Ultra 2023", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 1041102.04, "execs_total": 10420102, "fuzzers_used": 19}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "Apple Mac Studio M2 Ultra 2023, Linux VM guest, 16 threads assigned to VM", "compiler": "Ubuntu clang version 16.0.6", "target_arch": "aarch64-unknown-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3500.0, "cpu_model": "Apple Mac Studio M2 Ultra 2023", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 1022474.0, "execs_total": 10236560, "fuzzers_used": 20}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "Apple Mac Studio M2 Ultra 2023, Linux VM guest, 16 threads assigned to VM", "compiler": "Ubuntu clang version 16.0.6", "target_arch": "aarch64-unknown-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3500.0, "cpu_model": "Apple Mac Studio M2 Ultra 2023", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 960681.48, "execs_total": 9618077, "fuzzers_used": 21}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "Apple Mac Studio M2 Ultra 2023, Linux VM guest, 16 threads assigned to VM", "compiler": "Ubuntu clang version 16.0.6", "target_arch": "aarch64-unknown-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3500.0, "cpu_model": "Apple Mac Studio M2 Ultra 2023", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 853680.22, "execs_total": 8545665, "fuzzers_used": 22}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "Apple Mac Studio M2 Ultra 2023, Linux VM guest, 16 threads assigned to VM", "compiler": "Ubuntu clang version 16.0.6", "target_arch": "aarch64-unknown-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3500.0, "cpu_model": "Apple Mac Studio M2 Ultra 2023", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 799719.75, "execs_total": 8005071, "fuzzers_used": 23}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "Apple Mac Studio M2 Ultra 2023, Linux VM guest, 16 threads assigned to VM", "compiler": "Ubuntu clang version 16.0.6", "target_arch": "aarch64-unknown-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3500.0, "cpu_model": "Apple Mac Studio M2 Ultra 2023", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 797512.71, "execs_total": 7983371, "fuzzers_used": 24}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "Apple Mac Studio M2 Ultra 2023, Linux VM guest, 16 threads assigned to VM", "compiler": "Ubuntu clang version 16.0.6", "target_arch": "aarch64-unknown-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3500.0, "cpu_model": "Apple Mac Studio M2 Ultra 2023", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 659476.15, "execs_total": 6601599, "fuzzers_used": 25}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "Apple Mac Studio M2 Ultra 2023, Linux VM guest, 16 threads assigned to VM", "compiler": "Ubuntu clang version 16.0.6", "target_arch": "aarch64-unknown-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3500.0, "cpu_model": "Apple Mac Studio M2 Ultra 2023", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 560625.96, "execs_total": 5612503, "fuzzers_used": 26}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "Apple Mac Studio M2 Ultra 2023, Linux VM guest, 16 threads assigned to VM", "compiler": "Ubuntu clang version 16.0.6", "target_arch": "aarch64-unknown-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3500.0, "cpu_model": "Apple Mac Studio M2 Ultra 2023", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 537839.62, "execs_total": 5381649, "fuzzers_used": 27}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "Apple Mac Studio M2 Ultra 2023, Linux VM guest, 16 threads assigned to VM", "compiler": "Ubuntu clang version 16.0.6", "target_arch": "aarch64-unknown-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3500.0, "cpu_model": "Apple Mac Studio M2 Ultra 2023", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 510072.53, "execs_total": 5106056, "fuzzers_used": 28}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "Apple Mac Studio M2 Ultra 2023, Linux VM guest, 16 threads assigned to VM", "compiler": "Ubuntu clang version 16.0.6", "target_arch": "aarch64-unknown-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3500.0, "cpu_model": "Apple Mac Studio M2 Ultra 2023", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 408667.49, "execs_total": 4091795, "fuzzers_used": 29}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "Apple Mac Studio M2 Ultra 2023, Linux VM guest, 16 threads assigned to VM", "compiler": "Ubuntu clang version 16.0.6", "target_arch": "aarch64-unknown-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3500.0, "cpu_model": "Apple Mac Studio M2 Ultra 2023", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 453849.79, "execs_total": 4542311, "fuzzers_used": 30}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "Apple Mac Studio M2 Ultra 2023, Linux VM guest, 16 threads assigned to VM", "compiler": "Ubuntu clang version 16.0.6", "target_arch": "aarch64-unknown-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3500.0, "cpu_model": "Apple Mac Studio M2 Ultra 2023", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 405935.72, "execs_total": 4064268, "fuzzers_used": 31}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "Apple Mac Studio M2 Ultra 2023, Linux VM guest, 16 threads assigned to VM", "compiler": "Ubuntu clang version 16.0.6", "target_arch": "aarch64-unknown-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3500.0, "cpu_model": "Apple Mac Studio M2 Ultra 2023", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 579312.77, "execs_total": 5798912, "fuzzers_used": 32}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "Apple Mac Studio M2 Ultra 2023, Linux VM guest, 16 threads assigned to VM", "compiler": "Ubuntu clang version 16.0.6", "target_arch": "aarch64-unknown-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3500.0, "cpu_model": "Apple Mac Studio M2 Ultra 2023", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 470961.79, "execs_total": 4715503, "fuzzers_used": 33}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "Apple Mac Studio M2 Ultra 2023, Linux VM guest, 16 threads assigned to VM", "compiler": "Ubuntu clang version 16.0.6", "target_arch": "aarch64-unknown-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3500.0, "cpu_model": "Apple Mac Studio M2 Ultra 2023", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 436380.3, "execs_total": 4368099, "fuzzers_used": 34}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "Apple Mac Studio M2 Ultra 2023, Linux VM guest, 16 threads assigned to VM", "compiler": "Ubuntu clang version 16.0.6", "target_arch": "aarch64-unknown-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3500.0, "cpu_model": "Apple Mac Studio M2 Ultra 2023", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 439819.17, "execs_total": 4405705, "fuzzers_used": 35}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "Apple Mac Studio M2 Ultra 2023, Linux VM guest, 16 threads assigned to VM", "compiler": "Ubuntu clang version 16.0.6", "target_arch": "aarch64-unknown-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3500.0, "cpu_model": "Apple Mac Studio M2 Ultra 2023", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 407460.31, "execs_total": 4084528, "fuzzers_used": 36}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3514.326, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 119469.35, "execs_total": 1194813, "fuzzers_used": 1}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3599.748, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 237177.2, "execs_total": 2372250, "fuzzers_used": 2}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3455.647, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 358305.9, "execs_total": 3583655, "fuzzers_used": 3}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3599.67, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 475974.21, "execs_total": 4760218, "fuzzers_used": 4}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3598.813, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 594372.12, "execs_total": 5944793, "fuzzers_used": 5}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3584.545, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 711732.18, "execs_total": 7118626, "fuzzers_used": 6}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3599.377, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 824314.1, "execs_total": 8245020, "fuzzers_used": 7}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3598.535, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 936358.89, "execs_total": 9365349, "fuzzers_used": 8}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3469.977, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 1010050.77, "execs_total": 10102421, "fuzzers_used": 9}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3599.644, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 1087333.72, "execs_total": 10875294, "fuzzers_used": 10}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3473.935, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 1180500.37, "execs_total": 11807345, "fuzzers_used": 11}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3334.193, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 1284695.8, "execs_total": 12849848, "fuzzers_used": 12}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3436.186, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 1377659.89, "execs_total": 13779252, "fuzzers_used": 13}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3597.27, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 1471828.49, "execs_total": 14721973, "fuzzers_used": 14}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3466.893, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 1557812.41, "execs_total": 15581135, "fuzzers_used": 15}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3561.127, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 1634678.08, "execs_total": 16349952, "fuzzers_used": 16}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3598.848, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 1518908.2, "execs_total": 15192488, "fuzzers_used": 17}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3591.34, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 1470513.71, "execs_total": 14709207, "fuzzers_used": 18}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3598.619, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 1414625.05, "execs_total": 14156400, "fuzzers_used": 19}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3597.99, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 1355481.53, "execs_total": 13565462, "fuzzers_used": 20}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3598.232, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 1292684.55, "execs_total": 12934801, "fuzzers_used": 21}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3442.34, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 1234478.66, "execs_total": 12352256, "fuzzers_used": 22}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3598.796, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 1174550.37, "execs_total": 11752094, "fuzzers_used": 23}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3494.124, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 1125218.66, "execs_total": 11258330, "fuzzers_used": 24}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3350.261, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 1022021.81, "execs_total": 10226548, "fuzzers_used": 25}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3598.929, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 990339.75, "execs_total": 9908883, "fuzzers_used": 26}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3484.153, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 953861.38, "execs_total": 9543479, "fuzzers_used": 27}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3393.24, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 942151.65, "execs_total": 9426176, "fuzzers_used": 28}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3434.881, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 927072.1, "execs_total": 9275954, "fuzzers_used": 29}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3444.453, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 908669.71, "execs_total": 9092225, "fuzzers_used": 30}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3442.593, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 893432.26, "execs_total": 8938840, "fuzzers_used": 31}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3380.389, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 876618.01, "execs_total": 8770325, "fuzzers_used": 32}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3586.135, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 834676.33, "execs_total": 8350992, "fuzzers_used": 33}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3597.956, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 830200.25, "execs_total": 8306463, "fuzzers_used": 34}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3597.94, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 821667.96, "execs_total": 8220135, "fuzzers_used": 35}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3591.052, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 829075.87, "execs_total": 8294543, "fuzzers_used": 36}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3573.541, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 814422.62, "execs_total": 8148191, "fuzzers_used": 37}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3599.902, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 806770.85, "execs_total": 8071030, "fuzzers_used": 38}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3488.496, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 794433.8, "execs_total": 7947600, "fuzzers_used": 39}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3470.314, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 781022.61, "execs_total": 7813248, "fuzzers_used": 40}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3599.761, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 754394.26, "execs_total": 7546321, "fuzzers_used": 41}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3599.125, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 763116.33, "execs_total": 7634125, "fuzzers_used": 42}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3599.437, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 759323.54, "execs_total": 7596118, "fuzzers_used": 43}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3599.079, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 764198.14, "execs_total": 7644920, "fuzzers_used": 44}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3599.619, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 757777.51, "execs_total": 7580317, "fuzzers_used": 45}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3425.09, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 749357.06, "execs_total": 7496189, "fuzzers_used": 46}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3598.567, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 732083.87, "execs_total": 7323543, "fuzzers_used": 47}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3598.365, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 721133.28, "execs_total": 7214084, "fuzzers_used": 48}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3599.699, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 658925.82, "execs_total": 6591967, "fuzzers_used": 49}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3597.889, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 659890.97, "execs_total": 6601888, "fuzzers_used": 50}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3381.676, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 655176.63, "execs_total": 6554987, "fuzzers_used": 51}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3587.51, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 660889.12, "execs_total": 6612265, "fuzzers_used": 52}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3546.407, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 651803.54, "execs_total": 6520961, "fuzzers_used": 53}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3439.83, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 659012.17, "execs_total": 6593396, "fuzzers_used": 54}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3387.899, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 660016.18, "execs_total": 6603558, "fuzzers_used": 55}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3444.077, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 655931.36, "execs_total": 6561865, "fuzzers_used": 56}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3597.775, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 618906.23, "execs_total": 6192465, "fuzzers_used": 57}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3599.33, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 614008.28, "execs_total": 6143464, "fuzzers_used": 58}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3599.487, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 622400.85, "execs_total": 6227304, "fuzzers_used": 59}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3599.123, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 624883.06, "execs_total": 6251875, "fuzzers_used": 60}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3590.657, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 628668.94, "execs_total": 6289966, "fuzzers_used": 61}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3598.335, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 628892.17, "execs_total": 6292361, "fuzzers_used": 62}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3599.368, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 622065.07, "execs_total": 6224119, "fuzzers_used": 63}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3413.262, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 625528.06, "execs_total": 6258762, "fuzzers_used": 64}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3599.18, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 602248.19, "execs_total": 6025927, "fuzzers_used": 65}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3591.981, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 597615.89, "execs_total": 5979708, "fuzzers_used": 66}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3600.012, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 607270.98, "execs_total": 6076233, "fuzzers_used": 67}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3507.753, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 608945.09, "execs_total": 6092446, "fuzzers_used": 68}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3599.845, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 611736.03, "execs_total": 6121207, "fuzzers_used": 69}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3412.629, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 615031.23, "execs_total": 6153592, "fuzzers_used": 70}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3443.261, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 608202.64, "execs_total": 6084885, "fuzzers_used": 71}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3599.439, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 614339.09, "execs_total": 6146152, "fuzzers_used": 72}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3379.556, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 587046.59, "execs_total": 5873881, "fuzzers_used": 73}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3598.574, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 587238.27, "execs_total": 5875646, "fuzzers_used": 74}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3599.098, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 594097.56, "execs_total": 5944036, "fuzzers_used": 75}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3587.762, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 598450.35, "execs_total": 5987756, "fuzzers_used": 76}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3599.629, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 600430.29, "execs_total": 6007598, "fuzzers_used": 77}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3362.161, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 602014.19, "execs_total": 6023649, "fuzzers_used": 78}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3588.173, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 606146.9, "execs_total": 6065033, "fuzzers_used": 79}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3591.159, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 599360.46, "execs_total": 5997023, "fuzzers_used": 80}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3503.299, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 574792.78, "execs_total": 5751470, "fuzzers_used": 81}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3584.593, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 578265.29, "execs_total": 5785927, "fuzzers_used": 82}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3401.073, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 589985.07, "execs_total": 5903506, "fuzzers_used": 83}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3468.764, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 589281.87, "execs_total": 5895767, "fuzzers_used": 84}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3466.115, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 596581.77, "execs_total": 5969747, "fuzzers_used": 85}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3590.706, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 589017.68, "execs_total": 5893108, "fuzzers_used": 86}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3521.556, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 593403.75, "execs_total": 5937422, "fuzzers_used": 87}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3599.254, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 601611.06, "execs_total": 6019864, "fuzzers_used": 88}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3598.211, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 576056.15, "execs_total": 5763322, "fuzzers_used": 89}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3599.489, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 576151.97, "execs_total": 5764687, "fuzzers_used": 90}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3598.444, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 583769.1, "execs_total": 5841115, "fuzzers_used": 91}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3446.364, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 585285.47, "execs_total": 5856103, "fuzzers_used": 92}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3562.852, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 581524.67, "execs_total": 5818808, "fuzzers_used": 93}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3597.403, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 596383.31, "execs_total": 5967460, "fuzzers_used": 94}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3421.421, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 596239.29, "execs_total": 5965882, "fuzzers_used": 95}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3276.519, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 595382.67, "execs_total": 5957136, "fuzzers_used": 96}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3599.029, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 586144.68, "execs_total": 5865411, "fuzzers_used": 97}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3590.48, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 579467.06, "execs_total": 5798123, "fuzzers_used": 98}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3597.89, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 572801.45, "execs_total": 5731838, "fuzzers_used": 99}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3598.31, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 573916.1, "execs_total": 5742901, "fuzzers_used": 100}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3589.943, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 565823.06, "execs_total": 5660910, "fuzzers_used": 101}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3391.191, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 561854.84, "execs_total": 5621778, "fuzzers_used": 102}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3372.775, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 562717.02, "execs_total": 5630085, "fuzzers_used": 103}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3365.142, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 559273.67, "execs_total": 5596400, "fuzzers_used": 104}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3591.44, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 553209.58, "execs_total": 5535044, "fuzzers_used": 105}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3563.12, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 547678.42, "execs_total": 5480061, "fuzzers_used": 106}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3477.381, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 552316.36, "execs_total": 5526570, "fuzzers_used": 107}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3599.467, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 545257.97, "execs_total": 5455157, "fuzzers_used": 108}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3344.258, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 549190.03, "execs_total": 5495511, "fuzzers_used": 109}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3421.467, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 546845.0, "execs_total": 5472086, "fuzzers_used": 110}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3599.157, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 545239.46, "execs_total": 5455236, "fuzzers_used": 111}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3598.389, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 543139.24, "execs_total": 5434484, "fuzzers_used": 112}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3461.931, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 543252.43, "execs_total": 5435319, "fuzzers_used": 113}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3354.728, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 538720.77, "execs_total": 5390315, "fuzzers_used": 114}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3599.185, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 536681.55, "execs_total": 5369963, "fuzzers_used": 115}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3598.862, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 540956.43, "execs_total": 5412850, "fuzzers_used": 116}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3599.403, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 536348.84, "execs_total": 5367054, "fuzzers_used": 117}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3598.449, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 534734.41, "execs_total": 5350358, "fuzzers_used": 118}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3599.736, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 536060.28, "execs_total": 5363892, "fuzzers_used": 119}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3590.738, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 533480.83, "execs_total": 5338193, "fuzzers_used": 120}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3599.482, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 514271.98, "execs_total": 5145571, "fuzzers_used": 121}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3598.864, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 503271.79, "execs_total": 5035794, "fuzzers_used": 122}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3586.097, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 496011.52, "execs_total": 4963063, "fuzzers_used": 123}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3587.507, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 490784.42, "execs_total": 4910734, "fuzzers_used": 124}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3599.718, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 488441.09, "execs_total": 4887140, "fuzzers_used": 125}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3598.035, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 481281.33, "execs_total": 4815386, "fuzzers_used": 126}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3599.332, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 469294.96, "execs_total": 4695183, "fuzzers_used": 127}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3589.346, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 465563.78, "execs_total": 4657841, "fuzzers_used": 128}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3598.943, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 459922.67, "execs_total": 4601391, "fuzzers_used": 129}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3280.928, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 459384.3, "execs_total": 4596590, "fuzzers_used": 130}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3598.875, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 453310.58, "execs_total": 4535383, "fuzzers_used": 131}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3600.179, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 460246.7, "execs_total": 4604954, "fuzzers_used": 132}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3601.396, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 457201.82, "execs_total": 4574474, "fuzzers_used": 133}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3600.942, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 452487.43, "execs_total": 4527226, "fuzzers_used": 134}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3458.573, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 450514.18, "execs_total": 4507745, "fuzzers_used": 135}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3598.922, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 449479.52, "execs_total": 4496843, "fuzzers_used": 136}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3598.911, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 444691.06, "execs_total": 4449491, "fuzzers_used": 137}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3599.654, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 443497.81, "execs_total": 4437339, "fuzzers_used": 138}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3599.626, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 437981.1, "execs_total": 4382263, "fuzzers_used": 139}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3599.124, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 443055.68, "execs_total": 4432987, "fuzzers_used": 140}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3597.978, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 438908.41, "execs_total": 4391393, "fuzzers_used": 141}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3453.125, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 442841.02, "execs_total": 4430878, "fuzzers_used": 142}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3214.708, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 441891.92, "execs_total": 4421776, "fuzzers_used": 143}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3597.764, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 441860.76, "execs_total": 4421068, "fuzzers_used": 144}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3443.44, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 426935.73, "execs_total": 4272029, "fuzzers_used": 145}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3586.383, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 427322.41, "execs_total": 4275938, "fuzzers_used": 146}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3424.014, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 426914.69, "execs_total": 4271924, "fuzzers_used": 147}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3598.58, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 433246.64, "execs_total": 4335165, "fuzzers_used": 148}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3598.546, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 435016.77, "execs_total": 4352822, "fuzzers_used": 149}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3598.587, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 432197.7, "execs_total": 4324740, "fuzzers_used": 150}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3537.464, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 434928.88, "execs_total": 4351767, "fuzzers_used": 151}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3599.135, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 435174.29, "execs_total": 4354184, "fuzzers_used": 152}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3371.959, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 426852.22, "execs_total": 4271150, "fuzzers_used": 153}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3597.413, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 431241.89, "execs_total": 4315307, "fuzzers_used": 154}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3590.69, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 430842.14, "execs_total": 4311025, "fuzzers_used": 155}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3591.29, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 434156.3, "execs_total": 4344575, "fuzzers_used": 156}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3583.517, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 430896.1, "execs_total": 4311642, "fuzzers_used": 157}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3598.926, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 435704.89, "execs_total": 4360326, "fuzzers_used": 158}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3599.395, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 438155.8, "execs_total": 4384203, "fuzzers_used": 159}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3396.521, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 442883.53, "execs_total": 4432039, "fuzzers_used": 160}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3597.95, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 433993.37, "execs_total": 4342838, "fuzzers_used": 161}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3598.614, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 437174.96, "execs_total": 4374708, "fuzzers_used": 162}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3599.894, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 435745.93, "execs_total": 4360320, "fuzzers_used": 163}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3599.633, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 441564.58, "execs_total": 4418619, "fuzzers_used": 164}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3599.069, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 445500.18, "execs_total": 4457810, "fuzzers_used": 165}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3581.223, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 445887.53, "execs_total": 4461995, "fuzzers_used": 166}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3598.249, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 443509.97, "execs_total": 4438012, "fuzzers_used": 167}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3599.106, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 446851.67, "execs_total": 4471572, "fuzzers_used": 168}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3417.764, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 447685.22, "execs_total": 4479536, "fuzzers_used": 169}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3589.058, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 446730.72, "execs_total": 4470322, "fuzzers_used": 170}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3599.116, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 448668.48, "execs_total": 4489967, "fuzzers_used": 171}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3587.905, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 450972.11, "execs_total": 4513110, "fuzzers_used": 172}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3599.114, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 450615.23, "execs_total": 4509271, "fuzzers_used": 173}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3598.851, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 458016.89, "execs_total": 4583318, "fuzzers_used": 174}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3599.106, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 460677.5, "execs_total": 4609716, "fuzzers_used": 175}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3374.143, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 460763.9, "execs_total": 4610640, "fuzzers_used": 176}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3599.42, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 452298.55, "execs_total": 4526006, "fuzzers_used": 177}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3598.801, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 456748.89, "execs_total": 4570571, "fuzzers_used": 178}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3598.709, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 451289.94, "execs_total": 4516046, "fuzzers_used": 179}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3599.769, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 463235.15, "execs_total": 4635628, "fuzzers_used": 180}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3330.854, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 464366.11, "execs_total": 4646649, "fuzzers_used": 181}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3599.585, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 469453.17, "execs_total": 4697909, "fuzzers_used": 182}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3598.242, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 467300.47, "execs_total": 4676077, "fuzzers_used": 183}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3597.952, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 475115.57, "execs_total": 4754150, "fuzzers_used": 184}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3583.539, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 472179.98, "execs_total": 4724913, "fuzzers_used": 185}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3598.57, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 465528.62, "execs_total": 4658439, "fuzzers_used": 186}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3587.126, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 476194.69, "execs_total": 4765385, "fuzzers_used": 187}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3423.033, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 475886.86, "execs_total": 4762069, "fuzzers_used": 188}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3599.32, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 473599.91, "execs_total": 4739128, "fuzzers_used": 189}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3597.599, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 476949.52, "execs_total": 4772500, "fuzzers_used": 190}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3437.101, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 474259.76, "execs_total": 4745505, "fuzzers_used": 191}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "AWS EC2 r6a.48xlarge spot instance", "compiler": "clang version 15.0.7 (Amazon Linux 15.0.7-3.amzn2023.0.1)", "target_arch": "x86_64-amazon-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3599.17, "cpu_model": "AMD EPYC 7R13 Processor", "cpu_threads": 192}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 479848.23, "execs_total": 4801111, "fuzzers_used": 192}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "", "compiler": "Debian clang version 17.0.4 (++20231031083102+309d55140c46-1~exp1~20231031083155.63)", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4761.063, "cpu_model": "12th Gen Intel(R) Core(TM) i7-1270P", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 641219.02, "execs_total": 19251242, "fuzzers_used": 16}, "singlecore": {"execs_per_sec": 149778.22, "execs_total": 4493796, "fuzzers_used": 1}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "", "compiler": "Ubuntu clang version 17.0.2 (++20231003073128+b2417f51dbbd-1~exp1~20231003073233.51)", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3193.942, "cpu_model": "AMD EPYC 7282 16-Core Processor", "cpu_threads": 64}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 769000.8, "execs_total": 23084516, "fuzzers_used": 32}, "singlecore": {"execs_per_sec": 87198.85, "execs_total": 2616227, "fuzzers_used": 1}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.08a", "comment": "", "compiler": "Ubuntu clang version 14.0.0-1ubuntu1.1", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 3700.0, "cpu_model": "AMD Ryzen 5 PRO 4650G with Radeon Graphics", "cpu_threads": 12}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 704840.16, "execs_total": 21163992, "fuzzers_used": 12}, "singlecore": {"execs_per_sec": 95356.14, "execs_total": 2862114, "fuzzers_used": 1}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.09a", "comment": "", "compiler": "Debian clang version 14.0.6", "target_arch": "aarch64-unknown-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 2400.0, "cpu_model": "Raspberry Pi 5", "cpu_threads": 4}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 101114.23, "execs_total": 3036637, "fuzzers_used": 4}, "singlecore": {"execs_per_sec": 25786.11, "execs_total": 774460, "fuzzers_used": 1}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.07a", "comment": "", "compiler": "Debian clang version 17.0.0 (++20230417071830+ae77aceba5ad-1~exp1~20230417071935.630)", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4792.073, "cpu_model": "AMD Ryzen 9 5950X 16-Core Processor", "cpu_threads": 32}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 2339762.91, "execs_total": 70253164, "fuzzers_used": 32}, "singlecore": {"execs_per_sec": 161690.07, "execs_total": 4851838, "fuzzers_used": 1}}}}
|
||||||
|
{"config": {"afl_persistent_config": false, "afl_system_config": true, "afl_version": "++4.10c", "comment": "", "compiler": "clang version 17.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4675.949, "cpu_model": "AMD Ryzen 9 6900HS with Radeon Graphics", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 614403.91, "execs_total": 18435083, "fuzzers_used": 16}, "singlecore": {"execs_per_sec": 62859.9, "execs_total": 1886111, "fuzzers_used": 1}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.10c", "comment": "", "compiler": "clang version 17.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 4744.522, "cpu_model": "AMD Ryzen 9 6900HS with Radeon Graphics", "cpu_threads": 16}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 991132.96, "execs_total": 29737588, "fuzzers_used": 16}, "singlecore": {"execs_per_sec": 135501.07, "execs_total": 4066116, "fuzzers_used": 1}}}}
|
||||||
|
{"config": {"afl_persistent_config": false, "afl_system_config": true, "afl_version": "++4.10c", "comment": "", "compiler": "Ubuntu clang version 14.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 5399.822, "cpu_model": "AMD Ryzen 9 7950X3D 16-Core Processor", "cpu_threads": 32}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 1566279.42, "execs_total": 46994452, "fuzzers_used": 32}, "singlecore": {"execs_per_sec": 71565.56, "execs_total": 2147396, "fuzzers_used": 1}}}}
|
||||||
|
{"config": {"afl_persistent_config": true, "afl_system_config": true, "afl_version": "++4.10c", "comment": "", "compiler": "clang version 17.0.6", "target_arch": "x86_64-pc-linux-gnu"}, "hardware": {"cpu_fastest_core_mhz": 5478.258, "cpu_model": "AMD Ryzen 9 7950X3D 16-Core Processor", "cpu_threads": 32}, "targets": {"test-instr-persist-shmem": {"multicore": {"execs_per_sec": 2173959.15, "execs_total": 65229513, "fuzzers_used": 32}, "singlecore": {"execs_per_sec": 161960.29, "execs_total": 4859457, "fuzzers_used": 1}}}}
|
File diff suppressed because one or more lines are too long
@ -0,0 +1,281 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# Part of the aflplusplus project, requires Python 3.8+.
|
||||||
|
# Author: Chris Ball <chris@printf.net>, ported from Marc "van Hauser" Heuse's "benchmark.sh".
|
||||||
|
import argparse, asyncio, json, multiprocessing, os, platform, re, shutil, sys
|
||||||
|
from dataclasses import asdict, dataclass
|
||||||
|
from decimal import Decimal
|
||||||
|
from enum import Enum, auto
|
||||||
|
from pathlib import Path
|
||||||
|
from typing import Dict, List, Optional, Tuple
|
||||||
|
|
||||||
|
blue = lambda text: f"\033[1;94m{text}\033[0m"; gray = lambda text: f"\033[1;90m{text}\033[0m"
|
||||||
|
green = lambda text: f"\033[0;32m{text}\033[0m"; red = lambda text: f"\033[0;31m{text}\033[0m"
|
||||||
|
yellow = lambda text: f"\033[0;33m{text}\033[0m"
|
||||||
|
|
||||||
|
class Mode(Enum):
|
||||||
|
multicore = auto()
|
||||||
|
singlecore = auto()
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class Target:
|
||||||
|
source: Path
|
||||||
|
binary: Path
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class Run:
|
||||||
|
execs_per_sec: float
|
||||||
|
execs_total: float
|
||||||
|
fuzzers_used: int
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class Config:
|
||||||
|
afl_persistent_config: bool
|
||||||
|
afl_system_config: bool
|
||||||
|
afl_version: Optional[str]
|
||||||
|
comment: str
|
||||||
|
compiler: str
|
||||||
|
target_arch: str
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class Hardware:
|
||||||
|
cpu_fastest_core_mhz: float
|
||||||
|
cpu_model: str
|
||||||
|
cpu_threads: int
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class Results:
|
||||||
|
config: Optional[Config]
|
||||||
|
hardware: Optional[Hardware]
|
||||||
|
targets: Dict[str, Dict[str, Optional[Run]]]
|
||||||
|
|
||||||
|
all_modes = [Mode.singlecore, Mode.multicore]
|
||||||
|
all_targets = [
|
||||||
|
Target(source=Path("../utils/persistent_mode/test-instr.c").resolve(), binary=Path("test-instr-persist-shmem")),
|
||||||
|
Target(source=Path("../test-instr.c").resolve(), binary=Path("test-instr"))
|
||||||
|
]
|
||||||
|
modes = [mode.name for mode in all_modes]
|
||||||
|
targets = [str(target.binary) for target in all_targets]
|
||||||
|
cpu_count = multiprocessing.cpu_count()
|
||||||
|
env_vars = {
|
||||||
|
"AFL_DISABLE_TRIM": "1", "AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES": "1", "AFL_FAST_CAL": "1",
|
||||||
|
"AFL_NO_UI": "1", "AFL_TRY_AFFINITY": "1", "PATH": f'{str(Path("../").resolve())}:{os.environ["PATH"]}',
|
||||||
|
}
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter)
|
||||||
|
parser.add_argument("-b", "--basedir", help="directory to use for temp files", type=str, default="/tmp/aflpp-benchmark")
|
||||||
|
parser.add_argument("-d", "--debug", help="show verbose debugging output", action="store_true")
|
||||||
|
parser.add_argument("-r", "--runs", help="how many runs to average results over", type=int, default=3)
|
||||||
|
parser.add_argument("-f", "--fuzzers", help="how many afl-fuzz workers to use", type=int, default=cpu_count)
|
||||||
|
parser.add_argument("-m", "--mode", help="pick modes", action="append", default=modes, choices=modes)
|
||||||
|
parser.add_argument("-c", "--comment", help="add a comment about your setup", type=str, default="")
|
||||||
|
parser.add_argument("--cpu", help="override the detected CPU model name", type=str, default="")
|
||||||
|
parser.add_argument("--mhz", help="override the detected CPU MHz", type=str, default="")
|
||||||
|
parser.add_argument(
|
||||||
|
"-t", "--target", help="pick targets", action="append", default=["test-instr-persist-shmem"], choices=targets
|
||||||
|
)
|
||||||
|
args = parser.parse_args()
|
||||||
|
# Really unsatisfying argparse behavior: we want a default and to allow multiple choices, but if there's a manual choice
|
||||||
|
# it should override the default. Seems like we have to remove the default to get that and have correct help text?
|
||||||
|
if len(args.target) > 1:
|
||||||
|
args.target = args.target[1:]
|
||||||
|
if len(args.mode) > 2:
|
||||||
|
args.mode = args.mode[2:]
|
||||||
|
|
||||||
|
chosen_modes = [mode for mode in all_modes if mode.name in args.mode]
|
||||||
|
chosen_targets = [target for target in all_targets if str(target.binary) in args.target]
|
||||||
|
results = Results(config=None, hardware=None, targets={
|
||||||
|
str(t.binary): {m.name: None for m in chosen_modes} for t in chosen_targets}
|
||||||
|
)
|
||||||
|
debug = lambda text: args.debug and print(blue(text))
|
||||||
|
|
||||||
|
async def clean_up_tempfiles() -> None:
|
||||||
|
shutil.rmtree(f"{args.basedir}/in")
|
||||||
|
for target in chosen_targets:
|
||||||
|
target.binary.unlink()
|
||||||
|
for mode in chosen_modes:
|
||||||
|
shutil.rmtree(f"{args.basedir}/out-{mode.name}-{str(target.binary)}")
|
||||||
|
|
||||||
|
async def check_afl_persistent() -> bool:
|
||||||
|
with open("/proc/cmdline", "r") as cmdline:
|
||||||
|
return "mitigations=off" in cmdline.read().strip().split(" ")
|
||||||
|
|
||||||
|
async def check_afl_system() -> bool:
|
||||||
|
sysctl = next((s for s in ["sysctl", "/sbin/sysctl"] if shutil.which(s)), None)
|
||||||
|
if sysctl:
|
||||||
|
(returncode, stdout, _) = await run_command([sysctl, "kernel.randomize_va_space"])
|
||||||
|
return returncode == 0 and stdout.decode().rstrip().split(" = ")[1] == "0"
|
||||||
|
return False
|
||||||
|
|
||||||
|
async def prep_env() -> None:
|
||||||
|
Path(f"{args.basedir}/in").mkdir(exist_ok=True, parents=True)
|
||||||
|
with open(f"{args.basedir}/in/in.txt", "wb") as seed:
|
||||||
|
seed.write(b"\x00" * 10240)
|
||||||
|
|
||||||
|
async def compile_target(source: Path, binary: Path) -> None:
|
||||||
|
print(f" [*] Compiling the {binary} fuzzing harness for the benchmark to use.")
|
||||||
|
(returncode, stdout, stderr) = await run_command(
|
||||||
|
[str(Path("../afl-clang-lto").resolve()), "-o", str(Path(binary.resolve())), str(Path(source).resolve())]
|
||||||
|
)
|
||||||
|
if returncode == 0:
|
||||||
|
return
|
||||||
|
print(yellow(f" [*] afl-clang-lto was unable to compile; falling back to afl-cc."))
|
||||||
|
(returncode, stdout, stderr) = await run_command(
|
||||||
|
[str(Path("../afl-cc").resolve()), "-o", str(Path(binary.resolve())), str(Path(source).resolve())]
|
||||||
|
)
|
||||||
|
if returncode != 0:
|
||||||
|
sys.exit(red(f" [*] Error: afl-cc is unable to compile: {stderr.decode()} {stdout.decode()}"))
|
||||||
|
|
||||||
|
async def run_command(cmd: List[str]) -> Tuple[Optional[int], bytes, bytes]:
|
||||||
|
debug(f"Launching command: {cmd} with env {env_vars}")
|
||||||
|
p = await asyncio.create_subprocess_exec(
|
||||||
|
*cmd, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE, env=env_vars
|
||||||
|
)
|
||||||
|
stdout, stderr = await p.communicate()
|
||||||
|
debug(f"Output: {stdout.decode()} {stderr.decode()}")
|
||||||
|
return (p.returncode, stdout, stderr)
|
||||||
|
|
||||||
|
async def check_deps() -> None:
|
||||||
|
if not (plat := platform.system()) == "Linux": sys.exit(red(f" [*] {plat} is not supported by this script yet."))
|
||||||
|
if not os.access(Path("../afl-fuzz").resolve(), os.X_OK) and os.access(Path("../afl-cc").resolve(), os.X_OK) and (
|
||||||
|
os.path.exists(Path("../SanitizerCoveragePCGUARD.so").resolve())):
|
||||||
|
sys.exit(red(" [*] Compile AFL++: we need afl-fuzz, afl-clang-fast and SanitizerCoveragePCGUARD.so built."))
|
||||||
|
|
||||||
|
(returncode, stdout, stderr) = await run_command([str(Path("../afl-cc").resolve()), "-v"])
|
||||||
|
if returncode != 0:
|
||||||
|
sys.exit(red(f" [*] Error: afl-cc -v returned: {stderr.decode()} {stdout.decode()}"))
|
||||||
|
compiler = ""
|
||||||
|
target_arch = ""
|
||||||
|
for line in stderr.decode().split("\n"):
|
||||||
|
if "clang version" in line:
|
||||||
|
compiler = line
|
||||||
|
elif m := re.match(r"^Target: (.*)", line):
|
||||||
|
target_arch = m.group(1)
|
||||||
|
|
||||||
|
# Pick some sample settings from afl-{persistent,system}-config to try to see whether they were run.
|
||||||
|
afl_pc = await check_afl_persistent()
|
||||||
|
afl_sc = await check_afl_system()
|
||||||
|
if not afl_pc:
|
||||||
|
print(yellow(f" [*] afl-persistent-config did not run; run it to improve performance (and decrease security)."))
|
||||||
|
if not afl_sc:
|
||||||
|
print(yellow(f" [*] afl-system-config did not run; run it to improve performance (and decrease security)."))
|
||||||
|
results.config = Config(afl_persistent_config=afl_pc, afl_system_config=afl_sc, afl_version="",
|
||||||
|
comment=args.comment, compiler=compiler, target_arch=target_arch)
|
||||||
|
|
||||||
|
async def colon_values(filename: str, searchKey: str) -> List[str]:
|
||||||
|
"""Return a colon-separated value given a key in a file, e.g. 'cpu MHz : 4976.109')"""
|
||||||
|
with open(filename, "r") as fh:
|
||||||
|
kv_pairs = (line.split(": ", 1) for line in fh if ": " in line)
|
||||||
|
v_list = [v.rstrip() for k, v in kv_pairs if k.rstrip() == searchKey]
|
||||||
|
return v_list
|
||||||
|
|
||||||
|
async def describe_afl_config() -> str:
|
||||||
|
if results.config is None:
|
||||||
|
return "unknown"
|
||||||
|
elif results.config.afl_persistent_config and results.config.afl_system_config:
|
||||||
|
return "both"
|
||||||
|
elif results.config.afl_persistent_config:
|
||||||
|
return "persistent"
|
||||||
|
elif results.config.afl_system_config:
|
||||||
|
return "system"
|
||||||
|
else:
|
||||||
|
return "none"
|
||||||
|
|
||||||
|
async def save_benchmark_results() -> None:
|
||||||
|
"""Append a single row to the benchmark results in JSON Lines format (which is simple to write and diff)."""
|
||||||
|
with open("benchmark-results.jsonl", "a") as jsonfile:
|
||||||
|
json.dump(asdict(results), jsonfile, sort_keys=True)
|
||||||
|
jsonfile.write("\n")
|
||||||
|
print(blue(f" [*] Results have been written to the {jsonfile.name} file."))
|
||||||
|
with open("COMPARISON.md", "r+") as comparisonfile:
|
||||||
|
described_config = await describe_afl_config()
|
||||||
|
aflconfig = described_config.ljust(12)
|
||||||
|
if results.hardware is None:
|
||||||
|
return
|
||||||
|
cpu_model = results.hardware.cpu_model.ljust(51)
|
||||||
|
if cpu_model in comparisonfile.read():
|
||||||
|
print(blue(f" [*] Results have not been written to the COMPARISON.md file; this CPU is already present."))
|
||||||
|
return
|
||||||
|
cpu_mhz = str(round(results.hardware.cpu_fastest_core_mhz)).ljust(5)
|
||||||
|
if not "test-instr-persist-shmem" in results.targets or \
|
||||||
|
not "multicore" in results.targets["test-instr-persist-shmem"] or \
|
||||||
|
not "singlecore" in results.targets["test-instr-persist-shmem"] or \
|
||||||
|
results.targets["test-instr-persist-shmem"]["singlecore"] is None or \
|
||||||
|
results.targets["test-instr-persist-shmem"]["multicore"] is None:
|
||||||
|
return
|
||||||
|
single = str(round(results.targets["test-instr-persist-shmem"]["singlecore"].execs_per_sec)).ljust(10)
|
||||||
|
multi = str(round(results.targets["test-instr-persist-shmem"]["multicore"].execs_per_sec)).ljust(9)
|
||||||
|
cores = str(args.fuzzers).ljust(7)
|
||||||
|
comparisonfile.write(f"|{cpu_model} | {cpu_mhz} | {cores} | {single} | {multi} | {aflconfig} |\n")
|
||||||
|
print(blue(f" [*] Results have been written to the COMPARISON.md file."))
|
||||||
|
with open("COMPARISON.md", "r") as comparisonfile:
|
||||||
|
print(comparisonfile.read())
|
||||||
|
|
||||||
|
|
||||||
|
async def main() -> None:
|
||||||
|
try:
|
||||||
|
await clean_up_tempfiles()
|
||||||
|
except FileNotFoundError:
|
||||||
|
pass
|
||||||
|
await check_deps()
|
||||||
|
if args.mhz:
|
||||||
|
cpu_mhz = float(args.mhz)
|
||||||
|
else:
|
||||||
|
cpu_mhz_str = await colon_values("/proc/cpuinfo", "cpu MHz")
|
||||||
|
if len(cpu_mhz_str) == 0:
|
||||||
|
cpu_mhz_str.append("0")
|
||||||
|
cpu_mhz = max([float(c) for c in cpu_mhz_str]) # use the fastest CPU MHz for now
|
||||||
|
if args.cpu:
|
||||||
|
cpu_model = [args.cpu]
|
||||||
|
else:
|
||||||
|
cpu_model = await colon_values("/proc/cpuinfo", "model name") or [""]
|
||||||
|
results.hardware = Hardware(cpu_fastest_core_mhz=cpu_mhz, cpu_model=cpu_model[0], cpu_threads=cpu_count)
|
||||||
|
await prep_env()
|
||||||
|
print(f" [*] Ready, starting benchmark...")
|
||||||
|
for target in chosen_targets:
|
||||||
|
await compile_target(target.source, target.binary)
|
||||||
|
binary = str(target.binary)
|
||||||
|
for mode in chosen_modes:
|
||||||
|
if mode == Mode.multicore:
|
||||||
|
print(blue(f" [*] Using {args.fuzzers} fuzzers for multicore fuzzing "), end="")
|
||||||
|
print(blue("(use --fuzzers to override)." if args.fuzzers == cpu_count else f"(the default is {cpu_count})"))
|
||||||
|
execs_per_sec, execs_total = ([] for _ in range(2))
|
||||||
|
for run_idx in range(0, args.runs):
|
||||||
|
print(gray(f" [*] {mode.name} {binary} run {run_idx+1} of {args.runs}, execs/s: "), end="", flush=True)
|
||||||
|
fuzzers = range(0, args.fuzzers if mode == Mode.multicore else 1)
|
||||||
|
outdir = f"{args.basedir}/out-{mode.name}-{binary}"
|
||||||
|
cmds = []
|
||||||
|
for fuzzer_idx, afl in enumerate(fuzzers):
|
||||||
|
name = ["-o", outdir, "-M" if fuzzer_idx == 0 else "-S", str(afl)]
|
||||||
|
cmds.append(["afl-fuzz", "-i", f"{args.basedir}/in"] + name + ["-s", "123", "-V10", "-D", f"./{binary}"])
|
||||||
|
# Prepare the afl-fuzz tasks, and then block while waiting for them to finish.
|
||||||
|
fuzztasks = [run_command(cmds[cpu]) for cpu in fuzzers]
|
||||||
|
await asyncio.gather(*fuzztasks)
|
||||||
|
afl_versions = await colon_values(f"{outdir}/0/fuzzer_stats", "afl_version")
|
||||||
|
if results.config:
|
||||||
|
results.config.afl_version = afl_versions[0]
|
||||||
|
# Our score is the sum of all execs_per_sec entries in fuzzer_stats files for the run.
|
||||||
|
sectasks = [colon_values(f"{outdir}/{afl}/fuzzer_stats", "execs_per_sec") for afl in fuzzers]
|
||||||
|
all_execs_per_sec = await asyncio.gather(*sectasks)
|
||||||
|
execs = sum([Decimal(count[0]) for count in all_execs_per_sec])
|
||||||
|
print(green(execs))
|
||||||
|
execs_per_sec.append(execs)
|
||||||
|
# Also gather execs_total and total_run_time for this run.
|
||||||
|
exectasks = [colon_values(f"{outdir}/{afl}/fuzzer_stats", "execs_done") for afl in fuzzers]
|
||||||
|
all_execs_total = await asyncio.gather(*exectasks)
|
||||||
|
execs_total.append(sum([Decimal(count[0]) for count in all_execs_total]))
|
||||||
|
|
||||||
|
# (Using float() because Decimal() is not JSON-serializable.)
|
||||||
|
avg_afl_execs_per_sec = round(Decimal(sum(execs_per_sec) / len(execs_per_sec)), 2)
|
||||||
|
afl_execs_total = int(sum([Decimal(execs) for execs in execs_total]))
|
||||||
|
run = Run(execs_per_sec=float(avg_afl_execs_per_sec), execs_total=afl_execs_total, fuzzers_used=len(fuzzers))
|
||||||
|
results.targets[binary][mode.name] = run
|
||||||
|
print(f" [*] Average execs/sec for this test across all runs was: {green(avg_afl_execs_per_sec)}")
|
||||||
|
if (((max(execs_per_sec) - min(execs_per_sec)) / avg_afl_execs_per_sec) * 100) > 15:
|
||||||
|
print(yellow(" [*] The difference between your slowest and fastest runs was >15%, maybe try again?"))
|
||||||
|
|
||||||
|
await clean_up_tempfiles()
|
||||||
|
await save_benchmark_results()
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
asyncio.run(main())
|
||||||
|
|
@ -0,0 +1 @@
|
|||||||
|
include/config.h
|
@ -0,0 +1,121 @@
|
|||||||
|
cc_library_shared {
|
||||||
|
name: "libfuzzer-mutator",
|
||||||
|
vendor_available: true,
|
||||||
|
host_supported: true,
|
||||||
|
|
||||||
|
cflags: [
|
||||||
|
"-g",
|
||||||
|
"-O0",
|
||||||
|
"-funroll-loops",
|
||||||
|
"-fPIC",
|
||||||
|
"-fpermissive",
|
||||||
|
"-std=c++11",
|
||||||
|
"-Wno-unused-parameter",
|
||||||
|
"-Wno-unused-variable",
|
||||||
|
],
|
||||||
|
|
||||||
|
srcs: [
|
||||||
|
"libfuzzer/FuzzerCrossOver.cpp",
|
||||||
|
"libfuzzer/FuzzerDataFlowTrace.cpp",
|
||||||
|
"libfuzzer/FuzzerDriver.cpp",
|
||||||
|
"libfuzzer/FuzzerExtFunctionsDlsym.cpp",
|
||||||
|
"libfuzzer/FuzzerExtFunctionsWeak.cpp",
|
||||||
|
"libfuzzer/FuzzerExtFunctionsWindows.cpp",
|
||||||
|
"libfuzzer/FuzzerExtraCounters.cpp",
|
||||||
|
"libfuzzer/FuzzerFork.cpp",
|
||||||
|
"libfuzzer/FuzzerIO.cpp",
|
||||||
|
"libfuzzer/FuzzerIOPosix.cpp",
|
||||||
|
"libfuzzer/FuzzerIOWindows.cpp",
|
||||||
|
"libfuzzer/FuzzerLoop.cpp",
|
||||||
|
"libfuzzer/FuzzerMerge.cpp",
|
||||||
|
"libfuzzer/FuzzerMutate.cpp",
|
||||||
|
"libfuzzer/FuzzerSHA1.cpp",
|
||||||
|
"libfuzzer/FuzzerTracePC.cpp",
|
||||||
|
"libfuzzer/FuzzerUtil.cpp",
|
||||||
|
"libfuzzer/FuzzerUtilDarwin.cpp",
|
||||||
|
"libfuzzer/FuzzerUtilFuchsia.cpp",
|
||||||
|
"libfuzzer/FuzzerUtilLinux.cpp",
|
||||||
|
"libfuzzer/FuzzerUtilPosix.cpp",
|
||||||
|
"libfuzzer/FuzzerUtilWindows.cpp",
|
||||||
|
"libfuzzer/libfuzzer.cpp",
|
||||||
|
],
|
||||||
|
|
||||||
|
header_libs: [
|
||||||
|
"libafl_headers",
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
/*cc_library_shared {
|
||||||
|
name: "honggfuzz-mutator",
|
||||||
|
vendor_available: true,
|
||||||
|
host_supported: true,
|
||||||
|
|
||||||
|
cflags: [
|
||||||
|
"-g",
|
||||||
|
"-O0",
|
||||||
|
"-funroll-loops",
|
||||||
|
"-fPIC",
|
||||||
|
"-Wl,-Bsymbolic",
|
||||||
|
],
|
||||||
|
|
||||||
|
srcs: [
|
||||||
|
"honggfuzz/honggfuzz.c",
|
||||||
|
"honggfuzz/mangle.c",
|
||||||
|
// "../src/afl-perfomance.c",
|
||||||
|
],
|
||||||
|
|
||||||
|
header_libs: [
|
||||||
|
"libafl_headers",
|
||||||
|
],
|
||||||
|
}*/
|
||||||
|
|
||||||
|
cc_library_shared {
|
||||||
|
name: "radamsa-mutator",
|
||||||
|
vendor_available: true,
|
||||||
|
host_supported: true,
|
||||||
|
|
||||||
|
cflags: [
|
||||||
|
"-g",
|
||||||
|
"-O0",
|
||||||
|
"-funroll-loops",
|
||||||
|
"-fPIC",
|
||||||
|
"-Wno-unused-parameter",
|
||||||
|
"-Wno-unused-function",
|
||||||
|
],
|
||||||
|
|
||||||
|
srcs: [
|
||||||
|
"radamsa/libradamsa.c",
|
||||||
|
"radamsa/radamsa-mutator.c",
|
||||||
|
],
|
||||||
|
|
||||||
|
header_libs: [
|
||||||
|
"libafl_headers",
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
cc_library_shared {
|
||||||
|
name: "symcc-mutator",
|
||||||
|
vendor_available: true,
|
||||||
|
host_supported: true,
|
||||||
|
|
||||||
|
cflags: [
|
||||||
|
"-g",
|
||||||
|
"-O0",
|
||||||
|
"-funroll-loops",
|
||||||
|
"-fPIC",
|
||||||
|
"-Wno-unused-parameter",
|
||||||
|
"-Wno-pointer-sign",
|
||||||
|
],
|
||||||
|
|
||||||
|
srcs: [
|
||||||
|
"symcc/symcc.c",
|
||||||
|
],
|
||||||
|
|
||||||
|
header_libs: [
|
||||||
|
"libafl_headers",
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
subdirs = [
|
||||||
|
"libprotobuf-mutator-example",
|
||||||
|
]
|
@ -0,0 +1,86 @@
|
|||||||
|
# Custom Mutators
|
||||||
|
|
||||||
|
Custom mutators enhance and alter the mutation strategies of AFL++.
|
||||||
|
For further information and documentation on how to write your own, read [the docs](../docs/custom_mutators.md).
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
The `./examples` folder contains examples for custom mutators in python and C.
|
||||||
|
|
||||||
|
## Rust
|
||||||
|
|
||||||
|
In `./rust`, you will find rust bindings, including a simple example in `./rust/example` and an example for structured fuzzing, based on lain, in`./rust/example_lain`.
|
||||||
|
|
||||||
|
## Production-Ready Custom Mutators
|
||||||
|
|
||||||
|
This directory holds ready to use custom mutators.
|
||||||
|
Just type "make" in the individual subdirectories.
|
||||||
|
|
||||||
|
Use with e.g.
|
||||||
|
|
||||||
|
`AFL_CUSTOM_MUTATOR_LIBRARY=custom_mutators/radamsa/radamsa-mutator.so afl-fuzz ....`
|
||||||
|
|
||||||
|
and add `AFL_CUSTOM_MUTATOR_ONLY=1` if you only want to use the custom mutator.
|
||||||
|
|
||||||
|
Multiple custom mutators can be used by separating their paths with `:` in the environment variable.
|
||||||
|
|
||||||
|
### The AFL++ grammar agnostic grammar mutator
|
||||||
|
|
||||||
|
In `./autotokens` you find a token-level fuzzer that does not need to know
|
||||||
|
anything about the grammar of an input as long as it is in ascii and allows
|
||||||
|
whitespace.
|
||||||
|
It is very fast and effective.
|
||||||
|
|
||||||
|
If you are looking for an example of how to effectively create a custom
|
||||||
|
mutator take a look at this one.
|
||||||
|
|
||||||
|
### The AFL++ Grammar Mutator
|
||||||
|
|
||||||
|
If you use git to clone AFL++, then the following will incorporate our
|
||||||
|
excellent grammar custom mutator:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
git submodule update --init
|
||||||
|
```
|
||||||
|
|
||||||
|
Read the README in the [Grammar-Mutator] repository on how to use it.
|
||||||
|
|
||||||
|
[Grammar-Mutator]: https://github.com/AFLplusplus/Grammar-Mutator
|
||||||
|
|
||||||
|
Note that this custom mutator is not very good though!
|
||||||
|
|
||||||
|
### Other Mutators
|
||||||
|
|
||||||
|
atnwalk and gramatron are grammar custom mutators. Example grammars are
|
||||||
|
provided.
|
||||||
|
|
||||||
|
honggfuzz, libfuzzer and libafl are partial implementations based on the
|
||||||
|
mutator implementations of the respective fuzzers.
|
||||||
|
More for playing than serious usage.
|
||||||
|
|
||||||
|
radamsa is slow and not very good.
|
||||||
|
|
||||||
|
## 3rd Party Custom Mutators
|
||||||
|
|
||||||
|
### Superion Mutators
|
||||||
|
|
||||||
|
Adrian Tiron ported the Superion grammar fuzzer to AFL++, it is WIP and
|
||||||
|
requires cmake (among other things):
|
||||||
|
[https://github.com/adrian-rt/superion-mutator](https://github.com/adrian-rt/superion-mutator)
|
||||||
|
|
||||||
|
### libprotobuf Mutators
|
||||||
|
|
||||||
|
There are three WIP protobuf projects, that require work to be working though:
|
||||||
|
|
||||||
|
ASN.1 example:
|
||||||
|
[https://github.com/airbus-seclab/AFLplusplus-blogpost/tree/main/src/mutator](https://github.com/airbus-seclab/AFLplusplus-blogpost/tree/main/src/mutator)
|
||||||
|
|
||||||
|
transforms protobuf raw:
|
||||||
|
[https://github.com/bruce30262/libprotobuf-mutator_fuzzing_learning/tree/master/4_libprotobuf_aflpp_custom_mutator](https://github.com/bruce30262/libprotobuf-mutator_fuzzing_learning/tree/master/4_libprotobuf_aflpp_custom_mutator)
|
||||||
|
|
||||||
|
has a transform function you need to fill for your protobuf format, however
|
||||||
|
needs to be ported to the updated AFL++ custom mutator API (not much work):
|
||||||
|
[https://github.com/thebabush/afl-libprotobuf-mutator](https://github.com/thebabush/afl-libprotobuf-mutator)
|
||||||
|
|
||||||
|
same as above but is for current AFL++:
|
||||||
|
[https://github.com/P1umer/AFLplusplus-protobuf-mutator](https://github.com/P1umer/AFLplusplus-protobuf-mutator)
|
@ -0,0 +1,10 @@
|
|||||||
|
|
||||||
|
CFLAGS = -O3 -funroll-loops -fPIC -Wl,-Bsymbolic
|
||||||
|
|
||||||
|
all: aflpp-mutator.so
|
||||||
|
|
||||||
|
aflpp-mutator.so: aflpp.c
|
||||||
|
$(CC) $(CFLAGS) -I../../include -I. -shared -o aflpp-mutator.so aflpp.c ../../src/afl-performance.c
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f *.o *~ *.so core
|
@ -0,0 +1,8 @@
|
|||||||
|
# custum mutator: AFL++
|
||||||
|
|
||||||
|
this is the AFL++ havoc mutator as a custom mutator module for AFL++.
|
||||||
|
|
||||||
|
just type `make` to build
|
||||||
|
|
||||||
|
```AFL_CUSTOM_MUTATOR_LIBRARY=custom_mutators/aflpp/aflpp-mutator.so afl-fuzz ...```
|
||||||
|
|
@ -0,0 +1,90 @@
|
|||||||
|
#include "afl-fuzz.h"
|
||||||
|
#include "afl-mutations.h"
|
||||||
|
|
||||||
|
typedef struct my_mutator {
|
||||||
|
|
||||||
|
afl_state_t *afl;
|
||||||
|
u8 *buf;
|
||||||
|
u32 buf_size;
|
||||||
|
|
||||||
|
} my_mutator_t;
|
||||||
|
|
||||||
|
my_mutator_t *afl_custom_init(afl_state_t *afl, unsigned int seed) {
|
||||||
|
|
||||||
|
(void)seed;
|
||||||
|
|
||||||
|
my_mutator_t *data = calloc(1, sizeof(my_mutator_t));
|
||||||
|
if (!data) {
|
||||||
|
|
||||||
|
perror("afl_custom_init alloc");
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((data->buf = malloc(MAX_FILE)) == NULL) {
|
||||||
|
|
||||||
|
perror("afl_custom_init alloc");
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
data->buf_size = MAX_FILE;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
data->afl = afl;
|
||||||
|
|
||||||
|
return data;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* here we run the AFL++ mutator, which is the best! */
|
||||||
|
|
||||||
|
size_t afl_custom_fuzz(my_mutator_t *data, uint8_t *buf, size_t buf_size,
|
||||||
|
u8 **out_buf, uint8_t *add_buf, size_t add_buf_size,
|
||||||
|
size_t max_size) {
|
||||||
|
|
||||||
|
if (max_size > data->buf_size) {
|
||||||
|
|
||||||
|
u8 *ptr = realloc(data->buf, max_size);
|
||||||
|
|
||||||
|
if (!ptr) {
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
data->buf = ptr;
|
||||||
|
data->buf_size = max_size;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 havoc_steps = 1 + rand_below(data->afl, 16);
|
||||||
|
|
||||||
|
/* set everything up, costly ... :( */
|
||||||
|
memcpy(data->buf, buf, buf_size);
|
||||||
|
|
||||||
|
/* the mutation */
|
||||||
|
u32 out_buf_len = afl_mutate(data->afl, data->buf, buf_size, havoc_steps,
|
||||||
|
false, true, add_buf, add_buf_size, max_size);
|
||||||
|
|
||||||
|
/* return size of mutated data */
|
||||||
|
*out_buf = data->buf;
|
||||||
|
return out_buf_len;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deinitialize everything
|
||||||
|
*
|
||||||
|
* @param data The data ptr from afl_custom_init
|
||||||
|
*/
|
||||||
|
void afl_custom_deinit(my_mutator_t *data) {
|
||||||
|
|
||||||
|
free(data->buf);
|
||||||
|
free(data);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,10 @@
|
|||||||
|
|
||||||
|
CFLAGS = -O3 -funroll-loops -fPIC
|
||||||
|
|
||||||
|
all: aflpp-standalone
|
||||||
|
|
||||||
|
aflpp-standalone: aflpp-standalone.c
|
||||||
|
$(CC) $(CFLAGS) -DBIN_PATH=\"foo\" -I../../../include -I. -o aflpp-standalone aflpp-standalone.c ../../../src/afl-performance.c ../../../src/afl-fuzz-extras.c ../../../src/afl-common.c
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f *.o *~ aflpp-standalone core
|
@ -0,0 +1,10 @@
|
|||||||
|
# AFL++ standalone mutator
|
||||||
|
|
||||||
|
this is the AFL++ havoc mutator as a standalone mutator
|
||||||
|
|
||||||
|
just type `make` to build.
|
||||||
|
|
||||||
|
```
|
||||||
|
aflpp-standalone -h # to see all parameteres
|
||||||
|
cat file | aflpp-standalone -m 4 -x foo.dict - outputfile splicefile # example
|
||||||
|
```
|
@ -0,0 +1,252 @@
|
|||||||
|
#include "afl-fuzz.h"
|
||||||
|
#include "afl-mutations.h"
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <getopt.h>
|
||||||
|
|
||||||
|
static int max_havoc = 16, verbose;
|
||||||
|
static unsigned char *dict;
|
||||||
|
|
||||||
|
typedef struct my_mutator {
|
||||||
|
|
||||||
|
afl_state_t *afl;
|
||||||
|
u8 *buf;
|
||||||
|
u32 buf_size;
|
||||||
|
|
||||||
|
} my_mutator_t;
|
||||||
|
|
||||||
|
my_mutator_t *afl_custom_init(afl_state_t *afl, unsigned int seed) {
|
||||||
|
|
||||||
|
(void)seed;
|
||||||
|
|
||||||
|
my_mutator_t *data = calloc(1, sizeof(my_mutator_t));
|
||||||
|
if (!data) {
|
||||||
|
|
||||||
|
perror("afl_custom_init alloc");
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((data->buf = malloc(1024 * 1024)) == NULL) {
|
||||||
|
|
||||||
|
perror("afl_custom_init alloc");
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
data->buf_size = 1024 * 1024;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* fake AFL++ state */
|
||||||
|
data->afl = calloc(1, sizeof(afl_state_t));
|
||||||
|
data->afl->queue_cycle = 1;
|
||||||
|
data->afl->fsrv.dev_urandom_fd = open("/dev/urandom", O_RDONLY);
|
||||||
|
if (data->afl->fsrv.dev_urandom_fd < 0) {
|
||||||
|
|
||||||
|
PFATAL("Unable to open /dev/urandom");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
rand_set_seed(data->afl, getpid());
|
||||||
|
|
||||||
|
if (dict) {
|
||||||
|
|
||||||
|
load_extras(data->afl, dict);
|
||||||
|
if (verbose)
|
||||||
|
fprintf(stderr, "Loaded dictionary: %s (%u entries)\n", dict,
|
||||||
|
data->afl->extras_cnt);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return data;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* here we run the AFL++ mutator, which is the best! */
|
||||||
|
|
||||||
|
size_t afl_custom_fuzz(my_mutator_t *data, uint8_t *buf, size_t buf_size,
|
||||||
|
u8 **out_buf, uint8_t *add_buf, size_t add_buf_size,
|
||||||
|
size_t max_size) {
|
||||||
|
|
||||||
|
if (max_size > data->buf_size) {
|
||||||
|
|
||||||
|
u8 *ptr = realloc(data->buf, max_size);
|
||||||
|
|
||||||
|
if (!ptr) {
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
data->buf = ptr;
|
||||||
|
data->buf_size = max_size;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 havoc_steps = 1 + rand_below(data->afl, max_havoc);
|
||||||
|
if (verbose) fprintf(stderr, "Havoc steps: %u\n", havoc_steps);
|
||||||
|
|
||||||
|
/* set everything up, costly ... :( */
|
||||||
|
memcpy(data->buf, buf, buf_size);
|
||||||
|
|
||||||
|
/* the mutation */
|
||||||
|
u32 out_buf_len;
|
||||||
|
do {
|
||||||
|
|
||||||
|
out_buf_len = afl_mutate(data->afl, data->buf, buf_size, havoc_steps, false,
|
||||||
|
true, add_buf, add_buf_size, max_size);
|
||||||
|
|
||||||
|
} while (out_buf_len == buf_size && memcmp(buf, data->buf, buf_size) == 0);
|
||||||
|
|
||||||
|
/* return size of mutated data */
|
||||||
|
*out_buf = data->buf;
|
||||||
|
return out_buf_len;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
|
||||||
|
if (argc > 1 && strncmp(argv[1], "-h", 2) == 0) {
|
||||||
|
|
||||||
|
printf(
|
||||||
|
"Syntax: %s [-v] [-m maxmutations] [-x dict] [inputfile [outputfile "
|
||||||
|
"[splicefile]]]\n\n",
|
||||||
|
argv[0]);
|
||||||
|
printf(
|
||||||
|
"Reads a testcase from stdin when no input file (or '-') is "
|
||||||
|
"specified,\n");
|
||||||
|
printf(
|
||||||
|
"mutates according to AFL++'s mutation engine, and write to stdout "
|
||||||
|
"when '-' or\n");
|
||||||
|
printf(
|
||||||
|
"no output filename is given. As an optional third parameter you can "
|
||||||
|
"give a file\n");
|
||||||
|
printf("for splicing. Maximum input and output length is 1MB.\n");
|
||||||
|
printf("Options:\n");
|
||||||
|
printf(" -v verbose debug output to stderr.\n");
|
||||||
|
printf(" -m val max mutations (1-val, val default is 16)\n");
|
||||||
|
printf(" -x file dictionary file (AFL++ format)\n");
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
FILE *in = stdin, *out = stdout, *splice = NULL;
|
||||||
|
unsigned char *inbuf = malloc(1024 * 1024), *outbuf = NULL, *splicebuf = NULL;
|
||||||
|
int splicelen = 0, opt;
|
||||||
|
|
||||||
|
while ((opt = getopt(argc, argv, "vm:x:")) > 0) {
|
||||||
|
|
||||||
|
switch (opt) {
|
||||||
|
|
||||||
|
case 'm':
|
||||||
|
max_havoc = atoi(optarg);
|
||||||
|
break;
|
||||||
|
case 'v':
|
||||||
|
verbose = 1;
|
||||||
|
break;
|
||||||
|
case 'x':
|
||||||
|
dict = optarg;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
fprintf(stderr, "Error: unknown parameter -%c\n", opt);
|
||||||
|
exit(-1);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (max_havoc < 1) {
|
||||||
|
|
||||||
|
fprintf(stderr, "Error: illegal -m value\n");
|
||||||
|
exit(-1);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
my_mutator_t *data = afl_custom_init(NULL, 0);
|
||||||
|
|
||||||
|
if (argc > optind && strcmp(argv[optind], "-") != 0) {
|
||||||
|
|
||||||
|
if ((in = fopen(argv[optind], "r")) == NULL) {
|
||||||
|
|
||||||
|
perror(argv[1]);
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (verbose) fprintf(stderr, "Input: %s\n", argv[optind]);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t inlen = fread(inbuf, 1, 1024 * 1024, in);
|
||||||
|
|
||||||
|
if (!inlen) {
|
||||||
|
|
||||||
|
fprintf(stderr, "Error: empty file %s\n",
|
||||||
|
argv[optind] ? argv[optind] : "stdin");
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (argc > optind + 1 && strcmp(argv[optind + 1], "-") != 0) {
|
||||||
|
|
||||||
|
if ((out = fopen(argv[optind + 1], "w")) == NULL) {
|
||||||
|
|
||||||
|
perror(argv[optind + 1]);
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (verbose) fprintf(stderr, "Output: %s\n", argv[optind + 1]);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (argc > optind + 2) {
|
||||||
|
|
||||||
|
if ((splice = fopen(argv[optind + 2], "r")) == NULL) {
|
||||||
|
|
||||||
|
perror(argv[optind + 2]);
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (verbose) fprintf(stderr, "Splice: %s\n", argv[optind + 2]);
|
||||||
|
splicebuf = malloc(1024 * 1024);
|
||||||
|
size_t splicelen = fread(splicebuf, 1, 1024 * 1024, splice);
|
||||||
|
if (!splicelen) {
|
||||||
|
|
||||||
|
fprintf(stderr, "Error: empty file %s\n", argv[optind + 2]);
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (verbose) fprintf(stderr, "Mutation splice length: %zu\n", splicelen);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (verbose) fprintf(stderr, "Mutation input length: %zu\n", inlen);
|
||||||
|
unsigned int outlen = afl_custom_fuzz(data, inbuf, inlen, &outbuf, splicebuf,
|
||||||
|
splicelen, 1024 * 1024);
|
||||||
|
|
||||||
|
if (outlen == 0 || !outbuf) {
|
||||||
|
|
||||||
|
fprintf(stderr, "Error: no mutation data returned.\n");
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (verbose) fprintf(stderr, "Mutation output length: %u\n", outlen);
|
||||||
|
|
||||||
|
if (fwrite(outbuf, 1, outlen, out) != outlen) {
|
||||||
|
|
||||||
|
fprintf(stderr, "Warning: incomplete write.\n");
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,22 @@
|
|||||||
|
# An AFL++ custom mutator using TritonDSE
|
||||||
|
|
||||||
|
## Installing the requirements
|
||||||
|
|
||||||
|
`pip3 install tritondse`
|
||||||
|
|
||||||
|
## How to run with an example
|
||||||
|
|
||||||
|
```
|
||||||
|
../../afl-cc -o ../../test-instr ../../test-instr.c
|
||||||
|
mkdir -p in
|
||||||
|
echo aaaa > in/in
|
||||||
|
AFL_DISABLE_TRIM=1 AFL_CUSTOM_MUTATOR_ONLY=1 AFL_SYNC_TIME=1 AFL_PYTHON_MODULE=aflpp_tritondse PYTHONPATH=. ../../afl-fuzz -i in -o out -- ../../test-instr
|
||||||
|
```
|
||||||
|
|
||||||
|
Note that this custom mutator works differently, new finds are synced
|
||||||
|
after 10-60 seconds to the fuzzing instance. This is necessary because only
|
||||||
|
C/C++ custom mutators have access to the internal AFL++ state.
|
||||||
|
|
||||||
|
Note that you should run first with `AFL_DEBUG` for 5-10 minutes and see if
|
||||||
|
all important libraries and syscalls are hooked (look at `WARNING` and `CRITICAL`
|
||||||
|
output during the run, best use with `AFL_NO_UI=1`)
|
@ -0,0 +1,220 @@
|
|||||||
|
import sys
|
||||||
|
import os
|
||||||
|
import logging
|
||||||
|
import hashlib
|
||||||
|
|
||||||
|
from tritondse import CleLoader
|
||||||
|
from tritondse import CompositeData
|
||||||
|
from tritondse import Config
|
||||||
|
from tritondse import CoverageStrategy
|
||||||
|
from tritondse import ProcessState
|
||||||
|
from tritondse import Program
|
||||||
|
from tritondse import Seed
|
||||||
|
from tritondse import SeedFormat
|
||||||
|
from tritondse import SymbolicExecutor
|
||||||
|
from tritondse import SymbolicExplorator
|
||||||
|
|
||||||
|
is_debug = False
|
||||||
|
out_path = ""
|
||||||
|
input_file = None
|
||||||
|
prog = None
|
||||||
|
config = None
|
||||||
|
dse = None
|
||||||
|
cycle = 0
|
||||||
|
count = 0
|
||||||
|
finding = 0
|
||||||
|
hashes = set()
|
||||||
|
format = SeedFormat.RAW
|
||||||
|
|
||||||
|
def pre_exec_hook(se: SymbolicExecutor, state: ProcessState):
|
||||||
|
global count
|
||||||
|
global hashes
|
||||||
|
global finding
|
||||||
|
if se.seed.hash not in hashes:
|
||||||
|
hashes.add(se.seed.hash)
|
||||||
|
finding = 1
|
||||||
|
filename = out_path + "/id:" + f"{count:06}" + "," + se.seed.hash
|
||||||
|
if not os.path.exists(filename):
|
||||||
|
if is_debug:
|
||||||
|
print('Creating queue input ' + filename)
|
||||||
|
with open(filename, 'wb') as file:
|
||||||
|
if input_file:
|
||||||
|
file.write(se.seed.content.files[input_file])
|
||||||
|
else:
|
||||||
|
file.write(se.seed.content)
|
||||||
|
count += 1
|
||||||
|
#if input_file:
|
||||||
|
# if is_debug:
|
||||||
|
# print('Writing to ' + input_file + ' the content: ' + str(se.seed.content))
|
||||||
|
# with open(input_file, 'wb') as file:
|
||||||
|
# file.write(se.seed.content)
|
||||||
|
|
||||||
|
|
||||||
|
#def rtn_open(se: SymbolicExecutor, pstate: ProcessState, pc):
|
||||||
|
# """
|
||||||
|
# The open behavior.
|
||||||
|
# """
|
||||||
|
# logging.debug('open hooked')
|
||||||
|
#
|
||||||
|
# # Get arguments
|
||||||
|
# arg0 = pstate.get_argument_value(0) # const char *pathname
|
||||||
|
# flags = pstate.get_argument_value(1) # int flags
|
||||||
|
# mode = pstate.get_argument_value(2) # int mode
|
||||||
|
# arg0s = pstate.memory.read_string(arg0)
|
||||||
|
#
|
||||||
|
# # Concretize the whole path name
|
||||||
|
# pstate.concretize_memory_bytes(arg0, len(arg0s)+1) # Concretize the whole string + \0
|
||||||
|
#
|
||||||
|
# # We use flags as concrete value
|
||||||
|
# pstate.concretize_argument(1)
|
||||||
|
#
|
||||||
|
# # Use the flags to open the file in the write mode.
|
||||||
|
# mode = ""
|
||||||
|
# if (flags & 0xFF) == 0x00: # O_RDONLY
|
||||||
|
# mode = "r"
|
||||||
|
# elif (flags & 0xFF) == 0x01: # O_WRONLY
|
||||||
|
# mode = "w"
|
||||||
|
# elif (flags & 0xFF) == 0x02: # O_RDWR
|
||||||
|
# mode = "r+"
|
||||||
|
#
|
||||||
|
# if (flags & 0x0100): # O_CREAT
|
||||||
|
# mode += "x"
|
||||||
|
# if (flags & 0x0200): # O_APPEND
|
||||||
|
# mode = "a" # replace completely value
|
||||||
|
#
|
||||||
|
# if se.seed.is_file_defined(arg0s) and "r" in mode: # input file and opened in reading
|
||||||
|
# logging.info(f"opening an input file: {arg0s}")
|
||||||
|
# # Program is opening an input
|
||||||
|
# data = se.seed.get_file_input(arg0s)
|
||||||
|
# filedesc = pstate.create_file_descriptor(arg0s, io.BytesIO(data))
|
||||||
|
# fd = filedesc.id
|
||||||
|
# else:
|
||||||
|
# # Try to open it as a regular file
|
||||||
|
# try:
|
||||||
|
# fd = open(arg0s, mode) # use the mode here
|
||||||
|
# filedesc = pstate.create_file_descriptor(arg0s, fd)
|
||||||
|
# fd = filedesc.id
|
||||||
|
# except Exception as e:
|
||||||
|
# logging.debug(f"Failed to open {arg0s} {e}")
|
||||||
|
# fd = pstate.minus_one
|
||||||
|
#
|
||||||
|
# pstate.write_register("rax", fd) # write the return value
|
||||||
|
# pstate.cpu.program_counter = pstate.pop_stack_value() # pop the return value
|
||||||
|
# se.skip_instruction() # skip the current instruction so that the engine go straight fetching the next instruction
|
||||||
|
|
||||||
|
|
||||||
|
def init(seed):
|
||||||
|
global config
|
||||||
|
global dse
|
||||||
|
global format
|
||||||
|
global input_file
|
||||||
|
global is_debug
|
||||||
|
global out_path
|
||||||
|
global prog
|
||||||
|
# Load the program (LIEF-based program loader).
|
||||||
|
prog = CleLoader(os.environ['AFL_CUSTOM_INFO_PROGRAM'])
|
||||||
|
# Process other configuration environment variables.
|
||||||
|
argv = None
|
||||||
|
try:
|
||||||
|
foo = os.environ['AFL_DEBUG']
|
||||||
|
is_debug = True
|
||||||
|
except KeyError:
|
||||||
|
pass
|
||||||
|
if is_debug:
|
||||||
|
logging.basicConfig(level=logging.WARNING)
|
||||||
|
else:
|
||||||
|
logging.basicConfig(level=logging.CRITICAL)
|
||||||
|
try:
|
||||||
|
foo = os.environ['AFL_CUSTOM_INFO_OUT']
|
||||||
|
out_path = foo + '/../tritondse/queue'
|
||||||
|
except KeyError:
|
||||||
|
pass
|
||||||
|
try:
|
||||||
|
foo = os.environ['AFL_CUSTOM_INFO_PROGRAM_INPUT']
|
||||||
|
input_file = foo
|
||||||
|
except KeyError:
|
||||||
|
pass
|
||||||
|
try:
|
||||||
|
argv_list = os.environ['AFL_CUSTOM_INFO_PROGRAM_ARGV']
|
||||||
|
argv_tmp = [ os.environ['AFL_CUSTOM_INFO_PROGRAM'] ]
|
||||||
|
argv_tmp += argv_list.split()
|
||||||
|
argv = []
|
||||||
|
# now check for @@
|
||||||
|
for item in argv_tmp:
|
||||||
|
if "@@" in item:
|
||||||
|
input_file = out_path + '/../.input'
|
||||||
|
argv.append(input_file)
|
||||||
|
else:
|
||||||
|
argv.append(item)
|
||||||
|
except KeyError:
|
||||||
|
pass
|
||||||
|
# Create the output directory
|
||||||
|
os.makedirs(out_path, exist_ok=True)
|
||||||
|
# Debug
|
||||||
|
if is_debug:
|
||||||
|
print('DEBUG target: ' + os.environ['AFL_CUSTOM_INFO_PROGRAM'])
|
||||||
|
if argv:
|
||||||
|
print('DEBUG argv: ')
|
||||||
|
print(argv)
|
||||||
|
if input_file:
|
||||||
|
print('DEBUG input_file: ' + input_file)
|
||||||
|
print('DEBUG out_path: ' + out_path)
|
||||||
|
print('')
|
||||||
|
if input_file:
|
||||||
|
format = SeedFormat.COMPOSITE
|
||||||
|
# Now set up TritonDSE
|
||||||
|
config = Config(coverage_strategy = CoverageStrategy.PATH,
|
||||||
|
# debug = is_debug,
|
||||||
|
pipe_stdout = is_debug,
|
||||||
|
pipe_stderr = is_debug,
|
||||||
|
execution_timeout = 1,
|
||||||
|
program_argv = argv,
|
||||||
|
smt_timeout= 50,
|
||||||
|
seed_format = format)
|
||||||
|
# Create an instance of the Symbolic Explorator
|
||||||
|
dse = SymbolicExplorator(config, prog)
|
||||||
|
# Add callbacks.
|
||||||
|
dse.callback_manager.register_pre_execution_callback(pre_exec_hook)
|
||||||
|
#dse.callback_manager.register_function_callback("open", rtn_open)
|
||||||
|
|
||||||
|
|
||||||
|
def fuzz(buf, add_buf, max_size):
|
||||||
|
global finding
|
||||||
|
finding = 1
|
||||||
|
while finding == 1:
|
||||||
|
finding = 0
|
||||||
|
dse.step()
|
||||||
|
return b""
|
||||||
|
|
||||||
|
|
||||||
|
def queue_new_entry(filename_new_queue, filename_orig_queue):
|
||||||
|
global cycle
|
||||||
|
global dse
|
||||||
|
# Add seed to the worklist.
|
||||||
|
with open(filename_new_queue, "rb") as file:
|
||||||
|
data = file.read()
|
||||||
|
hash = hashlib.md5(data).hexdigest()
|
||||||
|
if hash not in hashes:
|
||||||
|
hashes.add(hash)
|
||||||
|
if is_debug:
|
||||||
|
print("NEW FILE " + filename_new_queue + " hash " + hash + " count " + str(cycle))
|
||||||
|
cycle += 1
|
||||||
|
if input_file:
|
||||||
|
seed = Seed(CompositeData(files={"stdin": b"", # nothing on stdin
|
||||||
|
input_file: data}))
|
||||||
|
else:
|
||||||
|
seed = Seed(data)
|
||||||
|
dse.add_input_seed(seed)
|
||||||
|
# Start exploration!
|
||||||
|
#dse.step()
|
||||||
|
#dse.explore()
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
# we simulate just doing one single fuzz in the custom mutator
|
||||||
|
def fuzz_count(buf):
|
||||||
|
return 1
|
||||||
|
|
||||||
|
|
||||||
|
def splice_optout():
|
||||||
|
pass
|
@ -0,0 +1,7 @@
|
|||||||
|
all: atnwalk.so
|
||||||
|
|
||||||
|
atnwalk.so: atnwalk.c
|
||||||
|
$(CC) -I ../../include/ -shared -fPIC -O3 -o atnwalk.so atnwalk.c
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f *.so *.o *~ core
|
@ -0,0 +1,43 @@
|
|||||||
|
# ATNwalk: Grammar-Based Fuzzing using Only Bit-Mutations
|
||||||
|
|
||||||
|
This is a custom mutator integration of ATNwalk that works by communicating via UNIX domain sockets.
|
||||||
|
|
||||||
|
Refer to [https://github.com/atnwalk/testbed](https://github.com/atnwalk/testbed) for detailed instructions on how to get ATNwalk running.
|
||||||
|
|
||||||
|
## Build
|
||||||
|
|
||||||
|
Just type `make` to build `atnwalk.so`.
|
||||||
|
|
||||||
|
## Run
|
||||||
|
|
||||||
|
**NOTE:** The commands below just demonstrate an example how running ATNwalk looks like and require a working [testbed](https://github.com/atnwalk/testbed)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# create the required random seed first
|
||||||
|
mkdir -p ~/campaign/example/seeds
|
||||||
|
cd ~/campaign/example/seeds
|
||||||
|
head -c1 /dev/urandom | ~/atnwalk/build/javascript/bin/decode -wb > seed.decoded 2> seed.encoded
|
||||||
|
|
||||||
|
# create the required atnwalk directory and copy the seed
|
||||||
|
cd ../
|
||||||
|
mkdir -p atnwalk/in
|
||||||
|
cp ./seeds/seed.encoded atnwalk/in/seed
|
||||||
|
cd atnwalk
|
||||||
|
|
||||||
|
# assign to a single core when benchmarking it, change the CPU number as required
|
||||||
|
CPU_ID=0
|
||||||
|
|
||||||
|
# start the ATNwalk server
|
||||||
|
nohup taskset -c ${CPU_ID} ${HOME}/atnwalk/build/javascript/bin/server 100 > server.log 2>&1 &
|
||||||
|
|
||||||
|
# start AFL++ with ATNwalk
|
||||||
|
AFL_SKIP_CPUFREQ=1 \
|
||||||
|
AFL_DISABLE_TRIM=1 \
|
||||||
|
AFL_CUSTOM_MUTATOR_ONLY=1 \
|
||||||
|
AFL_CUSTOM_MUTATOR_LIBRARY=${HOME}/AFLplusplus/custom_mutators/atnwalk/atnwalk.so \
|
||||||
|
AFL_POST_PROCESS_KEEP_ORIGINAL=1 \
|
||||||
|
~/AFLplusplus/afl-fuzz -t 100 -i in/ -o out -b ${CPU_ID} -- ~/jerryscript/build/bin/jerry
|
||||||
|
|
||||||
|
# make sure to kill the ATNwalk server process after you're done
|
||||||
|
kill "$(cat atnwalk.pid)"
|
||||||
|
```
|
@ -0,0 +1,540 @@
|
|||||||
|
#include "afl-fuzz.h"
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/un.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#define BUF_SIZE_INIT 4096
|
||||||
|
#define SOCKET_NAME "./atnwalk.socket"
|
||||||
|
|
||||||
|
// how many errors (e.g. timeouts) to tolerate until moving on to the next queue
|
||||||
|
// entry
|
||||||
|
#define ATNWALK_ERRORS_MAX 1
|
||||||
|
|
||||||
|
// how many execution timeouts to tolerate until moving on to the next queue
|
||||||
|
// entry
|
||||||
|
#define EXEC_TIMEOUT_MAX 2
|
||||||
|
|
||||||
|
// handshake constants
|
||||||
|
const uint8_t SERVER_ARE_YOU_ALIVE = 213;
|
||||||
|
const uint8_t SERVER_YES_I_AM_ALIVE = 42;
|
||||||
|
|
||||||
|
// control bits
|
||||||
|
const uint8_t SERVER_CROSSOVER_BIT = 0b00000001;
|
||||||
|
const uint8_t SERVER_MUTATE_BIT = 0b00000010;
|
||||||
|
const uint8_t SERVER_DECODE_BIT = 0b00000100;
|
||||||
|
const uint8_t SERVER_ENCODE_BIT = 0b00001000;
|
||||||
|
|
||||||
|
typedef struct atnwalk_mutator {
|
||||||
|
|
||||||
|
afl_state_t *afl;
|
||||||
|
uint8_t atnwalk_error_count;
|
||||||
|
uint64_t prev_timeouts;
|
||||||
|
uint32_t prev_hits;
|
||||||
|
uint32_t stage_havoc_cur;
|
||||||
|
uint32_t stage_havoc_max;
|
||||||
|
uint32_t stage_splice_cur;
|
||||||
|
uint32_t stage_splice_max;
|
||||||
|
uint8_t *fuzz_buf;
|
||||||
|
size_t fuzz_size;
|
||||||
|
uint8_t *post_process_buf;
|
||||||
|
size_t post_process_size;
|
||||||
|
|
||||||
|
} atnwalk_mutator_t;
|
||||||
|
|
||||||
|
int read_all(int fd, uint8_t *buf, size_t buf_size) {
|
||||||
|
|
||||||
|
int n;
|
||||||
|
size_t offset = 0;
|
||||||
|
while (offset < buf_size) {
|
||||||
|
|
||||||
|
n = read(fd, buf + offset, buf_size - offset);
|
||||||
|
if (n == -1) { return 0; }
|
||||||
|
offset += n;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int write_all(int fd, uint8_t *buf, size_t buf_size) {
|
||||||
|
|
||||||
|
int n;
|
||||||
|
size_t offset = 0;
|
||||||
|
while (offset < buf_size) {
|
||||||
|
|
||||||
|
n = write(fd, buf + offset, buf_size - offset);
|
||||||
|
if (n == -1) { return 0; }
|
||||||
|
offset += n;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void put_uint32(uint8_t *buf, uint32_t val) {
|
||||||
|
|
||||||
|
buf[0] = (uint8_t)(val >> 24);
|
||||||
|
buf[1] = (uint8_t)((val & 0x00ff0000) >> 16);
|
||||||
|
buf[2] = (uint8_t)((val & 0x0000ff00) >> 8);
|
||||||
|
buf[3] = (uint8_t)(val & 0x000000ff);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t to_uint32(uint8_t *buf) {
|
||||||
|
|
||||||
|
uint32_t val = 0;
|
||||||
|
val |= (((uint32_t)buf[0]) << 24);
|
||||||
|
val |= (((uint32_t)buf[1]) << 16);
|
||||||
|
val |= (((uint32_t)buf[2]) << 8);
|
||||||
|
val |= ((uint32_t)buf[3]);
|
||||||
|
return val;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void put_uint64(uint8_t *buf, uint64_t val) {
|
||||||
|
|
||||||
|
buf[0] = (uint8_t)(val >> 56);
|
||||||
|
buf[1] = (uint8_t)((val & 0x00ff000000000000) >> 48);
|
||||||
|
buf[2] = (uint8_t)((val & 0x0000ff0000000000) >> 40);
|
||||||
|
buf[3] = (uint8_t)((val & 0x000000ff00000000) >> 32);
|
||||||
|
buf[4] = (uint8_t)((val & 0x00000000ff000000) >> 24);
|
||||||
|
buf[5] = (uint8_t)((val & 0x0000000000ff0000) >> 16);
|
||||||
|
buf[6] = (uint8_t)((val & 0x000000000000ff00) >> 8);
|
||||||
|
buf[7] = (uint8_t)(val & 0x00000000000000ff);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize this custom mutator
|
||||||
|
*
|
||||||
|
* @param[in] afl a pointer to the internal state object. Can be ignored for
|
||||||
|
* now.
|
||||||
|
* @param[in] seed A seed for this mutator - the same seed should always mutate
|
||||||
|
* in the same way.
|
||||||
|
* @return Pointer to the data object this custom mutator instance should use.
|
||||||
|
* There may be multiple instances of this mutator in one afl-fuzz run!
|
||||||
|
* Return NULL on error.
|
||||||
|
*/
|
||||||
|
atnwalk_mutator_t *afl_custom_init(afl_state_t *afl, unsigned int seed) {
|
||||||
|
|
||||||
|
srand(seed);
|
||||||
|
atnwalk_mutator_t *data =
|
||||||
|
(atnwalk_mutator_t *)malloc(sizeof(atnwalk_mutator_t));
|
||||||
|
if (!data) {
|
||||||
|
|
||||||
|
perror("afl_custom_init alloc");
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
data->afl = afl;
|
||||||
|
data->prev_hits = 0;
|
||||||
|
data->fuzz_buf = (uint8_t *)malloc(BUF_SIZE_INIT);
|
||||||
|
data->fuzz_size = BUF_SIZE_INIT;
|
||||||
|
data->post_process_buf = (uint8_t *)malloc(BUF_SIZE_INIT);
|
||||||
|
data->post_process_size = BUF_SIZE_INIT;
|
||||||
|
return data;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int afl_custom_fuzz_count(atnwalk_mutator_t *data,
|
||||||
|
const unsigned char *buf, size_t buf_size) {
|
||||||
|
|
||||||
|
// afl_custom_fuzz_count is called exactly once before entering the
|
||||||
|
// 'stage-loop' for the current queue entry thus, we use it to reset the error
|
||||||
|
// count and to initialize stage variables (somewhat not intended by the API,
|
||||||
|
// but still better than rewriting the whole thing to have a custom mutator
|
||||||
|
// stage)
|
||||||
|
data->atnwalk_error_count = 0;
|
||||||
|
data->prev_timeouts = data->afl->total_tmouts;
|
||||||
|
|
||||||
|
// it might happen that on the last execution of the splice stage a new path
|
||||||
|
// is found we need to fix that here and count it
|
||||||
|
if (data->prev_hits) {
|
||||||
|
|
||||||
|
data->afl->stage_finds[STAGE_SPLICE] +=
|
||||||
|
data->afl->queued_items + data->afl->saved_crashes - data->prev_hits;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
data->prev_hits = data->afl->queued_items + data->afl->saved_crashes;
|
||||||
|
data->stage_havoc_cur = 0;
|
||||||
|
data->stage_splice_cur = 0;
|
||||||
|
|
||||||
|
// 50% havoc, 50% splice
|
||||||
|
data->stage_havoc_max = data->afl->stage_max >> 1;
|
||||||
|
if (data->stage_havoc_max < HAVOC_MIN) { data->stage_havoc_max = HAVOC_MIN; }
|
||||||
|
data->stage_splice_max = data->stage_havoc_max;
|
||||||
|
return data->stage_havoc_max + data->stage_splice_max;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t fail_fatal(int fd_socket, uint8_t **out_buf) {
|
||||||
|
|
||||||
|
if (fd_socket != -1) { close(fd_socket); }
|
||||||
|
*out_buf = NULL;
|
||||||
|
fprintf(stderr, "atnwalk.socket not found in current directory!\n");
|
||||||
|
exit(-1);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t fail_gracefully(int fd_socket, atnwalk_mutator_t *data, uint8_t *buf,
|
||||||
|
size_t buf_size, uint8_t **out_buf) {
|
||||||
|
|
||||||
|
if (fd_socket != -1) { close(fd_socket); }
|
||||||
|
data->atnwalk_error_count++;
|
||||||
|
if (data->atnwalk_error_count > ATNWALK_ERRORS_MAX) {
|
||||||
|
|
||||||
|
data->afl->stage_max = data->afl->stage_cur;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
*out_buf = buf;
|
||||||
|
return buf_size;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Perform custom mutations on a given input
|
||||||
|
*
|
||||||
|
* (Optional for now. Required in the future)
|
||||||
|
*
|
||||||
|
* @param[in] data pointer returned in afl_custom_init for this fuzz case
|
||||||
|
* @param[in] buf Pointer to input data to be mutated
|
||||||
|
* @param[in] buf_size Size of input data
|
||||||
|
* @param[out] out_buf the buffer we will work on. we can reuse *buf. NULL on
|
||||||
|
* error.
|
||||||
|
* @param[in] add_buf Buffer containing the additional test case
|
||||||
|
* @param[in] add_buf_size Size of the additional test case
|
||||||
|
* @param[in] max_size Maximum size of the mutated output. The mutation must not
|
||||||
|
* produce data larger than max_size.
|
||||||
|
* @return Size of the mutated output.
|
||||||
|
*/
|
||||||
|
size_t afl_custom_fuzz(atnwalk_mutator_t *data, uint8_t *buf, size_t buf_size,
|
||||||
|
uint8_t **out_buf, uint8_t *add_buf, size_t add_buf_size,
|
||||||
|
size_t max_size) {
|
||||||
|
|
||||||
|
struct sockaddr_un addr;
|
||||||
|
int fd_socket;
|
||||||
|
uint8_t ctrl_buf[8];
|
||||||
|
uint8_t wanted;
|
||||||
|
|
||||||
|
// let's display what's going on in a nice way
|
||||||
|
if (data->stage_havoc_cur == 0) {
|
||||||
|
|
||||||
|
data->afl->stage_name = (uint8_t *)"atnwalk - havoc";
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data->stage_havoc_cur == data->stage_havoc_max) {
|
||||||
|
|
||||||
|
data->afl->stage_name = (uint8_t *)"atnwalk - splice";
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// increase the respective havoc or splice counters
|
||||||
|
if (data->stage_havoc_cur < data->stage_havoc_max) {
|
||||||
|
|
||||||
|
data->stage_havoc_cur++;
|
||||||
|
data->afl->stage_cycles[STAGE_HAVOC]++;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
// if there is nothing to splice, continue with havoc and skip splicing this
|
||||||
|
// time
|
||||||
|
if (data->afl->ready_for_splicing_count < 1) {
|
||||||
|
|
||||||
|
data->stage_havoc_max = data->afl->stage_max;
|
||||||
|
data->stage_havoc_cur++;
|
||||||
|
data->afl->stage_cycles[STAGE_HAVOC]++;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
data->stage_splice_cur++;
|
||||||
|
data->afl->stage_cycles[STAGE_SPLICE]++;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// keep track of found new corpus seeds per stage
|
||||||
|
if (data->afl->queued_items + data->afl->saved_crashes > data->prev_hits) {
|
||||||
|
|
||||||
|
if (data->stage_splice_cur <= 1) {
|
||||||
|
|
||||||
|
data->afl->stage_finds[STAGE_HAVOC] +=
|
||||||
|
data->afl->queued_items + data->afl->saved_crashes - data->prev_hits;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
data->afl->stage_finds[STAGE_SPLICE] +=
|
||||||
|
data->afl->queued_items + data->afl->saved_crashes - data->prev_hits;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
data->prev_hits = data->afl->queued_items + data->afl->saved_crashes;
|
||||||
|
|
||||||
|
// check whether this input produces a lot of timeouts, if it does then
|
||||||
|
// abandon this queue entry
|
||||||
|
if (data->afl->total_tmouts - data->prev_timeouts >= EXEC_TIMEOUT_MAX) {
|
||||||
|
|
||||||
|
data->afl->stage_max = data->afl->stage_cur;
|
||||||
|
return fail_gracefully(-1, data, buf, buf_size, out_buf);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// initialize the socket
|
||||||
|
fd_socket = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||||
|
if (fd_socket == -1) { return fail_fatal(fd_socket, out_buf); }
|
||||||
|
memset(&addr, 0, sizeof(addr));
|
||||||
|
addr.sun_family = AF_UNIX;
|
||||||
|
strncpy(addr.sun_path, SOCKET_NAME, sizeof(addr.sun_path) - 1);
|
||||||
|
if (connect(fd_socket, (const struct sockaddr *)&addr, sizeof(addr)) == -1) {
|
||||||
|
|
||||||
|
return fail_fatal(fd_socket, out_buf);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// ask whether the server is alive
|
||||||
|
ctrl_buf[0] = SERVER_ARE_YOU_ALIVE;
|
||||||
|
if (!write_all(fd_socket, ctrl_buf, 1)) {
|
||||||
|
|
||||||
|
return fail_fatal(fd_socket, out_buf);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// see whether the server replies as expected
|
||||||
|
if (!read_all(fd_socket, ctrl_buf, 1) ||
|
||||||
|
ctrl_buf[0] != SERVER_YES_I_AM_ALIVE) {
|
||||||
|
|
||||||
|
return fail_fatal(fd_socket, out_buf);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// tell the server what we want to do
|
||||||
|
wanted = SERVER_MUTATE_BIT | SERVER_ENCODE_BIT;
|
||||||
|
|
||||||
|
// perform a crossover if we are splicing
|
||||||
|
if (data->stage_splice_cur > 0) { wanted |= SERVER_CROSSOVER_BIT; }
|
||||||
|
|
||||||
|
// tell the server what we want and how much data will be sent
|
||||||
|
ctrl_buf[0] = wanted;
|
||||||
|
put_uint32(ctrl_buf + 1, (uint32_t)buf_size);
|
||||||
|
if (!write_all(fd_socket, ctrl_buf, 5)) {
|
||||||
|
|
||||||
|
return fail_fatal(fd_socket, out_buf);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// send the data to mutate and encode
|
||||||
|
if (!write_all(fd_socket, buf, buf_size)) {
|
||||||
|
|
||||||
|
return fail_gracefully(fd_socket, data, buf, buf_size, out_buf);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wanted & SERVER_CROSSOVER_BIT) {
|
||||||
|
|
||||||
|
// since we requested crossover, we will first tell how much additional data
|
||||||
|
// is to be expected
|
||||||
|
put_uint32(ctrl_buf, (uint32_t)add_buf_size);
|
||||||
|
if (!write_all(fd_socket, ctrl_buf, 4)) {
|
||||||
|
|
||||||
|
return fail_gracefully(fd_socket, data, buf, buf_size, out_buf);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// send the additional data for crossover
|
||||||
|
if (!write_all(fd_socket, add_buf, add_buf_size)) {
|
||||||
|
|
||||||
|
return fail_gracefully(fd_socket, data, buf, buf_size, out_buf);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// lastly, a seed is required for crossover so send one
|
||||||
|
put_uint64(ctrl_buf, (uint64_t)rand());
|
||||||
|
if (!write_all(fd_socket, ctrl_buf, 8)) {
|
||||||
|
|
||||||
|
return fail_gracefully(fd_socket, data, buf, buf_size, out_buf);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// since we requested mutation, we need to provide a seed for that
|
||||||
|
put_uint64(ctrl_buf, (uint64_t)rand());
|
||||||
|
if (!write_all(fd_socket, ctrl_buf, 8)) {
|
||||||
|
|
||||||
|
return fail_gracefully(fd_socket, data, buf, buf_size, out_buf);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// obtain the required buffer size for the data that will be returned
|
||||||
|
if (!read_all(fd_socket, ctrl_buf, 4)) {
|
||||||
|
|
||||||
|
return fail_gracefully(fd_socket, data, buf, buf_size, out_buf);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t new_size = (size_t)to_uint32(ctrl_buf);
|
||||||
|
|
||||||
|
// if the data is too large then we ignore this round
|
||||||
|
if (new_size > max_size) {
|
||||||
|
|
||||||
|
return fail_gracefully(fd_socket, data, buf, buf_size, out_buf);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (new_size > buf_size) {
|
||||||
|
|
||||||
|
// buf is too small, need to use data->fuzz_buf, let's see whether we need
|
||||||
|
// to reallocate
|
||||||
|
if (new_size > data->fuzz_size) {
|
||||||
|
|
||||||
|
data->fuzz_size = new_size << 1;
|
||||||
|
data->fuzz_buf = (uint8_t *)realloc(data->fuzz_buf, data->fuzz_size);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
*out_buf = data->fuzz_buf;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
// new_size fits into buf, so re-use it
|
||||||
|
*out_buf = buf;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// obtain the encoded data
|
||||||
|
if (!read_all(fd_socket, *out_buf, new_size)) {
|
||||||
|
|
||||||
|
return fail_gracefully(fd_socket, data, buf, buf_size, out_buf);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
close(fd_socket);
|
||||||
|
return new_size;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A post-processing function to use right before AFL writes the test case to
|
||||||
|
* disk in order to execute the target.
|
||||||
|
*
|
||||||
|
* (Optional) If this functionality is not needed, simply don't define this
|
||||||
|
* function.
|
||||||
|
*
|
||||||
|
* @param[in] data pointer returned in afl_custom_init for this fuzz case
|
||||||
|
* @param[in] buf Buffer containing the test case to be executed
|
||||||
|
* @param[in] buf_size Size of the test case
|
||||||
|
* @param[out] out_buf Pointer to the buffer containing the test case after
|
||||||
|
* processing. External library should allocate memory for out_buf.
|
||||||
|
* The buf pointer may be reused (up to the given buf_size);
|
||||||
|
* @return Size of the output buffer after processing or the needed amount.
|
||||||
|
* A return of 0 indicates an error.
|
||||||
|
*/
|
||||||
|
size_t afl_custom_post_process(atnwalk_mutator_t *data, uint8_t *buf,
|
||||||
|
size_t buf_size, uint8_t **out_buf) {
|
||||||
|
|
||||||
|
struct sockaddr_un addr;
|
||||||
|
int fd_socket;
|
||||||
|
uint8_t ctrl_buf[8];
|
||||||
|
|
||||||
|
// initialize the socket
|
||||||
|
fd_socket = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||||
|
if (fd_socket == -1) { return fail_fatal(fd_socket, out_buf); }
|
||||||
|
memset(&addr, 0, sizeof(addr));
|
||||||
|
addr.sun_family = AF_UNIX;
|
||||||
|
strncpy(addr.sun_path, SOCKET_NAME, sizeof(addr.sun_path) - 1);
|
||||||
|
if (connect(fd_socket, (const struct sockaddr *)&addr, sizeof(addr)) == -1) {
|
||||||
|
|
||||||
|
return fail_fatal(fd_socket, out_buf);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// ask whether the server is alive
|
||||||
|
ctrl_buf[0] = SERVER_ARE_YOU_ALIVE;
|
||||||
|
if (!write_all(fd_socket, ctrl_buf, 1)) {
|
||||||
|
|
||||||
|
return fail_fatal(fd_socket, out_buf);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// see whether the server replies as expected
|
||||||
|
if (!read_all(fd_socket, ctrl_buf, 1) ||
|
||||||
|
ctrl_buf[0] != SERVER_YES_I_AM_ALIVE) {
|
||||||
|
|
||||||
|
return fail_fatal(fd_socket, out_buf);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// tell the server what we want and how much data will be sent
|
||||||
|
ctrl_buf[0] = SERVER_DECODE_BIT;
|
||||||
|
put_uint32(ctrl_buf + 1, (uint32_t)buf_size);
|
||||||
|
if (!write_all(fd_socket, ctrl_buf, 5)) {
|
||||||
|
|
||||||
|
return fail_gracefully(fd_socket, data, buf, buf_size, out_buf);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// send the data to decode
|
||||||
|
if (!write_all(fd_socket, buf, buf_size)) {
|
||||||
|
|
||||||
|
return fail_gracefully(fd_socket, data, buf, buf_size, out_buf);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// obtain the required buffer size for the data that will be returned
|
||||||
|
if (!read_all(fd_socket, ctrl_buf, 4)) {
|
||||||
|
|
||||||
|
return fail_gracefully(fd_socket, data, buf, buf_size, out_buf);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t new_size = (size_t)to_uint32(ctrl_buf);
|
||||||
|
|
||||||
|
// need to use data->post_process_buf, let's see whether we need to reallocate
|
||||||
|
if (new_size > data->post_process_size) {
|
||||||
|
|
||||||
|
data->post_process_size = new_size << 1;
|
||||||
|
data->post_process_buf =
|
||||||
|
(uint8_t *)realloc(data->post_process_buf, data->post_process_size);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
*out_buf = data->post_process_buf;
|
||||||
|
|
||||||
|
// obtain the decoded data
|
||||||
|
if (!read_all(fd_socket, *out_buf, new_size)) {
|
||||||
|
|
||||||
|
return fail_gracefully(fd_socket, data, buf, buf_size, out_buf);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
close(fd_socket);
|
||||||
|
return new_size;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deinitialize everything
|
||||||
|
*
|
||||||
|
* @param data The data ptr from afl_custom_init
|
||||||
|
*/
|
||||||
|
void afl_custom_deinit(atnwalk_mutator_t *data) {
|
||||||
|
|
||||||
|
free(data->fuzz_buf);
|
||||||
|
free(data->post_process_buf);
|
||||||
|
free(data);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,26 @@
|
|||||||
|
ifdef debug
|
||||||
|
CPPLAGS += -fsanitize=address
|
||||||
|
CXXFLAGS += -Wall
|
||||||
|
CC := clang
|
||||||
|
CXX := clang++
|
||||||
|
endif
|
||||||
|
ifdef DEBUG
|
||||||
|
CPPFLAGS += -fsanitize=address
|
||||||
|
CXXFLAGS += -Wall
|
||||||
|
CC := clang
|
||||||
|
CXX := clang++
|
||||||
|
endif
|
||||||
|
|
||||||
|
all: autotokens.so
|
||||||
|
|
||||||
|
afl-fuzz-queue.o: ../../src/afl-fuzz-queue.c
|
||||||
|
$(CC) -D_STANDALONE_MODULE=1 -I../../include -g -O3 $(CPPFLAGS) -fPIC -c -o ./afl-fuzz-queue.o ../../src/afl-fuzz-queue.c
|
||||||
|
|
||||||
|
afl-common.o: ../../src/afl-common.c
|
||||||
|
$(CC) -I../../include -g -O3 $(CPPFLAGS) -DBIN_PATH=\"dummy\" -Wno-pointer-sign -fPIC -c -o ./afl-common.o ../../src/afl-common.c
|
||||||
|
|
||||||
|
autotokens.so: afl-fuzz-queue.o afl-common.o autotokens.cpp
|
||||||
|
$(CXX) -Wno-deprecated -g -O3 $(CXXFLAGS) $(CPPFLAGS) -shared -fPIC -o autotokens.so -I../../include autotokens.cpp ./afl-fuzz-queue.o ../../src/afl-performance.o ./afl-common.o
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f autotokens.so *.o *~ core
|
@ -0,0 +1,34 @@
|
|||||||
|
# Autotokens
|
||||||
|
|
||||||
|
This implements an improved autotoken grammar fuzzing idea presented in
|
||||||
|
[Token-Level Fuzzing][https://www.usenix.org/system/files/sec21-salls.pdf].
|
||||||
|
It is a grammar fuzzer without actually knowing the grammar, but only works
|
||||||
|
with text based inputs.
|
||||||
|
|
||||||
|
It is recommended to run with together in an instance with `CMPLOG`.
|
||||||
|
|
||||||
|
If you have a dictionary (`-x`) this improves this custom grammar mutator.
|
||||||
|
|
||||||
|
If **not** running with `CMPLOG`, it is possible to set
|
||||||
|
`AFL_CUSTOM_MUTATOR_ONLY` to concentrate on grammar bug classes.
|
||||||
|
|
||||||
|
Do **not** set `AFL_DISABLE_TRIM` with this custom mutator!
|
||||||
|
|
||||||
|
## Configuration via environment variables
|
||||||
|
|
||||||
|
`AUTOTOKENS_ONLY_FAV` - only use this mutator on favorite queue items
|
||||||
|
`AUTOTOKENS_COMMENT` - what character or string starts a comment which will be
|
||||||
|
removed. Default: `/* ... */`
|
||||||
|
`AUTOTOKENS_FUZZ_COUNT_SHIFT` - reduce the number of fuzzing performed, shifting
|
||||||
|
the value by this number, e.g. 1.
|
||||||
|
`AUTOTOKENS_AUTO_DISABLE` - disable this module if the seeds are not ascii
|
||||||
|
(or no input and no (ascii) dictionary)
|
||||||
|
`AUTOTOKENS_LEARN_DICT` - learn from dictionaries?
|
||||||
|
0 = none
|
||||||
|
1 = only -x or autodict
|
||||||
|
2 = -x, autodict and `CMPLOG`
|
||||||
|
`AUTOTOKENS_CHANGE_MIN` - minimum number of mutations (1-256, default 8)
|
||||||
|
`AUTOTOKENS_CHANGE_MAX` - maximum number of mutations (1-4096, default 64)
|
||||||
|
`AUTOTOKENS_CREATE_FROM_THIN_AIR` - if only one small start file is present and
|
||||||
|
a dictionary loaded then create one initial
|
||||||
|
structure based on the dictionary.
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,19 @@
|
|||||||
|
|
||||||
|
CFLAGS = -g -O3 -funroll-loops -fPIC -D_STANDALONE_MODULE=1 -Wno-implicit-function-declaration
|
||||||
|
CXXFLAGS= -g -O3 -funroll-loops -fPIC -D_STANDALONE_MODULE=1
|
||||||
|
|
||||||
|
all: autotokens-standalone
|
||||||
|
|
||||||
|
autotokens.o: ../autotokens.cpp
|
||||||
|
$(CXX) $(CXXFLAGS) -I../../../include -I. -I../.. -c ../autotokens.cpp
|
||||||
|
|
||||||
|
autotokens-standalone: autotokens-standalone.c autotokens.o
|
||||||
|
$(CC) $(CFLAGS) -DBIN_PATH=\"foo\" -I../../../include -I. -c autotokens-standalone.c
|
||||||
|
$(CC) $(CFLAGS) -DBIN_PATH=\"foo\" -I../../../include -I. -c ../../../src/afl-performance.c
|
||||||
|
$(CC) $(CFLAGS) -DBIN_PATH=\"foo\" -I../../../include -I. -c ../../../src/afl-fuzz-extras.c
|
||||||
|
$(CC) $(CFLAGS) -DBIN_PATH=\"foo\" -I../../../include -I. -c ../../../src/afl-fuzz-queue.c
|
||||||
|
$(CC) $(CFLAGS) -DBIN_PATH=\"foo\" -I../../../include -I. -c ../../../src/afl-common.c
|
||||||
|
$(CXX) $(CFLAGS) -DBIN_PATH=\"foo\" -I../../../include -I. -o autotokens-standalone *.o
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f *.o *~ autotokens-standalone core
|
@ -0,0 +1,12 @@
|
|||||||
|
# Autotokens standalone mutator
|
||||||
|
|
||||||
|
this is a standalone version of the AFL++ autotokens custom mutator.
|
||||||
|
|
||||||
|
just type `make` to build.
|
||||||
|
|
||||||
|
You *MUST* use a dictionary file to have an effective grammarless grammar fuzzer!
|
||||||
|
|
||||||
|
```
|
||||||
|
autotokens-standalone -h # to see all parameteres
|
||||||
|
autotokens-standalone -x foo.dict inputfile outputfile # example
|
||||||
|
```
|
@ -0,0 +1,192 @@
|
|||||||
|
#include "afl-fuzz.h"
|
||||||
|
#include "afl-mutations.h"
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <getopt.h>
|
||||||
|
|
||||||
|
static int max_havoc = 16, verbose;
|
||||||
|
static unsigned char *dict, *mh = "16";
|
||||||
|
|
||||||
|
extern int module_disabled;
|
||||||
|
|
||||||
|
void *afl_custom_init(afl_state_t *, unsigned int);
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
|
||||||
|
if (argc > 1 && strncmp(argv[1], "-h", 2) == 0) {
|
||||||
|
|
||||||
|
printf(
|
||||||
|
"Syntax: %s [-v] [-m maxmutations] [-x dict] [inputfile [outputfile "
|
||||||
|
"[splicefile]]]\n\n",
|
||||||
|
argv[0]);
|
||||||
|
printf("Reads a testcase from a file (not stdin!),\n");
|
||||||
|
printf("writes to stdout when '-' or\n");
|
||||||
|
printf(
|
||||||
|
"no output filename is given. As an optional third parameter you can "
|
||||||
|
"give a file\n");
|
||||||
|
printf("for splicing. Maximum input and output length is 1MB.\n");
|
||||||
|
printf("Options:\n");
|
||||||
|
printf(" -v verbose debug output to stderr.\n");
|
||||||
|
printf(" -m val max mutations (1-val, val default is 16)\n");
|
||||||
|
printf(" -x file dictionary file (AFL++ format)\n");
|
||||||
|
printf("You can set the following environment variable parameters:\n");
|
||||||
|
printf("AUTOTOKENS_COMMENT` - what character or string starts a comment which will be\n");
|
||||||
|
printf(" removed. Default: \"/* ... */\"\n");
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
FILE *in = stdin, *out = stdout, *splice = NULL;
|
||||||
|
unsigned char *inbuf = malloc(1024 * 1024), *outbuf = NULL, *splicebuf = NULL;
|
||||||
|
int splicelen = 0, opt;
|
||||||
|
|
||||||
|
while ((opt = getopt(argc, argv, "vm:x:")) > 0) {
|
||||||
|
|
||||||
|
switch (opt) {
|
||||||
|
|
||||||
|
case 'm':
|
||||||
|
max_havoc = atoi(optarg);
|
||||||
|
mh = optarg;
|
||||||
|
break;
|
||||||
|
case 'v':
|
||||||
|
verbose = 1;
|
||||||
|
break;
|
||||||
|
case 'x':
|
||||||
|
dict = optarg;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
fprintf(stderr, "Error: unknown parameter -%c\n", opt);
|
||||||
|
exit(-1);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (max_havoc < 1) {
|
||||||
|
|
||||||
|
fprintf(stderr, "Error: illegal -m value\n");
|
||||||
|
exit(-1);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (argc > optind && strcmp(argv[optind], "-") != 0) {
|
||||||
|
|
||||||
|
if ((in = fopen(argv[optind], "r")) == NULL) {
|
||||||
|
|
||||||
|
perror(argv[1]);
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (verbose) fprintf(stderr, "Input: %s\n", argv[optind]);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t inlen = fread(inbuf, 1, 1024 * 1024, in);
|
||||||
|
|
||||||
|
if (!inlen) {
|
||||||
|
|
||||||
|
fprintf(stderr, "Error: empty file %s\n",
|
||||||
|
argv[optind] ? argv[optind] : "stdin");
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (argc > optind + 1 && strcmp(argv[optind + 1], "-") != 0) {
|
||||||
|
|
||||||
|
if ((out = fopen(argv[optind + 1], "w")) == NULL) {
|
||||||
|
|
||||||
|
perror(argv[optind + 1]);
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (verbose) fprintf(stderr, "Output: %s\n", argv[optind + 1]);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (argc > optind + 2) {
|
||||||
|
|
||||||
|
if ((splice = fopen(argv[optind + 2], "r")) == NULL) {
|
||||||
|
|
||||||
|
perror(argv[optind + 2]);
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (verbose) fprintf(stderr, "Splice: %s\n", argv[optind + 2]);
|
||||||
|
splicebuf = malloc(1024 * 1024);
|
||||||
|
size_t splicelen = fread(splicebuf, 1, 1024 * 1024, splice);
|
||||||
|
if (!splicelen) {
|
||||||
|
|
||||||
|
fprintf(stderr, "Error: empty file %s\n", argv[optind + 2]);
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (verbose) fprintf(stderr, "Mutation splice length: %zu\n", splicelen);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* configure autotokens */
|
||||||
|
setenv("AUTOTOKENS_LEARN_DICT", "1", 0);
|
||||||
|
setenv("AUTOTOKENS_CREATE_FROM_THIN_AIR", "1", 0);
|
||||||
|
setenv("AUTOTOKENS_CHANGE_MAX", mh, 0);
|
||||||
|
|
||||||
|
/* fake AFL++ state */
|
||||||
|
afl_state_t *afl = (afl_state_t *)calloc(1, sizeof(afl_state_t));
|
||||||
|
afl->queue_cycle = afl->havoc_div = afl->active_items = afl->queued_items = 1;
|
||||||
|
afl->shm.cmplog_mode = 0;
|
||||||
|
afl->fsrv.dev_urandom_fd = open("/dev/urandom", O_RDONLY);
|
||||||
|
if (afl->fsrv.dev_urandom_fd < 0) { PFATAL("Unable to open /dev/urandom"); }
|
||||||
|
|
||||||
|
rand_set_seed(afl, getpid());
|
||||||
|
|
||||||
|
if (dict) {
|
||||||
|
|
||||||
|
load_extras(afl, dict);
|
||||||
|
if (verbose)
|
||||||
|
fprintf(stderr, "Loaded dictionary: %s (%u entries)\n", dict,
|
||||||
|
afl->extras_cnt);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// setup a fake queue entry
|
||||||
|
afl->queue_buf = malloc(64);
|
||||||
|
afl->queue_buf[0] = afl->queue_cur =
|
||||||
|
(struct queue_entry *)malloc(sizeof(struct queue_entry));
|
||||||
|
afl->queue_cur->testcase_buf = inbuf;
|
||||||
|
afl->queue_cur->fname = (u8 *)argv[optind];
|
||||||
|
afl->queue_cur->len = inlen;
|
||||||
|
afl->queue_cur->perf_score = 100;
|
||||||
|
afl->queue_cur->favored = afl->queue_cur->is_ascii = 1;
|
||||||
|
// afl->custom_only = 1;
|
||||||
|
|
||||||
|
void *data = (void *)afl_custom_init(afl, (u32)0);
|
||||||
|
|
||||||
|
u8 res = afl_custom_queue_get(inbuf, (u8 *)argv[optind]);
|
||||||
|
|
||||||
|
if (verbose) fprintf(stderr, "Mutation input length: %zu\n", inlen);
|
||||||
|
unsigned int outlen = afl_custom_fuzz(data, inbuf, inlen, &outbuf, splicebuf,
|
||||||
|
splicelen, 1024 * 1024);
|
||||||
|
|
||||||
|
if (outlen == 0 || !outbuf) {
|
||||||
|
|
||||||
|
fprintf(stderr, "Error: no mutation data returned.\n");
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (verbose) fprintf(stderr, "Mutation output length: %u\n", outlen);
|
||||||
|
|
||||||
|
if (fwrite(outbuf, 1, outlen, out) != outlen) {
|
||||||
|
|
||||||
|
fprintf(stderr, "Warning: incomplete write.\n");
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,7 @@
|
|||||||
|
all: custom_send_tcp.so
|
||||||
|
|
||||||
|
custom_send_tcp.so:
|
||||||
|
$(CC) -Wno-unused-result -g -O3 -shared -fPIC -o custom_send_tcp.so -I../../include custom_send_tcp.c
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f custom_send_tcp.so *.o *~ core
|
@ -0,0 +1,13 @@
|
|||||||
|
# Send testcases via TCP custom mutator
|
||||||
|
|
||||||
|
This custom mutator sends the fuzzing testcases via TCP.
|
||||||
|
|
||||||
|
`AFL_CUSTOM_MUTATOR_LATE_SEND` - MUST be set!
|
||||||
|
`CUSTOM_SEND_IP` - the IP address to send to (basically only 127.0.0.1 makes sense)
|
||||||
|
`CUSTOM_SEND_PORT` - the TCP port to send to
|
||||||
|
`CUSTOM_SEND_READ` - if the custom mutator should wait for a reply from the target
|
||||||
|
|
||||||
|
Example:
|
||||||
|
```
|
||||||
|
CUSTOM_SEND_IP=127.0.0.1 CUSTOM_SEND_PORT=8000 CUSTOM_SEND_READ=1 AFL_CUSTOM_MUTATOR_LATE_SEND=1 AFL_CUSTOM_MUTATOR_LIBRARY=custom_send_tcp.so ./afl-fuzz ...
|
||||||
|
```
|
@ -0,0 +1,113 @@
|
|||||||
|
#include <time.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <sys/select.h>
|
||||||
|
|
||||||
|
#include "afl-fuzz.h"
|
||||||
|
|
||||||
|
static int my_debug = 0;
|
||||||
|
static int my_read = 0;
|
||||||
|
|
||||||
|
#define DEBUG(...) if (my_debug) printf(__VA_ARGS__)
|
||||||
|
|
||||||
|
typedef struct tcp_send_mutator {
|
||||||
|
afl_state_t* afl;
|
||||||
|
struct sockaddr_in server_addr;
|
||||||
|
} tcp_send_mutator_t;
|
||||||
|
|
||||||
|
void *afl_custom_init(afl_state_t* afl, uint32_t seed) {
|
||||||
|
const char* ip = getenv("CUSTOM_SEND_IP");
|
||||||
|
const char* port = getenv("CUSTOM_SEND_PORT");
|
||||||
|
|
||||||
|
if (getenv("AFL_DEBUG")) my_debug = 1;
|
||||||
|
if (getenv("CUSTOM_SEND_READ")) my_read = 1;
|
||||||
|
|
||||||
|
if (!ip || !port) {
|
||||||
|
fprintf(stderr, "You forgot to set CUSTOM_SEND_IP and/or CUSTOM_SEND_PORT\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
tcp_send_mutator_t* mutator = calloc(1, sizeof(tcp_send_mutator_t));
|
||||||
|
if (!mutator) {
|
||||||
|
fprintf(stderr, "Failed to allocate mutator struct\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
mutator->afl = afl;
|
||||||
|
|
||||||
|
bzero(&mutator->server_addr, sizeof(mutator->server_addr));
|
||||||
|
mutator->server_addr.sin_family = AF_INET;
|
||||||
|
if (inet_pton(AF_INET, ip, &mutator->server_addr.sin_addr) <= 0) {
|
||||||
|
fprintf(stderr, "Could not convert target ip address!\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
mutator->server_addr.sin_port = htons(atoi(port));
|
||||||
|
|
||||||
|
printf("[+] Custom tcp send mutator setup ready to go!\n");
|
||||||
|
|
||||||
|
return mutator;
|
||||||
|
}
|
||||||
|
|
||||||
|
int try_connect(tcp_send_mutator_t *mutator, int sock, int max_attempts) {
|
||||||
|
while (max_attempts > 0) {
|
||||||
|
if (connect(sock, (struct sockaddr*)&mutator->server_addr, sizeof(mutator->server_addr)) == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Even with AFL_CUSTOM_LATE_SEND=1, there is a race between the
|
||||||
|
// application under test having started to listen for connections and
|
||||||
|
// afl_custom_fuzz_send being called. To address this race, we attempt
|
||||||
|
// to connect N times and sleep a short period of time in between
|
||||||
|
// connection attempts.
|
||||||
|
struct timespec t;
|
||||||
|
t.tv_sec = 0;
|
||||||
|
t.tv_nsec = 100;
|
||||||
|
nanosleep(&t, NULL);
|
||||||
|
--max_attempts;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void afl_custom_fuzz_send(tcp_send_mutator_t *mutator, uint8_t *buf, size_t buf_size) {
|
||||||
|
int sock = socket(AF_INET, SOCK_STREAM, 0);
|
||||||
|
|
||||||
|
int written = 0;
|
||||||
|
if (sock >= 0 && try_connect(mutator, sock, 10000) == 0) {
|
||||||
|
DEBUG("connected, write()\n");
|
||||||
|
written = write(sock, buf, buf_size);
|
||||||
|
} else {
|
||||||
|
DEBUG("socket() or connect() error: %d\n", errno);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (written < 0) {
|
||||||
|
DEBUG("write() error: %d\n", errno);
|
||||||
|
} else if (my_read) {
|
||||||
|
struct timeval timeout;
|
||||||
|
timeout.tv_sec = 1;
|
||||||
|
timeout.tv_usec = 0;
|
||||||
|
|
||||||
|
fd_set set;
|
||||||
|
FD_ZERO(&set);
|
||||||
|
FD_SET(sock, &set);
|
||||||
|
|
||||||
|
int select_res = select(sock + 1, &set, NULL, NULL, &timeout);
|
||||||
|
if (select_res == -1) {
|
||||||
|
DEBUG("select() error: %d\n", errno);
|
||||||
|
} else if (select_res == 0) {
|
||||||
|
DEBUG("read() timeout!\n");
|
||||||
|
} else {
|
||||||
|
uint8_t buf[64];
|
||||||
|
(void)read(sock, buf, sizeof(buf));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
close(sock);
|
||||||
|
}
|
||||||
|
|
||||||
|
void afl_custom_deinit(tcp_send_mutator_t* mutator) {
|
||||||
|
free(mutator);
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
all: libexamplemutator.so
|
||||||
|
|
||||||
|
libexamplemutator.so:
|
||||||
|
$(CC) $(CFLAGS) -D_FORTIFY_SOURCE=2 -O3 -fPIC -shared -g -I ../../include example.c -o libexamplemutator.so
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -rf libexamplemutator.so
|
@ -0,0 +1,38 @@
|
|||||||
|
# Examples for the custom mutator
|
||||||
|
|
||||||
|
These are example and helper files for the custom mutator feature.
|
||||||
|
See [docs/custom_mutators.md](../../docs/custom_mutators.md) for more information
|
||||||
|
|
||||||
|
Note that if you compile with python3.7 you must use python3 scripts, and if
|
||||||
|
you use python2.7 to compile python2 scripts!
|
||||||
|
|
||||||
|
simple_example.c - most simplest example. generates a random sized buffer
|
||||||
|
filled with 'A'
|
||||||
|
|
||||||
|
example.c - this is a simple example written in C and should be compiled to a
|
||||||
|
shared library. Use make to compile it and produce libexamplemutator.so
|
||||||
|
|
||||||
|
example.py - this is the template you can use, the functions are there but they
|
||||||
|
are empty
|
||||||
|
|
||||||
|
post_library_gif.so.c - fix a fuzz input to ensure it is valid for GIF
|
||||||
|
|
||||||
|
post_library_png.so.c - fix a fuzz input to ensure it is valid for PNG
|
||||||
|
|
||||||
|
simple-chunk-replace.py - this is a simple example where chunks are replaced
|
||||||
|
|
||||||
|
common.py - this can be used for common functions and helpers.
|
||||||
|
the examples do not use this though. But you can :)
|
||||||
|
|
||||||
|
wrapper_afl_min.py - mutation of XML documents, loads XmlMutatorMin.py
|
||||||
|
|
||||||
|
XmlMutatorMin.py - module for XML mutation
|
||||||
|
|
||||||
|
custom_mutator_helpers.h is an header that defines some helper routines
|
||||||
|
like surgical_havoc_mutate() that allow to perform a randomly chosen
|
||||||
|
mutation from a subset of the havoc mutations.
|
||||||
|
If you do so, you have to specify -I /path/to/AFLplusplus/include when
|
||||||
|
compiling.
|
||||||
|
|
||||||
|
elf_header_mutator.c - example ELF header mutator based on
|
||||||
|
[LibGolf](https://github.com/xcellerator/libgolf/)
|
@ -0,0 +1,348 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
""" Mutation of XML documents, should be called from one of its wrappers (CLI, AFL, ...) """
|
||||||
|
|
||||||
|
from __future__ import print_function
|
||||||
|
from copy import deepcopy
|
||||||
|
from lxml import etree as ET
|
||||||
|
import random, re, io
|
||||||
|
|
||||||
|
|
||||||
|
###########################
|
||||||
|
# The XmlMutatorMin class #
|
||||||
|
###########################
|
||||||
|
|
||||||
|
|
||||||
|
class XmlMutatorMin:
|
||||||
|
|
||||||
|
"""
|
||||||
|
Optionals parameters:
|
||||||
|
seed Seed used by the PRNG (default: "RANDOM")
|
||||||
|
verbose Verbosity (default: False)
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, seed="RANDOM", verbose=False):
|
||||||
|
|
||||||
|
""" Initialize seed, database and mutators """
|
||||||
|
|
||||||
|
# Verbosity
|
||||||
|
self.verbose = verbose
|
||||||
|
|
||||||
|
# Initialize PRNG
|
||||||
|
self.seed = str(seed)
|
||||||
|
if self.seed == "RANDOM":
|
||||||
|
random.seed()
|
||||||
|
else:
|
||||||
|
if self.verbose:
|
||||||
|
print("Static seed '%s'" % self.seed)
|
||||||
|
random.seed(self.seed)
|
||||||
|
|
||||||
|
# Initialize input and output documents
|
||||||
|
self.input_tree = None
|
||||||
|
self.tree = None
|
||||||
|
|
||||||
|
# High-level mutators (no database needed)
|
||||||
|
hl_mutators_delete = [
|
||||||
|
"del_node_and_children",
|
||||||
|
"del_node_but_children",
|
||||||
|
"del_attribute",
|
||||||
|
"del_content",
|
||||||
|
] # Delete items
|
||||||
|
hl_mutators_fuzz = ["fuzz_attribute"] # Randomly change attribute values
|
||||||
|
|
||||||
|
# Exposed mutators
|
||||||
|
self.hl_mutators_all = hl_mutators_fuzz + hl_mutators_delete
|
||||||
|
|
||||||
|
def __parse_xml(self, xml):
|
||||||
|
|
||||||
|
""" Parse an XML string. Basic wrapper around lxml.parse() """
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Function parse() takes care of comments / DTD / processing instructions / ...
|
||||||
|
tree = ET.parse(io.BytesIO(xml))
|
||||||
|
except ET.ParseError:
|
||||||
|
raise RuntimeError("XML isn't well-formed!")
|
||||||
|
except LookupError as e:
|
||||||
|
raise RuntimeError(e)
|
||||||
|
|
||||||
|
# Return a document wrapper
|
||||||
|
return tree
|
||||||
|
|
||||||
|
def __exec_among(self, module, functions, min_times, max_times):
|
||||||
|
|
||||||
|
""" Randomly execute $functions between $min and $max times """
|
||||||
|
|
||||||
|
for i in xrange(random.randint(min_times, max_times)):
|
||||||
|
# Function names are mangled because they are "private"
|
||||||
|
getattr(module, "_XmlMutatorMin__" + random.choice(functions))()
|
||||||
|
|
||||||
|
def __serialize_xml(self, tree):
|
||||||
|
|
||||||
|
""" Serialize a XML document. Basic wrapper around lxml.tostring() """
|
||||||
|
|
||||||
|
return ET.tostring(
|
||||||
|
tree, with_tail=False, xml_declaration=True, encoding=tree.docinfo.encoding
|
||||||
|
)
|
||||||
|
|
||||||
|
def __ver(self, version):
|
||||||
|
|
||||||
|
""" Helper for displaying lxml version numbers """
|
||||||
|
|
||||||
|
return ".".join(map(str, version))
|
||||||
|
|
||||||
|
def reset(self):
|
||||||
|
|
||||||
|
""" Reset the mutator """
|
||||||
|
|
||||||
|
self.tree = deepcopy(self.input_tree)
|
||||||
|
|
||||||
|
def init_from_string(self, input_string):
|
||||||
|
|
||||||
|
""" Initialize the mutator from a XML string """
|
||||||
|
|
||||||
|
# Get a pointer to the top-element
|
||||||
|
self.input_tree = self.__parse_xml(input_string)
|
||||||
|
|
||||||
|
# Get a working copy
|
||||||
|
self.tree = deepcopy(self.input_tree)
|
||||||
|
|
||||||
|
def save_to_string(self):
|
||||||
|
|
||||||
|
""" Return the current XML document as UTF-8 string """
|
||||||
|
|
||||||
|
# Return a text version of the tree
|
||||||
|
return self.__serialize_xml(self.tree)
|
||||||
|
|
||||||
|
def __pick_element(self, exclude_root_node=False):
|
||||||
|
|
||||||
|
""" Pick a random element from the current document """
|
||||||
|
|
||||||
|
# Get a list of all elements, but nodes like PI and comments
|
||||||
|
elems = list(self.tree.getroot().iter(tag=ET.Element))
|
||||||
|
|
||||||
|
# Is the root node excluded?
|
||||||
|
if exclude_root_node:
|
||||||
|
start = 1
|
||||||
|
else:
|
||||||
|
start = 0
|
||||||
|
|
||||||
|
# Pick a random element
|
||||||
|
try:
|
||||||
|
elem_id = random.randint(start, len(elems) - 1)
|
||||||
|
elem = elems[elem_id]
|
||||||
|
except ValueError:
|
||||||
|
# Should only occurs if "exclude_root_node = True"
|
||||||
|
return (None, None)
|
||||||
|
|
||||||
|
return (elem_id, elem)
|
||||||
|
|
||||||
|
def __fuzz_attribute(self):
|
||||||
|
|
||||||
|
""" Fuzz (part of) an attribute value """
|
||||||
|
|
||||||
|
# Select a node to modify
|
||||||
|
(rand_elem_id, rand_elem) = self.__pick_element()
|
||||||
|
|
||||||
|
# Get all the attributes
|
||||||
|
attribs = rand_elem.keys()
|
||||||
|
|
||||||
|
# Is there attributes?
|
||||||
|
if len(attribs) < 1:
|
||||||
|
if self.verbose:
|
||||||
|
print("No attribute: can't replace!")
|
||||||
|
return
|
||||||
|
|
||||||
|
# Pick a random attribute
|
||||||
|
rand_attrib_id = random.randint(0, len(attribs) - 1)
|
||||||
|
rand_attrib = attribs[rand_attrib_id]
|
||||||
|
|
||||||
|
# We have the attribute to modify
|
||||||
|
# Get its value
|
||||||
|
attrib_value = rand_elem.get(rand_attrib)
|
||||||
|
# print("- Value: " + attrib_value)
|
||||||
|
|
||||||
|
# Should we work on the whole value?
|
||||||
|
func_call = "(?P<func>[a-zA-Z:\-]+)\((?P<args>.*?)\)"
|
||||||
|
p = re.compile(func_call)
|
||||||
|
l = p.findall(attrib_value)
|
||||||
|
if random.choice((True, False)) and l:
|
||||||
|
# Randomly pick one the function calls
|
||||||
|
(func, args) = random.choice(l)
|
||||||
|
# Split by "," and randomly pick one of the arguments
|
||||||
|
value = random.choice(args.split(","))
|
||||||
|
# Remove superfluous characters
|
||||||
|
unclean_value = value
|
||||||
|
value = value.strip(" ").strip("'")
|
||||||
|
# print("Selected argument: [%s]" % value)
|
||||||
|
else:
|
||||||
|
value = attrib_value
|
||||||
|
|
||||||
|
# For each type, define some possible replacement values
|
||||||
|
choices_number = (
|
||||||
|
"0",
|
||||||
|
"11111",
|
||||||
|
"-128",
|
||||||
|
"2",
|
||||||
|
"-1",
|
||||||
|
"1/3",
|
||||||
|
"42/0",
|
||||||
|
"1094861636 idiv 1.0",
|
||||||
|
"-1123329771506872 idiv 3.8",
|
||||||
|
"17=$numericRTF",
|
||||||
|
str(3 + random.randrange(0, 100)),
|
||||||
|
)
|
||||||
|
|
||||||
|
choices_letter = (
|
||||||
|
"P" * (25 * random.randrange(1, 100)),
|
||||||
|
"%s%s%s%s%s%s",
|
||||||
|
"foobar",
|
||||||
|
)
|
||||||
|
|
||||||
|
choices_alnum = (
|
||||||
|
"Abc123",
|
||||||
|
"020F0302020204030204",
|
||||||
|
"020F0302020204030204" * (random.randrange(5, 20)),
|
||||||
|
)
|
||||||
|
|
||||||
|
# Fuzz the value
|
||||||
|
if random.choice((True, False)) and value == "":
|
||||||
|
|
||||||
|
# Empty
|
||||||
|
new_value = value
|
||||||
|
|
||||||
|
elif random.choice((True, False)) and value.isdigit():
|
||||||
|
|
||||||
|
# Numbers
|
||||||
|
new_value = random.choice(choices_number)
|
||||||
|
|
||||||
|
elif random.choice((True, False)) and value.isalpha():
|
||||||
|
|
||||||
|
# Letters
|
||||||
|
new_value = random.choice(choices_letter)
|
||||||
|
|
||||||
|
elif random.choice((True, False)) and value.isalnum():
|
||||||
|
|
||||||
|
# Alphanumeric
|
||||||
|
new_value = random.choice(choices_alnum)
|
||||||
|
|
||||||
|
else:
|
||||||
|
|
||||||
|
# Default type
|
||||||
|
new_value = random.choice(choices_alnum + choices_letter + choices_number)
|
||||||
|
|
||||||
|
# If we worked on a substring, apply changes to the whole string
|
||||||
|
if value != attrib_value:
|
||||||
|
# No ' around empty values
|
||||||
|
if new_value != "" and value != "":
|
||||||
|
new_value = "'" + new_value + "'"
|
||||||
|
# Apply changes
|
||||||
|
new_value = attrib_value.replace(unclean_value, new_value)
|
||||||
|
|
||||||
|
# Log something
|
||||||
|
if self.verbose:
|
||||||
|
print(
|
||||||
|
"Fuzzing attribute #%i '%s' of tag #%i '%s'"
|
||||||
|
% (rand_attrib_id, rand_attrib, rand_elem_id, rand_elem.tag)
|
||||||
|
)
|
||||||
|
|
||||||
|
# Modify the attribute
|
||||||
|
rand_elem.set(rand_attrib, new_value.decode("utf-8"))
|
||||||
|
|
||||||
|
def __del_node_and_children(self):
|
||||||
|
|
||||||
|
"""High-level minimizing mutator
|
||||||
|
Delete a random node and its children (i.e. delete a random tree)"""
|
||||||
|
|
||||||
|
self.__del_node(True)
|
||||||
|
|
||||||
|
def __del_node_but_children(self):
|
||||||
|
|
||||||
|
"""High-level minimizing mutator
|
||||||
|
Delete a random node but its children (i.e. link them to the parent of the deleted node)"""
|
||||||
|
|
||||||
|
self.__del_node(False)
|
||||||
|
|
||||||
|
def __del_node(self, delete_children):
|
||||||
|
|
||||||
|
""" Called by the __del_node_* mutators """
|
||||||
|
|
||||||
|
# Select a node to modify (but the root one)
|
||||||
|
(rand_elem_id, rand_elem) = self.__pick_element(exclude_root_node=True)
|
||||||
|
|
||||||
|
# If the document includes only a top-level element
|
||||||
|
# Then we can't pick a element (given that "exclude_root_node = True")
|
||||||
|
|
||||||
|
# Is the document deep enough?
|
||||||
|
if rand_elem is None:
|
||||||
|
if self.verbose:
|
||||||
|
print("Can't delete a node: document not deep enough!")
|
||||||
|
return
|
||||||
|
|
||||||
|
# Log something
|
||||||
|
if self.verbose:
|
||||||
|
but_or_and = "and" if delete_children else "but"
|
||||||
|
print(
|
||||||
|
"Deleting tag #%i '%s' %s its children"
|
||||||
|
% (rand_elem_id, rand_elem.tag, but_or_and)
|
||||||
|
)
|
||||||
|
|
||||||
|
if delete_children is False:
|
||||||
|
# Link children of the random (soon to be deleted) node to its parent
|
||||||
|
for child in rand_elem:
|
||||||
|
rand_elem.getparent().append(child)
|
||||||
|
|
||||||
|
# Remove the node
|
||||||
|
rand_elem.getparent().remove(rand_elem)
|
||||||
|
|
||||||
|
def __del_content(self):
|
||||||
|
|
||||||
|
"""High-level minimizing mutator
|
||||||
|
Delete the attributes and children of a random node"""
|
||||||
|
|
||||||
|
# Select a node to modify
|
||||||
|
(rand_elem_id, rand_elem) = self.__pick_element()
|
||||||
|
|
||||||
|
# Log something
|
||||||
|
if self.verbose:
|
||||||
|
print("Reseting tag #%i '%s'" % (rand_elem_id, rand_elem.tag))
|
||||||
|
|
||||||
|
# Reset the node
|
||||||
|
rand_elem.clear()
|
||||||
|
|
||||||
|
def __del_attribute(self):
|
||||||
|
|
||||||
|
"""High-level minimizing mutator
|
||||||
|
Delete a random attribute from a random node"""
|
||||||
|
|
||||||
|
# Select a node to modify
|
||||||
|
(rand_elem_id, rand_elem) = self.__pick_element()
|
||||||
|
|
||||||
|
# Get all the attributes
|
||||||
|
attribs = rand_elem.keys()
|
||||||
|
|
||||||
|
# Is there attributes?
|
||||||
|
if len(attribs) < 1:
|
||||||
|
if self.verbose:
|
||||||
|
print("No attribute: can't delete!")
|
||||||
|
return
|
||||||
|
|
||||||
|
# Pick a random attribute
|
||||||
|
rand_attrib_id = random.randint(0, len(attribs) - 1)
|
||||||
|
rand_attrib = attribs[rand_attrib_id]
|
||||||
|
|
||||||
|
# Log something
|
||||||
|
if self.verbose:
|
||||||
|
print(
|
||||||
|
"Deleting attribute #%i '%s' of tag #%i '%s'"
|
||||||
|
% (rand_attrib_id, rand_attrib, rand_elem_id, rand_elem.tag)
|
||||||
|
)
|
||||||
|
|
||||||
|
# Delete the attribute
|
||||||
|
rand_elem.attrib.pop(rand_attrib)
|
||||||
|
|
||||||
|
def mutate(self, min=1, max=5):
|
||||||
|
|
||||||
|
""" Execute some high-level mutators between $min and $max times, then some medium-level ones """
|
||||||
|
|
||||||
|
# High-level mutation
|
||||||
|
self.__exec_among(self, self.hl_mutators_all, min, max)
|
@ -0,0 +1,40 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
# encoding: utf-8
|
||||||
|
"""
|
||||||
|
Module containing functions shared between multiple AFL modules
|
||||||
|
|
||||||
|
@author: Christian Holler (:decoder)
|
||||||
|
|
||||||
|
@license:
|
||||||
|
|
||||||
|
This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
|
||||||
|
@contact: choller@mozilla.com
|
||||||
|
"""
|
||||||
|
|
||||||
|
from __future__ import print_function
|
||||||
|
import random
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
|
||||||
|
|
||||||
|
def randel(l):
|
||||||
|
if not l:
|
||||||
|
return None
|
||||||
|
return l[random.randint(0, len(l) - 1)]
|
||||||
|
|
||||||
|
|
||||||
|
def randel_pop(l):
|
||||||
|
if not l:
|
||||||
|
return None
|
||||||
|
return l.pop(random.randint(0, len(l) - 1))
|
||||||
|
|
||||||
|
|
||||||
|
def write_exc_example(data, exc):
|
||||||
|
exc_name = re.sub(r"[^a-zA-Z0-9]", "_", repr(exc))
|
||||||
|
|
||||||
|
if not os.path.exists(exc_name):
|
||||||
|
with open(exc_name, "w") as f:
|
||||||
|
f.write(data)
|
@ -0,0 +1,53 @@
|
|||||||
|
//
|
||||||
|
// This is an example on how to use afl_custom_post_run
|
||||||
|
// It executes custom code each time after AFL++ executes the target
|
||||||
|
//
|
||||||
|
// cc -O3 -fPIC -shared -g -o custom_post_run.so -I../../include custom_post_run.c
|
||||||
|
// cd ../..
|
||||||
|
// afl-cc -o test-instr test-instr.c
|
||||||
|
// AFL_CUSTOM_MUTATOR_LIBRARY=custom_mutators/examples/custom_post_run.so \
|
||||||
|
// afl-fuzz -i in -o out -- ./test-instr -f /tmp/foo
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
#include "afl-fuzz.h"
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
typedef struct my_mutator {
|
||||||
|
|
||||||
|
afl_state_t *afl;
|
||||||
|
|
||||||
|
} my_mutator_t;
|
||||||
|
|
||||||
|
my_mutator_t *afl_custom_init(afl_state_t *afl, unsigned int seed) {
|
||||||
|
|
||||||
|
my_mutator_t *data = calloc(1, sizeof(my_mutator_t));
|
||||||
|
if (!data) {
|
||||||
|
|
||||||
|
perror("afl_custom_init alloc");
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
data->afl = afl;
|
||||||
|
|
||||||
|
return data;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void afl_custom_post_run(my_mutator_t *data) {
|
||||||
|
|
||||||
|
printf("hello from afl_custom_post_run\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void afl_custom_deinit(my_mutator_t *data) {
|
||||||
|
|
||||||
|
free(data);
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,63 @@
|
|||||||
|
//
|
||||||
|
// This is an example on how to use afl_custom_send
|
||||||
|
// It writes each mutated data set to /tmp/foo
|
||||||
|
// You can modify this to send to IPC, shared memory, etc.
|
||||||
|
//
|
||||||
|
// cc -O3 -fPIC -shared -g -o custom_send.so -I../../include custom_send.c
|
||||||
|
// cd ../..
|
||||||
|
// afl-cc -o test-instr test-instr.c
|
||||||
|
// AFL_CUSTOM_MUTATOR_LIBRARY=custom_mutators/examples/custom_send.so \
|
||||||
|
// afl-fuzz -i in -o out -- ./test-instr -f /tmp/foo
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
|
||||||
|
#include "afl-fuzz.h"
|
||||||
|
|
||||||
|
typedef struct my_mutator {
|
||||||
|
|
||||||
|
afl_state_t *afl;
|
||||||
|
|
||||||
|
} my_mutator_t;
|
||||||
|
|
||||||
|
my_mutator_t *afl_custom_init(afl_state_t *afl, unsigned int seed) {
|
||||||
|
|
||||||
|
my_mutator_t *data = calloc(1, sizeof(my_mutator_t));
|
||||||
|
if (!data) {
|
||||||
|
|
||||||
|
perror("afl_custom_init alloc");
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
data->afl = afl;
|
||||||
|
|
||||||
|
return data;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void afl_custom_fuzz_send(my_mutator_t *data, uint8_t *buf, size_t buf_size) {
|
||||||
|
|
||||||
|
int fd = open("/tmp/foo", O_CREAT | O_NOFOLLOW | O_TRUNC | O_RDWR, 0644);
|
||||||
|
|
||||||
|
if (fd >= 0) {
|
||||||
|
|
||||||
|
(void)write(fd, buf, buf_size);
|
||||||
|
close(fd);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void afl_custom_deinit(my_mutator_t *data) {
|
||||||
|
|
||||||
|
free(data);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,679 @@
|
|||||||
|
/*
|
||||||
|
AFL++ Custom Mutator for ELF Headers
|
||||||
|
Written by @echel0n <melih.sahin@protonmail.com>
|
||||||
|
based on libgolf.h by @xcellerator
|
||||||
|
$ gcc -O3 -fPIC -shared -o elf_mutator.so -I ~/AFLplusplus/include/
|
||||||
|
*/
|
||||||
|
#include "afl-fuzz.h"
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <linux/elf.h>
|
||||||
|
|
||||||
|
/* EI_ABIVERSION isn't used anymore and elf.h defines EI_PAD to be 0x09 */
|
||||||
|
#define EI_ABIVERSION 0x08
|
||||||
|
#define EI_PAD 0x09
|
||||||
|
/* Define the Architecture and ISA constants to match those in <linux/elf.h> */
|
||||||
|
#define X86_64 EM_X86_64
|
||||||
|
#define ARM32 EM_ARM
|
||||||
|
#define AARCH64 EM_AARCH64
|
||||||
|
#define uchar unsigned char
|
||||||
|
#define DATA_SIZE 0x100
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The ELF and Program headers are different sizes depending on 32- and 64-bit
|
||||||
|
* architectures
|
||||||
|
* taken from libgolf.h
|
||||||
|
*/
|
||||||
|
#define EHDR_T(x) Elf##x##_Ehdr
|
||||||
|
#define PHDR_T(x) Elf##x##_Phdr
|
||||||
|
#define EHDR(x) ehdr##x
|
||||||
|
#define PHDR(x) phdr##x
|
||||||
|
#define GET_EHDR(x) (&(elf_ptr->EHDR(x)));
|
||||||
|
#define GET_PHDR(x) (&(elf_ptr->PHDR(x)));
|
||||||
|
#define REF_EHDR(b, x) ((Elf##b##_Ehdr *)ehdr)->x
|
||||||
|
#define REF_PHDR(b, x) ((Elf##b##_Phdr *)phdr)->x
|
||||||
|
int ehdr_size;
|
||||||
|
int phdr_size;
|
||||||
|
/*
|
||||||
|
* This struct holds the bytes that will be executed, and the size.
|
||||||
|
*/
|
||||||
|
typedef struct text_segment {
|
||||||
|
|
||||||
|
size_t text_size;
|
||||||
|
unsigned char *text_segment;
|
||||||
|
|
||||||
|
} TextSegment;
|
||||||
|
|
||||||
|
// example shellcode that exits
|
||||||
|
// taken from libgolf.h
|
||||||
|
unsigned char buf[] = {0xb0, 0x3c, 0x31, 0xff, 0x0f, 0x05};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is the raw ELF file
|
||||||
|
* - EHDR(xx) is the ELF header
|
||||||
|
* - PHDR(xx) is the program header
|
||||||
|
* - text is the text segment
|
||||||
|
* - filename is the name of the golf'd binary
|
||||||
|
* - isa is the target architecture (X86_64, ARM32, AARCH64)
|
||||||
|
* taken from libgolf.h
|
||||||
|
*/
|
||||||
|
typedef struct rawbinary_t {
|
||||||
|
|
||||||
|
EHDR_T(32) EHDR(32);
|
||||||
|
PHDR_T(32) PHDR(32);
|
||||||
|
EHDR_T(64) EHDR(64);
|
||||||
|
PHDR_T(64) PHDR(64);
|
||||||
|
TextSegment text;
|
||||||
|
char *filename;
|
||||||
|
int isa;
|
||||||
|
|
||||||
|
} RawBinary;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copy an E_IDENT array into the corresponding fields in the ELF header
|
||||||
|
* Called by populate_ehdr()
|
||||||
|
* taken from libgolf.h
|
||||||
|
*/
|
||||||
|
int populate_e_ident(RawBinary *elf_ptr, unsigned char e_ident[]) {
|
||||||
|
|
||||||
|
int i;
|
||||||
|
/* Depending on whether the target ISA is 32- or 64-bit, set e_ident */
|
||||||
|
switch (elf_ptr->isa) {
|
||||||
|
|
||||||
|
case X86_64:
|
||||||
|
case AARCH64:
|
||||||
|
for (i = 0; i < EI_NIDENT; i++)
|
||||||
|
elf_ptr->EHDR(64).e_ident[i] = e_ident[i];
|
||||||
|
break;
|
||||||
|
case ARM32:
|
||||||
|
for (i = 0; i < EI_NIDENT; i++)
|
||||||
|
elf_ptr->EHDR(32).e_ident[i] = e_ident[i];
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
exit(1);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copy bytes from buf[] array into text_segment in ELF struct
|
||||||
|
* taken from libgolf.h
|
||||||
|
*/
|
||||||
|
int copy_text_segment(RawBinary *elf_ptr, unsigned char buf[], int text_size) {
|
||||||
|
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* Set size of text segment and allocate the buffer */
|
||||||
|
elf_ptr->text.text_size = text_size;
|
||||||
|
elf_ptr->text.text_segment =
|
||||||
|
malloc(elf_ptr->text.text_size * sizeof(unsigned char));
|
||||||
|
|
||||||
|
/* Copy the bytes into the text segment buffer */
|
||||||
|
for (i = 0; i < elf_ptr->text.text_size; i++) {
|
||||||
|
|
||||||
|
elf_ptr->text.text_segment[i] = buf[i];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Populate the ELF Header with sane values
|
||||||
|
* Returns a pointer to an EHDR struct
|
||||||
|
* taken from libgolf.h
|
||||||
|
*/
|
||||||
|
void *populate_ehdr(RawBinary *elf_ptr) {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set ehdr_size and phdr_size. Determined by whether target ISA is 32- or
|
||||||
|
* 64-bit.
|
||||||
|
*/
|
||||||
|
switch (elf_ptr->isa) {
|
||||||
|
|
||||||
|
case X86_64:
|
||||||
|
case AARCH64:
|
||||||
|
ehdr_size = sizeof(EHDR_T(64));
|
||||||
|
phdr_size = sizeof(PHDR_T(64));
|
||||||
|
break;
|
||||||
|
case ARM32:
|
||||||
|
ehdr_size = sizeof(EHDR_T(32));
|
||||||
|
phdr_size = sizeof(PHDR_T(32));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
exit(1);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Start with the E_IDENT area at the top of the file */
|
||||||
|
unsigned char e_ident[EI_NIDENT] = {0};
|
||||||
|
|
||||||
|
/* Magic Bytes */
|
||||||
|
e_ident[EI_MAG0] = 0x7F;
|
||||||
|
e_ident[EI_MAG1] = 0x45; // E
|
||||||
|
e_ident[EI_MAG2] = 0x4C; // L
|
||||||
|
e_ident[EI_MAG3] = 0x46; // F
|
||||||
|
|
||||||
|
/*
|
||||||
|
* EI_CLASS denotes the architecture:
|
||||||
|
* ELFCLASS32: 0x01
|
||||||
|
* ELFCLASS64: 0x02
|
||||||
|
*/
|
||||||
|
switch (elf_ptr->isa) {
|
||||||
|
|
||||||
|
case X86_64:
|
||||||
|
case AARCH64:
|
||||||
|
e_ident[EI_CLASS] = ELFCLASS64;
|
||||||
|
break;
|
||||||
|
case ARM32:
|
||||||
|
e_ident[EI_CLASS] = ELFCLASS32;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
exit(1);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* EI_DATA denotes the endianness:
|
||||||
|
* ELFDATA2LSB: 0x01
|
||||||
|
* ELFDATA2MSB: 0x02
|
||||||
|
*/
|
||||||
|
e_ident[EI_DATA] = ELFDATA2LSB;
|
||||||
|
|
||||||
|
/* EI_VERSION is always 0x01 */
|
||||||
|
e_ident[EI_VERSION] = EV_CURRENT;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* EI_OSABI defines the target OS. Ignored by most modern ELF parsers.
|
||||||
|
*/
|
||||||
|
e_ident[EI_OSABI] = ELFOSABI_NONE;
|
||||||
|
|
||||||
|
/* EI_ABIVERSION was for sub-classification. Un-defined since Linux 2.6 */
|
||||||
|
e_ident[EI_ABIVERSION] = 0x00;
|
||||||
|
|
||||||
|
/* EI_PAD is currently unused */
|
||||||
|
e_ident[EI_PAD] = 0x00;
|
||||||
|
|
||||||
|
/* Copy the E_IDENT section to the ELF struct */
|
||||||
|
populate_e_ident(elf_ptr, e_ident);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The remainder of the ELF header following E_IDENT follows.
|
||||||
|
*
|
||||||
|
* ehdr is a pointer to either an Elf32_Edhr, or Elf64_Ehdr struct.
|
||||||
|
*/
|
||||||
|
void *ehdr = NULL;
|
||||||
|
switch (elf_ptr->isa) {
|
||||||
|
|
||||||
|
case X86_64:
|
||||||
|
case AARCH64:
|
||||||
|
ehdr = (&(elf_ptr->EHDR(64)));
|
||||||
|
break;
|
||||||
|
case ARM32:
|
||||||
|
ehdr = (&(elf_ptr->EHDR(32)));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
exit(1);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Depending on whether the ISA is 32- or 64-bit determines the size of
|
||||||
|
* many of the fields in the ELF Header. This switch case deals with it.
|
||||||
|
*/
|
||||||
|
switch (elf_ptr->isa) {
|
||||||
|
|
||||||
|
// 64-Bit ISAs
|
||||||
|
case X86_64:
|
||||||
|
case AARCH64:
|
||||||
|
/*
|
||||||
|
* e_type specifies what kind of ELF file this is:
|
||||||
|
* ET_NONE: 0x00 // Unknown Type
|
||||||
|
* ET_REL: 0x01 // Relocatable
|
||||||
|
* ET_EXEC: 0x02 // Executable File
|
||||||
|
* ET_DYN: 0x03 // Shared Object
|
||||||
|
* ET_CORE: 0x04 // Core Dump
|
||||||
|
*/
|
||||||
|
REF_EHDR(64, e_type) = ET_EXEC; // 0x0002
|
||||||
|
|
||||||
|
/* e_machine specifies the target ISA */
|
||||||
|
REF_EHDR(64, e_machine) = elf_ptr->isa;
|
||||||
|
|
||||||
|
/* e_version is always set of 0x01 for the original ELF spec */
|
||||||
|
REF_EHDR(64, e_version) = EV_CURRENT; // 0x00000001
|
||||||
|
|
||||||
|
/*
|
||||||
|
* e_entry is the memory address of the entry point
|
||||||
|
* Set by set_entry_point() after p_vaddr is set in the phdr
|
||||||
|
*/
|
||||||
|
REF_EHDR(64, e_entry) = 0x0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* e_phoff points to the start of the program header, which
|
||||||
|
* immediately follows the ELF header
|
||||||
|
*/
|
||||||
|
REF_EHDR(64, e_phoff) = ehdr_size;
|
||||||
|
|
||||||
|
/* e_shoff points to the start of the section header table */
|
||||||
|
REF_EHDR(64, e_shoff) = 0x00;
|
||||||
|
|
||||||
|
/* e_flags is architecture dependent */
|
||||||
|
REF_EHDR(64, e_flags) = 0x0;
|
||||||
|
|
||||||
|
/* e_ehsize contains the size of the ELF header */
|
||||||
|
REF_EHDR(64, e_ehsize) = ehdr_size;
|
||||||
|
|
||||||
|
/* e_phentsize is the size of the program header */
|
||||||
|
REF_EHDR(64, e_phentsize) = phdr_size;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* e_phnum contains the number of entries in the program header
|
||||||
|
* e_phnum * e_phentsize = size of program header table
|
||||||
|
*/
|
||||||
|
REF_EHDR(64, e_phnum) = 0x1;
|
||||||
|
|
||||||
|
/* e_shentsize contains the size of a section header entry */
|
||||||
|
REF_EHDR(64, e_shentsize) = 0x0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* e_shnum contains the number of entries in the section header
|
||||||
|
* e_shnum * e_shentsize = size of section header table
|
||||||
|
*/
|
||||||
|
REF_EHDR(64, e_shnum) = 0x0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* e_shstrndx contains the index of the section header table that
|
||||||
|
* contains the section names
|
||||||
|
*/
|
||||||
|
REF_EHDR(64, e_shstrndx) = 0x0;
|
||||||
|
|
||||||
|
break;
|
||||||
|
// 32-Bit ISAs
|
||||||
|
case ARM32:
|
||||||
|
/*
|
||||||
|
* e_type specifies what kind of ELF file this is:
|
||||||
|
* ET_NONE: 0x00 // Unknown Type
|
||||||
|
* ET_REL: 0x01 // Relocatable
|
||||||
|
* ET_EXEC: 0x02 // Executable File
|
||||||
|
* ET_DYN: 0x03 // Shared Object
|
||||||
|
* ET_CORE: 0x04 // Core Dump
|
||||||
|
*/
|
||||||
|
REF_EHDR(32, e_type) = ET_EXEC; // 0x0002
|
||||||
|
|
||||||
|
/* e_machine specifies the target ISA */
|
||||||
|
REF_EHDR(32, e_machine) = elf_ptr->isa;
|
||||||
|
|
||||||
|
/* e_version is always set of 0x01 for the original ELF spec */
|
||||||
|
REF_EHDR(32, e_version) = EV_CURRENT; // 0x00000001
|
||||||
|
|
||||||
|
/*
|
||||||
|
* e_entry is the memory address of the entry point
|
||||||
|
* Set by set_entry_point() after p_vaddr is set in the phdr
|
||||||
|
*/
|
||||||
|
REF_EHDR(32, e_entry) = 0x0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* e_phoff points to the start of the program header, which
|
||||||
|
* immediately follows the ELF header
|
||||||
|
*/
|
||||||
|
REF_EHDR(32, e_phoff) = ehdr_size;
|
||||||
|
|
||||||
|
/* e_shoff points to the start of the section header table */
|
||||||
|
REF_EHDR(32, e_shoff) = 0x0i;
|
||||||
|
|
||||||
|
/* e_flags is architecture dependent */
|
||||||
|
REF_EHDR(32, e_flags) = 0x0;
|
||||||
|
|
||||||
|
/* e_ehsize contains the size of the ELF header */
|
||||||
|
REF_EHDR(32, e_ehsize) = ehdr_size;
|
||||||
|
|
||||||
|
/* e_phentsize is the size of the program header */
|
||||||
|
REF_EHDR(32, e_phentsize) = phdr_size;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* e_phnum contains the number of entries in the program header
|
||||||
|
* e_phnum * e_phentsize = size of program header table
|
||||||
|
*/
|
||||||
|
REF_EHDR(32, e_phnum) = 0x1;
|
||||||
|
|
||||||
|
/* e_shentsize contains the size of a section header entry */
|
||||||
|
REF_EHDR(32, e_shentsize) = 0x0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* e_shnum contains the number of entries in the section header
|
||||||
|
* e_shnum * e_shentsize = size of section header table
|
||||||
|
*/
|
||||||
|
REF_EHDR(32, e_shnum) = 0x0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* e_shstrndx contains the index of the section header table that
|
||||||
|
* contains the section names
|
||||||
|
*/
|
||||||
|
REF_EHDR(32, e_shnum) = 0x0;
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return ehdr;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Populate the program headers with sane values
|
||||||
|
* Returns a pointer to a PHDR struct
|
||||||
|
* taken from libgolf.h
|
||||||
|
*/
|
||||||
|
void *populate_phdr(RawBinary *elf_ptr) {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* All offsets are relative to the start of the program header (0x40)
|
||||||
|
*
|
||||||
|
* phdr is a pointer to either an Elf32_Phdr, or Elf64_Phdr struct.
|
||||||
|
*/
|
||||||
|
void *phdr = NULL;
|
||||||
|
switch (elf_ptr->isa) {
|
||||||
|
|
||||||
|
case X86_64:
|
||||||
|
case AARCH64:
|
||||||
|
phdr = (&(elf_ptr->PHDR(64)));
|
||||||
|
break;
|
||||||
|
case ARM32:
|
||||||
|
phdr = (&(elf_ptr->PHDR(32)));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
exit(1);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Depending on whether the ISA is 32- or 64-bit determines the size of
|
||||||
|
* many of the fields in the Progra Header. This switch case deals with it.
|
||||||
|
*/
|
||||||
|
switch (elf_ptr->isa) {
|
||||||
|
|
||||||
|
// 64-Bit ISAs
|
||||||
|
case X86_64:
|
||||||
|
case AARCH64:
|
||||||
|
/*
|
||||||
|
* p_type identifies what type of segment this is
|
||||||
|
* PT_NULL: 0x0 // Unused
|
||||||
|
* PT_LOAD: 0x1 // Loadable Segment
|
||||||
|
* PT_DYNAMIC: 0x2 // Dynamic Linker Information
|
||||||
|
* PT_INTERP: 0x3 // Interpreter Information
|
||||||
|
* PT_NOTE: 0x4 // Auxiliary Information
|
||||||
|
* PT_SHLIB: 0x5 // Reserved
|
||||||
|
* PT_PHDR: 0x6 // Segment with Program Header
|
||||||
|
* PT_TLS: 0x7 // Thread Local Storage
|
||||||
|
*/
|
||||||
|
REF_PHDR(64, p_type) = PT_LOAD; // 0x1
|
||||||
|
|
||||||
|
/*
|
||||||
|
* p_flags defines permissions for this section
|
||||||
|
* PF_R: 0x4 // Read
|
||||||
|
* PF_W: 0x2 // Write
|
||||||
|
* PF_X: 0x1 // Execute
|
||||||
|
*/
|
||||||
|
REF_PHDR(64, p_flags) = PF_R | PF_X; // 0x5
|
||||||
|
|
||||||
|
/*
|
||||||
|
* p_offset is the offset in the file image (relative to the start
|
||||||
|
* of the program header) for this segment.
|
||||||
|
*/
|
||||||
|
REF_PHDR(64, p_offset) = 0x0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* p_vaddr is the virtual address where this segment should be loaded
|
||||||
|
* p_paddr is for the physical address (unused by System V)
|
||||||
|
*/
|
||||||
|
REF_PHDR(64, p_vaddr) = 0x400000;
|
||||||
|
REF_PHDR(64, p_paddr) = 0x400000;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* p_filesz is the size of the segment in the file image
|
||||||
|
* p_memsz is the size of the segment in memory
|
||||||
|
*
|
||||||
|
* Note: p_filesz doesn't have to equal p_memsz
|
||||||
|
*/
|
||||||
|
REF_PHDR(64, p_filesz) = elf_ptr->text.text_size;
|
||||||
|
REF_PHDR(64, p_memsz) = elf_ptr->text.text_size;
|
||||||
|
|
||||||
|
break;
|
||||||
|
// 32-Bit ISAs
|
||||||
|
case ARM32:
|
||||||
|
/*
|
||||||
|
* p_type identifies what type of segment this is
|
||||||
|
* PT_NULL: 0x0 // Unused
|
||||||
|
* PT_LOAD: 0x1 // Loadable Segment
|
||||||
|
* PT_DYNAMIC: 0x2 // Dynamic Linker Information
|
||||||
|
* PT_INTERP: 0x3 // Interpreter Information
|
||||||
|
* PT_NOTE: 0x4 // Auxiliary Information
|
||||||
|
* PT_SHLIB: 0x5 // Reserved
|
||||||
|
* PT_PHDR: 0x6 // Segment with Program Header
|
||||||
|
* PT_TLS: 0x7 // Thread Local Storage
|
||||||
|
*/
|
||||||
|
REF_PHDR(32, p_type) = PT_LOAD; // 0x1
|
||||||
|
|
||||||
|
/*
|
||||||
|
* p_flags defines permissions for this section
|
||||||
|
* PF_R: 0x4 // Read
|
||||||
|
* PF_W: 0x2 // Write
|
||||||
|
* PF_X: 0x1 // Execute
|
||||||
|
*/
|
||||||
|
REF_PHDR(32, p_flags) = PF_R | PF_X; // 0x5
|
||||||
|
|
||||||
|
/*
|
||||||
|
* p_offset is the offset in the file image (relative to the start
|
||||||
|
* of the program header) for this segment.
|
||||||
|
*/
|
||||||
|
REF_PHDR(32, p_offset) = 0x0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* p_vaddr is the virtual address where this segment should be loaded
|
||||||
|
* p_paddr is for the physical address (unused by System V)
|
||||||
|
*/
|
||||||
|
REF_PHDR(32, p_vaddr) = 0x10000;
|
||||||
|
REF_PHDR(32, p_paddr) = 0x10000;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* p_filesz is the size of the segment in the file image
|
||||||
|
* p_memsz is the size of the segment in memory
|
||||||
|
*
|
||||||
|
* Note: p_filesz doesn't have to equal p_memsz
|
||||||
|
*/
|
||||||
|
REF_PHDR(32, p_filesz) = elf_ptr->text.text_size;
|
||||||
|
REF_PHDR(32, p_memsz) = elf_ptr->text.text_size;
|
||||||
|
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
exit(1);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* p_align is the memory alignment
|
||||||
|
*
|
||||||
|
* Note: p_vaddr = p_offset % p_align
|
||||||
|
*/
|
||||||
|
switch (elf_ptr->isa) {
|
||||||
|
|
||||||
|
case X86_64:
|
||||||
|
REF_PHDR(64, p_align) = 0x400000;
|
||||||
|
break;
|
||||||
|
case ARM32:
|
||||||
|
REF_PHDR(32, p_align) = 0x10000;
|
||||||
|
break;
|
||||||
|
case AARCH64:
|
||||||
|
REF_PHDR(64, p_align) = 0x400000;
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return phdr;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* e_entry depends on p_vaddr, so has to be set after populate_ehdr()
|
||||||
|
* and populate_phdr() have been called.
|
||||||
|
* taken from libgolf.h
|
||||||
|
*/
|
||||||
|
int set_entry_point(RawBinary *elf_ptr) {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Once the whole ELF file is copied into memory, control is handed to
|
||||||
|
* e_entry. Relative to the process's virtual memory address, the .text
|
||||||
|
* segment will be located immediately after the ELF and program header.
|
||||||
|
*
|
||||||
|
* ehdr and phdr are pointers to the ELF and Program headers respectively.
|
||||||
|
* The switch case casts and assigns them to the correct fields of the ELF
|
||||||
|
* struct, then sets ehdr->e_entry.
|
||||||
|
*/
|
||||||
|
void *ehdr, *phdr;
|
||||||
|
|
||||||
|
switch (elf_ptr->isa) {
|
||||||
|
|
||||||
|
case X86_64:
|
||||||
|
case AARCH64:
|
||||||
|
ehdr = GET_EHDR(64);
|
||||||
|
phdr = GET_PHDR(64);
|
||||||
|
REF_EHDR(64, e_entry) = REF_PHDR(64, p_vaddr) + ehdr_size + phdr_size;
|
||||||
|
break;
|
||||||
|
case ARM32:
|
||||||
|
ehdr = GET_EHDR(32);
|
||||||
|
phdr = GET_PHDR(32);
|
||||||
|
REF_EHDR(32, e_entry) = REF_PHDR(32, p_vaddr) + ehdr_size + phdr_size;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
exit(1);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef struct my_mutator {
|
||||||
|
|
||||||
|
afl_state_t *afl;
|
||||||
|
size_t trim_size_current;
|
||||||
|
int trimmming_steps;
|
||||||
|
int cur_step;
|
||||||
|
u8 *mutated_out, *post_process_buf, *trim_buf;
|
||||||
|
|
||||||
|
} my_mutator_t;
|
||||||
|
|
||||||
|
my_mutator_t *afl_custom_init(afl_state_t *afl, unsigned int seed) {
|
||||||
|
|
||||||
|
srand(seed); // needed also by surgical_havoc_mutate()
|
||||||
|
my_mutator_t *data = calloc(1, sizeof(my_mutator_t));
|
||||||
|
if (!data) {
|
||||||
|
|
||||||
|
perror("afl_custom_init alloc");
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((data->mutated_out = (u8 *)malloc(MAX_FILE)) == NULL) {
|
||||||
|
|
||||||
|
perror("afl_custom_init malloc");
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((data->post_process_buf = (u8 *)malloc(MAX_FILE)) == NULL) {
|
||||||
|
|
||||||
|
perror("afl_custom_init malloc");
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((data->trim_buf = (u8 *)malloc(MAX_FILE)) == NULL) {
|
||||||
|
|
||||||
|
perror("afl_custom_init malloc");
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
data->afl = afl;
|
||||||
|
return data;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t afl_custom_fuzz(my_mutator_t *data, uint8_t *in_buf, size_t buf_size,
|
||||||
|
u8 **out_buf, uint8_t *add_buf,
|
||||||
|
size_t add_buf_size, // add_buf can be NULL
|
||||||
|
size_t max_size) {
|
||||||
|
|
||||||
|
RawBinary elf_obj;
|
||||||
|
RawBinary *elf = &elf_obj;
|
||||||
|
elf->isa = 62;
|
||||||
|
Elf64_Ehdr *ehdr;
|
||||||
|
Elf64_Phdr *phdr;
|
||||||
|
copy_text_segment(elf, buf, sizeof(buf));
|
||||||
|
ehdr = populate_ehdr(elf);
|
||||||
|
phdr = populate_phdr(elf);
|
||||||
|
set_entry_point(elf);
|
||||||
|
|
||||||
|
size_t mutated_size = ehdr_size + phdr_size + elf->text.text_size;
|
||||||
|
int pos = 0;
|
||||||
|
// example fields
|
||||||
|
ehdr->e_ident[EI_CLASS] = (uint8_t *)(in_buf + pos++);
|
||||||
|
ehdr->e_ident[EI_DATA] = (uint8_t *)(in_buf + pos++);
|
||||||
|
ehdr->e_ident[EI_VERSION] = (uint8_t *)(in_buf + pos++);
|
||||||
|
ehdr->e_ident[EI_OSABI] = (uint8_t *)(in_buf + pos++);
|
||||||
|
for (int i = 0x8; i < 0x10; ++i) {
|
||||||
|
|
||||||
|
(ehdr->e_ident)[i] = (uint8_t *)(in_buf + pos++);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ehdr->e_version = (uint32_t *)(in_buf + pos);
|
||||||
|
pos += 4;
|
||||||
|
// sections headers
|
||||||
|
ehdr->e_shoff = (uint64_t *)(in_buf + pos);
|
||||||
|
pos += 8;
|
||||||
|
ehdr->e_shentsize = (uint16_t *)(in_buf + pos);
|
||||||
|
pos += 2;
|
||||||
|
ehdr->e_shnum = (uint16_t *)(in_buf + pos);
|
||||||
|
pos += 2;
|
||||||
|
ehdr->e_shstrndx = (uint16_t *)(in_buf + pos);
|
||||||
|
pos += 2;
|
||||||
|
ehdr->e_flags = (uint32_t *)(in_buf + pos);
|
||||||
|
pos += 4;
|
||||||
|
// physical addr
|
||||||
|
phdr->p_paddr = (uint64_t *)(in_buf + pos);
|
||||||
|
pos += 8;
|
||||||
|
phdr->p_align = (uint64_t *)(in_buf + pos);
|
||||||
|
pos += 8;
|
||||||
|
|
||||||
|
/* mimic GEN_ELF()
|
||||||
|
* Write:
|
||||||
|
* - ELF Header
|
||||||
|
* - Program Header
|
||||||
|
* - Text Segment
|
||||||
|
*/
|
||||||
|
memcpy(data->mutated_out, ehdr, ehdr_size);
|
||||||
|
memcpy(data->mutated_out + ehdr_size, phdr, phdr_size);
|
||||||
|
memcpy(data->mutated_out + ehdr_size + phdr_size, elf->text.text_segment,
|
||||||
|
elf->text.text_size);
|
||||||
|
|
||||||
|
*out_buf = data->mutated_out;
|
||||||
|
return mutated_size;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void afl_custom_deinit(my_mutator_t *data) {
|
||||||
|
|
||||||
|
free(data->post_process_buf);
|
||||||
|
free(data->mutated_out);
|
||||||
|
free(data->trim_buf);
|
||||||
|
free(data);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,347 @@
|
|||||||
|
/*
|
||||||
|
New Custom Mutator for AFL++
|
||||||
|
Written by Khaled Yakdan <yakdan@code-intelligence.de>
|
||||||
|
Andrea Fioraldi <andreafioraldi@gmail.com>
|
||||||
|
Shengtuo Hu <h1994st@gmail.com>
|
||||||
|
Dominik Maier <mail@dmnk.co>
|
||||||
|
*/
|
||||||
|
|
||||||
|
// You need to use -I/path/to/AFLplusplus/include -I.
|
||||||
|
#include "afl-fuzz.h"
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#define DATA_SIZE (100)
|
||||||
|
|
||||||
|
static const char *commands[] = {
|
||||||
|
|
||||||
|
"GET",
|
||||||
|
"PUT",
|
||||||
|
"DEL",
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct my_mutator {
|
||||||
|
|
||||||
|
afl_state_t *afl;
|
||||||
|
|
||||||
|
// any additional data here!
|
||||||
|
size_t trim_size_current;
|
||||||
|
int trimmming_steps;
|
||||||
|
int cur_step;
|
||||||
|
|
||||||
|
u8 *mutated_out, *post_process_buf, *trim_buf;
|
||||||
|
|
||||||
|
} my_mutator_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize this custom mutator
|
||||||
|
*
|
||||||
|
* @param[in] afl a pointer to the internal state object. Can be ignored for
|
||||||
|
* now.
|
||||||
|
* @param[in] seed A seed for this mutator - the same seed should always mutate
|
||||||
|
* in the same way.
|
||||||
|
* @return Pointer to the data object this custom mutator instance should use.
|
||||||
|
* There may be multiple instances of this mutator in one afl-fuzz run!
|
||||||
|
* Return NULL on error.
|
||||||
|
*/
|
||||||
|
my_mutator_t *afl_custom_init(afl_state_t *afl, unsigned int seed) {
|
||||||
|
|
||||||
|
srand(seed); // needed also by surgical_havoc_mutate()
|
||||||
|
|
||||||
|
my_mutator_t *data = calloc(1, sizeof(my_mutator_t));
|
||||||
|
if (!data) {
|
||||||
|
|
||||||
|
perror("afl_custom_init alloc");
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((data->mutated_out = (u8 *)malloc(MAX_FILE)) == NULL) {
|
||||||
|
|
||||||
|
perror("afl_custom_init malloc");
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((data->post_process_buf = (u8 *)malloc(MAX_FILE)) == NULL) {
|
||||||
|
|
||||||
|
perror("afl_custom_init malloc");
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((data->trim_buf = (u8 *)malloc(MAX_FILE)) == NULL) {
|
||||||
|
|
||||||
|
perror("afl_custom_init malloc");
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
data->afl = afl;
|
||||||
|
|
||||||
|
return data;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Perform custom mutations on a given input
|
||||||
|
*
|
||||||
|
* (Optional for now. Required in the future)
|
||||||
|
*
|
||||||
|
* @param[in] data pointer returned in afl_custom_init for this fuzz case
|
||||||
|
* @param[in] buf Pointer to input data to be mutated
|
||||||
|
* @param[in] buf_size Size of input data
|
||||||
|
* @param[out] out_buf the buffer we will work on. we can reuse *buf. NULL on
|
||||||
|
* error.
|
||||||
|
* @param[in] add_buf Buffer containing the additional test case
|
||||||
|
* @param[in] add_buf_size Size of the additional test case
|
||||||
|
* @param[in] max_size Maximum size of the mutated output. The mutation must not
|
||||||
|
* produce data larger than max_size.
|
||||||
|
* @return Size of the mutated output.
|
||||||
|
*/
|
||||||
|
size_t afl_custom_fuzz(my_mutator_t *data, uint8_t *buf, size_t buf_size,
|
||||||
|
u8 **out_buf, uint8_t *add_buf,
|
||||||
|
size_t add_buf_size, // add_buf can be NULL
|
||||||
|
size_t max_size) {
|
||||||
|
|
||||||
|
// Make sure that the packet size does not exceed the maximum size expected by
|
||||||
|
// the fuzzer
|
||||||
|
size_t mutated_size = DATA_SIZE <= max_size ? DATA_SIZE : max_size;
|
||||||
|
|
||||||
|
memcpy(data->mutated_out, buf, buf_size);
|
||||||
|
|
||||||
|
// Randomly select a command string to add as a header to the packet
|
||||||
|
memcpy(data->mutated_out, commands[rand() % 3], 3);
|
||||||
|
|
||||||
|
if (mutated_size > max_size) { mutated_size = max_size; }
|
||||||
|
|
||||||
|
*out_buf = data->mutated_out;
|
||||||
|
return mutated_size;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A post-processing function to use right before AFL writes the test case to
|
||||||
|
* disk in order to execute the target.
|
||||||
|
*
|
||||||
|
* (Optional) If this functionality is not needed, simply don't define this
|
||||||
|
* function.
|
||||||
|
*
|
||||||
|
* @param[in] data pointer returned in afl_custom_init for this fuzz case
|
||||||
|
* @param[in] buf Buffer containing the test case to be executed
|
||||||
|
* @param[in] buf_size Size of the test case
|
||||||
|
* @param[out] out_buf Pointer to the buffer containing the test case after
|
||||||
|
* processing. External library should allocate memory for out_buf.
|
||||||
|
* The buf pointer may be reused (up to the given buf_size);
|
||||||
|
* @return Size of the output buffer after processing or the needed amount.
|
||||||
|
* A return of 0 indicates an error.
|
||||||
|
*/
|
||||||
|
size_t afl_custom_post_process(my_mutator_t *data, uint8_t *buf,
|
||||||
|
size_t buf_size, uint8_t **out_buf) {
|
||||||
|
|
||||||
|
if (buf_size + 5 > MAX_FILE) { buf_size = MAX_FILE - 5; }
|
||||||
|
|
||||||
|
memcpy(data->post_process_buf + 5, buf, buf_size);
|
||||||
|
data->post_process_buf[0] = 'A';
|
||||||
|
data->post_process_buf[1] = 'F';
|
||||||
|
data->post_process_buf[2] = 'L';
|
||||||
|
data->post_process_buf[3] = '+';
|
||||||
|
data->post_process_buf[4] = '+';
|
||||||
|
|
||||||
|
*out_buf = data->post_process_buf;
|
||||||
|
|
||||||
|
return buf_size + 5;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method is called at the start of each trimming operation and receives
|
||||||
|
* the initial buffer. It should return the amount of iteration steps possible
|
||||||
|
* on this input (e.g. if your input has n elements and you want to remove
|
||||||
|
* them one by one, return n, if you do a binary search, return log(n),
|
||||||
|
* and so on...).
|
||||||
|
*
|
||||||
|
* If your trimming algorithm doesn't allow you to determine the amount of
|
||||||
|
* (remaining) steps easily (esp. while running), then you can alternatively
|
||||||
|
* return 1 here and always return 0 in post_trim until you are finished and
|
||||||
|
* no steps remain. In that case, returning 1 in post_trim will end the
|
||||||
|
* trimming routine. The whole current index/max iterations stuff is only used
|
||||||
|
* to show progress.
|
||||||
|
*
|
||||||
|
* (Optional)
|
||||||
|
*
|
||||||
|
* @param data pointer returned in afl_custom_init for this fuzz case
|
||||||
|
* @param buf Buffer containing the test case
|
||||||
|
* @param buf_size Size of the test case
|
||||||
|
* @return The amount of possible iteration steps to trim the input.
|
||||||
|
* negative on error.
|
||||||
|
*/
|
||||||
|
int32_t afl_custom_init_trim(my_mutator_t *data, uint8_t *buf,
|
||||||
|
size_t buf_size) {
|
||||||
|
|
||||||
|
// We simply trim once
|
||||||
|
data->trimmming_steps = 1;
|
||||||
|
|
||||||
|
data->cur_step = 0;
|
||||||
|
|
||||||
|
memcpy(data->trim_buf, buf, buf_size);
|
||||||
|
|
||||||
|
data->trim_size_current = buf_size;
|
||||||
|
|
||||||
|
return data->trimmming_steps;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method is called for each trimming operation. It doesn't have any
|
||||||
|
* arguments because we already have the initial buffer from init_trim and we
|
||||||
|
* can memorize the current state in *data. This can also save
|
||||||
|
* reparsing steps for each iteration. It should return the trimmed input
|
||||||
|
* buffer, where the returned data must not exceed the initial input data in
|
||||||
|
* length. Returning anything that is larger than the original data (passed
|
||||||
|
* to init_trim) will result in a fatal abort of AFLFuzz.
|
||||||
|
*
|
||||||
|
* (Optional)
|
||||||
|
*
|
||||||
|
* @param[in] data pointer returned in afl_custom_init for this fuzz case
|
||||||
|
* @param[out] out_buf Pointer to the buffer containing the trimmed test case.
|
||||||
|
* External library should allocate memory for out_buf.
|
||||||
|
* AFL++ will not release the memory after saving the test case.
|
||||||
|
* Keep a ref in *data.
|
||||||
|
* *out_buf = NULL is treated as error.
|
||||||
|
* @return Pointer to the size of the trimmed test case
|
||||||
|
*/
|
||||||
|
size_t afl_custom_trim(my_mutator_t *data, uint8_t **out_buf) {
|
||||||
|
|
||||||
|
*out_buf = data->trim_buf;
|
||||||
|
|
||||||
|
// Remove the last byte of the trimming input
|
||||||
|
return data->trim_size_current - 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method is called after each trim operation to inform you if your
|
||||||
|
* trimming step was successful or not (in terms of coverage). If you receive
|
||||||
|
* a failure here, you should reset your input to the last known good state.
|
||||||
|
*
|
||||||
|
* (Optional)
|
||||||
|
*
|
||||||
|
* @param[in] data pointer returned in afl_custom_init for this fuzz case
|
||||||
|
* @param success Indicates if the last trim operation was successful.
|
||||||
|
* @return The next trim iteration index (from 0 to the maximum amount of
|
||||||
|
* steps returned in init_trim). negative ret on failure.
|
||||||
|
*/
|
||||||
|
int32_t afl_custom_post_trim(my_mutator_t *data, int success) {
|
||||||
|
|
||||||
|
if (success) {
|
||||||
|
|
||||||
|
++data->cur_step;
|
||||||
|
return data->cur_step;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return data->trimmming_steps;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Perform a single custom mutation on a given input.
|
||||||
|
* This mutation is stacked with the other muatations in havoc.
|
||||||
|
*
|
||||||
|
* (Optional)
|
||||||
|
*
|
||||||
|
* @param[in] data pointer returned in afl_custom_init for this fuzz case
|
||||||
|
* @param[in] buf Pointer to the input data to be mutated and the mutated
|
||||||
|
* output
|
||||||
|
* @param[in] buf_size Size of input data
|
||||||
|
* @param[out] out_buf The output buffer. buf can be reused, if the content
|
||||||
|
* fits. *out_buf = NULL is treated as error.
|
||||||
|
* @param[in] max_size Maximum size of the mutated output. The mutation must
|
||||||
|
* not produce data larger than max_size.
|
||||||
|
* @return Size of the mutated output.
|
||||||
|
*/
|
||||||
|
size_t afl_custom_havoc_mutation(my_mutator_t *data, u8 *buf, size_t buf_size,
|
||||||
|
u8 **out_buf, size_t max_size) {
|
||||||
|
|
||||||
|
*out_buf = buf; // in-place mutation
|
||||||
|
|
||||||
|
if (buf_size <= sizeof(size_t)) { return buf_size; }
|
||||||
|
|
||||||
|
size_t victim = rand() % (buf_size - sizeof(size_t));
|
||||||
|
(*out_buf)[victim] += rand() % 10;
|
||||||
|
|
||||||
|
return buf_size;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the probability (in percentage) that afl_custom_havoc_mutation
|
||||||
|
* is called in havoc. By default it is 6 %.
|
||||||
|
*
|
||||||
|
* (Optional)
|
||||||
|
*
|
||||||
|
* @param[in] data pointer returned in afl_custom_init for this fuzz case
|
||||||
|
* @return The probability (0-100).
|
||||||
|
*/
|
||||||
|
uint8_t afl_custom_havoc_mutation_probability(my_mutator_t *data) {
|
||||||
|
|
||||||
|
return 5; // 5 %
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine whether the fuzzer should fuzz the queue entry or not.
|
||||||
|
*
|
||||||
|
* (Optional)
|
||||||
|
*
|
||||||
|
* @param[in] data pointer returned in afl_custom_init for this fuzz case
|
||||||
|
* @param filename File name of the test case in the queue entry
|
||||||
|
* @return Return True(1) if the fuzzer will fuzz the queue entry, and
|
||||||
|
* False(0) otherwise.
|
||||||
|
*/
|
||||||
|
uint8_t afl_custom_queue_get(my_mutator_t *data, const uint8_t *filename) {
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allow for additional analysis (e.g. calling a different tool that does a
|
||||||
|
* different kind of coverage and saves this for the custom mutator).
|
||||||
|
*
|
||||||
|
* (Optional)
|
||||||
|
*
|
||||||
|
* @param data pointer returned in afl_custom_init for this fuzz case
|
||||||
|
* @param filename_new_queue File name of the new queue entry
|
||||||
|
* @param filename_orig_queue File name of the original queue entry
|
||||||
|
* @return if the file contents was modified return 1 (True), 0 (False)
|
||||||
|
* otherwise
|
||||||
|
*/
|
||||||
|
uint8_t afl_custom_queue_new_entry(my_mutator_t *data,
|
||||||
|
const uint8_t *filename_new_queue,
|
||||||
|
const uint8_t *filename_orig_queue) {
|
||||||
|
|
||||||
|
/* Additional analysis on the original or new test case */
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deinitialize everything
|
||||||
|
*
|
||||||
|
* @param data The data ptr from afl_custom_init
|
||||||
|
*/
|
||||||
|
void afl_custom_deinit(my_mutator_t *data) {
|
||||||
|
|
||||||
|
free(data->post_process_buf);
|
||||||
|
free(data->mutated_out);
|
||||||
|
free(data->trim_buf);
|
||||||
|
free(data);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,192 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
# encoding: utf-8
|
||||||
|
"""
|
||||||
|
Example Python Module for AFLFuzz
|
||||||
|
|
||||||
|
@author: Christian Holler (:decoder)
|
||||||
|
|
||||||
|
@license:
|
||||||
|
|
||||||
|
This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
|
||||||
|
@contact: choller@mozilla.com
|
||||||
|
"""
|
||||||
|
|
||||||
|
import random
|
||||||
|
|
||||||
|
|
||||||
|
COMMANDS = [
|
||||||
|
b"GET",
|
||||||
|
b"PUT",
|
||||||
|
b"DEL",
|
||||||
|
b"AAAAAAAAAAAAAAAAA",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def init(seed):
|
||||||
|
"""
|
||||||
|
Called once when AFLFuzz starts up. Used to seed our RNG.
|
||||||
|
|
||||||
|
@type seed: int
|
||||||
|
@param seed: A 32-bit random value
|
||||||
|
"""
|
||||||
|
random.seed(seed)
|
||||||
|
|
||||||
|
|
||||||
|
def deinit():
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def fuzz(buf, add_buf, max_size):
|
||||||
|
"""
|
||||||
|
Called per fuzzing iteration.
|
||||||
|
|
||||||
|
@type buf: bytearray
|
||||||
|
@param buf: The buffer that should be mutated.
|
||||||
|
|
||||||
|
@type add_buf: bytearray
|
||||||
|
@param add_buf: A second buffer that can be used as mutation source.
|
||||||
|
|
||||||
|
@type max_size: int
|
||||||
|
@param max_size: Maximum size of the mutated output. The mutation must not
|
||||||
|
produce data larger than max_size.
|
||||||
|
|
||||||
|
@rtype: bytearray
|
||||||
|
@return: A new bytearray containing the mutated data
|
||||||
|
"""
|
||||||
|
ret = bytearray(100)
|
||||||
|
|
||||||
|
ret[:3] = random.choice(COMMANDS)
|
||||||
|
|
||||||
|
return ret
|
||||||
|
|
||||||
|
|
||||||
|
# Uncomment and implement the following methods if you want to use a custom
|
||||||
|
# trimming algorithm. See also the documentation for a better API description.
|
||||||
|
|
||||||
|
# def init_trim(buf):
|
||||||
|
# '''
|
||||||
|
# Called per trimming iteration.
|
||||||
|
#
|
||||||
|
# @type buf: bytearray
|
||||||
|
# @param buf: The buffer that should be trimmed.
|
||||||
|
#
|
||||||
|
# @rtype: int
|
||||||
|
# @return: The maximum number of trimming steps.
|
||||||
|
# '''
|
||||||
|
# global ...
|
||||||
|
#
|
||||||
|
# # Initialize global variables
|
||||||
|
#
|
||||||
|
# # Figure out how many trimming steps are possible.
|
||||||
|
# # If this is not possible for your trimming, you can
|
||||||
|
# # return 1 instead and always return 0 in post_trim
|
||||||
|
# # until you are done (then you return 1).
|
||||||
|
#
|
||||||
|
# return steps
|
||||||
|
#
|
||||||
|
# def trim():
|
||||||
|
# '''
|
||||||
|
# Called per trimming iteration.
|
||||||
|
#
|
||||||
|
# @rtype: bytearray
|
||||||
|
# @return: A new bytearray containing the trimmed data.
|
||||||
|
# '''
|
||||||
|
# global ...
|
||||||
|
#
|
||||||
|
# # Implement the actual trimming here
|
||||||
|
#
|
||||||
|
# return bytearray(...)
|
||||||
|
#
|
||||||
|
# def post_trim(success):
|
||||||
|
# '''
|
||||||
|
# Called after each trimming operation.
|
||||||
|
#
|
||||||
|
# @type success: bool
|
||||||
|
# @param success: Indicates if the last trim operation was successful.
|
||||||
|
#
|
||||||
|
# @rtype: int
|
||||||
|
# @return: The next trim index (0 to max number of steps) where max
|
||||||
|
# number of steps indicates the trimming is done.
|
||||||
|
# '''
|
||||||
|
# global ...
|
||||||
|
#
|
||||||
|
# if not success:
|
||||||
|
# # Restore last known successful input, determine next index
|
||||||
|
# else:
|
||||||
|
# # Just determine the next index, based on what was successfully
|
||||||
|
# # removed in the last step
|
||||||
|
#
|
||||||
|
# return next_index
|
||||||
|
#
|
||||||
|
# def post_process(buf):
|
||||||
|
# '''
|
||||||
|
# Called just before the execution to write the test case in the format
|
||||||
|
# expected by the target
|
||||||
|
#
|
||||||
|
# @type buf: bytearray
|
||||||
|
# @param buf: The buffer containing the test case to be executed
|
||||||
|
#
|
||||||
|
# @rtype: bytearray
|
||||||
|
# @return: The buffer containing the test case after
|
||||||
|
# '''
|
||||||
|
# return buf
|
||||||
|
# def post_run():
|
||||||
|
# '''
|
||||||
|
# Called after each time the execution of the target program by AFL++
|
||||||
|
# '''
|
||||||
|
# pass
|
||||||
|
#
|
||||||
|
# def havoc_mutation(buf, max_size):
|
||||||
|
# '''
|
||||||
|
# Perform a single custom mutation on a given input.
|
||||||
|
#
|
||||||
|
# @type buf: bytearray
|
||||||
|
# @param buf: The buffer that should be mutated.
|
||||||
|
#
|
||||||
|
# @type max_size: int
|
||||||
|
# @param max_size: Maximum size of the mutated output. The mutation must not
|
||||||
|
# produce data larger than max_size.
|
||||||
|
#
|
||||||
|
# @rtype: bytearray
|
||||||
|
# @return: A new bytearray containing the mutated data
|
||||||
|
# '''
|
||||||
|
# return mutated_buf
|
||||||
|
#
|
||||||
|
# def havoc_mutation_probability():
|
||||||
|
# '''
|
||||||
|
# Called for each `havoc_mutation`. Return the probability (in percentage)
|
||||||
|
# that `havoc_mutation` is called in havoc. Be default it is 6%.
|
||||||
|
#
|
||||||
|
# @rtype: int
|
||||||
|
# @return: The probability (0-100)
|
||||||
|
# '''
|
||||||
|
# return prob
|
||||||
|
#
|
||||||
|
# def queue_get(filename):
|
||||||
|
# '''
|
||||||
|
# Called at the beginning of each fuzz iteration to determine whether the
|
||||||
|
# test case should be fuzzed
|
||||||
|
#
|
||||||
|
# @type filename: str
|
||||||
|
# @param filename: File name of the test case in the current queue entry
|
||||||
|
#
|
||||||
|
# @rtype: bool
|
||||||
|
# @return: Return True if the custom mutator decides to fuzz the test case,
|
||||||
|
# and False otherwise
|
||||||
|
# '''
|
||||||
|
# return True
|
||||||
|
#
|
||||||
|
# def queue_new_entry(filename_new_queue, filename_orig_queue):
|
||||||
|
# '''
|
||||||
|
# Called after adding a new test case to the queue
|
||||||
|
#
|
||||||
|
# @type filename_new_queue: str
|
||||||
|
# @param filename_new_queue: File name of the new queue entry
|
||||||
|
#
|
||||||
|
# @type filename_orig_queue: str
|
||||||
|
# @param filename_orig_queue: File name of the original queue entry
|
||||||
|
# '''
|
||||||
|
# pass
|
@ -0,0 +1,132 @@
|
|||||||
|
/*
|
||||||
|
american fuzzy lop++ - postprocessor library example
|
||||||
|
--------------------------------------------------
|
||||||
|
|
||||||
|
Originally written by Michal Zalewski
|
||||||
|
Edited by Dominik Maier, 2020
|
||||||
|
|
||||||
|
Copyright 2015 Google Inc. 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
|
||||||
|
|
||||||
|
Postprocessor libraries can be passed to afl-fuzz to perform final cleanup
|
||||||
|
of any mutated test cases - for example, to fix up checksums in PNG files.
|
||||||
|
|
||||||
|
Please heed the following warnings:
|
||||||
|
|
||||||
|
1) In almost all cases, it is more productive to comment out checksum logic
|
||||||
|
in the targeted binary (as shown in ../libpng_no_checksum/). One possible
|
||||||
|
exception is the process of fuzzing binary-only software in QEMU mode.
|
||||||
|
|
||||||
|
2) The use of postprocessors for anything other than checksums is
|
||||||
|
questionable and may cause more harm than good. AFL is normally pretty good
|
||||||
|
about dealing with length fields, magic values, etc.
|
||||||
|
|
||||||
|
3) Postprocessors that do anything non-trivial must be extremely robust to
|
||||||
|
gracefully handle malformed data and other error conditions - otherwise,
|
||||||
|
they will crash and take afl-fuzz down with them. Be wary of reading past
|
||||||
|
*len and of integer overflows when calculating file offsets.
|
||||||
|
|
||||||
|
In other words, THIS IS PROBABLY NOT WHAT YOU WANT - unless you really,
|
||||||
|
honestly know what you're doing =)
|
||||||
|
|
||||||
|
With that out of the way: the postprocessor library is passed to afl-fuzz
|
||||||
|
via AFL_POST_LIBRARY. The library must be compiled with:
|
||||||
|
|
||||||
|
gcc -shared -Wall -O3 post_library.so.c -o post_library.so
|
||||||
|
|
||||||
|
AFL will call the afl_custom_post_process() function for every mutated output
|
||||||
|
buffer. From there, you have three choices:
|
||||||
|
|
||||||
|
1) If you don't want to modify the test case, simply set `*out_buf = in_buf`
|
||||||
|
and return the original `len`.
|
||||||
|
|
||||||
|
2) If you want to skip this test case altogether and have AFL generate a
|
||||||
|
new one, return 0.
|
||||||
|
Use this sparingly - it's faster than running the target program
|
||||||
|
with patently useless inputs, but still wastes CPU time.
|
||||||
|
|
||||||
|
3) If you want to modify the test case, allocate an appropriately-sized
|
||||||
|
buffer, move the data into that buffer, make the necessary changes, and
|
||||||
|
then return the new pointer as out_buf. Return an appropriate len
|
||||||
|
afterwards.
|
||||||
|
|
||||||
|
Note that the buffer will *not* be freed for you. To avoid memory leaks,
|
||||||
|
you need to free it or reuse it on subsequent calls (as shown below).
|
||||||
|
|
||||||
|
Alright. The example below shows a simple postprocessor that tries to make
|
||||||
|
sure that all input files start with "GIF89a".
|
||||||
|
|
||||||
|
PS. If you don't like C, you can try out the unix-based wrapper from
|
||||||
|
Ben Nagy instead: https://github.com/bnagy/aflfix
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "afl-fuzz.h"
|
||||||
|
|
||||||
|
/* Header that must be present at the beginning of every test case: */
|
||||||
|
|
||||||
|
#define HEADER "GIF89a"
|
||||||
|
|
||||||
|
typedef struct post_state {
|
||||||
|
|
||||||
|
size_t size;
|
||||||
|
|
||||||
|
} post_state_t;
|
||||||
|
|
||||||
|
void *afl_custom_init(void *afl) {
|
||||||
|
|
||||||
|
post_state_t *state = malloc(sizeof(post_state_t));
|
||||||
|
if (!state) {
|
||||||
|
|
||||||
|
perror("malloc");
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return state;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The actual postprocessor routine called by afl-fuzz: */
|
||||||
|
|
||||||
|
size_t afl_custom_post_process(post_state_t *data, unsigned char *in_buf,
|
||||||
|
unsigned int len, unsigned char **out_buf) {
|
||||||
|
|
||||||
|
/* we do in-place modification as we do not increase the size */
|
||||||
|
|
||||||
|
*out_buf = in_buf;
|
||||||
|
|
||||||
|
/* Skip execution altogether for buffers shorter than 6 bytes (just to
|
||||||
|
show how it's done). We can trust len to be sane. */
|
||||||
|
|
||||||
|
if (len < strlen(HEADER)) return 0;
|
||||||
|
|
||||||
|
/* Do nothing for buffers that already start with the expected header. */
|
||||||
|
|
||||||
|
if (!memcmp(in_buf, HEADER, strlen(HEADER))) { return len; }
|
||||||
|
|
||||||
|
/* Insert the new header. */
|
||||||
|
|
||||||
|
memcpy(*out_buf, HEADER, strlen(HEADER));
|
||||||
|
|
||||||
|
/* Return the new len. It hasn't changed, so it's just len. */
|
||||||
|
|
||||||
|
return len;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Gets called afterwards */
|
||||||
|
void afl_custom_deinit(post_state_t *data) {
|
||||||
|
|
||||||
|
free(data);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,135 @@
|
|||||||
|
/*
|
||||||
|
american fuzzy lop++ - postprocessor for PNG
|
||||||
|
------------------------------------------
|
||||||
|
|
||||||
|
Originally written by Michal Zalewski
|
||||||
|
|
||||||
|
Copyright 2015 Google Inc. All rights reserved.
|
||||||
|
Adapted to the new API, 2020 by Dominik Maier
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
See post_library.so.c for a general discussion of how to implement
|
||||||
|
postprocessors. This specific postprocessor attempts to fix up PNG
|
||||||
|
checksums, providing a slightly more complicated example than found
|
||||||
|
in post_library.so.c.
|
||||||
|
|
||||||
|
Compile with:
|
||||||
|
|
||||||
|
gcc -shared -Wall -O3 post_library_png.so.c -o post_library_png.so -lz
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <zlib.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include "afl-fuzz.h"
|
||||||
|
|
||||||
|
/* A macro to round an integer up to 4 kB. */
|
||||||
|
|
||||||
|
#define UP4K(_i) ((((_i) >> 12) + 1) << 12)
|
||||||
|
|
||||||
|
typedef struct post_state {
|
||||||
|
|
||||||
|
unsigned char *buf;
|
||||||
|
size_t size;
|
||||||
|
|
||||||
|
} post_state_t;
|
||||||
|
|
||||||
|
void *afl_custom_init(void *afl) {
|
||||||
|
|
||||||
|
post_state_t *state = malloc(sizeof(post_state_t));
|
||||||
|
if (!state) {
|
||||||
|
|
||||||
|
perror("malloc");
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
state->buf = calloc(sizeof(unsigned char), MAX_FILE);
|
||||||
|
if (!state->buf) {
|
||||||
|
|
||||||
|
free(state);
|
||||||
|
perror("calloc");
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return state;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t afl_custom_post_process(post_state_t *data, const unsigned char *in_buf,
|
||||||
|
unsigned int len,
|
||||||
|
const unsigned char **out_buf) {
|
||||||
|
|
||||||
|
/* Don't do anything if there's not enough room for the PNG header
|
||||||
|
(8 bytes). */
|
||||||
|
|
||||||
|
if (len < 8) {
|
||||||
|
|
||||||
|
*out_buf = in_buf;
|
||||||
|
return len;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int pos = 8;
|
||||||
|
|
||||||
|
/* Minimum size of a zero-length PNG chunk is 12 bytes; if we
|
||||||
|
don't have that, we can bail out. */
|
||||||
|
|
||||||
|
while (pos + 12 <= len) {
|
||||||
|
|
||||||
|
unsigned int chunk_len, real_cksum, file_cksum;
|
||||||
|
|
||||||
|
/* Chunk length is the first big-endian dword in the chunk. */
|
||||||
|
|
||||||
|
chunk_len = ntohl(*(uint32_t *)(in_buf + pos));
|
||||||
|
|
||||||
|
/* Bail out if chunk size is too big or goes past EOF. */
|
||||||
|
|
||||||
|
if (chunk_len > 1024 * 1024 || pos + 12 + chunk_len > len) break;
|
||||||
|
|
||||||
|
/* Chunk checksum is calculated for chunk ID (dword) and the actual
|
||||||
|
payload. */
|
||||||
|
|
||||||
|
real_cksum = htonl(crc32(0, in_buf + pos + 4, chunk_len + 4));
|
||||||
|
|
||||||
|
/* The in-file checksum is the last dword past the chunk data. */
|
||||||
|
|
||||||
|
file_cksum = *(uint32_t *)(in_buf + pos + 8 + chunk_len);
|
||||||
|
|
||||||
|
/* If the checksums do not match, we need to fix the file. */
|
||||||
|
|
||||||
|
if (real_cksum != file_cksum) {
|
||||||
|
|
||||||
|
*(uint32_t *)(data->buf + pos + 8 + chunk_len) = real_cksum;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Skip the entire chunk and move to the next one. */
|
||||||
|
|
||||||
|
pos += 12 + chunk_len;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
*out_buf = data->buf;
|
||||||
|
return len;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Gets called afterwards */
|
||||||
|
void afl_custom_deinit(post_state_t *data) {
|
||||||
|
|
||||||
|
free(data->buf);
|
||||||
|
free(data);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,66 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
# encoding: utf-8
|
||||||
|
"""
|
||||||
|
Simple Chunk Cross-Over Replacement Module for AFLFuzz
|
||||||
|
|
||||||
|
@author: Christian Holler (:decoder)
|
||||||
|
|
||||||
|
@license:
|
||||||
|
|
||||||
|
This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
|
||||||
|
@contact: choller@mozilla.com
|
||||||
|
"""
|
||||||
|
|
||||||
|
import random
|
||||||
|
|
||||||
|
|
||||||
|
def init(seed):
|
||||||
|
"""
|
||||||
|
Called once when AFLFuzz starts up. Used to seed our RNG.
|
||||||
|
|
||||||
|
@type seed: int
|
||||||
|
@param seed: A 32-bit random value
|
||||||
|
"""
|
||||||
|
# Seed our RNG
|
||||||
|
random.seed(seed)
|
||||||
|
|
||||||
|
|
||||||
|
def fuzz(buf, add_buf, max_size):
|
||||||
|
"""
|
||||||
|
Called per fuzzing iteration.
|
||||||
|
|
||||||
|
@type buf: bytearray
|
||||||
|
@param buf: The buffer that should be mutated.
|
||||||
|
|
||||||
|
@type add_buf: bytearray
|
||||||
|
@param add_buf: A second buffer that can be used as mutation source.
|
||||||
|
|
||||||
|
@type max_size: int
|
||||||
|
@param max_size: Maximum size of the mutated output. The mutation must not
|
||||||
|
produce data larger than max_size.
|
||||||
|
|
||||||
|
@rtype: bytearray
|
||||||
|
@return: A new bytearray containing the mutated data
|
||||||
|
"""
|
||||||
|
# Make a copy of our input buffer for returning
|
||||||
|
ret = bytearray(buf)
|
||||||
|
|
||||||
|
# Take a random fragment length between 2 and 32 (or less if add_buf is shorter)
|
||||||
|
fragment_len = random.randint(1, min(len(add_buf), 32))
|
||||||
|
|
||||||
|
# Determine a random source index where to take the data chunk from
|
||||||
|
rand_src_idx = random.randint(0, len(add_buf) - fragment_len)
|
||||||
|
|
||||||
|
# Determine a random destination index where to put the data chunk
|
||||||
|
rand_dst_idx = random.randint(0, len(buf))
|
||||||
|
|
||||||
|
# Make the chunk replacement
|
||||||
|
ret[rand_dst_idx : rand_dst_idx + fragment_len] = add_buf[
|
||||||
|
rand_src_idx : rand_src_idx + fragment_len
|
||||||
|
]
|
||||||
|
|
||||||
|
# Return data
|
||||||
|
return ret
|
@ -0,0 +1,74 @@
|
|||||||
|
// This simple example just creates random buffer <= 100 filled with 'A'
|
||||||
|
// needs -I /path/to/AFLplusplus/include
|
||||||
|
#include "afl-fuzz.h"
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#ifndef _FIXED_CHAR
|
||||||
|
#define _FIXED_CHAR 0x41
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct my_mutator {
|
||||||
|
|
||||||
|
afl_state_t *afl;
|
||||||
|
|
||||||
|
// Reused buffers:
|
||||||
|
u8 *fuzz_buf;
|
||||||
|
|
||||||
|
} my_mutator_t;
|
||||||
|
|
||||||
|
my_mutator_t *afl_custom_init(afl_state_t *afl, unsigned int seed) {
|
||||||
|
|
||||||
|
srand(seed);
|
||||||
|
my_mutator_t *data = calloc(1, sizeof(my_mutator_t));
|
||||||
|
if (!data) {
|
||||||
|
|
||||||
|
perror("afl_custom_init alloc");
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
data->fuzz_buf = (u8 *)malloc(MAX_FILE);
|
||||||
|
if (!data->fuzz_buf) {
|
||||||
|
|
||||||
|
perror("afl_custom_init malloc");
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
data->afl = afl;
|
||||||
|
|
||||||
|
return data;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t afl_custom_fuzz(my_mutator_t *data, uint8_t *buf, size_t buf_size,
|
||||||
|
u8 **out_buf, uint8_t *add_buf,
|
||||||
|
size_t add_buf_size, // add_buf can be NULL
|
||||||
|
size_t max_size) {
|
||||||
|
|
||||||
|
int size = (rand() % 100) + 1;
|
||||||
|
if (size > max_size) size = max_size;
|
||||||
|
|
||||||
|
memset(data->fuzz_buf, _FIXED_CHAR, size);
|
||||||
|
|
||||||
|
*out_buf = data->fuzz_buf;
|
||||||
|
return size;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deinitialize everything
|
||||||
|
*
|
||||||
|
* @param data The data ptr from afl_custom_init
|
||||||
|
*/
|
||||||
|
void afl_custom_deinit(my_mutator_t *data) {
|
||||||
|
|
||||||
|
free(data->fuzz_buf);
|
||||||
|
free(data);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,123 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
from XmlMutatorMin import XmlMutatorMin
|
||||||
|
|
||||||
|
# Default settings (production mode)
|
||||||
|
|
||||||
|
__mutator__ = None
|
||||||
|
__seed__ = "RANDOM"
|
||||||
|
__log__ = False
|
||||||
|
__log_file__ = "wrapper.log"
|
||||||
|
|
||||||
|
|
||||||
|
# AFL functions
|
||||||
|
def log(text):
|
||||||
|
"""
|
||||||
|
Logger
|
||||||
|
"""
|
||||||
|
|
||||||
|
global __seed__
|
||||||
|
global __log__
|
||||||
|
global __log_file__
|
||||||
|
|
||||||
|
if __log__:
|
||||||
|
with open(__log_file__, "a") as logf:
|
||||||
|
logf.write("[%s] %s\n" % (__seed__, text))
|
||||||
|
|
||||||
|
|
||||||
|
def init(seed):
|
||||||
|
"""
|
||||||
|
Called once when AFL starts up. Seed is used to identify the AFL instance in log files
|
||||||
|
"""
|
||||||
|
|
||||||
|
global __mutator__
|
||||||
|
global __seed__
|
||||||
|
|
||||||
|
# Get the seed
|
||||||
|
__seed__ = seed
|
||||||
|
|
||||||
|
# Create a global mutation class
|
||||||
|
try:
|
||||||
|
__mutator__ = XmlMutatorMin(__seed__, verbose=__log__)
|
||||||
|
log("init(): Mutator created")
|
||||||
|
except RuntimeError as e:
|
||||||
|
log("init(): Can't create mutator: %s" % e.message)
|
||||||
|
|
||||||
|
|
||||||
|
def fuzz(buf, add_buf, max_size):
|
||||||
|
"""
|
||||||
|
Called for each fuzzing iteration.
|
||||||
|
"""
|
||||||
|
|
||||||
|
global __mutator__
|
||||||
|
|
||||||
|
# Do we have a working mutator object?
|
||||||
|
if __mutator__ is None:
|
||||||
|
log("fuzz(): Can't fuzz, no mutator available")
|
||||||
|
return buf
|
||||||
|
|
||||||
|
# Try to use the AFL buffer
|
||||||
|
via_buffer = True
|
||||||
|
|
||||||
|
# Interpret the AFL buffer (an array of bytes) as a string
|
||||||
|
if via_buffer:
|
||||||
|
try:
|
||||||
|
buf_str = str(buf)
|
||||||
|
log("fuzz(): AFL buffer converted to a string")
|
||||||
|
except Exception:
|
||||||
|
via_buffer = False
|
||||||
|
log("fuzz(): Can't convert AFL buffer to a string")
|
||||||
|
|
||||||
|
# Load XML from the AFL string
|
||||||
|
if via_buffer:
|
||||||
|
try:
|
||||||
|
__mutator__.init_from_string(buf_str)
|
||||||
|
log(
|
||||||
|
"fuzz(): Mutator successfully initialized with AFL buffer (%d bytes)"
|
||||||
|
% len(buf_str)
|
||||||
|
)
|
||||||
|
except Exception:
|
||||||
|
via_buffer = False
|
||||||
|
log("fuzz(): Can't initialize mutator with AFL buffer")
|
||||||
|
|
||||||
|
# If init from AFL buffer wasn't succesful
|
||||||
|
if not via_buffer:
|
||||||
|
log("fuzz(): Returning unmodified AFL buffer")
|
||||||
|
return buf
|
||||||
|
|
||||||
|
# Sucessful initialization -> mutate
|
||||||
|
try:
|
||||||
|
__mutator__.mutate(max=5)
|
||||||
|
log("fuzz(): Input mutated")
|
||||||
|
except Exception:
|
||||||
|
log("fuzz(): Can't mutate input => returning buf")
|
||||||
|
return buf
|
||||||
|
|
||||||
|
# Convert mutated data to a array of bytes
|
||||||
|
try:
|
||||||
|
data = bytearray(__mutator__.save_to_string())
|
||||||
|
log("fuzz(): Mutated data converted as bytes")
|
||||||
|
except Exception:
|
||||||
|
log("fuzz(): Can't convert mutated data to bytes => returning buf")
|
||||||
|
return buf
|
||||||
|
|
||||||
|
# Everything went fine, returning mutated content
|
||||||
|
log("fuzz(): Returning %d bytes" % len(data))
|
||||||
|
return data
|
||||||
|
|
||||||
|
|
||||||
|
# Main (for debug)
|
||||||
|
if __name__ == "__main__":
|
||||||
|
|
||||||
|
__log__ = True
|
||||||
|
__log_file__ = "/dev/stdout"
|
||||||
|
__seed__ = "RANDOM"
|
||||||
|
|
||||||
|
init(__seed__)
|
||||||
|
|
||||||
|
in_1 = bytearray(
|
||||||
|
"<foo ddd='eeee'>ffff<a b='c' d='456' eee='ffffff'>zzzzzzzzzzzz</a><b yyy='YYY' zzz='ZZZ'></b></foo>"
|
||||||
|
)
|
||||||
|
in_2 = bytearray("<abc abc123='456' abcCBA='ppppppppppppppppppppppppppppp'/>")
|
||||||
|
out = fuzz(in_1, in_2)
|
||||||
|
print(out)
|
@ -0,0 +1 @@
|
|||||||
|
af8dd4a307e7b837f9fa2959549548ace4afe08b
|
@ -0,0 +1,49 @@
|
|||||||
|
# GramaTron
|
||||||
|
|
||||||
|
GramaTron is a coverage-guided fuzzer that uses grammar automatons to perform
|
||||||
|
grammar-aware fuzzing. Technical details about our framework are available in
|
||||||
|
the [ISSTA'21 paper](https://nebelwelt.net/files/21ISSTA.pdf). The artifact to
|
||||||
|
reproduce the experiments presented in the paper are present in `artifact/`.
|
||||||
|
Instructions to run a sample campaign and incorporate new grammars is presented
|
||||||
|
below:
|
||||||
|
|
||||||
|
## Compiling
|
||||||
|
|
||||||
|
Execute `./build_gramatron_mutator.sh`.
|
||||||
|
|
||||||
|
## Running
|
||||||
|
|
||||||
|
You have to set the grammar file to use with `GRAMATRON_AUTOMATION`:
|
||||||
|
|
||||||
|
```
|
||||||
|
export AFL_DISABLE_TRIM=1
|
||||||
|
export AFL_CUSTOM_MUTATOR_ONLY=1
|
||||||
|
export AFL_CUSTOM_MUTATOR_LIBRARY=./gramatron.so
|
||||||
|
export GRAMATRON_AUTOMATION=grammars/ruby/source_automata.json
|
||||||
|
afl-fuzz -i in -o out -- ./target
|
||||||
|
```
|
||||||
|
|
||||||
|
## Adding and testing a new grammar
|
||||||
|
|
||||||
|
- Specify in a JSON format for CFG. Examples are correspond `source.json` files.
|
||||||
|
- Run the automaton generation script (in `src/gramfuzz-mutator/preprocess`)
|
||||||
|
which will place the generated automaton in the same folder.
|
||||||
|
|
||||||
|
```
|
||||||
|
./preprocess/prep_automaton.sh <grammar_file> <start_symbol> [stack_limit]
|
||||||
|
|
||||||
|
E.g., ./preprocess/prep_automaton.sh ~/grammars/ruby/source.json PROGRAM
|
||||||
|
```
|
||||||
|
|
||||||
|
- If the grammar has no self-embedding rules, then you do not need to pass the
|
||||||
|
stack limit parameter. However, if it does have self-embedding rules, then you
|
||||||
|
need to pass the stack limit parameter. We recommend starting with `5` and
|
||||||
|
then increasing it if you need more complexity.
|
||||||
|
- To sanity-check that the automaton is generating inputs as expected, you can
|
||||||
|
use the `test` binary housed in `src/gramfuzz-mutator`.
|
||||||
|
|
||||||
|
```
|
||||||
|
./test SanityCheck <automaton_file>
|
||||||
|
|
||||||
|
E.g., ./test SanityCheck ~/grammars/ruby/source_automata.json
|
||||||
|
```
|
@ -0,0 +1,149 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
#
|
||||||
|
# american fuzzy lop++ - gramatron build script
|
||||||
|
# ------------------------------------------------
|
||||||
|
#
|
||||||
|
# Originally written by Nathan Voss <njvoss99@gmail.com>
|
||||||
|
#
|
||||||
|
# Adapted from code by Andrew Griffiths <agriffiths@google.com> and
|
||||||
|
# Michal Zalewski
|
||||||
|
#
|
||||||
|
# Adapted for AFLplusplus by Dominik Maier <mail@dmnk.co>
|
||||||
|
#
|
||||||
|
# Copyright 2017 Battelle Memorial Institute. All rights reserved.
|
||||||
|
# Copyright 2019-2023 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
|
||||||
|
#
|
||||||
|
# This script downloads, patches, and builds a version of Unicorn with
|
||||||
|
# minor tweaks to allow Unicorn-emulated binaries to be run under
|
||||||
|
# afl-fuzz.
|
||||||
|
#
|
||||||
|
# The modifications reside in patches/*. The standalone Unicorn library
|
||||||
|
# will be written to /usr/lib/libunicornafl.so, and the Python bindings
|
||||||
|
# will be installed system-wide.
|
||||||
|
#
|
||||||
|
# You must make sure that Unicorn Engine is not already installed before
|
||||||
|
# running this script. If it is, please uninstall it first.
|
||||||
|
|
||||||
|
JSONC_VERSION="$(cat ./JSONC_VERSION)"
|
||||||
|
JSONC_REPO="https://github.com/json-c/json-c"
|
||||||
|
|
||||||
|
echo "================================================="
|
||||||
|
echo "Gramatron Mutator build script"
|
||||||
|
echo "================================================="
|
||||||
|
echo
|
||||||
|
|
||||||
|
echo "[*] Performing basic sanity checks..."
|
||||||
|
|
||||||
|
PLT=`uname -s`
|
||||||
|
|
||||||
|
if [ ! -f "../../config.h" ]; then
|
||||||
|
|
||||||
|
echo "[-] Error: key files not found - wrong working directory?"
|
||||||
|
exit 1
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -f "../../src/afl-performance.o" ]; then
|
||||||
|
|
||||||
|
echo "[-] Error: you must build afl-fuzz first and not do a \"make clean\""
|
||||||
|
exit 1
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
PYTHONBIN=`command -v python3 || command -v python || command -v python2 || echo python3`
|
||||||
|
MAKECMD=make
|
||||||
|
TARCMD=tar
|
||||||
|
|
||||||
|
if [ "$PLT" = "Darwin" ]; then
|
||||||
|
CORES=`sysctl -n hw.ncpu`
|
||||||
|
TARCMD=tar
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$PLT" = "FreeBSD" ]; then
|
||||||
|
MAKECMD=gmake
|
||||||
|
CORES=`sysctl -n hw.ncpu`
|
||||||
|
TARCMD=gtar
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$PLT" = "NetBSD" ] || [ "$PLT" = "OpenBSD" ]; then
|
||||||
|
MAKECMD=gmake
|
||||||
|
CORES=`sysctl -n hw.ncpu`
|
||||||
|
TARCMD=gtar
|
||||||
|
fi
|
||||||
|
|
||||||
|
PREREQ_NOTFOUND=
|
||||||
|
for i in git $MAKECMD $TARCMD; do
|
||||||
|
|
||||||
|
T=`command -v "$i" 2>/dev/null`
|
||||||
|
|
||||||
|
if [ "$T" = "" ]; then
|
||||||
|
|
||||||
|
echo "[-] Error: '$i' not found. Run 'sudo apt-get install $i' or similar."
|
||||||
|
PREREQ_NOTFOUND=1
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
done
|
||||||
|
|
||||||
|
test -z "$CC" && export CC=cc
|
||||||
|
|
||||||
|
if echo "$CC" | grep -qF /afl-; then
|
||||||
|
|
||||||
|
echo "[-] Error: do not use afl-gcc or afl-clang to compile this tool."
|
||||||
|
PREREQ_NOTFOUND=1
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$PREREQ_NOTFOUND" = "1" ]; then
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "[+] All checks passed!"
|
||||||
|
|
||||||
|
echo "[*] Making sure json-c is checked out"
|
||||||
|
|
||||||
|
git status 1>/dev/null 2>/dev/null
|
||||||
|
if [ $? -eq 0 ]; then
|
||||||
|
echo "[*] initializing json-c submodule"
|
||||||
|
git submodule init || exit 1
|
||||||
|
git submodule update ./json-c 2>/dev/null # ignore errors
|
||||||
|
else
|
||||||
|
echo "[*] cloning json-c"
|
||||||
|
test -d json-c/.git || {
|
||||||
|
CNT=1
|
||||||
|
while [ '!' -d json-c/.git -a "$CNT" -lt 4 ]; do
|
||||||
|
echo "Trying to clone json-c (attempt $CNT/3)"
|
||||||
|
git clone "$JSONC_REPO"
|
||||||
|
CNT=`expr "$CNT" + 1`
|
||||||
|
done
|
||||||
|
}
|
||||||
|
fi
|
||||||
|
|
||||||
|
test -e json-c/.git || { echo "[-] not checked out, please install git or check your internet connection." ; exit 1 ; }
|
||||||
|
echo "[+] Got json-c."
|
||||||
|
|
||||||
|
test -e json-c/.libs/libjson-c.a || {
|
||||||
|
cd "json-c" || exit 1
|
||||||
|
echo "[*] Checking out $JSONC_VERSION"
|
||||||
|
sh -c 'git stash && git stash drop' 1>/dev/null 2>/dev/null
|
||||||
|
git checkout "$JSONC_VERSION" || exit 1
|
||||||
|
sh autogen.sh || exit 1
|
||||||
|
export CFLAGS=-fPIC
|
||||||
|
./configure --disable-shared || exit 1
|
||||||
|
make || exit 1
|
||||||
|
cd ..
|
||||||
|
}
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo
|
||||||
|
echo "[+] Json-c successfully prepared!"
|
||||||
|
echo "[+] Builing gramatron now."
|
||||||
|
$CC -O3 -g -fPIC -Wno-unused-result -Wl,--allow-multiple-definition -I../../include -o gramatron.so -shared -I. -I/prg/dev/include gramfuzz.c gramfuzz-helpers.c gramfuzz-mutators.c gramfuzz-util.c hashmap.c ../../src/afl-performance.o json-c/.libs/libjson-c.a || exit 1
|
||||||
|
echo
|
||||||
|
echo "[+] gramatron successfully built!"
|
@ -0,0 +1,336 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include "afl-fuzz.h"
|
||||||
|
#include "gramfuzz.h"
|
||||||
|
|
||||||
|
/*Slices from beginning till idx*/
|
||||||
|
Array *slice(Array *input, int idx) {
|
||||||
|
|
||||||
|
// printf("\nSlice idx:%d", idx);
|
||||||
|
terminal *origptr;
|
||||||
|
terminal *term_ptr;
|
||||||
|
Array * sliced = (Array *)malloc(sizeof(Array));
|
||||||
|
initArray(sliced, input->size);
|
||||||
|
// Populate dynamic array members
|
||||||
|
if (idx == 0) { return sliced; }
|
||||||
|
for (int x = 0; x < idx; x++) {
|
||||||
|
|
||||||
|
origptr = &input->start[x];
|
||||||
|
insertArray(sliced, origptr->state, origptr->symbol, origptr->symbol_len,
|
||||||
|
origptr->trigger_idx);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return sliced;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Slices from idx till end*/
|
||||||
|
Array *slice_inverse(Array *input, int idx) {
|
||||||
|
|
||||||
|
// printf("\nSlice idx:%d", idx);
|
||||||
|
terminal *origptr;
|
||||||
|
terminal *term_ptr;
|
||||||
|
Array * sliced = (Array *)malloc(sizeof(Array));
|
||||||
|
initArray(sliced, input->size);
|
||||||
|
for (int x = idx; x < input->used; x++) {
|
||||||
|
|
||||||
|
origptr = &input->start[x];
|
||||||
|
insertArray(sliced, origptr->state, origptr->symbol, origptr->symbol_len,
|
||||||
|
origptr->trigger_idx);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return sliced;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*Carves with `start` included and `end` excluded*/
|
||||||
|
Array *carve(Array *input, int start, int end) {
|
||||||
|
|
||||||
|
terminal *origptr;
|
||||||
|
terminal *term_ptr;
|
||||||
|
Array * sliced = (Array *)malloc(sizeof(Array));
|
||||||
|
initArray(sliced, input->size);
|
||||||
|
for (int x = start; x < end; x++) {
|
||||||
|
|
||||||
|
origptr = &input->start[x];
|
||||||
|
insertArray(sliced, origptr->state, origptr->symbol, origptr->symbol_len,
|
||||||
|
origptr->trigger_idx);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return sliced;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*Concats prefix + feature *mult*/
|
||||||
|
void concatPrefixFeature(Array *prefix, Array *feature) {
|
||||||
|
|
||||||
|
// XXX: Currently we have hardcoded the multiplication threshold for adding
|
||||||
|
// the recursive feature. Might want to fix it to choose a random number upper
|
||||||
|
// bounded by a static value instead.
|
||||||
|
terminal *featureptr;
|
||||||
|
int len = rand_below(global_afl, RECUR_THRESHOLD);
|
||||||
|
for (int x = 0; x < len; x++) {
|
||||||
|
|
||||||
|
for (int y = 0; y < feature->used; y++) {
|
||||||
|
|
||||||
|
featureptr = &feature->start[y];
|
||||||
|
insertArray(prefix, featureptr->state, featureptr->symbol,
|
||||||
|
featureptr->symbol_len, featureptr->trigger_idx);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void concatPrefixFeatureBench(Array *prefix, Array *feature) {
|
||||||
|
|
||||||
|
// XXX: Currently we have hardcoded the multiplication threshold for adding
|
||||||
|
// the recursive feature. Might want to fix it to choose a random number upper
|
||||||
|
// bounded by a static value instead.
|
||||||
|
terminal *featureptr;
|
||||||
|
int len =
|
||||||
|
5; // 5 is the number of times we compare performing random recursion.
|
||||||
|
for (int x = 0; x < len; x++) {
|
||||||
|
|
||||||
|
for (int y = 0; y < feature->used; y++) {
|
||||||
|
|
||||||
|
featureptr = &feature->start[y];
|
||||||
|
insertArray(prefix, featureptr->state, featureptr->symbol,
|
||||||
|
featureptr->symbol_len, featureptr->trigger_idx);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Array *spliceGF(Array *orig, Array *toSplice, int idx) {
|
||||||
|
|
||||||
|
terminal *toSplicePtr;
|
||||||
|
terminal *tempPtr;
|
||||||
|
// Iterate through the splice candidate from the `idx` till end
|
||||||
|
for (int x = idx; x < toSplice->used; x++) {
|
||||||
|
|
||||||
|
toSplicePtr = &toSplice->start[x];
|
||||||
|
insertArray(orig, toSplicePtr->state, toSplicePtr->symbol,
|
||||||
|
toSplicePtr->symbol_len, toSplicePtr->trigger_idx);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return orig;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Array *gen_input(state *pda, Array *input) {
|
||||||
|
|
||||||
|
state * state_ptr;
|
||||||
|
trigger * trigger_ptr;
|
||||||
|
terminal *term_ptr;
|
||||||
|
int offset = 0;
|
||||||
|
int randval, error;
|
||||||
|
// Generating an input for the first time
|
||||||
|
if (input == NULL) {
|
||||||
|
|
||||||
|
input = (Array *)calloc(1, sizeof(Array));
|
||||||
|
initArray(input, INIT_SIZE);
|
||||||
|
curr_state = init_state;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
while (curr_state != final_state) {
|
||||||
|
|
||||||
|
// Retrieving the state from the pda
|
||||||
|
state_ptr = pda + curr_state;
|
||||||
|
|
||||||
|
// Get a random trigger
|
||||||
|
randval = rand_below(global_afl, state_ptr->trigger_len);
|
||||||
|
trigger_ptr = (state_ptr->ptr) + randval;
|
||||||
|
|
||||||
|
// Insert into the dynamic array
|
||||||
|
insertArray(input, curr_state, trigger_ptr->term, trigger_ptr->term_len,
|
||||||
|
randval);
|
||||||
|
curr_state = trigger_ptr->dest;
|
||||||
|
offset += 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return input;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Array *gen_input_count(state *pda, Array *input, int *mut_count) {
|
||||||
|
|
||||||
|
state * state_ptr;
|
||||||
|
trigger * trigger_ptr;
|
||||||
|
terminal *term_ptr;
|
||||||
|
int offset = 0;
|
||||||
|
int randval, error;
|
||||||
|
// Generating an input for the first time
|
||||||
|
if (input == NULL) {
|
||||||
|
|
||||||
|
input = (Array *)calloc(1, sizeof(Array));
|
||||||
|
initArray(input, INIT_SIZE);
|
||||||
|
curr_state = init_state;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
while (curr_state != final_state) {
|
||||||
|
|
||||||
|
*mut_count += 1;
|
||||||
|
// Retrieving the state from the pda
|
||||||
|
state_ptr = pda + curr_state;
|
||||||
|
|
||||||
|
// Get a random trigger
|
||||||
|
randval = rand_below(global_afl, state_ptr->trigger_len);
|
||||||
|
trigger_ptr = (state_ptr->ptr) + randval;
|
||||||
|
|
||||||
|
// Insert into the dynamic array
|
||||||
|
insertArray(input, curr_state, trigger_ptr->term, trigger_ptr->term_len,
|
||||||
|
randval);
|
||||||
|
curr_state = trigger_ptr->dest;
|
||||||
|
offset += 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return input;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*Creates a candidate from walk with state hashmap and
|
||||||
|
* recursion hashmap
|
||||||
|
*/
|
||||||
|
|
||||||
|
Candidate *gen_candidate(Array *input) {
|
||||||
|
|
||||||
|
terminal * term_ptr;
|
||||||
|
IdxMap_new *idxmapPtr;
|
||||||
|
// Declare the State Hash Table
|
||||||
|
IdxMap_new *idxmapStart =
|
||||||
|
(IdxMap_new *)malloc(sizeof(IdxMap_new) * numstates);
|
||||||
|
for (int x = 0; x < numstates; x++) {
|
||||||
|
|
||||||
|
idxmapPtr = &idxmapStart[x];
|
||||||
|
utarray_new(idxmapPtr->nums, &ut_int_icd);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
char * trigger;
|
||||||
|
int state;
|
||||||
|
char * key;
|
||||||
|
Candidate *candidate = (Candidate *)malloc(sizeof(Candidate));
|
||||||
|
candidate->walk = input;
|
||||||
|
int offset = 0, error;
|
||||||
|
|
||||||
|
// Generate statemap for splicing
|
||||||
|
while (offset < input->used) {
|
||||||
|
|
||||||
|
term_ptr = &input->start[offset];
|
||||||
|
state = term_ptr->state;
|
||||||
|
// char *statenum = state + 1;
|
||||||
|
// int num = atoi(statenum);
|
||||||
|
idxmapPtr = &idxmapStart[state];
|
||||||
|
utarray_push_back(idxmapPtr->nums, &offset);
|
||||||
|
offset += 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
candidate->statemap = idxmapStart;
|
||||||
|
return candidate;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
char *get_state(char *trigger) {
|
||||||
|
|
||||||
|
// Get the state from transition
|
||||||
|
int trigger_idx = 0;
|
||||||
|
printf("\nTrigger:%s", trigger);
|
||||||
|
char *state = (char *)malloc(sizeof(char) * 10);
|
||||||
|
while (trigger[trigger_idx] != '_') {
|
||||||
|
|
||||||
|
state[trigger_idx] = trigger[trigger_idx];
|
||||||
|
trigger_idx += 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("\nTrigger Idx:%d", trigger_idx);
|
||||||
|
state[trigger_idx] = '\0';
|
||||||
|
return state;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_repr(Array *input, char *prefix) {
|
||||||
|
|
||||||
|
size_t offset = 0;
|
||||||
|
terminal *term_ptr;
|
||||||
|
char geninput[input->used * 100];
|
||||||
|
if (!input->used) {
|
||||||
|
|
||||||
|
printf("\n=============");
|
||||||
|
printf("\n%s:%s", prefix, "");
|
||||||
|
printf("\n=============");
|
||||||
|
return;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is done to create a null-terminated initial string
|
||||||
|
term_ptr = &input->start[offset];
|
||||||
|
strcpy(geninput, term_ptr->symbol);
|
||||||
|
offset += 1;
|
||||||
|
|
||||||
|
while (offset < input->used) {
|
||||||
|
|
||||||
|
term_ptr = &input->start[offset];
|
||||||
|
strcat(geninput, term_ptr->symbol);
|
||||||
|
offset += 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("\n=============");
|
||||||
|
printf("\n%s:%s", prefix, geninput);
|
||||||
|
printf("\n=============");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// int main(int argc, char*argv[]) {
|
||||||
|
|
||||||
|
// char *mode;
|
||||||
|
// if (argc == 1) {
|
||||||
|
|
||||||
|
// printf("\nUsage: ./gramfuzzer <mode>");
|
||||||
|
// return -1;
|
||||||
|
// }
|
||||||
|
// if (argc >= 2) {
|
||||||
|
|
||||||
|
// mode = argv[1];
|
||||||
|
// printf("\nMode:%s", mode);
|
||||||
|
// }
|
||||||
|
// if (! strcmp(mode, "Generate")) {
|
||||||
|
|
||||||
|
// GenInputBenchmark();
|
||||||
|
// }
|
||||||
|
// else if (! strcmp(mode, "RandomMutation")) {
|
||||||
|
|
||||||
|
// RandomMutationBenchmark();
|
||||||
|
// }
|
||||||
|
// else if (! strcmp(mode, "Splice")) {
|
||||||
|
|
||||||
|
// SpliceMutationBenchmark();
|
||||||
|
// }
|
||||||
|
// else if (! strcmp(mode, "Recursive")) {
|
||||||
|
|
||||||
|
// RandomRecursiveBenchmark();
|
||||||
|
// }
|
||||||
|
// else {
|
||||||
|
|
||||||
|
// printf("\nUnrecognized mode");
|
||||||
|
// return -1;
|
||||||
|
// }
|
||||||
|
// return 0;
|
||||||
|
// }
|
||||||
|
|
@ -0,0 +1,247 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include "afl-fuzz.h"
|
||||||
|
#include "gramfuzz.h"
|
||||||
|
|
||||||
|
Array *performRandomMutation(state *pda, Array *input) {
|
||||||
|
|
||||||
|
terminal *term_ptr;
|
||||||
|
// terminal *prev_ptr;
|
||||||
|
Array *mutated;
|
||||||
|
Array *sliced;
|
||||||
|
|
||||||
|
// Get offset at which to generate new input and slice it
|
||||||
|
int idx = rand_below(global_afl, input->used);
|
||||||
|
sliced = slice(input, idx);
|
||||||
|
// print_repr(sliced, "Slice");
|
||||||
|
|
||||||
|
// prev_ptr = & input->start[idx - 1];
|
||||||
|
// printf("\nState:%s Symbol:%s", prev_ptr->state, prev_ptr->symbol);
|
||||||
|
// Reset current state to that of the slice's last member
|
||||||
|
term_ptr = &input->start[idx];
|
||||||
|
curr_state = term_ptr->state;
|
||||||
|
// printf("\nState:%s Symbol:%s", curr_state, term_ptr->symbol);
|
||||||
|
|
||||||
|
// Set the next available cell to the one adjacent to this chosen point
|
||||||
|
mutated = gen_input(pda, sliced);
|
||||||
|
return mutated;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tries to perform splice operation between two automaton walks
|
||||||
|
UT_icd intpair_icd = {sizeof(intpair_t), NULL, NULL, NULL};
|
||||||
|
|
||||||
|
Array *performSpliceOne(Array *originput, IdxMap_new *statemap_orig,
|
||||||
|
Array *splicecand) {
|
||||||
|
|
||||||
|
UT_array * stateptr, *pairs;
|
||||||
|
intpair_t ip;
|
||||||
|
intpair_t *cand;
|
||||||
|
|
||||||
|
terminal *term_ptr;
|
||||||
|
Array * prefix;
|
||||||
|
int state;
|
||||||
|
|
||||||
|
// Initialize the dynamic holding the splice indice pairs
|
||||||
|
utarray_new(pairs, &intpair_icd);
|
||||||
|
// print_repr(originput, "Orig");
|
||||||
|
// print_repr(splicecand, "SpliceCand");
|
||||||
|
|
||||||
|
// Iterate through the splice candidate identifying potential splice points
|
||||||
|
// and pushing pair (orig_idx, splice_idx) to a dynamic array
|
||||||
|
for (int x = 0; x < splicecand->used; x++) {
|
||||||
|
|
||||||
|
term_ptr = &splicecand->start[x];
|
||||||
|
stateptr = statemap_orig[term_ptr->state].nums;
|
||||||
|
int length = utarray_len(stateptr);
|
||||||
|
if (length) {
|
||||||
|
|
||||||
|
int *splice_idx = (int *)utarray_eltptr(stateptr, rand_below(global_afl, length));
|
||||||
|
ip.orig_idx = *splice_idx;
|
||||||
|
ip.splice_idx = x;
|
||||||
|
utarray_push_back(pairs, &ip);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pick a random pair
|
||||||
|
int length = utarray_len(pairs);
|
||||||
|
cand = (intpair_t *)utarray_eltptr(pairs, rand_below(global_afl, length));
|
||||||
|
// printf("\n Orig_idx:%d Splice_idx:%d", cand->orig_idx, cand->splice_idx);
|
||||||
|
|
||||||
|
// Perform the splicing
|
||||||
|
prefix = slice(originput, cand->orig_idx);
|
||||||
|
Array *spliced = spliceGF(prefix, splicecand, cand->splice_idx);
|
||||||
|
// print_repr(spliced, "Spliced");
|
||||||
|
//
|
||||||
|
utarray_free(pairs);
|
||||||
|
|
||||||
|
return spliced;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
UT_array **get_dupes(Array *input, int *recur_len) {
|
||||||
|
|
||||||
|
// Variables related to finding duplicates
|
||||||
|
int offset = 0;
|
||||||
|
int state;
|
||||||
|
terminal * term_ptr;
|
||||||
|
IdxMap_new *idxMapPtr;
|
||||||
|
UT_array ** recurIdx;
|
||||||
|
|
||||||
|
// Declare the Recursive Map Table
|
||||||
|
IdxMap_new *idxmapStart =
|
||||||
|
(IdxMap_new *)malloc(sizeof(IdxMap_new) * numstates);
|
||||||
|
//
|
||||||
|
// UT_array *(recurIdx[numstates]);
|
||||||
|
recurIdx = malloc(sizeof(UT_array *) * numstates);
|
||||||
|
|
||||||
|
for (int x = 0; x < numstates; x++) {
|
||||||
|
|
||||||
|
idxMapPtr = &idxmapStart[x];
|
||||||
|
utarray_new(idxMapPtr->nums, &ut_int_icd);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Obtain frequency distribution of states
|
||||||
|
while (offset < input->used) {
|
||||||
|
|
||||||
|
term_ptr = &input->start[offset];
|
||||||
|
state = term_ptr->state;
|
||||||
|
// int num = atoi(state + 1);
|
||||||
|
idxMapPtr = &idxmapStart[state];
|
||||||
|
utarray_push_back(idxMapPtr->nums, &offset);
|
||||||
|
offset += 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Retrieve the duplicated states
|
||||||
|
offset = 0;
|
||||||
|
while (offset < numstates) {
|
||||||
|
|
||||||
|
idxMapPtr = &idxmapStart[offset];
|
||||||
|
int length = utarray_len(idxMapPtr->nums);
|
||||||
|
if (length >= 2) {
|
||||||
|
|
||||||
|
recurIdx[*recur_len] = idxMapPtr->nums;
|
||||||
|
*recur_len += 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// else {
|
||||||
|
|
||||||
|
// utarray_free(idxMapPtr->nums);
|
||||||
|
// }
|
||||||
|
offset += 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*recur_len) {
|
||||||
|
|
||||||
|
// Declare the return struct
|
||||||
|
// We use this struct so that we save the reference to IdxMap_new and free
|
||||||
|
// it after we have used it in doMult
|
||||||
|
// Get_Dupes_Ret* getdupesret =
|
||||||
|
// (Get_Dupes_Ret*)malloc(sizeof(Get_Dupes_Ret));
|
||||||
|
return recurIdx;
|
||||||
|
// getdupesret->idxmap = idxmapStart;
|
||||||
|
// getdupesret->recurIdx = recurIdx;
|
||||||
|
// return getdupesret;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Array *doMult(Array *input, UT_array **recur, int recurlen) {
|
||||||
|
|
||||||
|
int offset = 0;
|
||||||
|
int idx = rand_below(global_afl, recurlen);
|
||||||
|
UT_array *recurMap = recur[idx];
|
||||||
|
UT_array *recurPtr;
|
||||||
|
Array * prefix;
|
||||||
|
Array * postfix;
|
||||||
|
Array * feature;
|
||||||
|
|
||||||
|
// Choose two indices to get the recursive feature
|
||||||
|
int recurIndices = utarray_len(recurMap);
|
||||||
|
int firstIdx = 0;
|
||||||
|
int secondIdx = 0;
|
||||||
|
getTwoIndices(recurMap, recurIndices, &firstIdx, &secondIdx);
|
||||||
|
|
||||||
|
// Perform the recursive mut
|
||||||
|
// print_repr(input, "Orig");
|
||||||
|
prefix = slice(input, firstIdx);
|
||||||
|
// print_repr(prefix, "Prefix");
|
||||||
|
if (firstIdx < secondIdx) {
|
||||||
|
|
||||||
|
feature = carve(input, firstIdx, secondIdx);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
feature = carve(input, secondIdx, firstIdx);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// print_repr(feature, "Feature");
|
||||||
|
concatPrefixFeature(prefix, feature);
|
||||||
|
|
||||||
|
// GC allocated structures
|
||||||
|
free(feature->start);
|
||||||
|
free(feature);
|
||||||
|
// for(int x = 0; x < recurlen; x++) {
|
||||||
|
|
||||||
|
// utarray_free(recur[x]);
|
||||||
|
// }
|
||||||
|
// free(recur);
|
||||||
|
// print_repr(prefix, "Concat");
|
||||||
|
return spliceGF(prefix, input, secondIdx);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void getTwoIndices(UT_array *recur, int recurlen, int *firstIdx,
|
||||||
|
int *secondIdx) {
|
||||||
|
|
||||||
|
int ArrayRecurIndices[recurlen];
|
||||||
|
int offset = 0, *p;
|
||||||
|
// Unroll into an array
|
||||||
|
for (p = (int *)utarray_front(recur); p != NULL;
|
||||||
|
p = (int *)utarray_next(recur, p)) {
|
||||||
|
|
||||||
|
ArrayRecurIndices[offset] = *p;
|
||||||
|
offset += 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*Source:
|
||||||
|
* https://www.geeksforgeeks.org/shuffle-a-given-array-using-fisher-yates-shuffle-algorithm/
|
||||||
|
*/
|
||||||
|
for (int i = offset - 1; i > 0; i--) {
|
||||||
|
|
||||||
|
// Pick a random index from 0 to i
|
||||||
|
int j = rand_below(global_afl, i + 1);
|
||||||
|
|
||||||
|
// Swap arr[i] with the element at random index
|
||||||
|
swap(&ArrayRecurIndices[i], &ArrayRecurIndices[j]);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
*firstIdx = ArrayRecurIndices[0];
|
||||||
|
*secondIdx = ArrayRecurIndices[1];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void swap(int *a, int *b) {
|
||||||
|
|
||||||
|
int temp = *a;
|
||||||
|
*a = *b;
|
||||||
|
*b = temp;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,268 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include "afl-fuzz.h"
|
||||||
|
#include "gramfuzz.h"
|
||||||
|
#ifdef _GNU_SOURCE
|
||||||
|
#undef _GNU_SOURCE
|
||||||
|
#endif
|
||||||
|
#define _GNU_SOURCE
|
||||||
|
#include <sys/mman.h>
|
||||||
|
|
||||||
|
/* Dynamic Array for adding to the input repr
|
||||||
|
* */
|
||||||
|
void initArray(Array *a, size_t initialSize) {
|
||||||
|
|
||||||
|
a->start = (terminal *)calloc(1, sizeof(terminal) * initialSize);
|
||||||
|
a->used = 0;
|
||||||
|
a->size = initialSize;
|
||||||
|
a->inputlen = 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void insertArray(Array *a, int state, char *symbol, size_t symbol_len,
|
||||||
|
int trigger_idx) {
|
||||||
|
|
||||||
|
// a->used is the number of used entries, because a->array[a->used++] updates
|
||||||
|
// a->used only *after* the array has been accessed. Therefore a->used can go
|
||||||
|
// up to a->size
|
||||||
|
terminal *term_ptr;
|
||||||
|
if (a->used == a->size) {
|
||||||
|
|
||||||
|
a->size = a->size * sizeof(terminal);
|
||||||
|
a->start = (terminal *)realloc(a->start, a->size * sizeof(terminal));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add the element
|
||||||
|
term_ptr = &a->start[a->used];
|
||||||
|
term_ptr->state = state;
|
||||||
|
term_ptr->symbol = symbol;
|
||||||
|
term_ptr->symbol_len = symbol_len;
|
||||||
|
term_ptr->trigger_idx = trigger_idx;
|
||||||
|
|
||||||
|
// Increment the pointer
|
||||||
|
a->used += 1;
|
||||||
|
a->inputlen += symbol_len;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void freeArray(Array *a) {
|
||||||
|
|
||||||
|
terminal *ptr;
|
||||||
|
for (int x = 0; x < a->used; x++) {
|
||||||
|
|
||||||
|
ptr = &a->start[x];
|
||||||
|
free(ptr);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
a->start = NULL;
|
||||||
|
a->used = a->size = 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Dynamic array for adding indices of states/recursive features
|
||||||
|
* Source:
|
||||||
|
* https://stackoverflow.com/questions/3536153/c-dynamically-growing-array
|
||||||
|
*/
|
||||||
|
void initArrayIdx(IdxMap *a, size_t initialSize) {
|
||||||
|
|
||||||
|
a->array = (int *)malloc(initialSize * sizeof(int));
|
||||||
|
a->used = 0;
|
||||||
|
a->size = initialSize;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void insertArrayIdx(IdxMap *a, int idx) {
|
||||||
|
|
||||||
|
// a->used is the number of used entries, because a->array[a->used++] updates
|
||||||
|
// a->used only *after* the array has been accessed. Therefore a->used can go
|
||||||
|
// up to a->size
|
||||||
|
if (a->used == a->size) {
|
||||||
|
|
||||||
|
a->size *= 2;
|
||||||
|
a->array = (int *)realloc(a->array, a->size * sizeof(int));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
a->array[a->used++] = idx;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void freeArrayIdx(IdxMap *a) {
|
||||||
|
|
||||||
|
free(a->array);
|
||||||
|
a->array = NULL;
|
||||||
|
a->used = a->size = 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Dynamic array for adding potential splice points
|
||||||
|
*/
|
||||||
|
void initArraySplice(SpliceCandArray *a, size_t initialSize) {
|
||||||
|
|
||||||
|
a->start = (SpliceCand *)malloc(initialSize * sizeof(SpliceCand));
|
||||||
|
a->used = 0;
|
||||||
|
a->size = initialSize;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void insertArraySplice(SpliceCandArray *a, Candidate *candidate, int idx) {
|
||||||
|
|
||||||
|
// a->used is the number of used entries, because a->array[a->used++] updates
|
||||||
|
// a->used only *after* the array has been accessed. Therefore a->used can go
|
||||||
|
// up to a->size
|
||||||
|
SpliceCand *candptr;
|
||||||
|
if (a->used == a->size) {
|
||||||
|
|
||||||
|
a->size = a->size * sizeof(SpliceCand);
|
||||||
|
a->start = (SpliceCand *)realloc(a->start, a->size * sizeof(SpliceCand));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add the element
|
||||||
|
candptr = &a->start[a->used];
|
||||||
|
candptr->splice_cand = candidate;
|
||||||
|
candptr->idx = idx;
|
||||||
|
a->used += 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void freeArraySplice(IdxMap *a) {
|
||||||
|
|
||||||
|
free(a->array);
|
||||||
|
a->array = NULL;
|
||||||
|
a->used = a->size = 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int fact(int n) {
|
||||||
|
|
||||||
|
int i, f = 1;
|
||||||
|
for (i = 1; i <= n; i++) {
|
||||||
|
|
||||||
|
f *= i;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return f;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Uses the walk to create the input in-memory */
|
||||||
|
u8 *unparse_walk(Array *input) {
|
||||||
|
|
||||||
|
terminal *term_ptr;
|
||||||
|
int offset = 0;
|
||||||
|
u8 * unparsed = (u8 *)malloc(input->inputlen + 1);
|
||||||
|
term_ptr = &input->start[offset];
|
||||||
|
strcpy(unparsed, term_ptr->symbol);
|
||||||
|
offset += 1;
|
||||||
|
while (offset < input->used) {
|
||||||
|
|
||||||
|
term_ptr = &input->start[offset];
|
||||||
|
strcat(unparsed, term_ptr->symbol);
|
||||||
|
offset += 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return unparsed;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*Dump the input representation into a file*/
|
||||||
|
void write_input(Array *input, u8 *fn) {
|
||||||
|
|
||||||
|
FILE *fp;
|
||||||
|
// If file already exists, then skip creating the file
|
||||||
|
if (access(fn, F_OK) != -1) { return; }
|
||||||
|
|
||||||
|
fp = fopen(fn, "wbx+");
|
||||||
|
// If the input has already been flushed, then skip silently
|
||||||
|
if (fp == NULL) {
|
||||||
|
|
||||||
|
fprintf(stderr, "\n File '%s' could not be open, exiting\n", fn);
|
||||||
|
exit(1);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write the length parameters
|
||||||
|
fwrite(&input->used, sizeof(size_t), 1, fp);
|
||||||
|
fwrite(&input->size, sizeof(size_t), 1, fp);
|
||||||
|
fwrite(&input->inputlen, sizeof(size_t), 1, fp);
|
||||||
|
|
||||||
|
// Write the dynamic array to file
|
||||||
|
fwrite(input->start, input->size * sizeof(terminal), 1, fp);
|
||||||
|
// printf("\nUsed:%zu Size:%zu Inputlen:%zu", input->used, input->size,
|
||||||
|
// input->inputlen);
|
||||||
|
fclose(fp);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Array *parse_input(state *pda, FILE *fp) {
|
||||||
|
|
||||||
|
terminal *term;
|
||||||
|
state * state_ptr;
|
||||||
|
trigger * trigger;
|
||||||
|
int trigger_idx;
|
||||||
|
Array * input = (Array *)calloc(1, sizeof(Array));
|
||||||
|
|
||||||
|
// Read the length parameters
|
||||||
|
fread(&input->used, sizeof(size_t), 1, fp);
|
||||||
|
fread(&input->size, sizeof(size_t), 1, fp);
|
||||||
|
fread(&input->inputlen, sizeof(size_t), 1, fp);
|
||||||
|
|
||||||
|
terminal *start_ptr = (terminal *)calloc(input->size, sizeof(terminal));
|
||||||
|
if (!start_ptr) {
|
||||||
|
|
||||||
|
fprintf(stderr, "alloc failed!\n");
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read the dynamic array to memory
|
||||||
|
fread(start_ptr, input->size * sizeof(terminal), 1, fp);
|
||||||
|
// Update the pointers to the terminals since they would have
|
||||||
|
// changed
|
||||||
|
int idx = 0;
|
||||||
|
while (idx < input->used) {
|
||||||
|
|
||||||
|
terminal *term = &start_ptr[idx];
|
||||||
|
// Find the state
|
||||||
|
state_ptr = pda + term->state;
|
||||||
|
// Find the trigger and update the terminal address
|
||||||
|
trigger_idx = term->trigger_idx;
|
||||||
|
trigger = (state_ptr->ptr) + trigger_idx;
|
||||||
|
term->symbol = trigger->term;
|
||||||
|
idx += 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
input->start = start_ptr;
|
||||||
|
// printf("\nUsed:%zu Size:%zu Inputlen:%zu", input->used, input->size,
|
||||||
|
// input->inputlen);
|
||||||
|
|
||||||
|
return input;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read the input representation into memory
|
||||||
|
Array *read_input(state *pda, u8 *fn) {
|
||||||
|
|
||||||
|
FILE *fp;
|
||||||
|
fp = fopen(fn, "rb");
|
||||||
|
if (fp == NULL) {
|
||||||
|
|
||||||
|
fprintf(stderr, "\n File '%s' does not exist, exiting\n", fn);
|
||||||
|
exit(1);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Array *res = parse_input(pda, fp);
|
||||||
|
fclose(fp);
|
||||||
|
return res;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,429 @@
|
|||||||
|
// This simple example just creates random buffer <= 100 filled with 'A'
|
||||||
|
// needs -I /path/to/AFLplusplus/include
|
||||||
|
//#include "custom_mutator_helpers.h"
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "afl-fuzz.h"
|
||||||
|
#include "gramfuzz.h"
|
||||||
|
|
||||||
|
#define MUTATORS 4 // Specify the total number of mutators
|
||||||
|
|
||||||
|
typedef struct my_mutator {
|
||||||
|
|
||||||
|
afl_state_t *afl;
|
||||||
|
|
||||||
|
u8 * mutator_buf;
|
||||||
|
u8 * unparsed_input;
|
||||||
|
Array *mutated_walk;
|
||||||
|
Array *orig_walk;
|
||||||
|
|
||||||
|
IdxMap_new *statemap; // Keeps track of the statemap
|
||||||
|
UT_array ** recurIdx;
|
||||||
|
// Get_Dupes_Ret* getdupesret; // Recursive feature map
|
||||||
|
int recurlen;
|
||||||
|
|
||||||
|
int mut_alloced;
|
||||||
|
int orig_alloced;
|
||||||
|
int mut_idx; // Signals the current mutator being used, used to cycle through
|
||||||
|
// each mutator
|
||||||
|
|
||||||
|
unsigned int seed;
|
||||||
|
|
||||||
|
} my_mutator_t;
|
||||||
|
|
||||||
|
state *create_pda(u8 *automaton_file) {
|
||||||
|
|
||||||
|
struct json_object *parsed_json;
|
||||||
|
state * pda;
|
||||||
|
json_object * source_obj, *attr;
|
||||||
|
int arraylen, ii, ii2, trigger_len, error;
|
||||||
|
|
||||||
|
printf("\n[GF] Automaton file passed:%s", automaton_file);
|
||||||
|
// parsed_json =
|
||||||
|
// json_object_from_file("./gramfuzz/php_gnf_processed_full.json");
|
||||||
|
parsed_json = json_object_from_file(automaton_file);
|
||||||
|
|
||||||
|
// Getting final state
|
||||||
|
source_obj = json_object_object_get(parsed_json, "final_state");
|
||||||
|
printf("\t\nFinal=%s\n", json_object_get_string(source_obj));
|
||||||
|
final_state = atoi(json_object_get_string(source_obj));
|
||||||
|
|
||||||
|
// Getting initial state
|
||||||
|
source_obj = json_object_object_get(parsed_json, "init_state");
|
||||||
|
init_state = atoi(json_object_get_string(source_obj));
|
||||||
|
printf("\tInit=%s\n", json_object_get_string(source_obj));
|
||||||
|
|
||||||
|
// Getting number of states
|
||||||
|
source_obj = json_object_object_get(parsed_json, "numstates");
|
||||||
|
numstates = atoi(json_object_get_string(source_obj)) + 1;
|
||||||
|
printf("\tNumStates=%d\n", numstates);
|
||||||
|
|
||||||
|
// Allocate state space for each pda state
|
||||||
|
pda = (state *)calloc(atoi(json_object_get_string(source_obj)) + 1,
|
||||||
|
sizeof(state));
|
||||||
|
|
||||||
|
// Getting PDA representation
|
||||||
|
source_obj = json_object_object_get(parsed_json, "pda");
|
||||||
|
enum json_type type;
|
||||||
|
json_object_object_foreach(source_obj, key, val) {
|
||||||
|
|
||||||
|
state * state_ptr;
|
||||||
|
trigger *trigger_ptr;
|
||||||
|
int offset;
|
||||||
|
|
||||||
|
// Get the correct offset into the pda to store state information
|
||||||
|
state_ptr = pda;
|
||||||
|
offset = atoi(key);
|
||||||
|
state_ptr += offset;
|
||||||
|
// Store state string
|
||||||
|
state_ptr->state_name = offset;
|
||||||
|
|
||||||
|
// Create trigger array of structs
|
||||||
|
trigger_len = json_object_array_length(val);
|
||||||
|
state_ptr->trigger_len = trigger_len;
|
||||||
|
trigger_ptr = (trigger *)calloc(trigger_len, sizeof(trigger));
|
||||||
|
state_ptr->ptr = trigger_ptr;
|
||||||
|
|
||||||
|
for (ii = 0; ii < trigger_len; ii++) {
|
||||||
|
|
||||||
|
json_object *obj = json_object_array_get_idx(val, ii);
|
||||||
|
// Get all the trigger trigger attributes
|
||||||
|
attr = json_object_array_get_idx(obj, 0);
|
||||||
|
(trigger_ptr)->id = strdup(json_object_get_string(attr));
|
||||||
|
|
||||||
|
attr = json_object_array_get_idx(obj, 1);
|
||||||
|
trigger_ptr->dest = atoi(json_object_get_string(attr));
|
||||||
|
|
||||||
|
attr = json_object_array_get_idx(obj, 2);
|
||||||
|
if (!strcmp("\\n", json_object_get_string(attr))) {
|
||||||
|
|
||||||
|
trigger_ptr->term = strdup("\n");
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
trigger_ptr->term = strdup(json_object_get_string(attr));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
trigger_ptr->term_len = strlen(trigger_ptr->term);
|
||||||
|
trigger_ptr++;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete the JSON object
|
||||||
|
json_object_put(parsed_json);
|
||||||
|
|
||||||
|
return pda;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
my_mutator_t *afl_custom_init(afl_state_t *afl, unsigned int seed) {
|
||||||
|
|
||||||
|
my_mutator_t *data = calloc(1, sizeof(my_mutator_t));
|
||||||
|
if (!data) {
|
||||||
|
|
||||||
|
perror("afl_custom_init alloc");
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((data->mutator_buf = malloc(MAX_FILE)) == NULL) {
|
||||||
|
|
||||||
|
perror("mutator_buf alloc");
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
data->afl = afl;
|
||||||
|
global_afl = afl; // dirty
|
||||||
|
data->seed = seed;
|
||||||
|
|
||||||
|
data->mut_alloced = 0;
|
||||||
|
data->orig_alloced = 0;
|
||||||
|
data->mut_idx = 0;
|
||||||
|
data->recurlen = 0;
|
||||||
|
|
||||||
|
// data->mutator_buf = NULL;
|
||||||
|
// data->unparsed_input = NULL;
|
||||||
|
// data->mutated_walk = NULL;
|
||||||
|
// data->orig_walk = NULL;
|
||||||
|
//
|
||||||
|
// data->statemap = NULL; // Keeps track of the statemap
|
||||||
|
// data->recur_idx = NULL; // Will keep track of recursive feature indices
|
||||||
|
// u32 recur_len = 0; // The number of recursive features
|
||||||
|
// data->mutator_buf = NULL;
|
||||||
|
|
||||||
|
char *automaton_file = getenv("GRAMATRON_AUTOMATION");
|
||||||
|
if (automaton_file) {
|
||||||
|
|
||||||
|
pda = create_pda(automaton_file);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
fprintf(stderr,
|
||||||
|
"\nError: GrammaTron needs an automation json file set in "
|
||||||
|
"GRAMATRON_AUTOMATION\n");
|
||||||
|
exit(-1);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return data;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t afl_custom_fuzz(my_mutator_t *data, uint8_t *buf, size_t buf_size,
|
||||||
|
u8 **out_buf, uint8_t *add_buf, size_t add_buf_size,
|
||||||
|
size_t max_size) {
|
||||||
|
|
||||||
|
u8 *unparsed_input;
|
||||||
|
|
||||||
|
// Pick a mutator
|
||||||
|
// int choice = rand() % MUTATORS;
|
||||||
|
// data->mut_idx = 1;
|
||||||
|
// GC old mutant
|
||||||
|
if (data->mut_alloced) {
|
||||||
|
|
||||||
|
free(data->mutated_walk->start);
|
||||||
|
free(data->mutated_walk);
|
||||||
|
data->mut_alloced = 0;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
// printf("\nChoice:%d", choice);
|
||||||
|
|
||||||
|
if (data->mut_idx == 0) { // Perform random mutation
|
||||||
|
data->mutated_walk = performRandomMutation(pda, data->orig_walk);
|
||||||
|
data->mut_alloced = 1;
|
||||||
|
|
||||||
|
} else if (data->mut_idx == 1 &&
|
||||||
|
|
||||||
|
data->recurlen) { // Perform recursive mutation
|
||||||
|
data->mutated_walk =
|
||||||
|
doMult(data->orig_walk, data->recurIdx, data->recurlen);
|
||||||
|
data->mut_alloced = 1;
|
||||||
|
|
||||||
|
} else if (data->mut_idx == 2) { // Perform splice mutation
|
||||||
|
|
||||||
|
// we cannot use the supplied splice data so choose a new random file
|
||||||
|
u32 tid = rand_below(global_afl, data->afl->queued_items);
|
||||||
|
struct queue_entry *q = data->afl->queue_buf[tid];
|
||||||
|
|
||||||
|
// Read the input representation for the splice candidate
|
||||||
|
u8 * automaton_fn = alloc_printf("%s.aut", q->fname);
|
||||||
|
Array *spliceCandidate = read_input(pda, automaton_fn);
|
||||||
|
|
||||||
|
if (spliceCandidate) {
|
||||||
|
|
||||||
|
data->mutated_walk =
|
||||||
|
performSpliceOne(data->orig_walk, data->statemap, spliceCandidate);
|
||||||
|
data->mut_alloced = 1;
|
||||||
|
free(spliceCandidate->start);
|
||||||
|
free(spliceCandidate);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
data->mutated_walk = gen_input(pda, NULL);
|
||||||
|
data->mut_alloced = 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ck_free(automaton_fn);
|
||||||
|
|
||||||
|
} else { // Generate an input from scratch
|
||||||
|
|
||||||
|
data->mutated_walk = gen_input(pda, NULL);
|
||||||
|
data->mut_alloced = 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cycle to the next mutator
|
||||||
|
if (data->mut_idx == MUTATORS - 1)
|
||||||
|
data->mut_idx =
|
||||||
|
0; // Wrap around if we have reached end of the mutator list
|
||||||
|
else
|
||||||
|
data->mut_idx += 1;
|
||||||
|
|
||||||
|
// Unparse the mutated automaton walk
|
||||||
|
if (data->unparsed_input) { free(data->unparsed_input); }
|
||||||
|
data->unparsed_input = unparse_walk(data->mutated_walk);
|
||||||
|
*out_buf = data->unparsed_input;
|
||||||
|
|
||||||
|
return data->mutated_walk->inputlen;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create the automaton-based representation for the corresponding input
|
||||||
|
*
|
||||||
|
* @param data pointer returned in afl_custom_init for this fuzz case
|
||||||
|
* @param filename_new_queue File name of the new queue entry
|
||||||
|
* @param filename_orig_queue File name of the original queue entry
|
||||||
|
*/
|
||||||
|
u8 afl_custom_queue_new_entry(my_mutator_t * data,
|
||||||
|
const uint8_t *filename_new_queue,
|
||||||
|
const uint8_t *filename_orig_queue) {
|
||||||
|
|
||||||
|
// get the filename
|
||||||
|
u8 * automaton_fn, *unparsed_input;
|
||||||
|
Array *new_input;
|
||||||
|
s32 fd;
|
||||||
|
|
||||||
|
automaton_fn = alloc_printf("%s.aut", filename_new_queue);
|
||||||
|
// Check if this method is being called during initialization
|
||||||
|
|
||||||
|
// fprintf(stderr, "new: %s, old: %s, auto: %s\n",
|
||||||
|
// filename_new_queue,filename_orig_queue,automaton_fn);
|
||||||
|
|
||||||
|
if (filename_orig_queue) {
|
||||||
|
|
||||||
|
write_input(data->mutated_walk, automaton_fn);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
new_input = gen_input(pda, NULL);
|
||||||
|
write_input(new_input, automaton_fn);
|
||||||
|
|
||||||
|
// Update the placeholder file
|
||||||
|
if (unlink(filename_new_queue)) {
|
||||||
|
|
||||||
|
PFATAL("Unable to delete '%s'", filename_new_queue);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
unparsed_input = unparse_walk(new_input);
|
||||||
|
fd = open(filename_new_queue, O_WRONLY | O_CREAT | O_TRUNC,
|
||||||
|
S_IRUSR | S_IWUSR);
|
||||||
|
if (fd < 0) { PFATAL("Failed to update file '%s'", filename_new_queue); }
|
||||||
|
int written = write(fd, unparsed_input, new_input->inputlen + 1);
|
||||||
|
close(fd);
|
||||||
|
|
||||||
|
free(new_input->start);
|
||||||
|
free(new_input);
|
||||||
|
free(unparsed_input);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ck_free(automaton_fn);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the corresponding tree representation for the candidate that is to be
|
||||||
|
* mutated
|
||||||
|
*
|
||||||
|
* @param[in] data pointer returned in afl_custom_init for this fuzz case
|
||||||
|
* @param filename File name of the test case in the queue entry
|
||||||
|
* @return Return True(1) if the fuzzer will fuzz the queue entry, and
|
||||||
|
* False(0) otherwise.
|
||||||
|
*/
|
||||||
|
uint8_t afl_custom_queue_get(my_mutator_t *data, const uint8_t *filename) {
|
||||||
|
|
||||||
|
// get the filename
|
||||||
|
u8 * automaton_fn = alloc_printf("%s.aut", filename);
|
||||||
|
IdxMap_new *statemap_ptr;
|
||||||
|
terminal * term_ptr;
|
||||||
|
int state;
|
||||||
|
|
||||||
|
// TODO: I don't think we need to update pointers when reading back
|
||||||
|
// Probably build two different versions of read_input one for flushing
|
||||||
|
// inputs to disk and the other that
|
||||||
|
if (data->orig_alloced) {
|
||||||
|
|
||||||
|
free(data->orig_walk->start);
|
||||||
|
free(data->orig_walk);
|
||||||
|
data->orig_alloced = 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data->statemap) {
|
||||||
|
|
||||||
|
for (int x = 0; x < numstates; x++) {
|
||||||
|
|
||||||
|
utarray_free(data->statemap[x].nums);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
free(data->statemap);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data->recurIdx) {
|
||||||
|
|
||||||
|
data->recurlen = 0;
|
||||||
|
free(data->recurIdx);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
data->orig_walk = read_input(pda, automaton_fn);
|
||||||
|
data->orig_alloced = 1;
|
||||||
|
|
||||||
|
// Create statemap for the fuzz candidate
|
||||||
|
IdxMap_new *statemap_start =
|
||||||
|
(IdxMap_new *)malloc(sizeof(IdxMap_new) * numstates);
|
||||||
|
for (int x = 0; x < numstates; x++) {
|
||||||
|
|
||||||
|
statemap_ptr = &statemap_start[x];
|
||||||
|
utarray_new(statemap_ptr->nums, &ut_int_icd);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int offset = 0;
|
||||||
|
while (offset < data->orig_walk->used) {
|
||||||
|
|
||||||
|
term_ptr = &data->orig_walk->start[offset];
|
||||||
|
state = term_ptr->state;
|
||||||
|
statemap_ptr = &statemap_start[state];
|
||||||
|
utarray_push_back(statemap_ptr->nums, &offset);
|
||||||
|
offset += 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
data->statemap = statemap_start;
|
||||||
|
|
||||||
|
// Create recursive feature map (if it exists)
|
||||||
|
data->recurIdx = malloc(sizeof(UT_array *) * numstates);
|
||||||
|
// Retrieve the duplicated states
|
||||||
|
offset = 0;
|
||||||
|
while (offset < numstates) {
|
||||||
|
|
||||||
|
statemap_ptr = &data->statemap[offset];
|
||||||
|
int length = utarray_len(statemap_ptr->nums);
|
||||||
|
if (length >= 2) {
|
||||||
|
|
||||||
|
data->recurIdx[data->recurlen] = statemap_ptr->nums;
|
||||||
|
data->recurlen += 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
offset += 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// data->getdupesret = get_dupes(data->orig_walk, &data->recurlen);
|
||||||
|
|
||||||
|
ck_free(automaton_fn);
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deinitialize everything
|
||||||
|
*
|
||||||
|
* @param data The data ptr from afl_custom_init
|
||||||
|
*/
|
||||||
|
|
||||||
|
void afl_custom_deinit(my_mutator_t *data) {
|
||||||
|
|
||||||
|
free(data->mutator_buf);
|
||||||
|
free(data);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,255 @@
|
|||||||
|
#ifndef _GRAMFUZZ_H
|
||||||
|
|
||||||
|
#define _GRAMFUZZ_H
|
||||||
|
|
||||||
|
#include <json-c/json.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include "hashmap.h"
|
||||||
|
#include "uthash.h"
|
||||||
|
#include "utarray.h"
|
||||||
|
|
||||||
|
#define INIT_INPUTS 100 // No. of initial inputs to be generated
|
||||||
|
|
||||||
|
// Set this as `numstates` + 1 where `numstates` is retrieved from gen automata
|
||||||
|
// json #define STATES 63
|
||||||
|
|
||||||
|
#define INIT_SIZE 100 // Initial size of the dynamic array holding the input
|
||||||
|
|
||||||
|
#define SPLICE_CORPUS 10000
|
||||||
|
#define RECUR_THRESHOLD 6
|
||||||
|
#define SIZE_THRESHOLD 2048
|
||||||
|
|
||||||
|
#define FLUSH_INTERVAL \
|
||||||
|
3600 // Inputs that gave new coverage will be dumped every FLUSH_INTERVAL
|
||||||
|
// seconds
|
||||||
|
|
||||||
|
afl_state_t *global_afl;
|
||||||
|
|
||||||
|
typedef struct trigger {
|
||||||
|
|
||||||
|
char * id;
|
||||||
|
int dest;
|
||||||
|
char * term;
|
||||||
|
size_t term_len;
|
||||||
|
|
||||||
|
} trigger;
|
||||||
|
|
||||||
|
typedef struct state {
|
||||||
|
|
||||||
|
int state_name; // Integer State name
|
||||||
|
int trigger_len; // Number of triggers associated with this state
|
||||||
|
trigger *ptr; // Pointer to beginning of the list of triggers
|
||||||
|
|
||||||
|
} state;
|
||||||
|
|
||||||
|
typedef struct terminal {
|
||||||
|
|
||||||
|
int state;
|
||||||
|
int trigger_idx;
|
||||||
|
size_t symbol_len;
|
||||||
|
char * symbol;
|
||||||
|
|
||||||
|
} terminal;
|
||||||
|
|
||||||
|
typedef struct buckethash {
|
||||||
|
|
||||||
|
int freq;
|
||||||
|
|
||||||
|
} buckethash;
|
||||||
|
|
||||||
|
int init_state;
|
||||||
|
int curr_state;
|
||||||
|
int final_state;
|
||||||
|
int numstates;
|
||||||
|
|
||||||
|
/*****************
|
||||||
|
/ DYNAMIC ARRAY FOR WALKS
|
||||||
|
*****************/
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
|
||||||
|
size_t used;
|
||||||
|
size_t size;
|
||||||
|
size_t inputlen;
|
||||||
|
terminal *start;
|
||||||
|
|
||||||
|
} Array;
|
||||||
|
|
||||||
|
/*****************
|
||||||
|
/ DYNAMIC ARRAY FOR STATEMAPS/RECURSION MAPS
|
||||||
|
*****************/
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
|
||||||
|
int * array;
|
||||||
|
size_t used;
|
||||||
|
size_t size;
|
||||||
|
|
||||||
|
} IdxMap;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
|
||||||
|
UT_array *nums;
|
||||||
|
|
||||||
|
} IdxMap_new;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
|
||||||
|
IdxMap_new *idxmap;
|
||||||
|
UT_array ** recurIdx;
|
||||||
|
|
||||||
|
} Get_Dupes_Ret;
|
||||||
|
|
||||||
|
/* Candidate Struct */
|
||||||
|
typedef struct {
|
||||||
|
|
||||||
|
Array * walk;
|
||||||
|
IdxMap_new *statemap;
|
||||||
|
|
||||||
|
} Candidate;
|
||||||
|
|
||||||
|
/* Splice Mutation helpers*/
|
||||||
|
typedef struct {
|
||||||
|
|
||||||
|
Candidate *splice_cand;
|
||||||
|
int idx;
|
||||||
|
|
||||||
|
} SpliceCand;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
|
||||||
|
SpliceCand *start;
|
||||||
|
size_t used;
|
||||||
|
size_t size;
|
||||||
|
|
||||||
|
} SpliceCandArray;
|
||||||
|
|
||||||
|
// Initialize dynamic array for potential splice points
|
||||||
|
SpliceCand potential[SPLICE_CORPUS];
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
|
||||||
|
int orig_idx;
|
||||||
|
int splice_idx;
|
||||||
|
|
||||||
|
} intpair_t;
|
||||||
|
|
||||||
|
// Initialize dynamic array for potential splice points
|
||||||
|
// SpliceCand potential[SPLICE_CORPUS];
|
||||||
|
// IdxMap_new* rcuridx[STATES];
|
||||||
|
|
||||||
|
/* Prototypes*/
|
||||||
|
Array * slice(Array *, int);
|
||||||
|
state * create_pda(u8 *);
|
||||||
|
Array * gen_input(state *, Array *);
|
||||||
|
Array * gen_input_count(state *, Array *, int *);
|
||||||
|
int updatebucket(map_t, int);
|
||||||
|
void itoa(int, char *, int);
|
||||||
|
void strrreverse(char *, char *);
|
||||||
|
void dbg_hashmap(map_t);
|
||||||
|
void print_repr(Array *, char *);
|
||||||
|
int isSatisfied(map_t);
|
||||||
|
char * get_state(char *);
|
||||||
|
Candidate *gen_candidate(Array *);
|
||||||
|
|
||||||
|
Array *spliceGF(Array *, Array *, int);
|
||||||
|
Array *performSpliceOne(Array *, IdxMap_new *, Array *);
|
||||||
|
/* Mutation Methods*/
|
||||||
|
Array * performRandomMutation(state *, Array *);
|
||||||
|
Array * performRandomMutationCount(state *, Array *, int *);
|
||||||
|
Array * performSpliceMutationBench(state *, Array *, Candidate **);
|
||||||
|
UT_array **get_dupes(Array *, int *);
|
||||||
|
Array * doMult(Array *, UT_array **, int);
|
||||||
|
Array * doMultBench(Array *, UT_array **, int);
|
||||||
|
|
||||||
|
/* Benchmarks*/
|
||||||
|
void SpaceBenchmark(char *);
|
||||||
|
void GenInputBenchmark(char *, char *);
|
||||||
|
void RandomMutationBenchmark(char *, char *);
|
||||||
|
void MutationAggrBenchmark(char *, char *);
|
||||||
|
void SpliceMutationBenchmark(char *, char *);
|
||||||
|
void SpliceMutationBenchmarkOne(char *, char *);
|
||||||
|
void RandomRecursiveBenchmark(char *, char *);
|
||||||
|
|
||||||
|
/* Testers */
|
||||||
|
void SanityCheck(char *);
|
||||||
|
|
||||||
|
/*Helpers*/
|
||||||
|
void initArray(Array *, size_t);
|
||||||
|
void insertArray(Array *, int, char *, size_t, int);
|
||||||
|
void freeArray(Array *);
|
||||||
|
void initArrayIdx(IdxMap *, size_t);
|
||||||
|
void insertArrayIdx(IdxMap *, int);
|
||||||
|
void freeArrayIdx(IdxMap *);
|
||||||
|
void initArraySplice(SpliceCandArray *, size_t);
|
||||||
|
void insertArraySplice(SpliceCandArray *, Candidate *, int);
|
||||||
|
void freeArraySplice(IdxMap *);
|
||||||
|
void getTwoIndices(UT_array *, int, int *, int *);
|
||||||
|
void swap(int *, int *);
|
||||||
|
Array *slice_inverse(Array *, int);
|
||||||
|
void concatPrefixFeature(Array *, Array *);
|
||||||
|
void concatPrefixFeatureBench(Array *, Array *);
|
||||||
|
Array *carve(Array *, int, int);
|
||||||
|
int fact(int);
|
||||||
|
|
||||||
|
void add_to_corpus(struct json_object *, Array *);
|
||||||
|
struct json_object *term_to_json(terminal *);
|
||||||
|
|
||||||
|
/* Gramatron specific prototypes */
|
||||||
|
u8 * unparse_walk(Array *);
|
||||||
|
Array *performSpliceGF(state *, Array *, afl_state_t *);
|
||||||
|
void dump_input(u8 *, char *, int *);
|
||||||
|
void write_input(Array *, u8 *);
|
||||||
|
Array *read_input(state *, u8 *);
|
||||||
|
state *pda;
|
||||||
|
|
||||||
|
// // AFL-specific struct
|
||||||
|
// typedef uint8_t u8;
|
||||||
|
// typedef uint16_t u16;
|
||||||
|
// typedef uint32_t u32;
|
||||||
|
// #ifdef __x86_64__
|
||||||
|
// typedef unsigned long long u64;
|
||||||
|
// #else
|
||||||
|
// typedef uint64_t u64;
|
||||||
|
// #endif /* ^__x86_64__ */
|
||||||
|
//
|
||||||
|
// struct queue_entry {
|
||||||
|
|
||||||
|
// Array* walk; /* Pointer to the automaton walk*/
|
||||||
|
// u32 walk_len; /* Number of tokens in the input*/
|
||||||
|
// Candidate* cand; /* Preprocessed info about the
|
||||||
|
// candidate to allow for faster mutations*/
|
||||||
|
//
|
||||||
|
// u8* fname; /* File name for the test case */
|
||||||
|
// u32 len; /* Input length */
|
||||||
|
// UT_array** recur_idx; /* Keeps track of recursive feature
|
||||||
|
// indices*/
|
||||||
|
//
|
||||||
|
// u32 recur_len; /* The number of recursive features*/
|
||||||
|
//
|
||||||
|
// u8 cal_failed, /* Calibration failed? */
|
||||||
|
// trim_done, /* Trimmed? */
|
||||||
|
// was_fuzzed, /* Had any fuzzing done yet? */
|
||||||
|
// passed_det, /* Deterministic stages passed? */
|
||||||
|
// has_new_cov, /* Triggers new coverage? */
|
||||||
|
// var_behavior, /* Variable behavior? */
|
||||||
|
// favored, /* Currently favored? */
|
||||||
|
// fs_redundant; /* Marked as redundant in the fs? */
|
||||||
|
//
|
||||||
|
// u32 bitmap_size, /* Number of bits set in bitmap */
|
||||||
|
// exec_cksum; /* Checksum of the execution trace */
|
||||||
|
//
|
||||||
|
// u64 exec_us, /* Execution time (us) */
|
||||||
|
// handicap, /* Number of queue cycles behind */
|
||||||
|
// depth; /* Path depth */
|
||||||
|
//
|
||||||
|
// u8* trace_mini; /* Trace bytes, if kept */
|
||||||
|
// u32 tc_ref; /* Trace bytes ref count */
|
||||||
|
//
|
||||||
|
// struct queue_entry *next, /* Next element, if any */
|
||||||
|
// *next_100; /* 100 elements ahead */
|
||||||
|
//
|
||||||
|
// };
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -0,0 +1,606 @@
|
|||||||
|
{
|
||||||
|
"ARGLIST": [
|
||||||
|
"EXPR ',' ARGLIST",
|
||||||
|
"EXPR",
|
||||||
|
"EXPR ',' ARGLIST",
|
||||||
|
"EXPR"
|
||||||
|
],
|
||||||
|
"ARGS": [
|
||||||
|
"'()'",
|
||||||
|
"'(' ARGLIST ')'",
|
||||||
|
"'()'",
|
||||||
|
"'(' ARGLIST ')'"
|
||||||
|
],
|
||||||
|
"ARITHMETICOPERATION": [
|
||||||
|
"EXPR '/' EXPR",
|
||||||
|
"EXPR '*' EXPR",
|
||||||
|
"EXPR '+' EXPR",
|
||||||
|
"EXPR '-' EXPR",
|
||||||
|
"EXPR '%' EXPR",
|
||||||
|
"EXPR '**' EXPR",
|
||||||
|
"EXPR '++'"
|
||||||
|
],
|
||||||
|
"ARRAY": [
|
||||||
|
"'[' ARRAYCONTENT ']'",
|
||||||
|
"'[]'"
|
||||||
|
],
|
||||||
|
"ARRAYCONTENT": [
|
||||||
|
"EXPR ',' ARRAYCONTENT",
|
||||||
|
"EXPR"
|
||||||
|
],
|
||||||
|
"BOOLEAN": [
|
||||||
|
"'true'",
|
||||||
|
"'false'"
|
||||||
|
],
|
||||||
|
"BYTEWISEOPERATION": [
|
||||||
|
"EXPR '&' EXPR",
|
||||||
|
"EXPR '|' EXPR"
|
||||||
|
],
|
||||||
|
"COMPARISONOPERATION": [
|
||||||
|
"EXPR '<' EXPR"
|
||||||
|
],
|
||||||
|
"DECIMALDIGITS": [
|
||||||
|
"'20'",
|
||||||
|
"'1234'",
|
||||||
|
"'66'",
|
||||||
|
"'234_9'",
|
||||||
|
"'99999999999999999999'"
|
||||||
|
],
|
||||||
|
"DECIMALNUMBER": [
|
||||||
|
"DECIMALDIGITS"
|
||||||
|
],
|
||||||
|
"EXPR": [
|
||||||
|
"'(' EXPR ')'",
|
||||||
|
"VAR",
|
||||||
|
"'delete' SP EXPR",
|
||||||
|
"'new' SP IDENTIFIER ARGS",
|
||||||
|
"LITERAL",
|
||||||
|
"IDENTIFIER",
|
||||||
|
"METHODCALL",
|
||||||
|
"'(' ARITHMETICOPERATION ')'",
|
||||||
|
"'(' COMPARISONOPERATION ')'",
|
||||||
|
"'(' BYTEWISEOPERATION ')'",
|
||||||
|
"'(' LOGICALOPERATION ')'"
|
||||||
|
],
|
||||||
|
"IDENTIFIER": [
|
||||||
|
"'Object'",
|
||||||
|
"VAR",
|
||||||
|
"'Function'",
|
||||||
|
"'main'",
|
||||||
|
"'opt'",
|
||||||
|
"'Boolean'",
|
||||||
|
"'Symbol'",
|
||||||
|
"'JSON'",
|
||||||
|
"'Error'",
|
||||||
|
"'EvalError'",
|
||||||
|
"'RangeError'",
|
||||||
|
"'ReferenceError'",
|
||||||
|
"'SyntaxError'",
|
||||||
|
"'TypeError'",
|
||||||
|
"'URIError'",
|
||||||
|
"'this'",
|
||||||
|
"'Number'",
|
||||||
|
"'Math'",
|
||||||
|
"'Date'",
|
||||||
|
"'String'",
|
||||||
|
"'RegExp'",
|
||||||
|
"'Array'",
|
||||||
|
"'Int8Array'",
|
||||||
|
"'Uint8Array'",
|
||||||
|
"'Uint8ClampedArray'",
|
||||||
|
"'Int16Array'",
|
||||||
|
"'Uint16Array'",
|
||||||
|
"'Int32Array'",
|
||||||
|
"'Uint32Array'",
|
||||||
|
"'Float32Array'",
|
||||||
|
"'Float64Array'",
|
||||||
|
"'DataView'",
|
||||||
|
"'ArrayBuffer'",
|
||||||
|
"'Map'",
|
||||||
|
"'Set'",
|
||||||
|
"'WeakMap'",
|
||||||
|
"'WeakSet'",
|
||||||
|
"'Promise'",
|
||||||
|
"'AsyncFunction'",
|
||||||
|
"'asyncGenerator'",
|
||||||
|
"'Reflect'",
|
||||||
|
"'Proxy'",
|
||||||
|
"'Intl'",
|
||||||
|
"'Intl.Collator'",
|
||||||
|
"'Intl.DateTimeFormat'",
|
||||||
|
"'Intl.NumberFormat'",
|
||||||
|
"'Intl.PluralRules'",
|
||||||
|
"'WebAssembly'",
|
||||||
|
"'WebAssembly.Module'",
|
||||||
|
"'WebAssembly.Instance'",
|
||||||
|
"'WebAssembly.Memory'",
|
||||||
|
"'WebAssembly.Table'",
|
||||||
|
"'WebAssembly.CompileError'",
|
||||||
|
"'WebAssembly.LinkError'",
|
||||||
|
"'WebAssembly.RuntimeError'",
|
||||||
|
"'arguments'",
|
||||||
|
"'Infinity'",
|
||||||
|
"'NaN'",
|
||||||
|
"'undefined'",
|
||||||
|
"'null'",
|
||||||
|
"'console'",
|
||||||
|
"' '"
|
||||||
|
],
|
||||||
|
"IDENTIFIERLIST": [
|
||||||
|
"IDENTIFIER ',' IDENTIFIERLIST",
|
||||||
|
"'(' IDENTIFIERLIST '),' IDENTIFIERLIST",
|
||||||
|
"IDENTIFIER"
|
||||||
|
],
|
||||||
|
"JSBLOCK": [
|
||||||
|
"JSSTATEMENT",
|
||||||
|
"JSSTATEMENT JSBLOCK"
|
||||||
|
],
|
||||||
|
"JSSTATEMENT": [
|
||||||
|
"STATEMENT NEWLINE"
|
||||||
|
],
|
||||||
|
"LITERAL": [
|
||||||
|
"'null'",
|
||||||
|
"BOOLEAN",
|
||||||
|
"NUMBER",
|
||||||
|
"ARRAY"
|
||||||
|
],
|
||||||
|
"LOGICALOPERATION": [
|
||||||
|
"EXPR '&&' EXPR",
|
||||||
|
"EXPR '||' EXPR"
|
||||||
|
],
|
||||||
|
"METHODCALL": [
|
||||||
|
"OBJECT PROPERTY METHODCALL1"
|
||||||
|
],
|
||||||
|
"METHODCALL1": [
|
||||||
|
"'.' METHOD_NAME ARGS METHODCALL1",
|
||||||
|
"' '"
|
||||||
|
],
|
||||||
|
"METHOD_NAME": [
|
||||||
|
"IDENTIFIER",
|
||||||
|
"'print'",
|
||||||
|
"'eval'",
|
||||||
|
"'uneval'",
|
||||||
|
"'isFinite'",
|
||||||
|
"'isNaN'",
|
||||||
|
"'parseFloat'",
|
||||||
|
"'parseInt'",
|
||||||
|
"'decodeURI'",
|
||||||
|
"'decodeURIComponent'",
|
||||||
|
"'encodeURI'",
|
||||||
|
"'encodeURIComponent'",
|
||||||
|
"'escape'",
|
||||||
|
"'unescape'",
|
||||||
|
"'assign'",
|
||||||
|
"'create'",
|
||||||
|
"'defineProperty'",
|
||||||
|
"'defineProperties'",
|
||||||
|
"'entries'",
|
||||||
|
"'freeze'",
|
||||||
|
"'getOwnPropertyDescriptor'",
|
||||||
|
"'getOwnPropertyDescriptors'",
|
||||||
|
"'getOwnPropertyNames'",
|
||||||
|
"'getOwnPropertySymbols'",
|
||||||
|
"'getPrototypeOf'",
|
||||||
|
"'is'",
|
||||||
|
"'isExtensible'",
|
||||||
|
"'isFrozen'",
|
||||||
|
"'isSealed'",
|
||||||
|
"'keys'",
|
||||||
|
"'preventExtensions'",
|
||||||
|
"'seal'",
|
||||||
|
"'setPrototypeOf'",
|
||||||
|
"'values'",
|
||||||
|
"'__defineGetter__'",
|
||||||
|
"'__defineSetter__'",
|
||||||
|
"'__lookupGetter__'",
|
||||||
|
"'__lookupSetter__'",
|
||||||
|
"'hasOwnProperty'",
|
||||||
|
"'isPrototypeOf'",
|
||||||
|
"'propertyIsEnumerable'",
|
||||||
|
"'toSource'",
|
||||||
|
"'toLocaleString'",
|
||||||
|
"'toString'",
|
||||||
|
"'unwatch'",
|
||||||
|
"'valueOf'",
|
||||||
|
"'watch'",
|
||||||
|
"'apply'",
|
||||||
|
"'bind'",
|
||||||
|
"'call'",
|
||||||
|
"'isGenerator'",
|
||||||
|
"'valueOf'",
|
||||||
|
"'for'",
|
||||||
|
"'keyFor'",
|
||||||
|
"'stringify'",
|
||||||
|
"'isInteger'",
|
||||||
|
"'isSafeInteger'",
|
||||||
|
"'toInteger'",
|
||||||
|
"'toExponential'",
|
||||||
|
"'toFixed'",
|
||||||
|
"'toLocaleString'",
|
||||||
|
"'toPrecision'",
|
||||||
|
"'abs'",
|
||||||
|
"'acos'",
|
||||||
|
"'acosh'",
|
||||||
|
"'asin'",
|
||||||
|
"'asinh'",
|
||||||
|
"'atan'",
|
||||||
|
"'atanh'",
|
||||||
|
"'atan2'",
|
||||||
|
"'cbrt'",
|
||||||
|
"'ceil'",
|
||||||
|
"'clz32'",
|
||||||
|
"'cos'",
|
||||||
|
"'cosh'",
|
||||||
|
"'exp'",
|
||||||
|
"'expm1'",
|
||||||
|
"'floor'",
|
||||||
|
"'fround'",
|
||||||
|
"'hypot'",
|
||||||
|
"'imul'",
|
||||||
|
"'log'",
|
||||||
|
"'log1p'",
|
||||||
|
"'log10'",
|
||||||
|
"'log2'",
|
||||||
|
"'max'",
|
||||||
|
"'min'",
|
||||||
|
"'pow'",
|
||||||
|
"'random'",
|
||||||
|
"'round'",
|
||||||
|
"'sign'",
|
||||||
|
"'sin'",
|
||||||
|
"'sinh'",
|
||||||
|
"'sqrt'",
|
||||||
|
"'tan'",
|
||||||
|
"'tanh'",
|
||||||
|
"'trunc'",
|
||||||
|
"'now'",
|
||||||
|
"'parse'",
|
||||||
|
"'UTC'",
|
||||||
|
"'getDate'",
|
||||||
|
"'getDay'",
|
||||||
|
"'getFullYear'",
|
||||||
|
"'getHours'",
|
||||||
|
"'getMilliseconds'",
|
||||||
|
"'getMinutes'",
|
||||||
|
"'getMonth'",
|
||||||
|
"'getSeconds'",
|
||||||
|
"'getTime'",
|
||||||
|
"'getTimezoneOffset'",
|
||||||
|
"'getUTCDate'",
|
||||||
|
"'getUTCDay'",
|
||||||
|
"'getUTCFullYear'",
|
||||||
|
"'getUTCHours'",
|
||||||
|
"'getUTCMilliseconds'",
|
||||||
|
"'getUTCMinutes'",
|
||||||
|
"'getUTCMonth'",
|
||||||
|
"'getUTCSeconds'",
|
||||||
|
"'getYear'",
|
||||||
|
"'setDate'",
|
||||||
|
"'setFullYear'",
|
||||||
|
"'setHours'",
|
||||||
|
"'setMilliseconds'",
|
||||||
|
"'setMinutes'",
|
||||||
|
"'setMonth'",
|
||||||
|
"'setSeconds'",
|
||||||
|
"'setTime'",
|
||||||
|
"'setUTCDate'",
|
||||||
|
"'setUTCFullYear'",
|
||||||
|
"'setUTCHours'",
|
||||||
|
"'setUTCMilliseconds'",
|
||||||
|
"'setUTCMinutes'",
|
||||||
|
"'setUTCMonth'",
|
||||||
|
"'setUTCSeconds'",
|
||||||
|
"'setYear'",
|
||||||
|
"'toDateString'",
|
||||||
|
"'toISOString'",
|
||||||
|
"'toJSON'",
|
||||||
|
"'toGMTString'",
|
||||||
|
"'toLocaleDateString'",
|
||||||
|
"'toLocaleFormat'",
|
||||||
|
"'toLocaleString'",
|
||||||
|
"'toLocaleTimeString'",
|
||||||
|
"'toTimeString'",
|
||||||
|
"'toUTCString'",
|
||||||
|
"'indexOf'",
|
||||||
|
"'substring'",
|
||||||
|
"'charAt'",
|
||||||
|
"'strcmp'",
|
||||||
|
"'fromCharCode'",
|
||||||
|
"'fromCodePoint'",
|
||||||
|
"'raw'",
|
||||||
|
"'charCodeAt'",
|
||||||
|
"'slice'",
|
||||||
|
"'codePointAt'",
|
||||||
|
"'concat'",
|
||||||
|
"'includes'",
|
||||||
|
"'endsWith'",
|
||||||
|
"'lastIndexOf'",
|
||||||
|
"'localeCompare'",
|
||||||
|
"'match'",
|
||||||
|
"'normalize'",
|
||||||
|
"'padEnd'",
|
||||||
|
"'padStart'",
|
||||||
|
"'quote'",
|
||||||
|
"'repeat'",
|
||||||
|
"'replace'",
|
||||||
|
"'search'",
|
||||||
|
"'split'",
|
||||||
|
"'startsWith'",
|
||||||
|
"'substr'",
|
||||||
|
"'toLocaleLowerCase'",
|
||||||
|
"'toLocaleUpperCase'",
|
||||||
|
"'toLowerCase'",
|
||||||
|
"'toUpperCase'",
|
||||||
|
"'trim'",
|
||||||
|
"'trimleft'",
|
||||||
|
"'trimright'",
|
||||||
|
"'anchor'",
|
||||||
|
"'big'",
|
||||||
|
"'blink'",
|
||||||
|
"'bold'",
|
||||||
|
"'fixed'",
|
||||||
|
"'fontcolor'",
|
||||||
|
"'fontsize'",
|
||||||
|
"'italics'",
|
||||||
|
"'link'",
|
||||||
|
"'small'",
|
||||||
|
"'strike'",
|
||||||
|
"'sub'",
|
||||||
|
"'sup'",
|
||||||
|
"'compile'",
|
||||||
|
"'exec'",
|
||||||
|
"'test'",
|
||||||
|
"'from'",
|
||||||
|
"'isArray'",
|
||||||
|
"'of'",
|
||||||
|
"'copyWithin'",
|
||||||
|
"'fill'",
|
||||||
|
"'pop'",
|
||||||
|
"'push'",
|
||||||
|
"'reverse'",
|
||||||
|
"'shift'",
|
||||||
|
"'sort'",
|
||||||
|
"'splice'",
|
||||||
|
"'unshift'",
|
||||||
|
"'concat'",
|
||||||
|
"'join'",
|
||||||
|
"'every'",
|
||||||
|
"'filter'",
|
||||||
|
"'findIndex'",
|
||||||
|
"'forEach'",
|
||||||
|
"'map'",
|
||||||
|
"'reduce'",
|
||||||
|
"'reduceRight'",
|
||||||
|
"'some'",
|
||||||
|
"'move'",
|
||||||
|
"'getInt8'",
|
||||||
|
"'getUint8'",
|
||||||
|
"'getInt16'",
|
||||||
|
"'getUint16'",
|
||||||
|
"'getInt32'",
|
||||||
|
"'getUint32'",
|
||||||
|
"'getFloat32'",
|
||||||
|
"'getFloat64'",
|
||||||
|
"'setInt8'",
|
||||||
|
"'setUint8'",
|
||||||
|
"'setInt16'",
|
||||||
|
"'setUint16'",
|
||||||
|
"'setInt32'",
|
||||||
|
"'setUint32'",
|
||||||
|
"'setFloat32'",
|
||||||
|
"'setFloat64'",
|
||||||
|
"'isView'",
|
||||||
|
"'transfer'",
|
||||||
|
"'clear'",
|
||||||
|
"'get'",
|
||||||
|
"'has'",
|
||||||
|
"'set'",
|
||||||
|
"'add'",
|
||||||
|
"'splat'",
|
||||||
|
"'check'",
|
||||||
|
"'extractLane'",
|
||||||
|
"'replaceLane'",
|
||||||
|
"'load'",
|
||||||
|
"'load1'",
|
||||||
|
"'load2'",
|
||||||
|
"'load3'",
|
||||||
|
"'store'",
|
||||||
|
"'store1'",
|
||||||
|
"'store2'",
|
||||||
|
"'store3'",
|
||||||
|
"'addSaturate'",
|
||||||
|
"'div'",
|
||||||
|
"'mul'",
|
||||||
|
"'neg'",
|
||||||
|
"'reciprocalApproximation'",
|
||||||
|
"'reciprocalSqrtApproximation'",
|
||||||
|
"'subSaturate'",
|
||||||
|
"'shuffle'",
|
||||||
|
"'swizzle'",
|
||||||
|
"'maxNum'",
|
||||||
|
"'minNum'",
|
||||||
|
"'select'",
|
||||||
|
"'equal'",
|
||||||
|
"'notEqual'",
|
||||||
|
"'lessThan'",
|
||||||
|
"'lessThanOrEqual'",
|
||||||
|
"'greaterThan'",
|
||||||
|
"'greaterThanOrEqual'",
|
||||||
|
"'and'",
|
||||||
|
"'or'",
|
||||||
|
"'xor'",
|
||||||
|
"'not'",
|
||||||
|
"'shiftLeftByScalar'",
|
||||||
|
"'shiftRightByScalar'",
|
||||||
|
"'allTrue'",
|
||||||
|
"'anyTrue'",
|
||||||
|
"'fromFloat32x4'",
|
||||||
|
"'fromFloat32x4Bits'",
|
||||||
|
"'fromFloat64x2Bits'",
|
||||||
|
"'fromInt32x4'",
|
||||||
|
"'fromInt32x4Bits'",
|
||||||
|
"'fromInt16x8Bits'",
|
||||||
|
"'fromInt8x16Bits'",
|
||||||
|
"'fromUint32x4'",
|
||||||
|
"'fromUint32x4Bits'",
|
||||||
|
"'fromUint16x8Bits'",
|
||||||
|
"'fromUint8x16Bits'",
|
||||||
|
"'neg'",
|
||||||
|
"'compareExchange'",
|
||||||
|
"'exchange'",
|
||||||
|
"'wait'",
|
||||||
|
"'wake'",
|
||||||
|
"'isLockFree'",
|
||||||
|
"'all'",
|
||||||
|
"'race'",
|
||||||
|
"'reject'",
|
||||||
|
"'resolve'",
|
||||||
|
"'catch'",
|
||||||
|
"'then'",
|
||||||
|
"'finally'",
|
||||||
|
"'next'",
|
||||||
|
"'throw'",
|
||||||
|
"'close'",
|
||||||
|
"'send'",
|
||||||
|
"'apply'",
|
||||||
|
"'construct'",
|
||||||
|
"'deleteProperty'",
|
||||||
|
"'ownKeys'",
|
||||||
|
"'getCanonicalLocales'",
|
||||||
|
"'supportedLocalesOf'",
|
||||||
|
"'resolvedOptions'",
|
||||||
|
"'formatToParts'",
|
||||||
|
"'resolvedOptions'",
|
||||||
|
"'instantiate'",
|
||||||
|
"'instantiateStreaming'",
|
||||||
|
"'compileStreaming'",
|
||||||
|
"'validate'",
|
||||||
|
"'customSections'",
|
||||||
|
"'exports'",
|
||||||
|
"'imports'",
|
||||||
|
"'grow'",
|
||||||
|
"'super'",
|
||||||
|
"'in'",
|
||||||
|
"'instanceof'",
|
||||||
|
"' '"
|
||||||
|
],
|
||||||
|
"NEWLINE": [
|
||||||
|
"'\\n'"
|
||||||
|
],
|
||||||
|
"NUMBER": [
|
||||||
|
"'1/2'",
|
||||||
|
"'1E2'",
|
||||||
|
"'1E02'",
|
||||||
|
"'1E+02'",
|
||||||
|
"'-1'",
|
||||||
|
"'-1.00'",
|
||||||
|
"'-1/2'",
|
||||||
|
"'-1E2'",
|
||||||
|
"'-1E02'",
|
||||||
|
"'-1E+02'",
|
||||||
|
"'1/0'",
|
||||||
|
"'0/0'",
|
||||||
|
"'-2147483648/-1'",
|
||||||
|
"'-9223372036854775808/-1'",
|
||||||
|
"'-0'",
|
||||||
|
"'-0.0'",
|
||||||
|
"'+0'"
|
||||||
|
],
|
||||||
|
"OBJECT": [
|
||||||
|
"IDENTIFIER"
|
||||||
|
],
|
||||||
|
"PROGRAM": [
|
||||||
|
"JSBLOCK"
|
||||||
|
],
|
||||||
|
"PROPERTY": [
|
||||||
|
"'.length' PROPERTY",
|
||||||
|
"'.prototype' PROPERTY",
|
||||||
|
"'.constructor' PROPERTY",
|
||||||
|
"'.__proto__' PROPERTY",
|
||||||
|
"'.__noSuchMethod__' PROPERTY",
|
||||||
|
"'.__count__' PROPERTY",
|
||||||
|
"'.__parent__' PROPERTY",
|
||||||
|
"'.arguments' PROPERTY",
|
||||||
|
"'.arity' PROPERTY",
|
||||||
|
"'.caller' PROPERTY",
|
||||||
|
"'.name' PROPERTY",
|
||||||
|
"'.displayName' PROPERTY",
|
||||||
|
"'.iterator' PROPERTY",
|
||||||
|
"'.asyncIterator' PROPERTY",
|
||||||
|
"'.match' PROPERTY",
|
||||||
|
"'.replace' PROPERTY",
|
||||||
|
"'.search' PROPERTY",
|
||||||
|
"'.split' PROPERTY",
|
||||||
|
"'.hasInstance' PROPERTY",
|
||||||
|
"'.isConcatSpreadable' PROPERTY",
|
||||||
|
"'.unscopables' PROPERTY",
|
||||||
|
"'.species' PROPERTY",
|
||||||
|
"'.toPrimitive' PROPERTY",
|
||||||
|
"'.toStringTag' PROPERTY",
|
||||||
|
"'.fileName' PROPERTY",
|
||||||
|
"'.lineNumber' PROPERTY",
|
||||||
|
"'.columnNumber' PROPERTY",
|
||||||
|
"'.message' PROPERTY",
|
||||||
|
"'.name' PROPERTY",
|
||||||
|
"'.EPSILON' PROPERTY",
|
||||||
|
"'.MAX_SAFE_INTEGER' PROPERTY",
|
||||||
|
"'.MAX_VALUE' PROPERTY",
|
||||||
|
"'.MIN_SAFE_INTEGER' PROPERTY",
|
||||||
|
"'.MIN_VALUE' PROPERTY",
|
||||||
|
"'.NaN' PROPERTY",
|
||||||
|
"'.NEGATIVE_INFINITY' PROPERTY",
|
||||||
|
"'.POSITIVE_INFINITY' PROPERTY",
|
||||||
|
"'.E' PROPERTY",
|
||||||
|
"'.LN2' PROPERTY",
|
||||||
|
"'.LN10' PROPERTY",
|
||||||
|
"'.LOG2E' PROPERTY",
|
||||||
|
"'.LOG10E' PROPERTY",
|
||||||
|
"'.PI' PROPERTY",
|
||||||
|
"'.SQRT1_2' PROPERTY",
|
||||||
|
"'.SQRT2' PROPERTY",
|
||||||
|
"'.flags' PROPERTY",
|
||||||
|
"'.global' PROPERTY",
|
||||||
|
"'.ignoreCase' PROPERTY",
|
||||||
|
"'.multiline' PROPERTY",
|
||||||
|
"'.source' PROPERTY",
|
||||||
|
"'.sticky' PROPERTY",
|
||||||
|
"'.unicode' PROPERTY",
|
||||||
|
"'.buffer' PROPERTY",
|
||||||
|
"'.byteLength' PROPERTY",
|
||||||
|
"'.byteOffset' PROPERTY",
|
||||||
|
"'.BYTES_PER_ELEMENT' PROPERTY",
|
||||||
|
"'.compare' PROPERTY",
|
||||||
|
"'.format' PROPERTY",
|
||||||
|
"'.callee' PROPERTY",
|
||||||
|
"'.caller' PROPERTY",
|
||||||
|
"'.memory' PROPERTY",
|
||||||
|
"'.exports' PROPERTY",
|
||||||
|
"' '"
|
||||||
|
],
|
||||||
|
"SP": [
|
||||||
|
"' '"
|
||||||
|
],
|
||||||
|
"STATEMENT": [
|
||||||
|
"EXPR ';'",
|
||||||
|
"'var' SP VAR '=' EXPR ';'",
|
||||||
|
"'let' SP VAR '=' EXPR ';'",
|
||||||
|
"VAR '=' EXPR ';'",
|
||||||
|
"VAR PROPERTY '=' EXPR ';'",
|
||||||
|
"VAR '[' DECIMALNUMBER ']' '=' EXPR ';'",
|
||||||
|
"'const' SP VAR '=' EXPR ';'",
|
||||||
|
"'typeof' SP EXPR ';'",
|
||||||
|
"'void' SP EXPR ';'",
|
||||||
|
"'return' SP EXPR ';'",
|
||||||
|
"VAR ':'"
|
||||||
|
],
|
||||||
|
"VAR": [
|
||||||
|
"'a'",
|
||||||
|
"'b'",
|
||||||
|
"'c'",
|
||||||
|
"'d'",
|
||||||
|
"'e'",
|
||||||
|
"'f'",
|
||||||
|
"'g'",
|
||||||
|
"'h'"
|
||||||
|
]
|
||||||
|
}
|
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
@ -0,0 +1,434 @@
|
|||||||
|
/*
|
||||||
|
* Generic map implementation.
|
||||||
|
*/
|
||||||
|
#include "hashmap.h"
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#define INITIAL_SIZE (256)
|
||||||
|
#define MAX_CHAIN_LENGTH (8)
|
||||||
|
|
||||||
|
/* We need to keep keys and values */
|
||||||
|
typedef struct _hashmap_element {
|
||||||
|
|
||||||
|
char *key;
|
||||||
|
int in_use;
|
||||||
|
any_t data;
|
||||||
|
|
||||||
|
} hashmap_element;
|
||||||
|
|
||||||
|
/* A hashmap has some maximum size and current size,
|
||||||
|
* as well as the data to hold. */
|
||||||
|
typedef struct _hashmap_map {
|
||||||
|
|
||||||
|
int table_size;
|
||||||
|
int size;
|
||||||
|
hashmap_element *data;
|
||||||
|
|
||||||
|
} hashmap_map;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return an empty hashmap, or NULL on failure.
|
||||||
|
*/
|
||||||
|
map_t hashmap_new() {
|
||||||
|
|
||||||
|
hashmap_map *m = (hashmap_map *)malloc(sizeof(hashmap_map));
|
||||||
|
if (!m) goto err;
|
||||||
|
|
||||||
|
m->data = (hashmap_element *)calloc(INITIAL_SIZE, sizeof(hashmap_element));
|
||||||
|
if (!m->data) goto err;
|
||||||
|
|
||||||
|
m->table_size = INITIAL_SIZE;
|
||||||
|
m->size = 0;
|
||||||
|
|
||||||
|
return m;
|
||||||
|
err:
|
||||||
|
if (m) hashmap_free(m);
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The implementation here was originally done by Gary S. Brown. I have
|
||||||
|
borrowed the tables directly, and made some minor changes to the
|
||||||
|
crc32-function (including changing the interface). //ylo */
|
||||||
|
|
||||||
|
/* ============================================================= */
|
||||||
|
/* COPYRIGHT (C) 1986 Gary S. Brown. You may use this program, or */
|
||||||
|
/* code or tables extracted from it, as desired without restriction. */
|
||||||
|
/* */
|
||||||
|
/* First, the polynomial itself and its table of feedback terms. The */
|
||||||
|
/* polynomial is */
|
||||||
|
/* X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0 */
|
||||||
|
/* */
|
||||||
|
/* Note that we take it "backwards" and put the highest-order term in */
|
||||||
|
/* the lowest-order bit. The X^32 term is "implied"; the LSB is the */
|
||||||
|
/* X^31 term, etc. The X^0 term (usually shown as "+1") results in */
|
||||||
|
/* the MSB being 1. */
|
||||||
|
/* */
|
||||||
|
/* Note that the usual hardware shift register implementation, which */
|
||||||
|
/* is what we're using (we're merely optimizing it by doing eight-bit */
|
||||||
|
/* chunks at a time) shifts bits into the lowest-order term. In our */
|
||||||
|
/* implementation, that means shifting towards the right. Why do we */
|
||||||
|
/* do it this way? Because the calculated CRC must be transmitted in */
|
||||||
|
/* order from highest-order term to lowest-order term. UARTs transmit */
|
||||||
|
/* characters in order from LSB to MSB. By storing the CRC this way, */
|
||||||
|
/* we hand it to the UART in the order low-byte to high-byte; the UART */
|
||||||
|
/* sends each low-bit to hight-bit; and the result is transmission bit */
|
||||||
|
/* by bit from highest- to lowest-order term without requiring any bit */
|
||||||
|
/* shuffling on our part. Reception works similarly. */
|
||||||
|
/* */
|
||||||
|
/* The feedback terms table consists of 256, 32-bit entries. Notes: */
|
||||||
|
/* */
|
||||||
|
/* The table can be generated at runtime if desired; code to do so */
|
||||||
|
/* is shown later. It might not be obvious, but the feedback */
|
||||||
|
/* terms simply represent the results of eight shift/xor opera- */
|
||||||
|
/* tions for all combinations of data and CRC register values. */
|
||||||
|
/* */
|
||||||
|
/* The values must be right-shifted by eight bits by the "updcrc" */
|
||||||
|
/* logic; the shift must be unsigned (bring in zeroes). On some */
|
||||||
|
/* hardware you could probably optimize the shift in assembler by */
|
||||||
|
/* using byte-swap instructions. */
|
||||||
|
/* polynomial $edb88320 */
|
||||||
|
/* */
|
||||||
|
/* -------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
static unsigned long crc32_tab[] = {
|
||||||
|
|
||||||
|
0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
|
||||||
|
0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
|
||||||
|
0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
|
||||||
|
0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
|
||||||
|
0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L,
|
||||||
|
0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,
|
||||||
|
0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L,
|
||||||
|
0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
|
||||||
|
0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L,
|
||||||
|
0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL,
|
||||||
|
0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L,
|
||||||
|
0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
|
||||||
|
0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L,
|
||||||
|
0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL,
|
||||||
|
0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL,
|
||||||
|
0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
|
||||||
|
0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL,
|
||||||
|
0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L,
|
||||||
|
0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L,
|
||||||
|
0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
|
||||||
|
0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL,
|
||||||
|
0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L,
|
||||||
|
0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L,
|
||||||
|
0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
|
||||||
|
0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L,
|
||||||
|
0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L,
|
||||||
|
0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L,
|
||||||
|
0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
|
||||||
|
0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L,
|
||||||
|
0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL,
|
||||||
|
0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL,
|
||||||
|
0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
|
||||||
|
0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L,
|
||||||
|
0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL,
|
||||||
|
0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL,
|
||||||
|
0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
|
||||||
|
0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL,
|
||||||
|
0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L,
|
||||||
|
0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL,
|
||||||
|
0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
|
||||||
|
0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL,
|
||||||
|
0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L,
|
||||||
|
0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L,
|
||||||
|
0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
|
||||||
|
0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L,
|
||||||
|
0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L,
|
||||||
|
0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L,
|
||||||
|
0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
|
||||||
|
0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L,
|
||||||
|
0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L,
|
||||||
|
0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL,
|
||||||
|
0x2d02ef8dL};
|
||||||
|
|
||||||
|
/* Return a 32-bit CRC of the contents of the buffer. */
|
||||||
|
|
||||||
|
unsigned long crc32(const unsigned char *s, unsigned int len) {
|
||||||
|
|
||||||
|
unsigned int i;
|
||||||
|
unsigned long crc32val;
|
||||||
|
|
||||||
|
crc32val = 0;
|
||||||
|
for (i = 0; i < len; i++) {
|
||||||
|
|
||||||
|
crc32val = crc32_tab[(crc32val ^ s[i]) & 0xff] ^ (crc32val >> 8);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return crc32val;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Hashing function for a string
|
||||||
|
*/
|
||||||
|
unsigned int hashmap_hash_int(hashmap_map *m, char *keystring) {
|
||||||
|
|
||||||
|
unsigned long key = crc32((unsigned char *)(keystring), strlen(keystring));
|
||||||
|
|
||||||
|
/* Robert Jenkins' 32 bit Mix Function */
|
||||||
|
key += (key << 12);
|
||||||
|
key ^= (key >> 22);
|
||||||
|
key += (key << 4);
|
||||||
|
key ^= (key >> 9);
|
||||||
|
key += (key << 10);
|
||||||
|
key ^= (key >> 2);
|
||||||
|
key += (key << 7);
|
||||||
|
key ^= (key >> 12);
|
||||||
|
|
||||||
|
/* Knuth's Multiplicative Method */
|
||||||
|
key = (key >> 3) * 2654435761;
|
||||||
|
|
||||||
|
return key % m->table_size;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return the integer of the location in data
|
||||||
|
* to store the point to the item, or MAP_FULL.
|
||||||
|
*/
|
||||||
|
int hashmap_hash(map_t in, char *key) {
|
||||||
|
|
||||||
|
int curr;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* Cast the hashmap */
|
||||||
|
hashmap_map *m = (hashmap_map *)in;
|
||||||
|
|
||||||
|
/* If full, return immediately */
|
||||||
|
if (m->size >= (m->table_size / 2)) return MAP_FULL;
|
||||||
|
|
||||||
|
/* Find the best index */
|
||||||
|
curr = hashmap_hash_int(m, key);
|
||||||
|
|
||||||
|
/* Linear probing */
|
||||||
|
for (i = 0; i < MAX_CHAIN_LENGTH; i++) {
|
||||||
|
|
||||||
|
if (m->data[curr].in_use == 0) return curr;
|
||||||
|
|
||||||
|
if (m->data[curr].in_use == 1 && (strcmp(m->data[curr].key, key) == 0))
|
||||||
|
return curr;
|
||||||
|
|
||||||
|
curr = (curr + 1) % m->table_size;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return MAP_FULL;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Doubles the size of the hashmap, and rehashes all the elements
|
||||||
|
*/
|
||||||
|
int hashmap_rehash(map_t in) {
|
||||||
|
|
||||||
|
int i;
|
||||||
|
int old_size;
|
||||||
|
hashmap_element *curr;
|
||||||
|
|
||||||
|
/* Setup the new elements */
|
||||||
|
hashmap_map * m = (hashmap_map *)in;
|
||||||
|
hashmap_element *temp =
|
||||||
|
(hashmap_element *)calloc(2 * m->table_size, sizeof(hashmap_element));
|
||||||
|
if (!temp) return MAP_OMEM;
|
||||||
|
|
||||||
|
/* Update the array */
|
||||||
|
curr = m->data;
|
||||||
|
m->data = temp;
|
||||||
|
|
||||||
|
/* Update the size */
|
||||||
|
old_size = m->table_size;
|
||||||
|
m->table_size = 2 * m->table_size;
|
||||||
|
m->size = 0;
|
||||||
|
|
||||||
|
/* Rehash the elements */
|
||||||
|
for (i = 0; i < old_size; i++) {
|
||||||
|
|
||||||
|
int status;
|
||||||
|
|
||||||
|
if (curr[i].in_use == 0) continue;
|
||||||
|
|
||||||
|
status = hashmap_put(m, curr[i].key, curr[i].data);
|
||||||
|
if (status != MAP_OK) return status;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
free(curr);
|
||||||
|
|
||||||
|
return MAP_OK;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Add a pointer to the hashmap with some key
|
||||||
|
*/
|
||||||
|
int hashmap_put(map_t in, char *key, any_t value) {
|
||||||
|
|
||||||
|
int index;
|
||||||
|
hashmap_map *m;
|
||||||
|
|
||||||
|
/* Cast the hashmap */
|
||||||
|
m = (hashmap_map *)in;
|
||||||
|
|
||||||
|
/* Find a place to put our value */
|
||||||
|
index = hashmap_hash(in, key);
|
||||||
|
while (index == MAP_FULL) {
|
||||||
|
|
||||||
|
if (hashmap_rehash(in) == MAP_OMEM) { return MAP_OMEM; }
|
||||||
|
index = hashmap_hash(in, key);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set the data */
|
||||||
|
m->data[index].data = value;
|
||||||
|
m->data[index].key = key;
|
||||||
|
m->data[index].in_use = 1;
|
||||||
|
m->size++;
|
||||||
|
|
||||||
|
return MAP_OK;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get your pointer out of the hashmap with a key
|
||||||
|
*/
|
||||||
|
int hashmap_get(map_t in, char *key, any_t *arg) {
|
||||||
|
|
||||||
|
int curr;
|
||||||
|
int i;
|
||||||
|
hashmap_map *m;
|
||||||
|
|
||||||
|
/* Cast the hashmap */
|
||||||
|
m = (hashmap_map *)in;
|
||||||
|
|
||||||
|
/* Find data location */
|
||||||
|
curr = hashmap_hash_int(m, key);
|
||||||
|
|
||||||
|
/* Linear probing, if necessary */
|
||||||
|
for (i = 0; i < MAX_CHAIN_LENGTH; i++) {
|
||||||
|
|
||||||
|
int in_use = m->data[curr].in_use;
|
||||||
|
if (in_use == 1) {
|
||||||
|
|
||||||
|
if (strcmp(m->data[curr].key, key) == 0) {
|
||||||
|
|
||||||
|
*arg = (m->data[curr].data);
|
||||||
|
return MAP_OK;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
curr = (curr + 1) % m->table_size;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
*arg = NULL;
|
||||||
|
|
||||||
|
/* Not found */
|
||||||
|
return MAP_MISSING;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Iterate the function parameter over each element in the hashmap. The
|
||||||
|
* additional any_t argument is passed to the function as its first
|
||||||
|
* argument and the hashmap element is the second.
|
||||||
|
*/
|
||||||
|
int hashmap_iterate(map_t in, PFany f, any_t item) {
|
||||||
|
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* Cast the hashmap */
|
||||||
|
hashmap_map *m = (hashmap_map *)in;
|
||||||
|
|
||||||
|
/* On empty hashmap, return immediately */
|
||||||
|
if (hashmap_length(m) <= 0) return MAP_MISSING;
|
||||||
|
|
||||||
|
/* Linear probing */
|
||||||
|
for (i = 0; i < m->table_size; i++)
|
||||||
|
if (m->data[i].in_use != 0) {
|
||||||
|
|
||||||
|
any_t data = (any_t)(m->data[i].data);
|
||||||
|
int status = f(item, data);
|
||||||
|
if (status != MAP_OK) { return status; }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return MAP_OK;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Remove an element with that key from the map
|
||||||
|
*/
|
||||||
|
int hashmap_remove(map_t in, char *key) {
|
||||||
|
|
||||||
|
int i;
|
||||||
|
int curr;
|
||||||
|
hashmap_map *m;
|
||||||
|
|
||||||
|
/* Cast the hashmap */
|
||||||
|
m = (hashmap_map *)in;
|
||||||
|
|
||||||
|
/* Find key */
|
||||||
|
curr = hashmap_hash_int(m, key);
|
||||||
|
|
||||||
|
/* Linear probing, if necessary */
|
||||||
|
for (i = 0; i < MAX_CHAIN_LENGTH; i++) {
|
||||||
|
|
||||||
|
int in_use = m->data[curr].in_use;
|
||||||
|
if (in_use == 1) {
|
||||||
|
|
||||||
|
if (strcmp(m->data[curr].key, key) == 0) {
|
||||||
|
|
||||||
|
/* Blank out the fields */
|
||||||
|
m->data[curr].in_use = 0;
|
||||||
|
m->data[curr].data = NULL;
|
||||||
|
m->data[curr].key = NULL;
|
||||||
|
|
||||||
|
/* Reduce the size */
|
||||||
|
m->size--;
|
||||||
|
return MAP_OK;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
curr = (curr + 1) % m->table_size;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Data not found */
|
||||||
|
return MAP_MISSING;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Deallocate the hashmap */
|
||||||
|
void hashmap_free(map_t in) {
|
||||||
|
|
||||||
|
hashmap_map *m = (hashmap_map *)in;
|
||||||
|
free(m->data);
|
||||||
|
free(m);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return the length of the hashmap */
|
||||||
|
int hashmap_length(map_t in) {
|
||||||
|
|
||||||
|
hashmap_map *m = (hashmap_map *)in;
|
||||||
|
if (m != NULL)
|
||||||
|
return m->size;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,83 @@
|
|||||||
|
/*
|
||||||
|
* Generic hashmap manipulation functions
|
||||||
|
*
|
||||||
|
* Originally by Elliot C Back -
|
||||||
|
* http://elliottback.com/wp/hashmap-implementation-in-c/
|
||||||
|
*
|
||||||
|
* Modified by Pete Warden to fix a serious performance problem, support strings
|
||||||
|
* as keys and removed thread synchronization - http://petewarden.typepad.com
|
||||||
|
*/
|
||||||
|
#ifndef __HASHMAP_H__
|
||||||
|
#define __HASHMAP_H__
|
||||||
|
|
||||||
|
#define MAP_MISSING -3 /* No such element */
|
||||||
|
#define MAP_FULL -2 /* Hashmap is full */
|
||||||
|
#define MAP_OMEM -1 /* Out of Memory */
|
||||||
|
#define MAP_OK 0 /* OK */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* any_t is a pointer. This allows you to put arbitrary structures in
|
||||||
|
* the hashmap.
|
||||||
|
*/
|
||||||
|
typedef void *any_t;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PFany is a pointer to a function that can take two any_t arguments
|
||||||
|
* and return an integer. Returns status code..
|
||||||
|
*/
|
||||||
|
typedef int (*PFany)(any_t, any_t);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* map_t is a pointer to an internally maintained data structure.
|
||||||
|
* Clients of this package do not need to know how hashmaps are
|
||||||
|
* represented. They see and manipulate only map_t's.
|
||||||
|
*/
|
||||||
|
typedef any_t map_t;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return an empty hashmap. Returns NULL if empty.
|
||||||
|
*/
|
||||||
|
extern map_t hashmap_new();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Iteratively call f with argument (item, data) for
|
||||||
|
* each element data in the hashmap. The function must
|
||||||
|
* return a map status code. If it returns anything other
|
||||||
|
* than MAP_OK the traversal is terminated. f must
|
||||||
|
* not reenter any hashmap functions, or deadlock may arise.
|
||||||
|
*/
|
||||||
|
extern int hashmap_iterate(map_t in, PFany f, any_t item);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Add an element to the hashmap. Return MAP_OK or MAP_OMEM.
|
||||||
|
*/
|
||||||
|
extern int hashmap_put(map_t in, char *key, any_t value);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get an element from the hashmap. Return MAP_OK or MAP_MISSING.
|
||||||
|
*/
|
||||||
|
extern int hashmap_get(map_t in, char *key, any_t *arg);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Remove an element from the hashmap. Return MAP_OK or MAP_MISSING.
|
||||||
|
*/
|
||||||
|
extern int hashmap_remove(map_t in, char *key);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get any element. Return MAP_OK or MAP_MISSING.
|
||||||
|
* remove - should the element be removed from the hashmap
|
||||||
|
*/
|
||||||
|
extern int hashmap_get_one(map_t in, any_t *arg, int remove);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Free the hashmap
|
||||||
|
*/
|
||||||
|
extern void hashmap_free(map_t in);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get the current size of a hashmap
|
||||||
|
*/
|
||||||
|
extern int hashmap_length(map_t in);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -0,0 +1,275 @@
|
|||||||
|
import sys
|
||||||
|
import json
|
||||||
|
import re
|
||||||
|
from collections import defaultdict
|
||||||
|
# import pygraphviz as pgv
|
||||||
|
|
||||||
|
gram_data = None
|
||||||
|
state_count = 1
|
||||||
|
pda = []
|
||||||
|
worklist = []
|
||||||
|
state_stacks = {}
|
||||||
|
|
||||||
|
# === If user provides upper bound on the stack size during FSA creation ===
|
||||||
|
# Specifies the upper bound to which the stack is allowed to grow
|
||||||
|
# If for any generated state, the stack size is >= stack_limit then this
|
||||||
|
# state is not expanded further.
|
||||||
|
stack_limit = None
|
||||||
|
# Holds the set of unexpanded rules owing to the user-passed stack constraint limit
|
||||||
|
unexpanded_rules = set()
|
||||||
|
|
||||||
|
def main(grammar, limit):
|
||||||
|
global worklist, gram_data, stack_limit
|
||||||
|
current = '0'
|
||||||
|
stack_limit = limit
|
||||||
|
if stack_limit:
|
||||||
|
print ('[X] Operating in bounded stack mode')
|
||||||
|
|
||||||
|
with open(grammar, 'r') as fd:
|
||||||
|
gram_data = json.load(fd)
|
||||||
|
start_symbol = gram_data["Start"][0]
|
||||||
|
worklist.append([current, [start_symbol]])
|
||||||
|
# print (grammar)
|
||||||
|
filename = (grammar.split('/')[-1]).split('.')[0]
|
||||||
|
|
||||||
|
|
||||||
|
while worklist:
|
||||||
|
# Take an element from the worklist
|
||||||
|
# print ('================')
|
||||||
|
# print ('Worklist:', worklist)
|
||||||
|
element = worklist.pop(0)
|
||||||
|
prep_transitions(element)
|
||||||
|
|
||||||
|
pda_file = filename + '_transition.json'
|
||||||
|
graph_file = filename + '.png'
|
||||||
|
# print ('XXXXXXXXXXXXXXXX')
|
||||||
|
# print ('PDA file:%s Png graph file:%s' % (pda_file, graph_file))
|
||||||
|
# XXX Commented out because visualization of current version of PHP causes segfault
|
||||||
|
# Create the graph and dump the transitions to a file
|
||||||
|
# create_graph(filename)
|
||||||
|
transformed = postprocess()
|
||||||
|
with open(filename + '_automata.json', 'w+') as fd:
|
||||||
|
json.dump(transformed, fd)
|
||||||
|
with open(filename + '_transition.json', 'w+') as fd:
|
||||||
|
json.dump(pda, fd)
|
||||||
|
if not unexpanded_rules:
|
||||||
|
print ('[X] No unexpanded rules, absolute FSA formed')
|
||||||
|
exit(0)
|
||||||
|
else:
|
||||||
|
print ('[X] Certain rules were not expanded due to stack size limit. Inexact approximation has been created and the disallowed rules have been put in {}_disallowed.json'.format(filename))
|
||||||
|
print ('[X] Number of unexpanded rules:', len(unexpanded_rules))
|
||||||
|
with open(filename + '_disallowed.json', 'w+') as fd:
|
||||||
|
json.dump(list(unexpanded_rules), fd)
|
||||||
|
|
||||||
|
def create_graph(filename):
|
||||||
|
'''
|
||||||
|
Creates a DOT representation of the PDA
|
||||||
|
'''
|
||||||
|
global pda
|
||||||
|
G = pgv.AGraph(strict = False, directed = True)
|
||||||
|
for transition in pda:
|
||||||
|
print ('Transition:', transition)
|
||||||
|
G.add_edge(transition['source'], transition['dest'],
|
||||||
|
label = 'Term:{}'.format(transition['terminal']))
|
||||||
|
G.layout(prog = 'dot')
|
||||||
|
print ('Do it up 2')
|
||||||
|
G.draw(filename + '.png')
|
||||||
|
|
||||||
|
def prep_transitions(element):
|
||||||
|
'''
|
||||||
|
Generates transitions
|
||||||
|
'''
|
||||||
|
global gram_data, state_count, pda, worklist, state_stacks, stack_limit, unexpanded_rules
|
||||||
|
state = element[0]
|
||||||
|
try:
|
||||||
|
nonterminal = element[1][0]
|
||||||
|
except IndexError:
|
||||||
|
# Final state was encountered, pop from worklist without doing anything
|
||||||
|
return
|
||||||
|
rules = gram_data[nonterminal]
|
||||||
|
count = 1
|
||||||
|
for rule in rules:
|
||||||
|
isRecursive = False
|
||||||
|
# print ('Current state:', state)
|
||||||
|
terminal, ss, termIsRegex = tokenize(rule)
|
||||||
|
transition = get_template()
|
||||||
|
transition['trigger'] = '_'.join([state, str(count)])
|
||||||
|
transition['source'] = state
|
||||||
|
transition['dest'] = str(state_count)
|
||||||
|
transition['ss'] = ss
|
||||||
|
transition['terminal'] = terminal
|
||||||
|
transition['rule'] = "{} -> {}".format(nonterminal, rule )
|
||||||
|
if termIsRegex:
|
||||||
|
transition['termIsRegex'] = True
|
||||||
|
|
||||||
|
# Creating a state stack for the new state
|
||||||
|
try:
|
||||||
|
state_stack = state_stacks[state][:]
|
||||||
|
except:
|
||||||
|
state_stack = []
|
||||||
|
if len(state_stack):
|
||||||
|
state_stack.pop(0)
|
||||||
|
if ss:
|
||||||
|
for symbol in ss[::-1]:
|
||||||
|
state_stack.insert(0, symbol)
|
||||||
|
transition['stack'] = state_stack
|
||||||
|
|
||||||
|
# Check if a recursive transition state being created, if so make a backward
|
||||||
|
# edge and don't add anything to the worklist
|
||||||
|
# print (state_stacks)
|
||||||
|
if state_stacks:
|
||||||
|
for state_element, stack in state_stacks.items():
|
||||||
|
# print ('Stack:', sorted(stack))
|
||||||
|
# print ('State stack:', sorted(state_stack))
|
||||||
|
if sorted(stack) == sorted(state_stack):
|
||||||
|
transition['dest'] = state_element
|
||||||
|
# print ('Recursive:', transition)
|
||||||
|
pda.append(transition)
|
||||||
|
count += 1
|
||||||
|
isRecursive = True
|
||||||
|
break
|
||||||
|
# If a recursive transition exercised don't add the same transition as a new
|
||||||
|
# edge, continue onto the next transitions
|
||||||
|
if isRecursive:
|
||||||
|
continue
|
||||||
|
|
||||||
|
# If the generated state has a stack size > stack_limit then that state is abandoned
|
||||||
|
# and not added to the FSA or the worklist for further expansion
|
||||||
|
if stack_limit:
|
||||||
|
if (len(transition['stack']) > stack_limit):
|
||||||
|
unexpanded_rules.add(transition['rule'])
|
||||||
|
continue
|
||||||
|
|
||||||
|
# Create transitions for the non-recursive relations and add to the worklist
|
||||||
|
# print ('Normal:', transition)
|
||||||
|
# print ('State2:', state)
|
||||||
|
pda.append(transition)
|
||||||
|
worklist.append([transition['dest'], transition['stack']])
|
||||||
|
state_stacks[transition['dest']] = state_stack
|
||||||
|
state_count += 1
|
||||||
|
count += 1
|
||||||
|
|
||||||
|
def tokenize(rule):
|
||||||
|
'''
|
||||||
|
Gets the terminal and the corresponding stack symbols from a rule in GNF form
|
||||||
|
'''
|
||||||
|
pattern = re.compile("([r])*\'([\s\S]+)\'([\s\S]*)")
|
||||||
|
terminal = None
|
||||||
|
ss = None
|
||||||
|
termIsRegex = False
|
||||||
|
match = pattern.match(rule)
|
||||||
|
if match.group(1):
|
||||||
|
termIsRegex = True
|
||||||
|
if match.group(2):
|
||||||
|
terminal = match.group(2)
|
||||||
|
else:
|
||||||
|
raise AssertionError("Rule is not in GNF form")
|
||||||
|
|
||||||
|
if match.group(3):
|
||||||
|
ss = (match.group(3)).split()
|
||||||
|
|
||||||
|
return terminal, ss, termIsRegex
|
||||||
|
|
||||||
|
def get_template():
|
||||||
|
transition_template = {
|
||||||
|
'trigger':None,
|
||||||
|
'source': None,
|
||||||
|
'dest': None,
|
||||||
|
'termIsRegex': False,
|
||||||
|
'terminal' : None,
|
||||||
|
'stack': []
|
||||||
|
}
|
||||||
|
return transition_template
|
||||||
|
|
||||||
|
def postprocess():
|
||||||
|
'''
|
||||||
|
Creates a representation to be passed on to the C-module
|
||||||
|
'''
|
||||||
|
global pda
|
||||||
|
final_struct = {}
|
||||||
|
memoized = defaultdict(list)
|
||||||
|
# Supporting data structures for if stack limit is imposed
|
||||||
|
culled_pda = []
|
||||||
|
culled_final = []
|
||||||
|
num_transitions = 0 # Keep track of number of transitions
|
||||||
|
|
||||||
|
|
||||||
|
states, final, initial = _get_states()
|
||||||
|
|
||||||
|
print (initial)
|
||||||
|
assert len(initial) == 1, 'More than one init state found'
|
||||||
|
|
||||||
|
# Cull transitions to states which were not expanded owing to the stack limit
|
||||||
|
if stack_limit:
|
||||||
|
|
||||||
|
blocklist = []
|
||||||
|
for final_state in final:
|
||||||
|
for transition in pda:
|
||||||
|
if (transition["dest"] == final_state) and (len(transition["stack"]) > 0):
|
||||||
|
blocklist.append(transition["dest"])
|
||||||
|
continue
|
||||||
|
else:
|
||||||
|
culled_pda.append(transition)
|
||||||
|
|
||||||
|
culled_final = [state for state in final if state not in blocklist]
|
||||||
|
|
||||||
|
assert len(culled_final) == 1, 'More than one final state found'
|
||||||
|
|
||||||
|
for transition in culled_pda:
|
||||||
|
state = transition["source"]
|
||||||
|
if transition["dest"] in blocklist:
|
||||||
|
continue
|
||||||
|
num_transitions += 1
|
||||||
|
memoized[state].append([transition["trigger"], transition["dest"],
|
||||||
|
transition["terminal"]])
|
||||||
|
final_struct["init_state"] = initial
|
||||||
|
final_struct["final_state"] = culled_final[0]
|
||||||
|
# The reason we do this is because when states are culled, the indexing is
|
||||||
|
# still relative to the actual number of states hence we keep numstates recorded
|
||||||
|
# as the original number of states
|
||||||
|
print ('[X] Actual Number of states:', len(memoized.keys()))
|
||||||
|
print ('[X] Number of transitions:', num_transitions)
|
||||||
|
print ('[X] Original Number of states:', len(states))
|
||||||
|
final_struct["numstates"] = len(states)
|
||||||
|
final_struct["pda"] = memoized
|
||||||
|
return final_struct
|
||||||
|
|
||||||
|
# Running FSA construction in exact approximation mode and postprocessing it like so
|
||||||
|
for transition in pda:
|
||||||
|
state = transition["source"]
|
||||||
|
memoized[state].append([transition["trigger"], transition["dest"],
|
||||||
|
transition["terminal"]])
|
||||||
|
|
||||||
|
final_struct["init_state"] = initial
|
||||||
|
final_struct["final_state"] = final[0]
|
||||||
|
print ('[X] Actual Number of states:', len(memoized.keys()))
|
||||||
|
final_struct["numstates"] = len(memoized.keys())
|
||||||
|
final_struct["pda"] = memoized
|
||||||
|
return final_struct
|
||||||
|
|
||||||
|
|
||||||
|
def _get_states():
|
||||||
|
source = set()
|
||||||
|
dest = set()
|
||||||
|
global pda
|
||||||
|
for transition in pda:
|
||||||
|
source.add(transition["source"])
|
||||||
|
dest.add(transition["dest"])
|
||||||
|
source_copy = source.copy()
|
||||||
|
source_copy.update(dest)
|
||||||
|
return list(source_copy), list(dest.difference(source)), str(''.join(list(source.difference(dest))))
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
import argparse
|
||||||
|
parser = argparse.ArgumentParser(description = 'Script to convert GNF grammar to PDA')
|
||||||
|
parser.add_argument(
|
||||||
|
'--gf',
|
||||||
|
type = str,
|
||||||
|
help = 'Location of GNF grammar')
|
||||||
|
parser.add_argument(
|
||||||
|
'--limit',
|
||||||
|
type = int,
|
||||||
|
default = None,
|
||||||
|
help = 'Specify the upper bound for the stack size')
|
||||||
|
args = parser.parse_args()
|
||||||
|
main(args.gf, args.limit)
|
@ -0,0 +1,289 @@
|
|||||||
|
import sys
|
||||||
|
import re
|
||||||
|
import copy
|
||||||
|
import json
|
||||||
|
from string import ascii_uppercase
|
||||||
|
from itertools import combinations
|
||||||
|
from collections import defaultdict
|
||||||
|
|
||||||
|
NONTERMINALSET = []
|
||||||
|
COUNT = 1
|
||||||
|
|
||||||
|
def main(grammar_file, out, start):
|
||||||
|
grammar = None
|
||||||
|
# If grammar file is a preprocessed NT file, then skip preprocessing
|
||||||
|
if '.json' in grammar_file:
|
||||||
|
with open(grammar_file, 'r') as fd:
|
||||||
|
grammar = json.load(fd)
|
||||||
|
elif '.g4' in grammar_file:
|
||||||
|
with open(grammar_file, 'r') as fd:
|
||||||
|
data = fd.readlines()
|
||||||
|
grammar = preprocess(data)
|
||||||
|
else:
|
||||||
|
raise('Unknwown file format passed. Accepts (.g4/.json)')
|
||||||
|
|
||||||
|
with open('debug_preprocess.json', 'w+') as fd:
|
||||||
|
json.dump(grammar, fd)
|
||||||
|
grammar = remove_unit(grammar) # eliminates unit productions
|
||||||
|
with open('debug_unit.json', 'w+') as fd:
|
||||||
|
json.dump(grammar, fd)
|
||||||
|
grammar = remove_mixed(grammar) # eliminate terminals existing with non-terminals
|
||||||
|
with open('debug_mixed.json', 'w+') as fd:
|
||||||
|
json.dump(grammar, fd)
|
||||||
|
grammar = break_rules(grammar) # eliminate rules with more than two non-terminals
|
||||||
|
with open('debug_break.json', 'w+') as fd:
|
||||||
|
json.dump(grammar, fd)
|
||||||
|
grammar = gnf(grammar)
|
||||||
|
|
||||||
|
# Dump GNF form of the grammar with only reachable rules
|
||||||
|
# reachable_grammar = get_reachable(grammar, start)
|
||||||
|
# with open('debug_gnf_reachable.json', 'w+') as fd:
|
||||||
|
# json.dump(reachable_grammar, fd)
|
||||||
|
with open('debug_gnf.json', 'w+') as fd:
|
||||||
|
json.dump(grammar, fd)
|
||||||
|
|
||||||
|
grammar["Start"] = [start]
|
||||||
|
with open(out, 'w+') as fd:
|
||||||
|
json.dump(grammar, fd)
|
||||||
|
|
||||||
|
def get_reachable(grammar, start):
|
||||||
|
'''
|
||||||
|
Returns a grammar without dead rules
|
||||||
|
'''
|
||||||
|
reachable_nt = set()
|
||||||
|
worklist = list()
|
||||||
|
processed = set()
|
||||||
|
reachable_grammar = dict()
|
||||||
|
worklist.append(start)
|
||||||
|
|
||||||
|
while worklist:
|
||||||
|
nt = worklist.pop(0)
|
||||||
|
processed.add(nt)
|
||||||
|
reachable_grammar[nt] = grammar[nt]
|
||||||
|
rules = grammar[nt]
|
||||||
|
for rule in rules:
|
||||||
|
tokens = gettokens(rule)
|
||||||
|
for token in tokens:
|
||||||
|
if not isTerminal(token):
|
||||||
|
if token not in processed:
|
||||||
|
worklist.append(token)
|
||||||
|
return reachable_grammar
|
||||||
|
|
||||||
|
|
||||||
|
def gettokens(rule):
|
||||||
|
pattern = re.compile("([^\s\"\']+)|\"([^\"]*)\"|\'([^\']*)\'")
|
||||||
|
return [matched.group(0) for matched in pattern.finditer(rule)]
|
||||||
|
|
||||||
|
def gnf(grammar):
|
||||||
|
old_grammar = copy.deepcopy(grammar)
|
||||||
|
new_grammar = defaultdict(list)
|
||||||
|
isgnf = False
|
||||||
|
while not isgnf:
|
||||||
|
for lhs, rules in old_grammar.items():
|
||||||
|
for rule in rules:
|
||||||
|
tokens = gettokens(rule)
|
||||||
|
if len(tokens) == 1 and isTerminal(rule):
|
||||||
|
new_grammar[lhs].append(rule)
|
||||||
|
continue
|
||||||
|
startoken = tokens[0]
|
||||||
|
endrule = tokens[1:]
|
||||||
|
if not isTerminal(startoken):
|
||||||
|
newrules = []
|
||||||
|
extendrules = old_grammar[startoken]
|
||||||
|
for extension in extendrules:
|
||||||
|
temprule = endrule[:]
|
||||||
|
temprule.insert(0, extension)
|
||||||
|
newrules.append(temprule)
|
||||||
|
for newnew in newrules:
|
||||||
|
new_grammar[lhs].append(' '.join(newnew))
|
||||||
|
else:
|
||||||
|
new_grammar[lhs].append(rule)
|
||||||
|
isgnf = True
|
||||||
|
for lhs, rules in new_grammar.items():
|
||||||
|
for rule in rules:
|
||||||
|
# if "\' \'" or isTerminal(rule):
|
||||||
|
tokens = gettokens(rule)
|
||||||
|
if len(tokens) == 1 and isTerminal(rule):
|
||||||
|
continue
|
||||||
|
startoken = tokens[0]
|
||||||
|
if not isTerminal(startoken):
|
||||||
|
isgnf = False
|
||||||
|
break
|
||||||
|
if not isgnf:
|
||||||
|
old_grammar = copy.deepcopy(new_grammar)
|
||||||
|
new_grammar = defaultdict(list)
|
||||||
|
return new_grammar
|
||||||
|
|
||||||
|
|
||||||
|
def preprocess(data):
|
||||||
|
productions = []
|
||||||
|
production = []
|
||||||
|
for line in data:
|
||||||
|
if line != '\n':
|
||||||
|
production.append(line)
|
||||||
|
else:
|
||||||
|
productions.append(production)
|
||||||
|
production = []
|
||||||
|
final_rule_set = {}
|
||||||
|
for production in productions:
|
||||||
|
rules = []
|
||||||
|
init = production[0]
|
||||||
|
nonterminal = init.split(':')[0]
|
||||||
|
rules.append(strip_chars(init.split(':')[1]).strip('| '))
|
||||||
|
for production_rule in production[1:]:
|
||||||
|
rules.append(strip_chars(production_rule.split('|')[0]))
|
||||||
|
final_rule_set[nonterminal] = rules
|
||||||
|
# for line in data:
|
||||||
|
# if line != '\n':
|
||||||
|
# production.append(line)
|
||||||
|
return final_rule_set
|
||||||
|
|
||||||
|
def remove_unit(grammar):
|
||||||
|
nounitproductions = False
|
||||||
|
old_grammar = copy.deepcopy(grammar)
|
||||||
|
new_grammar = defaultdict(list)
|
||||||
|
while not nounitproductions:
|
||||||
|
for lhs, rules in old_grammar.items():
|
||||||
|
for rhs in rules:
|
||||||
|
# Checking if the rule is a unit production rule
|
||||||
|
if len(gettokens(rhs)) == 1:
|
||||||
|
if not isTerminal(rhs):
|
||||||
|
new_grammar[lhs].extend([rule for rule in old_grammar[rhs]])
|
||||||
|
else:
|
||||||
|
new_grammar[lhs].append(rhs)
|
||||||
|
else:
|
||||||
|
new_grammar[lhs].append(rhs)
|
||||||
|
# Checking there are no unit productions left in the grammar
|
||||||
|
nounitproductions = True
|
||||||
|
for lhs, rules in new_grammar.items():
|
||||||
|
for rhs in rules:
|
||||||
|
if len(gettokens(rhs)) == 1:
|
||||||
|
if not isTerminal(rhs):
|
||||||
|
nounitproductions = False
|
||||||
|
break
|
||||||
|
if not nounitproductions:
|
||||||
|
break
|
||||||
|
# Unit productions are still there in the grammar -- repeat the process
|
||||||
|
if not nounitproductions:
|
||||||
|
old_grammar = copy.deepcopy(new_grammar)
|
||||||
|
new_grammar = defaultdict(list)
|
||||||
|
return new_grammar
|
||||||
|
|
||||||
|
def isTerminal(rule):
|
||||||
|
# pattern = re.compile("([r]*\'[\s\S]+\')")
|
||||||
|
pattern = re.compile("\'(.*?)\'")
|
||||||
|
match = pattern.match(rule)
|
||||||
|
if match:
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
def remove_mixed(grammar):
|
||||||
|
'''
|
||||||
|
Remove rules where there are terminals mixed in with non-terminals
|
||||||
|
'''
|
||||||
|
new_grammar = defaultdict(list)
|
||||||
|
for lhs, rules in grammar.items():
|
||||||
|
for rhs in rules:
|
||||||
|
# tokens = rhs.split(' ')
|
||||||
|
regen_rule = []
|
||||||
|
tokens = gettokens(rhs)
|
||||||
|
if len(gettokens(rhs)) == 1:
|
||||||
|
new_grammar[lhs].append(rhs)
|
||||||
|
continue
|
||||||
|
for token in tokens:
|
||||||
|
# Identify if there is a terminal in the RHS
|
||||||
|
if isTerminal(token):
|
||||||
|
# Check if a corresponding nonterminal already exists
|
||||||
|
nonterminal = terminal_exist(token, new_grammar)
|
||||||
|
if nonterminal:
|
||||||
|
regen_rule.append(nonterminal)
|
||||||
|
else:
|
||||||
|
new_nonterm = get_nonterminal()
|
||||||
|
new_grammar[new_nonterm].append(token)
|
||||||
|
regen_rule.append(new_nonterm)
|
||||||
|
else:
|
||||||
|
regen_rule.append(token)
|
||||||
|
new_grammar[lhs].append(' '.join(regen_rule))
|
||||||
|
return new_grammar
|
||||||
|
|
||||||
|
def break_rules(grammar):
|
||||||
|
new_grammar = defaultdict(list)
|
||||||
|
old_grammar = copy.deepcopy(grammar)
|
||||||
|
nomulti = False
|
||||||
|
while not nomulti:
|
||||||
|
for lhs, rules in old_grammar.items():
|
||||||
|
for rhs in rules:
|
||||||
|
tokens = gettokens(rhs)
|
||||||
|
if len(tokens) > 2 and (not isTerminal(rhs)):
|
||||||
|
split = tokens[:-1]
|
||||||
|
nonterminal = terminal_exist(' '.join(split), new_grammar)
|
||||||
|
if nonterminal:
|
||||||
|
newrule = ' '.join([nonterminal, tokens[-1]])
|
||||||
|
new_grammar[lhs].append(newrule)
|
||||||
|
else:
|
||||||
|
nonterminal = get_nonterminal()
|
||||||
|
new_grammar[nonterminal].append(' '.join(split))
|
||||||
|
newrule = ' '.join([nonterminal, tokens[-1]])
|
||||||
|
new_grammar[lhs].append(newrule)
|
||||||
|
else:
|
||||||
|
new_grammar[lhs].append(rhs)
|
||||||
|
nomulti = True
|
||||||
|
for lhs, rules in new_grammar.items():
|
||||||
|
for rhs in rules:
|
||||||
|
# tokens = rhs.split(' ')
|
||||||
|
tokens = gettokens(rhs)
|
||||||
|
if len(tokens) > 2 and (not isTerminal(rhs)):
|
||||||
|
nomulti = False
|
||||||
|
break
|
||||||
|
if not nomulti:
|
||||||
|
old_grammar = copy.deepcopy(new_grammar)
|
||||||
|
new_grammar = defaultdict(list)
|
||||||
|
return new_grammar
|
||||||
|
|
||||||
|
def strip_chars(rule):
|
||||||
|
return rule.strip('\n\t ')
|
||||||
|
|
||||||
|
def get_nonterminal():
|
||||||
|
global NONTERMINALSET
|
||||||
|
if NONTERMINALSET:
|
||||||
|
return NONTERMINALSET.pop(0)
|
||||||
|
else:
|
||||||
|
_repopulate()
|
||||||
|
return NONTERMINALSET.pop(0)
|
||||||
|
|
||||||
|
def _repopulate():
|
||||||
|
global COUNT
|
||||||
|
global NONTERMINALSET
|
||||||
|
NONTERMINALSET = [''.join(x) for x in list(combinations(ascii_uppercase, COUNT))]
|
||||||
|
COUNT += 1
|
||||||
|
|
||||||
|
def terminal_exist(token, grammar):
|
||||||
|
for nonterminal, rules in grammar.items():
|
||||||
|
if token in rules:
|
||||||
|
return nonterminal
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
import argparse
|
||||||
|
parser = argparse.ArgumentParser(description = 'Script to convert grammar to GNF form')
|
||||||
|
parser.add_argument(
|
||||||
|
'--gf',
|
||||||
|
type = str,
|
||||||
|
required = True,
|
||||||
|
help = 'Location of grammar file')
|
||||||
|
parser.add_argument(
|
||||||
|
'--out',
|
||||||
|
type = str,
|
||||||
|
required = True,
|
||||||
|
help = 'Location of output file')
|
||||||
|
parser.add_argument(
|
||||||
|
'--start',
|
||||||
|
type = str,
|
||||||
|
required = True,
|
||||||
|
help = 'Start token')
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
main(args.gf, args.out, args.start)
|
@ -0,0 +1,38 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# This script creates a FSA describing the input grammar *.g4
|
||||||
|
|
||||||
|
if [ ! "$#" -lt 4 ]; then
|
||||||
|
echo "Usage: ./prep_pda.sh <grammar_file> <start> [stack_limit]"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
GRAMMAR_FILE=$1
|
||||||
|
GRAMMAR_DIR="$(dirname $GRAMMAR_FILE)"
|
||||||
|
START="$2"
|
||||||
|
STACK_LIMIT="$3"
|
||||||
|
|
||||||
|
# Get filename
|
||||||
|
FILE=$(basename -- "$GRAMMAR_FILE")
|
||||||
|
echo "File:$FILE"
|
||||||
|
FILENAME="${FILE%.*}"
|
||||||
|
echo "Name:$FILENAME"
|
||||||
|
|
||||||
|
|
||||||
|
# Create the GNF form of the grammar
|
||||||
|
CMD="python gnf_converter.py --gf $GRAMMAR_FILE --out ${FILENAME}.json --start $START"
|
||||||
|
$CMD
|
||||||
|
|
||||||
|
# Generate grammar automaton
|
||||||
|
# Check if user provided a stack limit
|
||||||
|
if [ -z "${STACK_LIMIT}" ]; then
|
||||||
|
CMD="python3 construct_automata.py --gf ${FILENAME}.json"
|
||||||
|
else
|
||||||
|
CMD="python construct_automata.py --gf ${FILENAME}.json --limit ${STACK_LIMIT}"
|
||||||
|
fi
|
||||||
|
echo $CMD
|
||||||
|
$CMD
|
||||||
|
|
||||||
|
# Move PDA to the source dir of the grammar
|
||||||
|
echo "Copying ${FILENAME}_automata.json to $GRAMMAR_DIR"
|
||||||
|
mv "${FILENAME}_automata.json" $GRAMMAR_DIR/
|
@ -0,0 +1,154 @@
|
|||||||
|
/* This is the testing module for Gramatron
|
||||||
|
*/
|
||||||
|
#include "afl-fuzz.h"
|
||||||
|
#include "gramfuzz.h"
|
||||||
|
|
||||||
|
#define NUMINPUTS 50
|
||||||
|
|
||||||
|
state *create_pda(u8 *automaton_file) {
|
||||||
|
|
||||||
|
struct json_object *parsed_json;
|
||||||
|
state * pda;
|
||||||
|
json_object * source_obj, *attr;
|
||||||
|
int arraylen, ii, ii2, trigger_len, error;
|
||||||
|
|
||||||
|
printf("\n[GF] Automaton file passed:%s", automaton_file);
|
||||||
|
// parsed_json =
|
||||||
|
// json_object_from_file("./gramfuzz/php_gnf_processed_full.json");
|
||||||
|
parsed_json = json_object_from_file(automaton_file);
|
||||||
|
|
||||||
|
// Getting final state
|
||||||
|
source_obj = json_object_object_get(parsed_json, "final_state");
|
||||||
|
printf("\t\nFinal=%s\n", json_object_get_string(source_obj));
|
||||||
|
final_state = atoi(json_object_get_string(source_obj));
|
||||||
|
|
||||||
|
// Getting initial state
|
||||||
|
source_obj = json_object_object_get(parsed_json, "init_state");
|
||||||
|
init_state = atoi(json_object_get_string(source_obj));
|
||||||
|
printf("\tInit=%s\n", json_object_get_string(source_obj));
|
||||||
|
|
||||||
|
// Getting number of states
|
||||||
|
source_obj = json_object_object_get(parsed_json, "numstates");
|
||||||
|
numstates = atoi(json_object_get_string(source_obj)) + 1;
|
||||||
|
printf("\tNumStates=%d\n", numstates);
|
||||||
|
|
||||||
|
// Allocate state space for each pda state
|
||||||
|
pda = (state *)calloc(atoi(json_object_get_string(source_obj)) + 1,
|
||||||
|
sizeof(state));
|
||||||
|
|
||||||
|
// Getting PDA representation
|
||||||
|
source_obj = json_object_object_get(parsed_json, "pda");
|
||||||
|
enum json_type type;
|
||||||
|
json_object_object_foreach(source_obj, key, val) {
|
||||||
|
|
||||||
|
state * state_ptr;
|
||||||
|
trigger *trigger_ptr;
|
||||||
|
int offset;
|
||||||
|
|
||||||
|
// Get the correct offset into the pda to store state information
|
||||||
|
state_ptr = pda;
|
||||||
|
offset = atoi(key);
|
||||||
|
state_ptr += offset;
|
||||||
|
|
||||||
|
// Store state string
|
||||||
|
state_ptr->state_name = offset;
|
||||||
|
|
||||||
|
// Create trigger array of structs
|
||||||
|
trigger_len = json_object_array_length(val);
|
||||||
|
state_ptr->trigger_len = trigger_len;
|
||||||
|
trigger_ptr = (trigger *)calloc(trigger_len, sizeof(trigger));
|
||||||
|
state_ptr->ptr = trigger_ptr;
|
||||||
|
printf("\nName:%d Trigger:%d", offset, trigger_len);
|
||||||
|
|
||||||
|
for (ii = 0; ii < trigger_len; ii++) {
|
||||||
|
|
||||||
|
json_object *obj = json_object_array_get_idx(val, ii);
|
||||||
|
// Get all the trigger trigger attributes
|
||||||
|
attr = json_object_array_get_idx(obj, 0);
|
||||||
|
(trigger_ptr)->id = strdup(json_object_get_string(attr));
|
||||||
|
|
||||||
|
attr = json_object_array_get_idx(obj, 1);
|
||||||
|
trigger_ptr->dest = atoi(json_object_get_string(attr));
|
||||||
|
|
||||||
|
attr = json_object_array_get_idx(obj, 2);
|
||||||
|
if (!strcmp("\\n", json_object_get_string(attr))) {
|
||||||
|
|
||||||
|
trigger_ptr->term = strdup("\n");
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
trigger_ptr->term = strdup(json_object_get_string(attr));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
trigger_ptr->term_len = strlen(trigger_ptr->term);
|
||||||
|
trigger_ptr++;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete the JSON object
|
||||||
|
json_object_put(parsed_json);
|
||||||
|
|
||||||
|
return pda;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void SanityCheck(char *automaton_path) {
|
||||||
|
|
||||||
|
state * pda = create_pda(automaton_path);
|
||||||
|
int count = 0, state;
|
||||||
|
Get_Dupes_Ret *getdupesret;
|
||||||
|
IdxMap_new * statemap;
|
||||||
|
IdxMap_new * statemap_ptr;
|
||||||
|
terminal * term_ptr;
|
||||||
|
|
||||||
|
while (count < NUMINPUTS) {
|
||||||
|
|
||||||
|
// Perform input generation
|
||||||
|
Array *generated = gen_input(pda, NULL);
|
||||||
|
print_repr(generated, "Gen");
|
||||||
|
count += 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
|
||||||
|
char * mode;
|
||||||
|
char * automaton_path;
|
||||||
|
char * output_dir = NULL;
|
||||||
|
struct timeval tv;
|
||||||
|
struct timeval tz;
|
||||||
|
// gettimeofday(&tv, &tz);
|
||||||
|
srand(1337);
|
||||||
|
if (argc == 3) {
|
||||||
|
|
||||||
|
mode = argv[1];
|
||||||
|
automaton_path = strdup(argv[2]);
|
||||||
|
printf("\nMode:%s Path:%s", mode, automaton_path);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
printf("\nUsage: ./test <mode> <automaton_path>");
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strcmp(mode, "SanityCheck")) {
|
||||||
|
|
||||||
|
SanityCheck(automaton_path);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
printf("\nUnrecognized mode");
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,57 @@
|
|||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <json-c/json.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include "hashmap.h"
|
||||||
|
#include "uthash.h"
|
||||||
|
#include "utarray.h"
|
||||||
|
|
||||||
|
#define INIT_SIZE 100 // Initial size of the dynamic array holding the input
|
||||||
|
|
||||||
|
typedef struct terminal {
|
||||||
|
|
||||||
|
int state;
|
||||||
|
int trigger_idx;
|
||||||
|
size_t symbol_len;
|
||||||
|
char * symbol;
|
||||||
|
|
||||||
|
} terminal;
|
||||||
|
|
||||||
|
typedef struct trigger {
|
||||||
|
|
||||||
|
char * id;
|
||||||
|
int dest;
|
||||||
|
char * term;
|
||||||
|
size_t term_len;
|
||||||
|
|
||||||
|
} trigger;
|
||||||
|
|
||||||
|
typedef struct state {
|
||||||
|
|
||||||
|
int state_name; // Integer State name
|
||||||
|
int trigger_len; // Number of triggers associated with this state
|
||||||
|
trigger *ptr; // Pointer to beginning of the list of triggers
|
||||||
|
|
||||||
|
} state;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
|
||||||
|
size_t used;
|
||||||
|
size_t size;
|
||||||
|
size_t inputlen;
|
||||||
|
terminal *start;
|
||||||
|
|
||||||
|
} Array;
|
||||||
|
|
||||||
|
int init_state;
|
||||||
|
int curr_state;
|
||||||
|
int final_state;
|
||||||
|
|
||||||
|
state *create_pda(char *);
|
||||||
|
Array *gen_input(state *, Array *);
|
||||||
|
void print_repr(Array *, char *);
|
||||||
|
void initArray(Array *, size_t);
|
||||||
|
void insertArray(Array *, int, char *, size_t, int);
|
||||||
|
|
@ -0,0 +1,392 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) 2008-2018, Troy D. Hanson http://troydhanson.github.com/uthash/
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||||
|
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||||
|
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||||
|
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||||
|
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* a dynamic array implementation using macros
|
||||||
|
*/
|
||||||
|
#ifndef UTARRAY_H
|
||||||
|
#define UTARRAY_H
|
||||||
|
|
||||||
|
#define UTARRAY_VERSION 2.1.0
|
||||||
|
|
||||||
|
#include <stddef.h> /* size_t */
|
||||||
|
#include <string.h> /* memset, etc */
|
||||||
|
#include <stdlib.h> /* exit */
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
|
#define UTARRAY_UNUSED __attribute__((__unused__))
|
||||||
|
#else
|
||||||
|
#define UTARRAY_UNUSED
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef oom
|
||||||
|
#error \
|
||||||
|
"The name of macro 'oom' has been changed to 'utarray_oom'. Please update your code."
|
||||||
|
#define utarray_oom() oom()
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef utarray_oom
|
||||||
|
#define utarray_oom() exit(-1)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef void(ctor_f)(void *dst, const void *src);
|
||||||
|
typedef void(dtor_f)(void *elt);
|
||||||
|
typedef void(init_f)(void *elt);
|
||||||
|
typedef struct {
|
||||||
|
|
||||||
|
size_t sz;
|
||||||
|
init_f *init;
|
||||||
|
ctor_f *copy;
|
||||||
|
dtor_f *dtor;
|
||||||
|
|
||||||
|
} UT_icd;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
|
||||||
|
unsigned i, n; /* i: index of next available slot, n: num slots */
|
||||||
|
UT_icd icd; /* initializer, copy and destructor functions */
|
||||||
|
char * d; /* n slots of size icd->sz*/
|
||||||
|
|
||||||
|
} UT_array;
|
||||||
|
|
||||||
|
#define utarray_init(a, _icd) \
|
||||||
|
do { \
|
||||||
|
\
|
||||||
|
memset(a, 0, sizeof(UT_array)); \
|
||||||
|
(a)->icd = *(_icd); \
|
||||||
|
\
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define utarray_done(a) \
|
||||||
|
do { \
|
||||||
|
\
|
||||||
|
if ((a)->n) { \
|
||||||
|
\
|
||||||
|
if ((a)->icd.dtor) { \
|
||||||
|
\
|
||||||
|
unsigned _ut_i; \
|
||||||
|
for (_ut_i = 0; _ut_i < (a)->i; _ut_i++) { \
|
||||||
|
\
|
||||||
|
(a)->icd.dtor(utarray_eltptr(a, _ut_i)); \
|
||||||
|
\
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
} \
|
||||||
|
free((a)->d); \
|
||||||
|
\
|
||||||
|
} \
|
||||||
|
(a)->n = 0; \
|
||||||
|
\
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define utarray_new(a, _icd) \
|
||||||
|
do { \
|
||||||
|
\
|
||||||
|
(a) = (UT_array *)malloc(sizeof(UT_array)); \
|
||||||
|
if ((a) == NULL) { utarray_oom(); } \
|
||||||
|
utarray_init(a, _icd); \
|
||||||
|
\
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define utarray_free(a) \
|
||||||
|
do { \
|
||||||
|
\
|
||||||
|
utarray_done(a); \
|
||||||
|
free(a); \
|
||||||
|
\
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define utarray_reserve(a, by) \
|
||||||
|
do { \
|
||||||
|
\
|
||||||
|
if (((a)->i + (by)) > (a)->n) { \
|
||||||
|
\
|
||||||
|
char *utarray_tmp; \
|
||||||
|
while (((a)->i + (by)) > (a)->n) { \
|
||||||
|
\
|
||||||
|
(a)->n = ((a)->n ? (2 * (a)->n) : 8); \
|
||||||
|
\
|
||||||
|
} \
|
||||||
|
utarray_tmp = (char *)realloc((a)->d, (a)->n * (a)->icd.sz); \
|
||||||
|
if (utarray_tmp == NULL) { utarray_oom(); } \
|
||||||
|
(a)->d = utarray_tmp; \
|
||||||
|
\
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define utarray_push_back(a, p) \
|
||||||
|
do { \
|
||||||
|
\
|
||||||
|
utarray_reserve(a, 1); \
|
||||||
|
if ((a)->icd.copy) { \
|
||||||
|
\
|
||||||
|
(a)->icd.copy(_utarray_eltptr(a, (a)->i++), p); \
|
||||||
|
\
|
||||||
|
} else { \
|
||||||
|
\
|
||||||
|
memcpy(_utarray_eltptr(a, (a)->i++), p, (a)->icd.sz); \
|
||||||
|
\
|
||||||
|
}; \
|
||||||
|
\
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define utarray_pop_back(a) \
|
||||||
|
do { \
|
||||||
|
\
|
||||||
|
if ((a)->icd.dtor) { \
|
||||||
|
\
|
||||||
|
(a)->icd.dtor(_utarray_eltptr(a, --((a)->i))); \
|
||||||
|
\
|
||||||
|
} else { \
|
||||||
|
\
|
||||||
|
(a)->i--; \
|
||||||
|
\
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define utarray_extend_back(a) \
|
||||||
|
do { \
|
||||||
|
\
|
||||||
|
utarray_reserve(a, 1); \
|
||||||
|
if ((a)->icd.init) { \
|
||||||
|
\
|
||||||
|
(a)->icd.init(_utarray_eltptr(a, (a)->i)); \
|
||||||
|
\
|
||||||
|
} else { \
|
||||||
|
\
|
||||||
|
memset(_utarray_eltptr(a, (a)->i), 0, (a)->icd.sz); \
|
||||||
|
\
|
||||||
|
} \
|
||||||
|
(a)->i++; \
|
||||||
|
\
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define utarray_len(a) ((a)->i)
|
||||||
|
|
||||||
|
#define utarray_eltptr(a, j) (((j) < (a)->i) ? _utarray_eltptr(a, j) : NULL)
|
||||||
|
#define _utarray_eltptr(a, j) ((a)->d + ((a)->icd.sz * (j)))
|
||||||
|
|
||||||
|
#define utarray_insert(a, p, j) \
|
||||||
|
do { \
|
||||||
|
\
|
||||||
|
if ((j) > (a)->i) utarray_resize(a, j); \
|
||||||
|
utarray_reserve(a, 1); \
|
||||||
|
if ((j) < (a)->i) { \
|
||||||
|
\
|
||||||
|
memmove(_utarray_eltptr(a, (j) + 1), _utarray_eltptr(a, j), \
|
||||||
|
((a)->i - (j)) * ((a)->icd.sz)); \
|
||||||
|
\
|
||||||
|
} \
|
||||||
|
if ((a)->icd.copy) { \
|
||||||
|
\
|
||||||
|
(a)->icd.copy(_utarray_eltptr(a, j), p); \
|
||||||
|
\
|
||||||
|
} else { \
|
||||||
|
\
|
||||||
|
memcpy(_utarray_eltptr(a, j), p, (a)->icd.sz); \
|
||||||
|
\
|
||||||
|
}; \
|
||||||
|
(a)->i++; \
|
||||||
|
\
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define utarray_inserta(a, w, j) \
|
||||||
|
do { \
|
||||||
|
\
|
||||||
|
if (utarray_len(w) == 0) break; \
|
||||||
|
if ((j) > (a)->i) utarray_resize(a, j); \
|
||||||
|
utarray_reserve(a, utarray_len(w)); \
|
||||||
|
if ((j) < (a)->i) { \
|
||||||
|
\
|
||||||
|
memmove(_utarray_eltptr(a, (j) + utarray_len(w)), _utarray_eltptr(a, j), \
|
||||||
|
((a)->i - (j)) * ((a)->icd.sz)); \
|
||||||
|
\
|
||||||
|
} \
|
||||||
|
if ((a)->icd.copy) { \
|
||||||
|
\
|
||||||
|
unsigned _ut_i; \
|
||||||
|
for (_ut_i = 0; _ut_i < (w)->i; _ut_i++) { \
|
||||||
|
\
|
||||||
|
(a)->icd.copy(_utarray_eltptr(a, (j) + _ut_i), \
|
||||||
|
_utarray_eltptr(w, _ut_i)); \
|
||||||
|
\
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
} else { \
|
||||||
|
\
|
||||||
|
memcpy(_utarray_eltptr(a, j), _utarray_eltptr(w, 0), \
|
||||||
|
utarray_len(w) * ((a)->icd.sz)); \
|
||||||
|
\
|
||||||
|
} \
|
||||||
|
(a)->i += utarray_len(w); \
|
||||||
|
\
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define utarray_resize(dst, num) \
|
||||||
|
do { \
|
||||||
|
\
|
||||||
|
unsigned _ut_i; \
|
||||||
|
if ((dst)->i > (unsigned)(num)) { \
|
||||||
|
\
|
||||||
|
if ((dst)->icd.dtor) { \
|
||||||
|
\
|
||||||
|
for (_ut_i = (num); _ut_i < (dst)->i; ++_ut_i) { \
|
||||||
|
\
|
||||||
|
(dst)->icd.dtor(_utarray_eltptr(dst, _ut_i)); \
|
||||||
|
\
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
} else if ((dst)->i < (unsigned)(num)) { \
|
||||||
|
\
|
||||||
|
utarray_reserve(dst, (num) - (dst)->i); \
|
||||||
|
if ((dst)->icd.init) { \
|
||||||
|
\
|
||||||
|
for (_ut_i = (dst)->i; _ut_i < (unsigned)(num); ++_ut_i) { \
|
||||||
|
\
|
||||||
|
(dst)->icd.init(_utarray_eltptr(dst, _ut_i)); \
|
||||||
|
\
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
} else { \
|
||||||
|
\
|
||||||
|
memset(_utarray_eltptr(dst, (dst)->i), 0, \
|
||||||
|
(dst)->icd.sz *((num) - (dst)->i)); \
|
||||||
|
\
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
} \
|
||||||
|
(dst)->i = (num); \
|
||||||
|
\
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define utarray_concat(dst, src) \
|
||||||
|
do { \
|
||||||
|
\
|
||||||
|
utarray_inserta(dst, src, utarray_len(dst)); \
|
||||||
|
\
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define utarray_erase(a, pos, len) \
|
||||||
|
do { \
|
||||||
|
\
|
||||||
|
if ((a)->icd.dtor) { \
|
||||||
|
\
|
||||||
|
unsigned _ut_i; \
|
||||||
|
for (_ut_i = 0; _ut_i < (len); _ut_i++) { \
|
||||||
|
\
|
||||||
|
(a)->icd.dtor(utarray_eltptr(a, (pos) + _ut_i)); \
|
||||||
|
\
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
} \
|
||||||
|
if ((a)->i > ((pos) + (len))) { \
|
||||||
|
\
|
||||||
|
memmove(_utarray_eltptr(a, pos), _utarray_eltptr(a, (pos) + (len)), \
|
||||||
|
((a)->i - ((pos) + (len))) * (a)->icd.sz); \
|
||||||
|
\
|
||||||
|
} \
|
||||||
|
(a)->i -= (len); \
|
||||||
|
\
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define utarray_renew(a, u) \
|
||||||
|
do { \
|
||||||
|
\
|
||||||
|
if (a) \
|
||||||
|
utarray_clear(a); \
|
||||||
|
else \
|
||||||
|
utarray_new(a, u); \
|
||||||
|
\
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define utarray_clear(a) \
|
||||||
|
do { \
|
||||||
|
\
|
||||||
|
if ((a)->i > 0) { \
|
||||||
|
\
|
||||||
|
if ((a)->icd.dtor) { \
|
||||||
|
\
|
||||||
|
unsigned _ut_i; \
|
||||||
|
for (_ut_i = 0; _ut_i < (a)->i; _ut_i++) { \
|
||||||
|
\
|
||||||
|
(a)->icd.dtor(_utarray_eltptr(a, _ut_i)); \
|
||||||
|
\
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
} \
|
||||||
|
(a)->i = 0; \
|
||||||
|
\
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define utarray_sort(a, cmp) \
|
||||||
|
do { \
|
||||||
|
\
|
||||||
|
qsort((a)->d, (a)->i, (a)->icd.sz, cmp); \
|
||||||
|
\
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define utarray_find(a, v, cmp) bsearch((v), (a)->d, (a)->i, (a)->icd.sz, cmp)
|
||||||
|
|
||||||
|
#define utarray_front(a) (((a)->i) ? (_utarray_eltptr(a, 0)) : NULL)
|
||||||
|
#define utarray_next(a, e) \
|
||||||
|
(((e) == NULL) ? utarray_front(a) \
|
||||||
|
: (((a)->i != utarray_eltidx(a, e) + 1) \
|
||||||
|
? _utarray_eltptr(a, utarray_eltidx(a, e) + 1) \
|
||||||
|
: NULL))
|
||||||
|
#define utarray_prev(a, e) \
|
||||||
|
(((e) == NULL) ? utarray_back(a) \
|
||||||
|
: ((utarray_eltidx(a, e) != 0) \
|
||||||
|
? _utarray_eltptr(a, utarray_eltidx(a, e) - 1) \
|
||||||
|
: NULL))
|
||||||
|
#define utarray_back(a) (((a)->i) ? (_utarray_eltptr(a, (a)->i - 1)) : NULL)
|
||||||
|
#define utarray_eltidx(a, e) (((char *)(e) - (a)->d) / (a)->icd.sz)
|
||||||
|
|
||||||
|
/* last we pre-define a few icd for common utarrays of ints and strings */
|
||||||
|
static void utarray_str_cpy(void *dst, const void *src) {
|
||||||
|
|
||||||
|
char **_src = (char **)src, **_dst = (char **)dst;
|
||||||
|
*_dst = (*_src == NULL) ? NULL : strdup(*_src);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void utarray_str_dtor(void *elt) {
|
||||||
|
|
||||||
|
char **eltc = (char **)elt;
|
||||||
|
if (*eltc != NULL) free(*eltc);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static const UT_icd ut_str_icd UTARRAY_UNUSED = {
|
||||||
|
|
||||||
|
sizeof(char *), NULL, utarray_str_cpy, utarray_str_dtor};
|
||||||
|
static const UT_icd ut_int_icd UTARRAY_UNUSED = {sizeof(int), NULL, NULL, NULL};
|
||||||
|
static const UT_icd ut_ptr_icd UTARRAY_UNUSED = {sizeof(void *), NULL, NULL,
|
||||||
|
NULL};
|
||||||
|
|
||||||
|
#endif /* UTARRAY_H */
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue