Skip to content

Commit fe51286

Browse files
TinyInst Update (#968)
* tmp * more * save * TODO * fix * update to tinyinst on crates * dep * fmt * shmem done * cpp fmt * clp * fmt * why?? * ver * more makefile.toml * windows test * Update build_and_test.yml * fix * a * install * fmt * fix * only macos and win * more * The order matters * remove * fmt * chg * typo Co-authored-by: Andrea Fioraldi <[email protected]>
1 parent 3b68399 commit fe51286

File tree

13 files changed

+557
-90
lines changed

13 files changed

+557
-90
lines changed

.github/workflows/build_and_test.yml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,9 @@ jobs:
173173
run: rustup toolchain install nightly --component rustfmt --component clippy --allow-downgrade
174174
- name: Add no_std toolchain
175175
run: rustup toolchain install nightly-x86_64-unknown-linux-gnu ; rustup component add rust-src --toolchain nightly-x86_64-unknown-linux-gnu
176+
- name: Install cxxbridge
177+
if: runner.os == 'macOS'
178+
run: cargo install cxxbridge-cmd
176179
- name: Install python (macOS)
177180
# Removing macOS things already installed in CI against failed linking
178181
if: runner.os == 'macOS'
@@ -255,10 +258,14 @@ jobs:
255258
- name: install cargo-make
256259
run: cargo install --force cargo-make
257260
- uses: ilammy/msvc-dev-cmd@v1
261+
- name: install cxx bridge
262+
run: cargo install cxxbridge-cmd
258263
- name: Build fuzzers/frida_libpng
259264
run: cd fuzzers/frida_libpng/ && cargo make test
260265
- name: Build fuzzers/frida_gdiplus
261266
run: cd fuzzers/frida_gdiplus/ && cargo make test
267+
- name: Build fuzzers/tinyinst_simple
268+
run: cd fuzzers/tinyinst_simple/ && cargo make test
262269

263270
macos:
264271
runs-on: macOS-latest
@@ -271,6 +278,8 @@ jobs:
271278
run: rustup toolchain install nightly --component rustfmt --component clippy --allow-downgrade
272279
- name: Install deps
273280
run: brew install z3 gtk+3
281+
- name: Install cxxbridge
282+
run: cargo install cxxbridge-cmd
274283
- uses: actions/checkout@v3
275284
- uses: Swatinem/rust-cache@v2
276285
- name: MacOS Build

fuzzers/tinyinst_simple/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ edition = "2021"
66
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
77

88
[dependencies]
9-
libafl = { version = "0.8.1", path = "../../libafl", features = ["tui"] }
10-
libafl_tinyinst = { version = "0.8.1", path = "../../libafl_tinyinst" }
9+
libafl = { version = "0.8.2", path = "../../libafl", features = ["introspection"] }
10+
libafl_tinyinst = { version = "0.8.2", path = "../../libafl_tinyinst" }
1111
[profile.release]
1212
codegen-units = 1
1313
opt-level = 3

fuzzers/tinyinst_simple/Makefile.toml

Lines changed: 52 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,56 @@
1-
[tasks.build_test]
2-
command = "cl"
3-
args = ["./test/test.c", "-o", "./test/test.exe"]
1+
[tasks.unsupported]
2+
script_runner="@shell"
3+
script='''
4+
echo "Cargo-make not integrated yet on this"
5+
'''
46

7+
# Harness
8+
[tasks.harness]
9+
linux_alias = "unsupported"
10+
mac_alias = "unsupported"
11+
windows_alias = "harness_windows"
12+
13+
[tasks.harness_windows]
14+
script='''
15+
cl test\test.cpp -o test.exe
16+
'''
17+
18+
# Fuzzer
19+
[tasks.fuzzer]
20+
linux_alias = "unsupported"
21+
mac_alias = "unsupported"
22+
windows_alias = "fuzzer_windows"
23+
24+
[tasks.fuzzer_windows]
25+
dependencies = ["harness"]
26+
command = "cargo"
27+
args = ["build", "--release"]
28+
29+
# Run the fuzzer
530
[tasks.run]
6-
dependencies = ["build_test"]
31+
linux_alias = "unsupported"
32+
mac_alias = "unsupported"
33+
windows_alias = "run_windows"
34+
35+
[tasks.run_windows]
36+
dependencies = ["harness", "fuzzer"]
737
command = "cargo"
838
args = ["run", "--release"]
39+
40+
41+
# Run the fuzzer
42+
[tasks.test]
43+
linux_alias = "unsupported"
44+
mac_alias = "unsupported"
45+
windows_alias = "test_windows"
46+
47+
[tasks.test_windows]
48+
script_runner = "@shell"
49+
script='''
50+
copy .\target\release\tinyinst_simple.exe .
51+
start "" "tinyinst_simple.exe"
52+
#ping is for timeout
53+
ping -n 10 127.0.0.1>NUL && taskkill /im tinyinst_simple.exe /F
54+
>nul 2>nul dir /a-d "corpus_discovered\*" && (echo Files exist) || (exit /b 1337)
55+
'''
56+
dependencies = [ "harness", "fuzzer" ]

fuzzers/tinyinst_simple/README.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1-
# Run Instruction
1+
# Tinyinst example
2+
This is a fuzzer example to show how libafl_tinyinst works
3+
4+
## How to build
5+
1. Build the harness with `cl test\test.cpp -o test.exe`
6+
2. Build the fuzzer with `cargo build --release`. The fuzzer is `target\release\tinyinst_simple.exe`
7+
8+
## Run with cargo-make
9+
Or, you can simple run it using cargo-make
210
1. Open up developer powershell so that you have access to cl (Windows Default Compiler)
311
2. Run `cargo make run` to run the fuzzer

fuzzers/tinyinst_simple/src/main.rs

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
11
use std::path::PathBuf;
22

3+
#[cfg(target_vendor = "apple")]
4+
use libafl::bolts::shmem::UnixShMemProvider;
5+
#[cfg(windows)]
6+
use libafl::bolts::shmem::Win32ShMemProvider;
37
use libafl::{
48
bolts::{
59
rands::{RandomSeed, StdRand},
10+
shmem::ShMemProvider,
611
tuples::tuple_list,
712
},
813
corpus::{CachedOnDiskCorpus, Corpus, OnDiskCorpus, Testcase},
@@ -17,17 +22,30 @@ use libafl::{
1722
state::StdState,
1823
Fuzzer, StdFuzzer,
1924
};
20-
use libafl_tinyinst::executor::TinyInstExecutor;
25+
use libafl_tinyinst::executor::TinyInstExecutorBuilder;
2126
static mut COVERAGE: Vec<u64> = vec![];
2227

28+
#[cfg(not(any(target_vendor = "apple", windows)))]
29+
fn main() {}
30+
31+
#[cfg(any(target_vendor = "apple", windows))]
2332
fn main() {
2433
// Tinyinst things
2534
let tinyinst_args = vec!["-instrument_module".to_string(), "test.exe".to_string()];
2635

27-
let args = vec![".\\test\\test.exe".to_string(), "@@".to_string()];
36+
// use shmem to pass testcases
37+
let args = vec!["test.exe".to_string(), "-m".to_string(), "@@".to_string()];
38+
39+
// use file to pass testcases
40+
// let args = vec!["test.exe".to_string(), "-f".to_string(), "@@".to_string()];
2841

2942
let observer = unsafe { ListObserver::new("cov", &mut COVERAGE) };
3043
let mut feedback = ListFeedback::with_observer(&observer);
44+
#[cfg(windows)]
45+
let mut shmem_provider = Win32ShMemProvider::new().unwrap();
46+
47+
#[cfg(target_vendor = "apple")]
48+
let mut shmem_provider = UnixShMemProvider::new().unwrap();
3149

3250
let input = BytesInput::new(b"bad".to_vec());
3351
let rand = StdRand::new();
@@ -46,13 +64,15 @@ fn main() {
4664

4765
let mut mgr = SimpleEventManager::new(monitor);
4866
let mut executor = unsafe {
49-
TinyInstExecutor::new(
50-
&mut COVERAGE,
51-
tinyinst_args,
52-
args,
53-
5000,
54-
tuple_list!(observer),
55-
)
67+
TinyInstExecutorBuilder::new()
68+
.tinyinst_args(tinyinst_args)
69+
.program_args(args)
70+
.use_shmem()
71+
.persistent("test.exe".to_string(), "fuzz".to_string(), 1, 10000)
72+
.timeout(std::time::Duration::new(5, 0))
73+
.shmem_provider(&mut shmem_provider)
74+
.build(&mut COVERAGE, tuple_list!(observer))
75+
.unwrap()
5676
};
5777
let mutator = StdScheduledMutator::new(havoc_mutations());
5878
let mut stages = tuple_list!(StdMutationalStage::new(mutator));

fuzzers/tinyinst_simple/test/test.c

Lines changed: 0 additions & 36 deletions
This file was deleted.

fuzzers/tinyinst_simple/test/test.cpp

Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
/*
2+
Copyright 2020 Google LLC
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
https://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
#define _CRT_SECURE_NO_WARNINGS
18+
19+
#include <stdio.h>
20+
#include <stdlib.h>
21+
#include <fcntl.h>
22+
#include <string.h>
23+
#include <inttypes.h>
24+
25+
// shared memory stuff
26+
27+
#if defined(WIN32) || defined(_WIN32) || defined(__WIN32)
28+
#include <windows.h>
29+
#else
30+
#include <sys/mman.h>
31+
#endif
32+
33+
#define MAX_SAMPLE_SIZE 1000000
34+
#define SHM_SIZE (4 + MAX_SAMPLE_SIZE)
35+
unsigned char *shm_data;
36+
37+
bool use_shared_memory;
38+
39+
#if defined(WIN32) || defined(_WIN32) || defined(__WIN32)
40+
41+
int setup_shmem(const char *name) {
42+
HANDLE map_file;
43+
44+
map_file = OpenFileMapping(FILE_MAP_ALL_ACCESS, // read/write access
45+
FALSE, // do not inherit the name
46+
name); // name of mapping object
47+
48+
if (map_file == NULL) {
49+
printf("Error accessing shared memory\n");
50+
return 0;
51+
}
52+
53+
shm_data = (unsigned char *)MapViewOfFile(
54+
map_file, // handle to map object
55+
FILE_MAP_ALL_ACCESS, // read/write permission
56+
0, 0, SHM_SIZE);
57+
58+
if (shm_data == NULL) {
59+
printf("Error accessing shared memory\n");
60+
return 0;
61+
}
62+
63+
return 1;
64+
}
65+
66+
#else
67+
68+
int setup_shmem(const char *name) {
69+
int fd;
70+
71+
// get shared memory file descriptor (NOT a file)
72+
fd = shm_open(name, O_RDONLY, S_IRUSR | S_IWUSR);
73+
if (fd == -1) {
74+
printf("Error in shm_open\n");
75+
return 0;
76+
}
77+
78+
// map shared memory to process address space
79+
shm_data =
80+
(unsigned char *)mmap(NULL, SHM_SIZE, PROT_READ, MAP_SHARED, fd, 0);
81+
if (shm_data == MAP_FAILED) {
82+
printf("Error in mmap\n");
83+
return 0;
84+
}
85+
86+
return 1;
87+
}
88+
89+
#endif
90+
91+
// used to force a crash
92+
char *crash = NULL;
93+
94+
// ensure we can find the target
95+
96+
#if defined(WIN32) || defined(_WIN32) || defined(__WIN32)
97+
#define FUZZ_TARGET_MODIFIERS __declspec(dllexport)
98+
#else
99+
#define FUZZ_TARGET_MODIFIERS __attribute__((noinline))
100+
#endif
101+
102+
// actual target function
103+
104+
void FUZZ_TARGET_MODIFIERS fuzz(char *name) {
105+
char *sample_bytes = NULL;
106+
uint32_t sample_size = 0;
107+
108+
// read the sample either from file or
109+
// shared memory
110+
if (use_shared_memory) {
111+
sample_size = *(uint32_t *)(shm_data);
112+
if (sample_size > MAX_SAMPLE_SIZE) sample_size = MAX_SAMPLE_SIZE;
113+
sample_bytes = (char *)malloc(sample_size);
114+
memcpy(sample_bytes, shm_data + sizeof(uint32_t), sample_size);
115+
} else {
116+
FILE *fp = fopen(name, "rb");
117+
if (!fp) {
118+
printf("Error opening %s a\n", name);
119+
return;
120+
}
121+
fseek(fp, 0, SEEK_END);
122+
sample_size = ftell(fp);
123+
fseek(fp, 0, SEEK_SET);
124+
sample_bytes = (char *)malloc(sample_size);
125+
fread(sample_bytes, 1, sample_size, fp);
126+
fclose(fp);
127+
}
128+
// printf("sample_bytes: %s", sample_bytes);
129+
if (sample_size >= 4) {
130+
// check if the sample spells "test"
131+
if (*(uint32_t *)(sample_bytes) == 0x74736574) {
132+
// if so, crash
133+
crash[0] = 1;
134+
}
135+
}
136+
137+
if (sample_bytes) free(sample_bytes);
138+
}
139+
140+
int main(int argc, char **argv) {
141+
if (argc != 3) {
142+
printf("Usage: %s <-f|-m> <file or shared memory name>\n", argv[0]);
143+
return 0;
144+
}
145+
if (!strcmp(argv[1], "-m")) {
146+
use_shared_memory = true;
147+
} else if (!strcmp(argv[1], "-f")) {
148+
use_shared_memory = false;
149+
} else {
150+
printf("Usage: %s <-f|-m> <file or shared memory name>\n", argv[0]);
151+
return 0;
152+
}
153+
154+
// map shared memory here as we don't want to do it
155+
// for every operation
156+
if (use_shared_memory) {
157+
if (!setup_shmem(argv[2])) { printf("Error mapping shared memory\n"); }
158+
}
159+
160+
fuzz(argv[2]);
161+
162+
return 0;
163+
}

0 commit comments

Comments
 (0)