libfuzzer clone compiler wrapper

This commit is contained in:
Andrea Fioraldi 2020-11-20 14:07:25 +01:00
parent c617f3a397
commit d4e3668c48
7 changed files with 174 additions and 7 deletions

4
.gitignore vendored
View File

@ -1,4 +1,8 @@
target target
Cargo.lock Cargo.lock
*.o
*.a
*.so
.vscode .vscode

View File

@ -7,4 +7,7 @@ edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
afl = { path = "../../../" } afl = { path = "../../" }
[lib]
crate-type = ["staticlib", "cdylib"]

84
fuzzers/libfuzzer/compiler Executable file
View File

@ -0,0 +1,84 @@
#!/usr/bin/env python3
import subprocess
import sys
import os
script_dir = os.path.dirname(os.path.realpath(os.path.abspath(__file__)))
is_cxx = "++" in sys.argv[0]
def cc_exec(args):
if os.getenv("AFL_CC"):
cc_name = os.environ["AFL_CC"]
else:
cc_name = "clang"
if is_cxx:
if os.getenv("AFL_CXX"):
cc_name = os.environ["AFL_CXX"]
else:
cc_name = "clang++"
argv = [cc_name] + args
#print(" ".join(argv))
return subprocess.run(argv)
def common_opts():
return [
"-g",
]
def cc_mode():
args = common_opts()
args += sys.argv[1:]
if os.getenv("AFL_USE_ASAN"):
args += ["-fsanitize=address"]
if os.getenv("AFL_USE_MSAN"):
args += ["-fsanitize=memory"]
if os.getenv("AFL_USE_UBSAN"):
args += [
"-fsanitize=undefined",
"-fsanitize-undefined-trap-on-error",
"-fno-sanitize-recover=all",
]
return cc_exec(args)
def ld_mode():
args = common_opts()
args += sys.argv[1:]
args += [
os.path.join(script_dir, "runtime", "rt.o"),
os.path.join(script_dir, "target", "release", "liblibfuzzer.a"),
]
if os.getenv("AFL_USE_ASAN"):
args += ["-fsanitize=address"]
if os.getenv("AFL_USE_MSAN"):
args += ["-fsanitize=memory"]
if os.getenv("AFL_USE_UBSAN"):
args += [
"-fsanitize=undefined",
"-fsanitize-undefined-trap-on-error",
"-fno-sanitize-recover=all",
]
args += ["-pthread", "-ldl"] # for Rust
return cc_exec(args)
def is_ld_mode():
return not ("--version" in sys.argv or "--target-help" in sys.argv or
"-c" in sys.argv or "-E" in sys.argv or "-S" in sys.argv or
"-shared" in sys.argv)
#print("\x1b[0;36m" + os.path.basename(sys.argv[0]) + " 1.0a\x1b[0m by <andreafioraldi@gmail.com>")
if len(sys.argv) <= 1:
cc_exec(sys.argv[1:])
elif is_ld_mode():
ld_mode()
else:
cc_mode()

View File

@ -0,0 +1,10 @@
CC ?= clang
all: rt.o
rt.o: rt.c
$(CC) -c rt.c
clean:
rm -f rt.o

View File

@ -0,0 +1,15 @@
__attribute__((weak)) int LLVMFuzzerInitialize(int *argc, char ***argv);
void afl_libfuzzer_main();
int main(int argc, char** argv) {
if (LLVMFuzzerInitialize)
LLVMFuzzerInitialize(&argc, &argv);
afl_libfuzzer_main();
return 0;
}

View File

@ -5,17 +5,24 @@ use afl::engines::{DefaultEngine, DefaultState, Engine};
use afl::executors::inmemory::InMemoryExecutor; use afl::executors::inmemory::InMemoryExecutor;
use afl::executors::{Executor, ExitKind}; use afl::executors::{Executor, ExitKind};
use afl::inputs::bytes::BytesInput; use afl::inputs::bytes::BytesInput;
use afl::mutators::scheduled::{ use afl::mutators::scheduled::{mutation_bitflip, ComposedByMutations, DefaultScheduledMutator};
mutation_bitflip, ComposedByMutations, DefaultScheduledMutator,
};
use afl::stages::mutational::DefaultMutationalStage; use afl::stages::mutational::DefaultMutationalStage;
use afl::utils::DefaultRand; use afl::utils::DefaultRand;
fn harness<I>(_executor: &dyn Executor<I>, _buf: &[u8]) -> ExitKind { extern "C" {
/// int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size)
fn LLVMFuzzerTestOneInput(data: *const u8, size: usize) -> i32;
}
fn harness<I>(_executor: &dyn Executor<I>, buf: &[u8]) -> ExitKind {
unsafe {
LLVMFuzzerTestOneInput(buf.as_ptr(), buf.len());
}
ExitKind::Ok ExitKind::Ok
} }
pub fn main() { #[no_mangle]
pub extern "C" fn afl_libfuzzer_main() {
let rand = DefaultRand::new(0).into(); let rand = DefaultRand::new(0).into();
let mut corpus = InMemoryCorpus::<BytesInput, _>::new(&rand); let mut corpus = InMemoryCorpus::<BytesInput, _>::new(&rand);
@ -40,4 +47,3 @@ pub fn main() {
} }
println!("OK"); println!("OK");
} }

45
fuzzers/libfuzzer/test/test.c Executable file
View File

@ -0,0 +1,45 @@
#include <stdio.h>
#include <stdint.h>
// gcc -shared -o libdemo.so demo-so.c -w
int target_func(char *buf, int size) {
printf("buffer:%p, size:%p\n", buf, size);
switch (buf[0]) {
case 1:
puts("222");
if (buf[1] == '\x44') {
puts("null ptr deference");
*(char *)(0) = 1;
}
break;
case 0xff:
if (buf[2] == '\xff') {
if (buf[1] == '\x44') {
puts("crash....");
*(char *)(0xdeadbeef) = 1;
}
}
break;
default:
puts("default action");
break;
}
return 1;
}
int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
return target_func(Data, Size);
}