Skip to content

Installation

Prerequisites

Before building Crucible, ensure the following tools are installed:

Tool Version Purpose
Go 1.23+ Build Crucible CLI tools
clang 14+ Compile libFuzzer harnesses
cmake 3.14+ Build llama.cpp
AFL++ (optional) Alternative fuzzing engine
make any Build orchestration

AFL++ is optional

You only need AFL++ if you plan to use the AFL fuzzing engine. The default workflow uses libFuzzer, which ships with clang.

macOS: use Homebrew LLVM

Apple clang does not include -fsanitize=fuzzer. Install LLVM via Homebrew and use it instead:

brew install llvm
export CC=$(brew --prefix llvm)/bin/clang
export CXX=$(brew --prefix llvm)/bin/clang++

Install from source

Clone the repository and build all binaries:

git clone https://github.com/professor-moody/crucible.git
cd crucible
make build

This produces three binaries in the project root:

Binary Description
crucible Main CLI — run campaigns, check status
crucible-gen Seed corpus generator (structural + mutated)
crucible-triage Crash triage and report generation

Install Go tools only

If you only need the Go command-line tools and do not plan to compile native harnesses, you can install directly with go install:

go install github.com/professor-moody/crucible/cmd/...@latest

Warning

This installs the Go binaries but does not build the libFuzzer or AFL++ harnesses. You will still need to follow the harness build steps to fuzz native code.


Building harnesses

Crucible ships harness source that links against llama.cpp to exercise the GGUF parsing paths. Building a harness requires a local llama.cpp checkout.

1. Clone llama.cpp:

git clone https://github.com/ggml-org/llama.cpp.git ~/src/llama.cpp

2. Build the instrumented llama.cpp library:

The harness links against llama.cpp static libraries built with ASan, UBSan, and fuzzer-no-link. This step produces build-fuzz/ inside the llama.cpp tree:

make -C targets/llamacpp build-fuzz LLAMA_CPP=~/src/llama.cpp

3. Build the libFuzzer harness:

make harness-libfuzzer LLAMA_CPP=~/src/llama.cpp

This compiles crucible-libfuzzer — a standalone binary instrumented with libFuzzer coverage feedback.

AFL++ harness

To build the AFL++ harness instead, run:

make harness-afl LLAMA_CPP=/path/to/llama.cpp

See Configuration — Makefile targets for the full list of build targets.


Docker

Not currently planned

Crucible's build process relies on linking against locally-built llama.cpp (and optionally whisper.cpp, stable-diffusion.cpp, and other target libraries) with sanitizer instrumentation. This makes containerization impractical for active fuzzing — the harness binaries need to match the exact target version and build flags you are testing against.

For reproducible builds on Linux, use scripts/build-linux.sh which handles dependency setup and multi-harness compilation on a fresh system.


Verify installation

After building, confirm that the tools are available:

crucible --help

Expected output:

Crucible is a structure-aware fuzzer targeting the attack surface between
model distribution and inference execution: file format parsers (GGUF), serving
protocols (ggml-rpc), template engines (Jinja2), and API endpoints. It combines
format-aware mutation with systematic input validation auditing.

Usage:
  crucible [command]

Available Commands:
  completion  Generate the autocompletion script for the specified shell
  coverage    Collect and report code coverage
  generate    Generate mutated GGUF corpus
  help        Help about any command
  minimize    Minimize the corpus
  report      Generate CVE-ready reports from triaged crashes
  run         Run a fuzzing campaign
  status      Show campaign statistics
  triage      Triage crash outputs

Flags:
  -h, --help   help for crucible

Use "crucible [command] --help" for more information about a command.

You can also verify the other binaries:

crucible-gen --help
crucible-triage --help

Next: Quick Start — generate a corpus, build a harness, and launch your first fuzzing campaign.