Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactored mutation functions to offer a generic toolkit for mutating data #37

Open
wants to merge 6 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ ahash = "0.8"
rustc-hash = "1.1.0"
indexmap = "2.1"
smallvec = { version = "1", features = ["union", "const_generics"] }
regex = "1"
num-traits = "0.2"

# For addr2line implementation
addr2line = "0.21"
Expand Down
2 changes: 2 additions & 0 deletions docker/utils/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,8 @@ echo "" >> $RC_LOCAL

echo "echo [+] waiting for processes to finish" >> $RC_LOCAL
echo "wait" >> $RC_LOCAL
echo "sleep 5" >> $RC_LOCAL
echo "wait" >> $RC_LOCAL

# Add a newline
echo "" >> $RC_LOCAL
Expand Down
1 change: 1 addition & 0 deletions examples/08_textinput_mujs/.dockerignore
23 changes: 23 additions & 0 deletions examples/08_textinput_mujs/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# snapshot-specific
snapshot/
snapshot_image
src/constants.rs
dict/

# rust build artifacts
debug/
target/
Cargo.lock
**/*.rs.bk
*.pdb

# built harness binaries
harness/mujs_harness
harness/mujs-*

# other misc data
perf.data*
flamegraph.svg
strace.log
fuzz*.log
*.log
2 changes: 2 additions & 0 deletions examples/08_textinput_mujs/.solutions/magic_crash.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
var r = magic(-10000000);
console.log(r);
1 change: 1 addition & 0 deletions examples/08_textinput_mujs/.solutions/party_crash.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
party(1, 1, 1, 40);
25 changes: 25 additions & 0 deletions examples/08_textinput_mujs/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
[package]
name = "mujs_fuzzer"
version = "0.1.0"
edition = "2021"
exclude = ["qemu_snapshot", "snapshot"]

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
snapchange = { path = "../../" }
log = "0.4"

[build-dependencies]
regex = "1"

[features]
default = []
redqueen = ["snapchange/redqueen"]

[profile.release]
panic = "abort"
lto = true
codegen-units = 1
opt-level = 3
debug = true
25 changes: 25 additions & 0 deletions examples/08_textinput_mujs/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# build environment -- feel free to adapt to your needs.

FROM alpine:edge as base

RUN apk --no-cache upgrade \
&& apk add --no-cache --initramfs-diskless-boot \
python3 gdb musl-dbg \
curl tar \
build-base perf \
clang lld compiler-rt

COPY ./harness/ /opt/
RUN ls -alR /opt/
RUN make -C /opt/

#### switch to snapchang container ####
FROM ghcr.io/awslabs/snapchange

# copy whole root filesystem from build environment to this container layer
# SNAPSHOT_INPUT is the location that the snapshotting script will create.
COPY --from=base / "$SNAPSHOT_INPUT"

# set the path to the target within the root filesystem of the build environment
ENV SNAPSHOT_ENTRYPOINT="/opt/mujs_harness"
ENV SNAPSHOT_GDB_MODE="detach"
64 changes: 64 additions & 0 deletions examples/08_textinput_mujs/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
DOCKER ?= docker
FUZZ_CORES ?= /2

DOCKER_IMAGE_NAME ?= snapchange_example8

all: base_images test

base_images:
# Build the base snapchange image used for snapshotting
$(MAKE) -C ../../docker

snapshot_image: Dockerfile harness/main.c harness/Makefile
ifeq ($(VERBOSE),1)
$(DOCKER) build -t $(DOCKER_IMAGE_NAME):snapshot . -f $<
endif
$(DOCKER) build -q -t $(DOCKER_IMAGE_NAME):snapshot . -f $< > $@

snapshot: snapshot_image
ifeq ($(VERBOSE),1)
$(DOCKER) run --rm -i \
-v $(shell realpath -m ./snapshot):/snapshot \
-e SNAPSHOT_IMGTYPE=initramfs \
$(shell cat $<)
else
$(DOCKER) run --rm -i \
-v $(shell realpath -m ./snapshot):/snapshot \
-e SNAPSHOT_IMGTYPE=initramfs \
$(shell cat $<) \
>/dev/null 2>&1
endif
cd snapshot; if ! test -L input; then rm -rf input || true; ln -s ../input; fi
cd snapshot; if ! test -L dict; then rm -rf dict || true; ln -s ../dict/; fi

dict: dict.txt
-mkdir -p dict
python make_dict.py $<
echo "magic" > dict/magic
echo "party" > dict/party

fuzzer: dict
cargo build -r

fuzz: snapshot
cargo run -r -- -p ./snapshot fuzz -c $(FUZZ_CORES)

fuzz-%: snapshot
cargo run -r -- -p ./snapshot fuzz -c $(FUZZ_CORES) --stop-after-time $(shell echo $@ | sed 's/fuzz-//g')m
# .PHONY: fuzz-1 fuzz-2 fuzz-3 fuzz-4 fuzz-5

test: snapshot fuzzer reset
./test.sh

reset: snapshot
cd snapshot && ./reset.sh

clean: clean-docker
-$(RM) -rf snapshot target

clean-docker:
-$(DOCKER) rmi `cat ./snapshot_image`
-$(DOCKER) rmi $(DOCKER_IMAGE_NAME):snapshot
-$(RM) snapshot_image

.PHONY: fuzzer all base_images test reset fuzz
5 changes: 5 additions & 0 deletions examples/08_textinput_mujs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Tutorial 8 - Using the text input type

This fuzzer uses the `TextInput` type to introduce more useful mutations for
common text-based formats such as programming or markup languages.

30 changes: 30 additions & 0 deletions examples/08_textinput_mujs/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
use regex::Regex;
use std::fs;
use std::fs::File;
use std::io::Write;

fn main() {
println!("cargo:rerun-if-changed=snapshot/fuzzvm.qemuregs");
println!("cargo:rerun-if-changed=snapshot/vm.log");

let qemuregs = fs::read_to_string("./snapshot/fuzzvm.qemuregs").unwrap();
let mut w = File::create("src/constants.rs").unwrap();

writeln!(w, "#![allow(unused)]").unwrap();

let re = Regex::new(r"CR3=([0-9A-Fa-f]+)").unwrap();
let captures = re.captures(&qemuregs).unwrap();
let cr3 = &captures.get(1).unwrap().as_str();
writeln!(w, "pub const CR3: u64 = 0x{};", cr3).unwrap();

let re = Regex::new(r"RIP=([0-9A-Fa-f]+)").unwrap();
let captures = re.captures(&qemuregs).unwrap();
let rip = &captures.get(1).unwrap().as_str();
writeln!(w, "pub const RIP: u64 = 0x{};", rip).unwrap();

let vmlog = fs::read_to_string("./snapshot/vm.log").unwrap();
let re = Regex::new(r"SNAPSHOT buffer: (0x[0-9A-Fa-f]+)").unwrap();
let captures = re.captures(&vmlog).unwrap();
let input_addr = &captures.get(1).unwrap().as_str();
writeln!(w, "pub const INPUT: u64 = {};", input_addr).unwrap();
}
177 changes: 177 additions & 0 deletions examples/08_textinput_mujs/dict.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
abstract
arguments
await
boolean
break
byte
case
catch
char
class
const
continue
debugger
default
delete
do
double
else
enum
eval
export
extends
false
final
finally
float
for
function
goto
if
implements
import
in
instanceof
int
interface
let
long
native
new
null
package
private
protected
public
return
short
static
super
switch
synchronized
this
throw
throws
transient
true
try
typeof
var
void
volatile
while
with
yield

Array
Date
eval
function
hasOwnProperty
Infinity
isFinite
isNaN
isPrototypeOf
length
Math
NaN
name
Number
Object
prototype
String
toString
undefined
valueOf


Math.round
Math.pow
Math.sqrt
Math.abs
math.ceil
Math.floor
Math.sin
Math.cos
Math.max
Math.min

Array.forEach
Array.map
Array.filter
Array.reduce
Array.reduceRight
Array.every
Array.some
Array.indexOf
Array.lastIndexOf
Array.find
Array.findIndex

+
-
*
**
/
%
++
--
==
===
<
>
>=
<=
=
+=
-=
*=
/=
%=
**=
<<=
>>=
&
&=
;

()
(0)
(1)
("a")
(0, 0)
(1, 1)
("a", "a")
(0, 0, 0)
(1, 1, 1)
("a", "a", "a")
(0, 0, 0, 0)
(1, 1, 1, 1)
("a", "a", "a", "a")
(0, 0, 0, 0, 0)
(1, 1, 1, 1, 1)
("a", "a", "a", "a", "a")


[0]
[1]
[-1]

[0, 0]
[0, 0, 0]
[0, 0, 0, 0]
[0, 0, 0, 0, 0]

{"name": "john", "surname": "doe", "age": 30}
{}

function(){}

var a = function(){};

0.0
1e10
-1
-254
-255

5 changes: 5 additions & 0 deletions examples/08_textinput_mujs/harness/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
mujs-1.3.4.tar.gz
mujs-1.3.4
mujs_harness
.cache
compile_commands.json
Loading