Dominik Maier 663a33168e
Associated types for Corpus, State (#767)
* Associated types for Corpus, State

* cleanup

* fix no_std

* drop unused clauses

* Corpus

* cleanup

* adding things

* fixed fuzzer

* remove phantom data

* python

* progress?

* more more

* oof

* wow it builds?

* python fixes, tests

* fix python fun

* black fmt for python

* clippy, added Nop things

* fixes

* fix merge

* make it compile (#836)

* doc-test fixes, prelude-b-gone for cargo-hack compat

* fixes for windows, concolic

* really fix windows, maybe

* imagine using windows

* ...

* elide I generic when used with S: State

* Elide many, many generics, but at what cost?

* progress on push

* Constraint HasCorpus, HasSolutions at trait definition

* remove unused feature

* remove unstable usage since we constrained HasCorpus at definition

* compiled, but still no type inference for MaxMapFeedback

* cleanup inprocess

* resolve some std conflicts

* simplify map

* undo unnecessary cfg specification

* fix breaking test case for CI on no-std

* fix concolic build failures

* fix macos build

* fixes for windows build

* timeout fixes for windows build

* fix pybindings issues

* fixup qemu

* fix outstanding local build issues

* maybe fix windows inprocess

* doc fixes

* unbridled fury

* de-associate State from Feedback, replace with generic as AT inference is not sufficient to derive specialisation for MapFeedback

* merge update

* refactor + speed up fuzzer builds by sharing build work

* cleanup lingering compiler errors

* lol missed one

* revert QEMU-Nyx change, not sure how I did that

* move HasInput to inputs

* HasInput => KnowsInput

* update bounds to enforce via associated types

* disentangle observers with fuzzer

* revert --target; update some fuzzers to match new API

* resolve outstanding fuzzer build blockers (that I can run on my system)

* fixes for non-linux unixes

* fix for windows

* Knows => Uses, final fixes for windows

* <guttural screaming>

* fixes for concolic

* loosen bound for frida executor so windows builds correctly

* cleanup generics for eventmanager/eventprocessor to drop observers requirement

* improve inference over fuzz_one and friends

* update migration notes

* fixes for python bindings

* fixes for generic counts in event managers

* finish migration notes

* post-merge fix

Co-authored-by: Addison Crump <addison.crump@cispa.de>
2022-10-24 03:22:26 +02:00

122 lines
3.4 KiB
Rust

use libafl;
#[cfg(target_os = "linux")]
use libafl_qemu;
use libafl_sugar;
use pyo3::{prelude::*, types::PyDict};
const LIBAFL_CODE: &str = r#"
class BaseObserver:
def flush(self):
pass
def pre_exec(self, state, input):
pass
def post_exec(self, state, input, exit_kind):
pass
def pre_exec_child(self, state, input):
pass
def post_exec_child(self, state, input, exit_kind):
pass
def name(self):
return type(self).__name__
def as_observer(self):
return Observer.new_py(self)
class BaseFeedback:
def init_state(self, state):
pass
def is_interesting(self, state, mgr, input, observers, exit_kind) -> bool:
return False
def append_metadata(self, state, testcase):
pass
def discard_metadata(self, state, input):
pass
def name(self):
return type(self).__name__
def as_feedback(self):
return Feedback.new_py(self)
class BaseExecutor:
def observers(self) -> ObserversTuple:
raise NotImplementedError('Implement this yourself')
def run_target(self, fuzzer, state, mgr, input) -> ExitKind:
raise NotImplementedError('Implement this yourself')
def as_executor(self):
return Executor.new_py(self)
class BaseStage:
def perform(self, fuzzer, executor, state, manager, corpus_idx):
pass
def as_stage(self):
return Stage.new_py(self)
class BaseMutator:
def mutate(self, state, input, stage_idx):
pass
def post_exec(self, state, stage_idx, corpus_idx):
pass
def as_mutator(self):
return Mutator.new_py(self)
class FnStage(BaseStage):
def __init__(self, fn):
self.fn = fn
def __call__(self, fuzzer, executor, state, manager, corpus_idx):
self.fn(fuzzer, executor, state, manager, corpus_idx)
def perform(self, fuzzer, executor, state, manager, corpus_idx):
self.fn(fuzzer, executor, state, manager, corpus_idx)
def feedback_not(a):
return NotFeedback(a).as_feedback()
def feedback_and(a, b):
return EagerAndFeedback(a, b).as_feedback()
def feedback_and_fast(a, b):
return FastAndFeedback(a, b).as_feedback()
def feedback_or(a, b):
return EagerOrFeedback(a, b).as_feedback()
def feedback_or_fast(a, b):
return FastOrFeedback(a, b).as_feedback()
"#;
#[pymodule]
#[pyo3(name = "pylibafl")]
pub fn python_module(py: Python, m: &PyModule) -> PyResult<()> {
let modules = py.import("sys")?.getattr("modules")?;
let sugar_module = PyModule::new(py, "sugar")?;
libafl_sugar::python_module(py, sugar_module)?;
m.add_submodule(sugar_module)?;
modules.set_item("pylibafl.sugar", sugar_module)?;
#[cfg(target_os = "linux")]
let qemu_module = PyModule::new(py, "qemu")?;
#[cfg(target_os = "linux")]
libafl_qemu::python_module(py, qemu_module)?;
#[cfg(target_os = "linux")]
m.add_submodule(qemu_module)?;
#[cfg(target_os = "linux")]
modules.set_item("pylibafl.qemu", qemu_module)?;
let libafl_module = PyModule::new(py, "libafl")?;
libafl::pybind::python_module(py, libafl_module)?;
libafl_module.add("__builtins__", py.import("builtins")?)?;
let locals = PyDict::new(py);
py.run(LIBAFL_CODE, Some(libafl_module.dict()), Some(locals))?;
for (key, val) in locals.iter() {
libafl_module.add(key.extract::<&str>()?, val)?;
}
m.add_submodule(libafl_module)?;
modules.set_item("pylibafl.libafl", libafl_module)?;
Ok(())
}