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

libafl_wizard #1344

Draft
wants to merge 24 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
cdfd37e
Initial commit for GSOC's 2023 Fuzzer Template Generator project
matheusbaptistella Jul 5, 2023
a1104de
Minor changes
matheusbaptistella Jul 5, 2023
307fe4c
Changed questions file from CSV to TOML
matheusbaptistella Jul 6, 2023
b7eabdd
Merge branch 'main' of github.com:matheusbaptistella/LibAFL into liba…
matheusbaptistella Jul 6, 2023
c1e1d5e
Merge branch 'main' of github.com:matheusbaptistella/LibAFL into liba…
matheusbaptistella Jul 17, 2023
2e8974e
Added variable number of answers/next questions
matheusbaptistella Jul 17, 2023
f146edb
Added an image overview of the questions diagram
matheusbaptistella Jul 17, 2023
0b4b4de
Merge branch 'main' of github.com:matheusbaptistella/LibAFL into liba…
matheusbaptistella Jul 24, 2023
babb7cb
Added custom errors to validate the questions.
matheusbaptistella Jul 24, 2023
9cc7077
Changed some aspects of the approach to deliver an initial working ge…
matheusbaptistella Aug 2, 2023
21ad866
Changed some questions and added file functionality
matheusbaptistella Aug 9, 2023
e6d9947
Corrected a question that was wrong
matheusbaptistella Aug 9, 2023
b1f21ab
Renamed the project to libafl_wizar. Removed unwanted features. Curre…
matheusbaptistella Aug 15, 2023
2d62c14
Updated the questions.
matheusbaptistella Aug 15, 2023
5c4669f
Added the UI and changed some logic
matheusbaptistella Aug 27, 2023
4effc52
Added flowchart image feature and the ui.
matheusbaptistella Nov 9, 2023
992da1f
Removed the UI and replaced it by a CLI interface.
matheusbaptistella Nov 14, 2023
0ee6bb5
Developed an initial set of question and the functions to write code …
matheusbaptistella Nov 22, 2023
93ae225
Corrected the methods to arrange code and write it to the file
matheusbaptistella Nov 27, 2023
b570b74
(WIP) Added functions to arrange module imports
matheusbaptistella Dec 19, 2023
b71d705
(WIP) Restructured the functions related to imports.
matheusbaptistella Dec 21, 2023
b4e68d1
Implemented functions to arrange imports.
matheusbaptistella Dec 26, 2023
ea612f0
Added documentation and begin refactoring the imports function
matheusbaptistella Jan 3, 2024
a5fb809
Finished the wizard.
matheusbaptistella Jan 7, 2024
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
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ members = [
"libafl_cc",
"libafl_targets",
"libafl_frida",
"libafl_ftg",
"libafl_qemu",
"libafl_tinyinst",
"libafl_sugar",
Expand Down
17 changes: 17 additions & 0 deletions libafl_ftg/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
[package]
name = "libafl_ftg"
version = "0.1.0"
edition = "2021"
authors = ["matheus <[email protected]>"]
description = "libafl's fuzzer template generator"
documentation = "TODO"
repository = "https://github.com/AFLplusplus/LibAFL/"
readme = "../README.md"
license = "MIT OR Apache-2.0"
keywords = ["fuzzing", "testing", "security"]
categories = ["TODO"]

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

[dependencies]
csv = "1.2.2"
1 change: 1 addition & 0 deletions libafl_ftg/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
TODO
29 changes: 29 additions & 0 deletions libafl_ftg/questions.csv
domenukk marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
name;content;answer1;answer2;next1;next2;previous
Introduction;Description;Yes;Sure;1;1;0
Do you have the target's source code?;Description;Yes;No;2;3;0
Can you provide a harness function?;Description;Yes;No;3;3;0
Do you want to use a map to track coverage?;Description;Yes;No;4;7;0
Do you need multiple maps?;Description;Yes;No;5;5;0
Do you know the size of the map at compile time?;Description;Yes;No;6;6;0
Do you want to improve input selection by adding a hit counts map?;Description;Yes;No;7;7;0
Do you want to consider the logged values of CMP instructions?;Description;Yes;No;8;8;0
Do you want to consider the backtrace after the harness crashes?;Description;Yes;No;9;9;0
Do you want to keep track of the testcases' runtime?;Description;Yes;No;10;11;0
Do you want to consider a timeout as a solution?;Description;Yes;No;11;11;0
Do you want to consider a crash as a solution?;Description;Yes;No;12;12;0
Do you want to manage the testcases in memory or on disk?;Description;In memory; On disk;13;14;0
Do you want to manage only in memory or in memory and on disk?;Description;In memory;Both;16;16;0
Do you want to manage only on disk or on disk and in memory?;Description;On disk;Both;15;16;0
Do you want to load testcases from disk to memory using a cache?;Description;Yes;No;16;16;0
Do you want to see stats about the fuzzing campaign?;Description;Yes;No;17;20;0
Do you want to see the stats in a UI style?;Description;Yes;No;18;18;0
Do you want to store the stats to a file?;Description;Yes;No;19;20;0
Do you want to store them to a TOML or JSON file?;Description;TOML;JSON;20;20;0
Do you want to restart your fuzzer every time a solution is achieved?;Description;Yes;No;21;21;0
Do you want to load testcases from the corpus using a queue policy?;Description;Yes;No;22;22;0
Do you want to prioritize smaller and faster testcases?;Description;Yes;No;23;23;0
Can your target corrupt memory used by the fuzzer?;Description;Yes;No;24;24;0
Do you want to set a timeout before each run?;Description;Yes;No;25;25;0
Do you want to generate an initial set of inputs?;Description;Yes;No;26;26;0
Do you want to schedule mutations?;Description;Yes;No;27;27;0
Do you want to use the StdMutationalStage?;Description;Yes;No;28;28;0
94 changes: 94 additions & 0 deletions libafl_ftg/src/lib.rs
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps consider using an existing TUI crate instead of managing the UI yourself?

Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
use std::error::Error;

// Used to copy the fields of a question.
type QuestionTup = (String, String, String, String, usize, usize, usize);

// This reresents a "node": the answer of a Question might lead to different Questions (different nodes).
#[derive(Clone)]
pub struct Question {
name: String, // The question that will be asked.
content: String, // Description related to the question, to help the user.
answer1: String, // One of the possible answers that may result, either in another question, or a component.
answer2: String, // Same.
next1: usize, // The next question (or the choice of an specific component), if answer1 is chosen.
next2: usize, // The next question (or the choice of an specific component), if answer2 is chosen.
previous: usize, // The question that lead to the current one (possible UNDO functionality implementation).
}

impl Question {
// Builds the diagram of questions from the csv file (this will probably be changed, the csv is used only for demonstrative purposes).
// The diagram is a vector of Questions (vector of nodes): each Question, depending on the answer, will have the index of the next Question
// that should be asked.
pub fn new() -> Result<Vec<Question>, Box<dyn Error>> {
let mut reader = csv::ReaderBuilder::new()
.delimiter(b';')
.from_path("questions.csv")?;

let mut questions_diagram: Vec<Question> = Vec::new();

for result in reader.deserialize() {
let question: QuestionTup = result?;

questions_diagram.push(Question {
name: question.0,
content: question.1,
answer1: question.2,
answer2: question.3,
next1: question.4,
next2: question.5,
previous: question.6,
});
}

Ok(questions_diagram)
}

pub fn print_question(&self) -> () {
print!("{esc}c", esc = 27 as char);
println!("=========================\nFuzzer Template Generator\n=========================");
println!("{}\n", self.name);
println!("{}\n", self.content);
println!("\t{}\t{}\tUndo", self.answer1, self.answer2);
}

// Checks if the answer given by the user is one of the possibilities that the generator expects.
pub fn validate_answer(&self, input: &mut String) -> bool {
if input.ends_with("\r\n") {
input.truncate(input.len() - 2);
} else if input.ends_with("\n") {
input.truncate(input.len() - 1);
}

// For now we dont check for variants (with the implementation of an interface this wont be necessary).
// The "Undo" option makes the generator go back to the previous question, so if the user do something
// by mistake, they can correct it.
if (input == &self.answer1) || (input == &self.answer2) || (input == "Undo") {
return true;
}

false
}

pub fn next_question(
&self,
q_diagram: &mut Vec<Question>,
input: &String,
q_index: usize,
) -> usize {
// If it's equal to answer1, we go to next1, which is the next question if answer1 is chosen.
if input == &self.answer1 {
// We save the index of the current question in the 'previous' field of the next one.
q_diagram[self.next1].previous = q_index;

self.next1
} else if input == &self.answer2 {
q_diagram[self.next2].previous = q_index;

self.next2
}
// Undo option.
else {
self.previous
}
}
}
52 changes: 52 additions & 0 deletions libafl_ftg/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
use std::{error::Error, io, process};

use libafl_ftg::Question;

fn run() -> Result<(), Box<dyn Error>> {
// Mutable because we have to update the index of the 'previous' field.
let mut q_diagram = Question::new()?;

// Basically, a q_diagram[q_index] is asked, answered by the user and then the generator moves on to the next q_diagram[q_index], until the last one is asked.
// Note that not all the questions are going to be asked. So if the user chooses not to use a monitor, the generator shouldn't ask
// if he wants a monitor with a UI style or a Simple monitor.
let mut q_index = 0;
let mut input = String::new();

while q_index < q_diagram.len() {
q_diagram[q_index].print_question();

io::stdin()
.read_line(&mut input)
.expect("Error reading input");

while !q_diagram[q_index].validate_answer(&mut input) {
println!("Please type a valid answer:");
input = "".to_string();
io::stdin()
.read_line(&mut input)
.expect("Error reading input");
}

if q_index < q_diagram.len() - 1 {
q_index = q_diagram[q_index]
.clone()
.next_question(&mut q_diagram, &input, q_index);
} else {
q_index += 1;
}

input = "".to_string();
}

print!("{esc}c", esc = 27 as char);
println!("\nAll questions answered!!!\n\nShutting down...");

Ok(())
}

fn main() {
if let Err(err) = run() {
println!("{}", err);
process::exit(1);
}
}