Ledger-Donjon/absolution
GitHub: Ledger-Donjon/absolution
Stars: 0 | Forks: 0
# Absolution
Absolution lets you specify an invariant for a program’s global state and fuzz its entrypoints from states uniformly sampled from that invariant. This helps surface bugs in any interleaving of calls, assuming the fuzzer can explore the space sufficiently.
## How it works
1. Parse globals from your C translation unit(s) using [aro](https://github.com/Vexu/aro).
2. Build flattened globals containing fields, padding, and domains.
3. Optionally apply a `.zon` invariant to constrain field values (per-element `.values` / `.pointers`, or whole-field blobs with `.whole_values` on array-shaped fields; see [USAGE.md](USAGE.md)).
4. Emit `fuzzer.c` with sampling, invariant checking, and libFuzzer entrypoint.
5. Emit a symbol redefinition file for `objcopy` (handles `static` globals across translation units).
6. Write an optional seed file sized to the required random bytes.
## Requirements
- **Zig 0.16.0** (per `build.zig.zon`)
- **C toolchain** with libFuzzer support (e.g., `clang -fsanitize=fuzzer`)
- **objcopy** (GNU binutils or `llvm-objcopy`) — for static symbol redefinition
## Quick start
# Build absolution
zig build -Doptimize=ReleaseFast
# Show CLI help
./zig-out/bin/absolution -h
# Generate fuzzer sources from one or more translation units
./zig-out/bin/absolution \
-t path/to/module_a.c \
-t path/to/module_b.c \
--entry MyTestOneInput \
--out fuzzer.c \
--redef fuzzer.redef \
--seed fuzzer.seed \
-- -I path/to/include -DMY_DEFINE=42
# Compile targets, apply objcopy, link, and run
clang -g -c module_a.c -o module_a.o
clang -g -c module_b.c -o module_b.o
# (apply objcopy --redefine-sym / --globalize-symbol per fuzzer.redef)
clang -g -fsanitize=fuzzer,address fuzzer.c harness.c module_a.o module_b.o -o fuzzer
mkdir -p corpus && cp fuzzer.seed corpus/
./fuzzer corpus/
## CMake integration
Absolution ships CMake modules for `find_package(Absolution)`. After installing,
add fuzzing to an existing CMake project with a single function call:
find_package(Absolution REQUIRED)
absolution_add_fuzzer(
NAME fuzz_my_target
TARGETS src/module_a.c src/module_b.c
HARNESS fuzz/my_harness.c
ENTRY MyTestOneInput
INCLUDE_DIRECTORIES "${CMAKE_SOURCE_DIR}/include"
COMPILE_DEFINITIONS "MY_DEFINE=42"
)
This creates a CMake target that handles the full pipeline: run absolution,
compile objects, apply `objcopy` symbol redefinitions, and link the final fuzzer
binary with sanitizers.
See **[example/protocol_parser/](example/protocol_parser/)** for a complete
working example with multiple translation units.
## Testing
zig build test # Run unit tests
zig run scripts/integration.zig # Integration tests
zig run scripts/integration.zig -- foo # Run only tests matching "foo"
## Documentation
- **[USAGE.md](USAGE.md)** — Detailed usage guide with examples and behavior reference
- **[CONTRIBUTING.md](CONTRIBUTING.md)** — Code organization and development workflow
- **[example/protocol_parser/](example/protocol_parser/)** — Complete CMake integration example