Skip to content

Commit

Permalink
steps 1 and 2 complete
Browse files Browse the repository at this point in the history
  • Loading branch information
epi052 committed Nov 11, 2021
1 parent 9eba49f commit 46b1a11
Show file tree
Hide file tree
Showing 7 changed files with 112 additions and 113 deletions.
1 change: 1 addition & 0 deletions exercise-1/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ build = "build.rs"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
libafl = "0.6.1"
clap = "3.0.0-beta.5"
2 changes: 1 addition & 1 deletion exercise-1/Makefile.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ rm -rf .cur_input* timeouts
cwd = "xpdf"
script = """
make --silent clean
rm -rf install
rm -rf built-with-*
"""

[tasks.cargo-clean]
Expand Down
58 changes: 31 additions & 27 deletions exercise-1/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,49 +3,53 @@ use std::process::Command;

fn main() {
println!("cargo:rerun-if-changed=build.rs");
println!("cargo:rerun-if-changed=src/main.rs");

let cwd = env::current_dir().unwrap().to_string_lossy().to_string();
let xpdf_dir = format!("{}/xpdf", cwd);

// make clean; remove any leftover gunk from prior builds
Command::new("make")
.arg("clean")
.current_dir(xpdf_dir.clone())
.current_dir(&xpdf_dir)
.status()
.expect("Couldn't clean xpdf directory");

// clean doesn't know about the install directory we use to build, remove it as well
// clean doesn't know about the built-with-* directories we use to build, remove them as well
Command::new("rm")
.arg("-r")
.arg("-v")
.arg("-f")
.arg(&format!("{}/install", xpdf_dir))
.current_dir(xpdf_dir.clone())
.arg(&format!("{}/built-with-lto", xpdf_dir))
.arg(&format!("{}/built-with-fast", xpdf_dir))
.current_dir(&xpdf_dir)
.status()
.expect("Couldn't clean xpdf's install directory");
.expect("Couldn't clean xpdf's built-with-* directories");

// export LLVM_CONFIG=llvm-config-11
env::set_var("LLVM_CONFIG", "llvm-config-11");

// configure with afl-clang-fast and set install directory to ./xpdf/install
Command::new("./configure")
.arg(&format!("--prefix={}/install", xpdf_dir))
.env("CC", "/usr/local/bin/afl-clang-fast")
.env("CXX", "/usr/local/bin/afl-clang-fast++")
.current_dir(xpdf_dir.clone())
.status()
.expect("Couldn't configure xpdf to build using afl-clang-fast");

// make && make install
Command::new("make")
.current_dir(xpdf_dir.clone())
.status()
.expect("Couldn't make xpdf");

Command::new("make")
.arg("install")
.current_dir(xpdf_dir)
.status()
.expect("Couldn't install xpdf");
for (build_dir, compiler) in [("fast", "afl-clang-fast"), ("lto", "afl-clang-lto")] {
// configure with `compiler` and set install directory to ./xpdf/built-with-`build_dir`
Command::new("./configure")
.arg(&format!("--prefix={}/built-with-{}", xpdf_dir, build_dir))
.env("CC", format!("/usr/local/bin/{}", compiler))
.env("CXX", format!("/usr/local/bin/{}++", compiler))
.current_dir(&xpdf_dir)
.status()
.expect(&format!(
"Couldn't configure xpdf to build using afl-clang-{}",
compiler
));

// make && make install
Command::new("make")
.current_dir(&xpdf_dir)
.status()
.expect("Couldn't make xpdf");

Command::new("make")
.arg("install")
.current_dir(&xpdf_dir)
.status()
.expect("Couldn't install xpdf");
}
}
36 changes: 29 additions & 7 deletions exercise-1/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,32 @@ use libafl::{feedback_and_fast, feedback_or, Fuzzer, StdFuzzer};
use std::path::PathBuf;
use std::time::Duration;

use clap::{App, Arg};

/// Size of coverage map shared between observer and executor
const MAP_SIZE: usize = 65536;

/// parse -c/--compiler from cli; return "fast" or "lto"
fn get_compiler_from_cli() -> String {
let matches = App::new("fuzzer")
.arg(
Arg::new("compiler")
.possible_values(&["fast", "lto"])
.short('c')
.long("compiler")
.value_name("COMPILER")
.about("choose your afl-clang variant (default: fast)")
.takes_value(true)
.default_value("fast"),
)
.get_matches();

String::from(matches.value_of("compiler").unwrap())
}

