mirror of
https://github.com/AFLplusplus/AFLplusplus.git
synced 2025-06-14 02:58:08 +00:00
better tritondse support
This commit is contained in:
@ -7,6 +7,7 @@ from tritondse import Config
|
|||||||
from tritondse import CoverageStrategy
|
from tritondse import CoverageStrategy
|
||||||
from tritondse import ProcessState
|
from tritondse import ProcessState
|
||||||
from tritondse import Program
|
from tritondse import Program
|
||||||
|
from tritondse import CleLoader
|
||||||
from tritondse import Seed
|
from tritondse import Seed
|
||||||
from tritondse import SeedFormat
|
from tritondse import SeedFormat
|
||||||
from tritondse import SymbolicExecutor
|
from tritondse import SymbolicExecutor
|
||||||
@ -16,7 +17,7 @@ from tritondse import SymbolicExplorator
|
|||||||
#logging.basicConfig(level=logging.INFO)
|
#logging.basicConfig(level=logging.INFO)
|
||||||
|
|
||||||
is_debug = False
|
is_debug = False
|
||||||
out_path = "out/tritondse/queue"
|
out_path = ""
|
||||||
input_file = None
|
input_file = None
|
||||||
prog = None
|
prog = None
|
||||||
config = None
|
config = None
|
||||||
@ -29,28 +30,38 @@ def pre_exec_hook(se: SymbolicExecutor, state: ProcessState):
|
|||||||
#logging.info(f"[PRE-EXEC] Processing seed: {se.seed.hash}, \
|
#logging.info(f"[PRE-EXEC] Processing seed: {se.seed.hash}, \
|
||||||
# ({repr(se.seed.content)})")
|
# ({repr(se.seed.content)})")
|
||||||
global count
|
global count
|
||||||
global hasshes
|
global hashes
|
||||||
|
print('DEBUG - prehook')
|
||||||
if se.seed.hash not in hashes:
|
if se.seed.hash not in hashes:
|
||||||
hashes.add(se.seed.hash)
|
hashes.add(se.seed.hash)
|
||||||
filename = out_path + "/id:" + f"{count:06}" + "," + se.seed.hash
|
filename = out_path + "/id:" + f"{count:06}" + "," + se.seed.hash
|
||||||
if not os.path.exists(filename):
|
if not os.path.exists(filename):
|
||||||
|
if is_debug:
|
||||||
|
print('Creating queue input ' + filename)
|
||||||
with open(filename, 'wb') as file:
|
with open(filename, 'wb') as file:
|
||||||
file.write(se.seed.content)
|
file.write(se.seed.content)
|
||||||
count += 1
|
count += 1
|
||||||
|
else:
|
||||||
|
print('has hash: ' + se.seed.hash)
|
||||||
if input_file:
|
if input_file:
|
||||||
|
if is_debug:
|
||||||
|
print('Writing to ' + input_file + ' the content: ' + str(se.seed.content))
|
||||||
with open(input_file, 'wb') as file:
|
with open(input_file, 'wb') as file:
|
||||||
file.write(se.seed.content)
|
file.write(se.seed.content)
|
||||||
|
else:
|
||||||
|
print('no input!')
|
||||||
|
|
||||||
|
|
||||||
def init(seed):
|
def init(seed):
|
||||||
global prog
|
global prog
|
||||||
global config
|
global config
|
||||||
global dse
|
global dse
|
||||||
|
global out_path
|
||||||
global input_file
|
global input_file
|
||||||
global is_debug
|
global is_debug
|
||||||
# Load the program (LIEF-based program loader).
|
# Load the program (LIEF-based program loader).
|
||||||
prog = Program(os.environ['TRITON_DSE_TARGET'])
|
prog = CleLoader(os.environ['AFL_CUSTOM_INFO_PROGRAM'])
|
||||||
# Set the configuration.
|
# Process other configuration environment variables.
|
||||||
argv = None
|
argv = None
|
||||||
try:
|
try:
|
||||||
foo = os.environ['AFL_DEBUG']
|
foo = os.environ['AFL_DEBUG']
|
||||||
@ -58,15 +69,42 @@ def init(seed):
|
|||||||
except KeyError:
|
except KeyError:
|
||||||
pass
|
pass
|
||||||
try:
|
try:
|
||||||
argv_list = os.environ['TRITON_DSE_TARGET_ARGV']
|
foo = os.environ['AFL_CUSTOM_INFO_OUT']
|
||||||
argv = argv_list.split()
|
out_path = foo + '/../tritondse/queue'
|
||||||
except KeyError:
|
except KeyError:
|
||||||
pass
|
pass
|
||||||
try:
|
try:
|
||||||
foo = os.environ['TRITON_DSE_TARGET_INPUT']
|
foo = os.environ['AFL_CUSTOM_INFO_PROGRAM_INPUT']
|
||||||
input_file = foo
|
input_file = foo
|
||||||
except KeyError:
|
except KeyError:
|
||||||
pass
|
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('')
|
||||||
|
# Now set up TritonDSE
|
||||||
config = Config(coverage_strategy = CoverageStrategy.PATH,
|
config = Config(coverage_strategy = CoverageStrategy.PATH,
|
||||||
debug = is_debug,
|
debug = is_debug,
|
||||||
pipe_stdout = is_debug,
|
pipe_stdout = is_debug,
|
||||||
@ -79,8 +117,6 @@ def init(seed):
|
|||||||
dse = SymbolicExplorator(config, prog)
|
dse = SymbolicExplorator(config, prog)
|
||||||
# Add callbacks.
|
# Add callbacks.
|
||||||
dse.callback_manager.register_pre_execution_callback(pre_exec_hook)
|
dse.callback_manager.register_pre_execution_callback(pre_exec_hook)
|
||||||
# Create the output directory
|
|
||||||
os.makedirs(out_path, exist_ok=True)
|
|
||||||
|
|
||||||
|
|
||||||
#def fuzz(buf, add_buf, max_size):
|
#def fuzz(buf, add_buf, max_size):
|
||||||
|
@ -304,6 +304,34 @@ Note: for some distributions, you might also need the package `python[3]-apt`.
|
|||||||
In case your setup is different, set the necessary variables like this:
|
In case your setup is different, set the necessary variables like this:
|
||||||
`PYTHON_INCLUDE=/path/to/python/include LDFLAGS=-L/path/to/python/lib make`.
|
`PYTHON_INCLUDE=/path/to/python/include LDFLAGS=-L/path/to/python/lib make`.
|
||||||
|
|
||||||
|
### Helpers
|
||||||
|
|
||||||
|
For C/C++ custom mutators you get a pointer to `afl_state_t *afl` in the
|
||||||
|
`afl_custom_init()` which contains all information that you need.
|
||||||
|
Note that if you access it, you need to recompile your custom mutator if
|
||||||
|
you update AFL++ because the structure might have changed!
|
||||||
|
|
||||||
|
For mutators written in Python, Rust, GO, etc. there are a few environment
|
||||||
|
variables set to help you to get started:
|
||||||
|
|
||||||
|
`AFL_CUSTOM_INFO_PROGRAM` - the program name of the target that is executed.
|
||||||
|
If your custom mutator is used with modes like Qemu (`-Q`), this will still
|
||||||
|
contain the target program, not afl-qemu-trace.
|
||||||
|
|
||||||
|
`AFL_CUSTOM_INFO_PROGRAM_INPUT` - if the `-f` parameter is used with afl-fuzz
|
||||||
|
then this value is found in this environment variable.
|
||||||
|
|
||||||
|
`AFL_CUSTOM_INFO_PROGRAM_ARGV` - this contains the parameters given to the
|
||||||
|
target program and still has the `@@` identifier in there.
|
||||||
|
|
||||||
|
Note: If `AFL_CUSTOM_INFO_PROGRAM_INPUT` is empty and `AFL_CUSTOM_INFO_PROGRAM_ARGV`
|
||||||
|
is either empty or does not contain `@@` then the target gets the input via
|
||||||
|
`stdin`.
|
||||||
|
|
||||||
|
`AFL_CUSTOM_INFO_OUT` - This is the output directory for this fuzzer instance,
|
||||||
|
so if `afl-fuzz` was called with `-o out -S foobar`, then this will be set to
|
||||||
|
`out/foobar`.
|
||||||
|
|
||||||
### Custom Mutator Preparation
|
### Custom Mutator Preparation
|
||||||
|
|
||||||
For C/C++ mutators, the source code must be compiled as a shared object:
|
For C/C++ mutators, the source code must be compiled as a shared object:
|
||||||
|
@ -37,6 +37,10 @@ static char *afl_environment_variables[] = {
|
|||||||
"AFL_CRASH_EXITCODE",
|
"AFL_CRASH_EXITCODE",
|
||||||
"AFL_CUSTOM_MUTATOR_LIBRARY",
|
"AFL_CUSTOM_MUTATOR_LIBRARY",
|
||||||
"AFL_CUSTOM_MUTATOR_ONLY",
|
"AFL_CUSTOM_MUTATOR_ONLY",
|
||||||
|
"AFL_CUSTOM_INFO_PROGRAM",
|
||||||
|
"AFL_CUSTOM_INFO_PROGRAM_ARGV",
|
||||||
|
"AFL_CUSTOM_INFO_PROGRAM_INPUT",
|
||||||
|
"AFL_CUSTOM_INFO_OUT",
|
||||||
"AFL_CXX",
|
"AFL_CXX",
|
||||||
"AFL_CYCLE_SCHEDULES",
|
"AFL_CYCLE_SCHEDULES",
|
||||||
"AFL_DEBUG",
|
"AFL_DEBUG",
|
||||||
|
@ -1530,29 +1530,6 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (afl->limit_time_sig > 0 && afl->custom_mutators_count) {
|
|
||||||
|
|
||||||
if (afl->custom_only) {
|
|
||||||
|
|
||||||
FATAL("Custom mutators are incompatible with MOpt (-L)");
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 custom_fuzz = 0;
|
|
||||||
LIST_FOREACH(&afl->custom_mutator_list, struct custom_mutator, {
|
|
||||||
|
|
||||||
if (el->afl_custom_fuzz) { custom_fuzz = 1; }
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
if (custom_fuzz) {
|
|
||||||
|
|
||||||
WARNF("afl_custom_fuzz is incompatible with MOpt (-L)");
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if (afl->afl_env.afl_max_det_extras) {
|
if (afl->afl_env.afl_max_det_extras) {
|
||||||
|
|
||||||
s32 max_det_extras = atoi(afl->afl_env.afl_max_det_extras);
|
s32 max_det_extras = atoi(afl->afl_env.afl_max_det_extras);
|
||||||
@ -1827,8 +1804,76 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
printf("DEBUG: rand %06d is %u\n", counter, rand_below(afl, 65536));
|
printf("DEBUG: rand %06d is %u\n", counter, rand_below(afl, 65536));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (!getenv("AFL_CUSTOM_INFO_PROGRAM")) {
|
||||||
|
|
||||||
|
setenv("AFL_CUSTOM_INFO_PROGRAM", argv[optind], 1);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!getenv("AFL_CUSTOM_INFO_PROGRAM_INPUT") && afl->fsrv.out_file) {
|
||||||
|
|
||||||
|
setenv("AFL_CUSTOM_INFO_PROGRAM_INPUT", afl->fsrv.out_file, 1);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
u8 envbuf[8096] = "", tmpbuf[8096] = "";
|
||||||
|
for (s32 i = optind + 1; i < argc; ++i) {
|
||||||
|
|
||||||
|
strcpy(tmpbuf, envbuf);
|
||||||
|
if (strchr(argv[i], ' ') && !strchr(argv[i], '"') &&
|
||||||
|
!strchr(argv[i], '\'')) {
|
||||||
|
|
||||||
|
if (!strchr(argv[i], '\'')) {
|
||||||
|
|
||||||
|
snprintf(envbuf, sizeof(tmpbuf), "%s '%s'", tmpbuf, argv[i]);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
snprintf(envbuf, sizeof(tmpbuf), "%s \"%s\"", tmpbuf, argv[i]);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
snprintf(envbuf, sizeof(tmpbuf), "%s %s", tmpbuf, argv[i]);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
setenv("AFL_CUSTOM_INFO_PROGRAM_ARGV", envbuf + 1, 1);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
setenv("AFL_CUSTOM_INFO_OUT", afl->out_dir, 1); // same as __AFL_OUT_DIR
|
||||||
|
|
||||||
setup_custom_mutators(afl);
|
setup_custom_mutators(afl);
|
||||||
|
|
||||||
|
if (afl->limit_time_sig > 0 && afl->custom_mutators_count) {
|
||||||
|
|
||||||
|
if (afl->custom_only) {
|
||||||
|
|
||||||
|
FATAL("Custom mutators are incompatible with MOpt (-L)");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 custom_fuzz = 0;
|
||||||
|
LIST_FOREACH(&afl->custom_mutator_list, struct custom_mutator, {
|
||||||
|
|
||||||
|
if (el->afl_custom_fuzz) { custom_fuzz = 1; }
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
if (custom_fuzz) {
|
||||||
|
|
||||||
|
WARNF("afl_custom_fuzz is incompatible with MOpt (-L)");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
write_setup_file(afl, argc, argv);
|
write_setup_file(afl, argc, argv);
|
||||||
|
|
||||||
setup_cmdline_file(afl, argv + optind);
|
setup_cmdline_file(afl, argv + optind);
|
||||||
|
Reference in New Issue
Block a user