Introduction to Honggfuzz
Honggfuzz is a modern, powerful, and actively maintained fuzzing framework designed for finding security vulnerabilities and stability bugs in software. Unlike traditional fuzzers that rely purely on random mutation, Honggfuzz leverages hardware-based feedback (Intel BTS, Intel PT, and hardware performance counters) and software-based instrumentation (SanitizerCoverage, ASAN, LibFuzzer integration) to achieve deep code exploration. It supports fuzzing of binaries, libraries, and network services, and works across Linux, macOS, Windows, and Android. Whether you're auditing a custom C library, testing a JavaScript engine, or hardening a network daemon, Honggfuzz provides the tooling to uncover hidden edge cases and crashes.
Why Honggfuzz Matters for Developers
🚀 Deploy your AI agent in 10 minutes
Managed Hermes hosting. Zero DevOps. 100M tokens/mo included.
Try it free →Fuzzing has become a cornerstone of secure software development. Honggfuzz stands out for several reasons:
- Hardware-assisted feedback – Uses Intel Branch Tracing Store (BTS) or Intel Processor Trace (PT) to observe exact code paths without heavy instrumentation overhead, making it extremely fast on compatible CPUs.
- Low-latency persistent fuzzing – Supports in-process fuzzing via forkserver and persistent mode, reducing fork overhead and enabling hundreds of executions per second.
- Cross-platform support – Runs on Linux, macOS, Windows (via Cygwin or WSL), and Android, covering diverse development environments.
- Rich sanitizer integration – Works seamlessly with AddressSanitizer (ASAN), UndefinedBehaviorSanitizer (UBSAN), and MemorySanitizer to turn subtle corruption into immediate crashes.
- Network fuzzing – Can fuzz clients and servers over TCP/UDP, including protocols like HTTP, DNS, and custom binary protocols.
- Dictionary and grammar support – Accepts user-provided dictionaries and grammar-based mutations to guide fuzzing toward meaningful input structures.
By integrating Honggfuzz into your CI/CD pipeline or regular testing workflow, you can continuously stress-test your code against billions of mutated inputs, catching bugs before they reach production.
Installation and Setup
Honggfuzz is primarily developed on Linux but can be built on other platforms. The recommended approach is to clone the repository and compile from source to get the latest features.
Prerequisites
- A Unix-like environment (Linux, macOS, or Windows Subsystem for Linux)
make,gcc/clang, and standard build toolslibbfd(binutils-dev) andlibunwindfor detailed crash reports- For hardware feedback: Intel CPU with BTS or PT support (optional but recommended)
Building from Source
# Clone the repository
git clone https://github.com/google/honggfuzz.git
cd honggfuzz
# Build Honggfuzz and its supporting tools
make
# Optionally, install system-wide
sudo make install
After building, the main executable honggfuzz will be available in the project directory. You can verify the build with:
./honggfuzz --help
For sanitizer-based fuzzing, ensure you have a recent Clang compiler with sanitizer support. The hfuzz_cc / hfuzz-clang helpers simplify building target binaries with the correct instrumentation.
Core Concepts and Architecture
Honggfuzz operates by running a target program repeatedly with mutated inputs, monitoring its behavior through feedback mechanisms, and saving any inputs that cause crashes or discover new code paths. The key components are:
- Fuzzing engine – Mutates input files using a combination of deterministic and random strategies, including bit flips, arithmetic operations, splicing, and dictionary tokens.
- Feedback mechanism – Collects coverage data via hardware events (BTS/PT) or software instrumentation (SanitizerCoverage). The fuzzer uses this data to prioritize inputs that increase code coverage.
- Crash triaging – Automatically deduplicates crashes based on stack hashes and produces unique crash reports.
- Forkserver and persistent mode – Forks a new process for each input (or reuses a process in persistent mode) to isolate crashes and achieve high throughput.
Basic Fuzzing Workflow
The simplest way to start fuzzing is to provide a set of initial seed files (corpus) and the command line that runs the target program, using the magic @@ placeholder for the input file path.
Fuzzing a File-Parsing Application
Assume you have a tool called parse-image that reads a file from disk and processes it:
# Prepare a minimal corpus directory with valid samples
mkdir corpus
cp some-valid-image.jpg corpus/
# Run Honggfuzz, replacing @@ with the mutated input file
honggfuzz -i corpus -o results -- ./parse-image @@
Flags explained:
-i corpus– Directory containing initial seed files.-o results– Directory where crashes and interesting inputs are saved.--– Separator between honggfuzz options and the target command.@@– Placeholder replaced by honggfuzz with the path to the current mutated input.
Using Sanitizer Instrumentation
For maximum bug detection, compile your target with AddressSanitizer (ASAN) and UndefinedBehaviorSanitizer (UBSAN). Honggfuzz provides hfuzz-clang wrappers to simplify this.
# Compile target with sanitizers and coverage feedback
hfuzz-clang -g -fsanitize=address,undefined -fprofile-instr-generate -fcoverage-mapping \
-o parse-image-san parse-image.c -ljpeg
# Create a directory for sanitizer-compatible output
mkdir results
# Fuzz with hardware feedback disabled (software coverage used instead)
honggfuzz -i corpus -o results --linux_perf_ignore_pt -- ./parse-image-san @@
The --linux_perf_ignore_pt flag disables Intel PT/BTS hardware feedback, falling back to SanitizerCoverage counters. This is useful when hardware tracing is unavailable or you prefer the sanitizer coverage granularity.
Advanced Usage Techniques
Persistent Fuzzing (In-Process)
Persistent fuzzing avoids the overhead of spawning a new process per input. The target is invoked once, and then a loop repeatedly calls a function with new input. Honggfuzz supports persistent mode via the __AFL_FUZZ_INIT and __AFL_FUZZ macros, originally from AFL.
Example target harness for a function parse(const uint8_t* data, size_t len):
#include <stdint.h>
#include <stddef.h>
#include "parse.h"
#ifdef __AFL_FUZZ_INIT
__AFL_FUZZ_INIT();
#endif
int main(int argc, char **argv) {
#ifdef __AFL_FUZZ_INIT
// AFL persistent mode initialization
unsigned char *buf = __AFL_FUZZ_INIT();
while (__AFL_FUZZ(10000)) { // loop 10000 iterations
size_t len = __AFL_FUZZ_SIZE();
parse(buf, len);
}
return 0;
#else
// Non-persistent fallback: read from stdin
// ... (not shown)
#endif
}
Compile with hfuzz-clang and run with the --persistent flag:
hfuzz-clang -g -fsanitize=address -o persistent-parse persistent-parse.c
honggfuzz --persistent -i corpus -o results --linux_perf_ignore_pt -- ./persistent-parse
Persistent mode can achieve thousands of executions per second, dramatically accelerating bug discovery.
Network Fuzzing (TCP/UDP)
Honggfuzz can act as a network client or server to fuzz protocols. It connects to a real service and sends mutated traffic, or listens for connections and responds with mutated data.
To fuzz an HTTP server running locally on port 8080:
honggfuzz --net_client --target TCP:127.0.0.1:8080 \
-i http_corpus -o net_results --timeout 10 \
--call_stdin_only -- ./http-server-replay @@
The --net_client flag tells Honggfuzz to connect to the specified TCP address and send the mutated input. The target program (http-server-replay) typically just reads stdin and writes to the socket, but you can customize behavior. For complex protocols, you can provide a dedicated fuzzing harness that manages the connection and passes input via stdin.
Dictionary and Grammar Support
Honggfuzz accepts dictionaries (lists of keywords or tokens) to improve mutation quality. Create a plain text file with one token per line:
# dictionary.txt
GET
POST
HTTP/1.1
Host:
User-Agent:
Content-Length:
Use the --dict option to feed the dictionary:
honggfuzz -i http_corpus --dict dictionary.txt -o results -- ./http-parser @@
For more structured formats, consider using grammar-based fuzzing in combination with Honggfuzz as the backend executor, though Honggfuzz itself focuses on mutation-based fuzzing.
Crash Analysis and Triage
Honggfuzz automatically saves crashing inputs in the output directory under results/. Each crash is hashed based on its call stack, so unique bugs are separated. You can analyze them manually:
# List unique crashes
honggfuzz --print_crashdir results
# Replay a specific crash to see the stack trace
honggfuzz --run_crash_file results/SIGABRT.PC.ffffcafe.CODE.ASAN.h1234.fuzz -- ./target @@
For deeper inspection, run the crashing input under GDB or with ASAN symbolization enabled.
Integrating with LibFuzzer Fuzzing Harnesses
Honggfuzz can directly execute LibFuzzer-style fuzz targets (functions named LLVMFuzzerTestOneInput). This allows you to reuse existing fuzzing harnesses written for LibFuzzer with Honggfuzz's hardware feedback and persistent mode.
# Compile a LibFuzzer harness as a shared library
hfuzz-clang -fsanitize=address,undefined -fPIC -shared -o harness.so harness.c
# Run Honggfuzz with the library
honggfuzz --libfuzzer -- ./harness.so
The --libfuzzer flag enables the LibFuzzer interface, and Honggfuzz handles input delivery and feedback collection transparently.
Best Practices for Effective Fuzzing
- Start with a good corpus – Collect diverse, valid input files that exercise different code paths. A rich corpus accelerates coverage discovery.
- Always compile with sanitizers – ASAN and UBSAN catch memory corruption, overflows, and undefined behavior that might otherwise go unnoticed.
- Use persistent mode when possible – For library APIs or internal functions, a persistent harness can increase throughput by 10x or more.
- Enable hardware feedback on supported CPUs – Intel PT provides precise coverage with near-zero overhead. If unavailable, fall back to SanitizerCoverage.
- Monitor and minimize timeouts – Set appropriate
--timeoutvalues to avoid wasting time on slow inputs while still catching algorithmic complexity issues. - Deduplicate crashes diligently – Use Honggfuzz's built-in triage to focus on unique bugs. Validate each crash with a debugger to avoid false positives.
- Fuzz continuously – Integrate Honggfuzz into CI pipelines using tools like
honggfuzz-psor Docker containers. Run nightly fuzzing campaigns on critical components. - Combine with symbolic execution or grammar tools – For complex formats (e.g., parsers), supplement mutation fuzzing with grammar-aware tools or custom mutators.
- Isolate network fuzzing – Run network targets in isolated environments (containers/VMs) to prevent accidental damage to live systems.
Example: Fuzzing a JSON Parser End-to-End
Let's walk through a concrete scenario: fuzzing a simple JSON parsing library to find crashes and assertion failures.
Assume the library exposes a function json_parse(const char* input, size_t length).
Step 1: Write the Harness
#include <stdint.h>
#include <stddef.h>
#include "json.h"
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
// Ensure null-termination for the parser
if (size == 0) return 0;
char *str = malloc(size + 1);
if (!str) return 0;
memcpy(str, data, size);
str[size] = '\0';
json_parse(str, size);
free(str);
return 0; // Non-zero return values signal interesting cases in LibFuzzer mode
}
Step 2: Compile with Sanitizers
hfuzz-clang -g -fsanitize=address,undefined -fPIC -shared -o json-harness.so json-harness.c libjson.a
Step 3: Prepare Corpus
mkdir json-corpus
# Add some valid JSON files
echo '{"key":"value"}' > json-corpus/valid1.json
echo '[1,2,3]' > json-corpus/valid2.json
Step 4: Launch Fuzzing
honggfuzz --libfuzzer --timeout 5 -i json-corpus -o json-results -- ./json-harness.so
Step 5: Monitor and Triage
Watch the terminal output for crash counts and coverage progress. After a few hours (or days), inspect the results:
honggfuzz --print_crashdir json-results
# Replay interesting crashes
honggfuzz --run_crash_file json-results/SIGABRT... -- ./json-harness.so
Each crash can then be analyzed, fixed, and added to regression tests.
Conclusion
Honggfuzz is a versatile and high-performance fuzzer that deserves a place in every developer's security testing toolkit. Its combination of hardware-assisted feedback, sanitizer integration, persistent fuzzing, and network fuzzing capabilities makes it suitable for a wide range of targets – from tiny library functions to complex network services. By following the practices outlined in this guide, you can systematically uncover bugs that static analysis and manual review miss, ultimately delivering more robust and secure software. Start with a small corpus, instrument your build with sanitizers, and let Honggfuzz do the heavy lifting of mutation and crash discovery. The result will be a stronger codebase and greater confidence in your software's resilience.