fn main() {
let compiler = get_compiler_from_cli();

//
// Component: Corpus
//
Expand Down Expand Up @@ -171,18 +193,18 @@ fn main() {
// ForkserverExecutor and sets a timeout before each run. This gives us an executor
// that implements an AFL-like mechanism that will spawn child processes to fuzz
let fork_server = ForkserverExecutor::new(
"./xpdf/install/bin/pdftotext".to_string(),
&[String::from("@@")],
// we're passing testcases via on-disk file; set to use_shmem_testcase to false
false,
format!("./xpdf/built-with-{}/bin/pdftotext", compiler),
&[],
// we're passing testcases via shmem; set to use_shmem_testcase to true
true,
tuple_list!(edges_observer, time_observer),
).unwrap();
)
.unwrap();

let timeout = Duration::from_millis(5000);

// ./pdftotext @@
let mut executor = TimeoutForkserverExecutor::new(fork_server, timeout)
.unwrap();
let mut executor = TimeoutForkserverExecutor::new(fork_server, timeout).unwrap();

// In case the corpus is empty (i.e. on first run), load existing test cases from on-disk
// corpus
Expand Down
44 changes: 44 additions & 0 deletions exercise-1/time-comparison.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#!/bin/bash

function exec-fuzzer() {
# parameters:
# fuzzer: should be either "lto" or "fast"
# timeout: in seconds
# cpu: which core to bind, default is 7
fuzzer="${1}"
timeout="${2}"
declare -i cpu="${3}" || 7

# last_update should look like this
# [Stats #0] clients: 1, corpus: 425, objectives: 0, executions: 23597, exec/sec: 1511
last_update=$(timeout "${timeout}" taskset -c "${cpu}" ../target/release/exercise-one-solution -c "${fuzzer}" | grep Stats | tail -1)

# regex + cut below will return the total # of executions
total_execs=$(echo $last_update | egrep -o "executions: ([0-9]+)" | cut -f2 -d' ')

execs_per_sec=$((total_execs/"${timeout}"))

echo $execs_per_sec
}

function average_of_five_runs() {
# parameters:
# fuzzer: should be either "lto" or "fast"
fuzzer="${1}"
declare -i total_execs_per_sec=0
declare -i total_runs=5
timeout=120

for i in $(seq 1 "${total_runs}");
do
current=$(exec-fuzzer "${fuzzer}" "${timeout}" $((i+1)))
total_execs_per_sec=$((total_execs_per_sec+current))
echo "[${fuzzer}][${i}] - ${current} execs/sec"
done

final=$((total_execs_per_sec/total_runs))
echo "[${fuzzer}][avg] - ${final} execs/sec"
}

#average_of_five_runs fast
average_of_five_runs lto
35 changes: 6 additions & 29 deletions exercise-1/xpdf/xpdf/PDFDoc.cc
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
#include <unistd.h>
#ifdef WIN32
# include <windows.h>
#endif
Expand Down Expand Up @@ -43,6 +44,8 @@
#define headerSearchSize 1024 // read this many bytes at beginning of
// file to look for '%PDF'

__AFL_FUZZ_INIT();

//------------------------------------------------------------------------
// PDFDoc
//------------------------------------------------------------------------
Expand All @@ -65,39 +68,13 @@ PDFDoc::PDFDoc(GString *fileNameA, GString *ownerPassword,
outline = NULL;
#endif

fileName = fileNameA;
fileName1 = fileName;


// try to open file
fileName2 = NULL;
#ifdef VMS
if (!(file = fopen(fileName1->getCString(), "rb", "ctx=stm"))) {
error(-1, "Couldn't open file '%s'", fileName1->getCString());
errCode = errOpenFile;
return;
}
#else
if (!(file = fopen(fileName1->getCString(), "rb"))) {
fileName2 = fileName->copy();
fileName2->lowerCase();
if (!(file = fopen(fileName2->getCString(), "rb"))) {
fileName2->upperCase();
if (!(file = fopen(fileName2->getCString(), "rb"))) {
error(-1, "Couldn't open file '%s'", fileName->getCString());
delete fileName2;
errCode = errOpenFile;
return;
}
}
delete fileName2;
}
#endif
unsigned char *buf = __AFL_FUZZ_TESTCASE_BUF;
int len = __AFL_FUZZ_TESTCASE_LEN;

// create stream
obj.initNull();
str = new FileStream(file, 0, gFalse, 0, &obj);

str = new MemStream((char *) buf, 0, (Guint) len, &obj);
ok = setup(ownerPassword, userPassword);
}

Expand Down
49 changes: 0 additions & 49 deletions exercise-1/xpdf/xpdf/pdftotext.cc
Original file line number Diff line number Diff line change
Expand Up @@ -101,42 +101,6 @@ int main(int argc, char *argv[]) {

exitCode = 99;

// parse args
ok = parseArgs(argDesc, &argc, argv);
if (!ok || argc < 2 || argc > 3 || printVersion || printHelp) {
fprintf(stderr, "pdftotext version %s\n", xpdfVersion);
fprintf(stderr, "%s\n", xpdfCopyright);
if (!printVersion) {
printUsage("pdftotext", "<PDF-file> [<text-file>]", argDesc);
}
goto err0;
}
fileName = new GString(argv[1]);

// read config file
globalParams = new GlobalParams(cfgFileName);
if (textEncName[0]) {
globalParams->setTextEncoding(textEncName);
}
if (textEOL[0]) {
if (!globalParams->setTextEOL(textEOL)) {
fprintf(stderr, "Bad '-eol' value on command line\n");
}
}
if (noPageBreaks) {
globalParams->setTextPageBreaks(gFalse);
}
if (quiet) {
globalParams->setErrQuiet(quiet);
}

// get mapping to output encoding
if (!(uMap = globalParams->getTextEncoding())) {
error(-1, "Couldn't get text encoding");
delete fileName;
goto err1;
}

// open PDF file
if (ownerPassword[0] != '\001') {
ownerPW = new GString(ownerPassword);
Expand Down Expand Up @@ -230,19 +194,6 @@ int main(int argc, char *argv[]) {
}
}

// write text file
textOut = new TextOutputDev(textFileName->getCString(),
physLayout, rawOrder, htmlMeta);
if (textOut->isOk()) {
doc->displayPages(textOut, firstPage, lastPage, 72, 72, 0,
gFalse, gTrue, gFalse);
} else {
delete textOut;
exitCode = 2;
goto err3;
}
delete textOut;

// write end of HTML file
if (htmlMeta) {
if (!textFileName->cmp("-")) {
Expand Down

0 comments on commit 46b1a11

Please sign in to comment.