1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
//! A coverage-guided fuzzing framework for Internet Computer canisters.
//!
//! This framework is built on `libafl` and `pocket-ic` to find bugs in IC canisters
//! by automatically generating and executing a vast number of inputs.
//! It supports both Rust and Motoko canisters.
//!
//! ## Getting Started
//!
//! To create a fuzzer, implement the [`orchestrator::FuzzerOrchestrator`] trait.
//! This trait defines the setup and execution logic for your
//! fuzzing campaign.
//!
//! ```no_run
//! use canfuzz::fuzzer::{CanisterBuilder, FuzzerBuilder, FuzzerState, WasmPath};
//! use canfuzz::orchestrator::FuzzerOrchestrator;
//! use canfuzz::libafl::executors::ExitKind;
//! use canfuzz::libafl::inputs::BytesInput;
//! use std::path::PathBuf;
//!
//! // 1. Define a struct for your fuzzer using the macro.
//! canfuzz::define_fuzzer_state!(MyFuzzer);
//!
//! // 2. Implement the fuzzing logic.
//! impl FuzzerOrchestrator for MyFuzzer {
//! fn init(&mut self) {
//! // Setup PocketIc and install canisters automatically.
//! self.as_mut().setup_canisters();
//! }
//!
//! fn corpus_dir(&self) -> PathBuf {
//! PathBuf::from("./corpus")
//! }
//!
//! fn execute(&self, input: BytesInput) -> ExitKind {
//! let payload: Vec<u8> = input.into();
//! println!("Executing input: {:?}", payload);
//! // Execute a canister call with the input.
//! ExitKind::Ok
//! }
//! }
//!
//! // 4. Set up and run the fuzzer.
//! fn main() {
//! let canister = CanisterBuilder::new("my_target_canister")
//! .with_wasm_path("./my_canister.wasm")
//! .as_coverage()
//! .build();
//!
//! let state = FuzzerBuilder::new()
//! .name("my_fuzzer")
//! .with_canister(canister)
//! .build();
//!
//! let mut fuzzer = MyFuzzer(state);
//! fuzzer.run();
//! }
//! ```
//!
//! ## Instruction Count Maximization
//!
//! To maximize the number of IC instructions consumed by a canister method, enable
//! instruction counting during wasm instrumentation and override
//! [`FuzzerOrchestrator::instruction_config`](orchestrator::FuzzerOrchestrator::instruction_config)
//! to return an [`InstructionConfig`](orchestrator::InstructionConfig) with `enabled: true`. No changes to the target canister source code are required — the
//! framework automatically wraps exported methods to read `ic0.performance_counter`.
//! Each time a new maximum is reached, the input is logged and saved to the corpus directory.
//! Optionally set `max_instruction_count` to flag inputs that exceed a threshold as crashes.
//!
//! See the `decode_candid_by_instructions` example for a complete demonstration.
//!
//! For a complete example, see the `examples/` directory in the project repository.
// re-export libAFL and libAFL_bolts
pub use libafl;
pub use libafl_bolts;