Mastering Honggfuzz on Android: Setup, Execution, and Deep Code Insights

This article introduces the Google‑maintained honggfuzz fuzzing engine, explains how to integrate it into the Android AOSP build, run multi‑threaded fuzzing on devices, and dives into the core source modules, coverage sharing mechanisms, and the extensive mutation strategies that power its effectiveness.

OPPO Amber Lab
OPPO Amber Lab
OPPO Amber Lab
Mastering Honggfuzz on Android: Setup, Execution, and Deep Code Insights

1. honggfuzz Usage

honggfuzz is a high‑efficiency, feedback‑driven fuzzing engine maintained by Google that supports Linux, FreeBSD, NetBSD, macOS, Windows, and Android platforms. It is used by large‑scale projects such as OSS‑Fuzz and has discovered many CVE vulnerabilities. On Android, honggfuzz can directly reuse AOSP fuzzing test cases, making it easy to learn and port.

1.1 Deploying honggfuzz in AOSP

honggfuzz is not integrated into AOSP like libFuzzer or AFL++. It must be compiled separately for arm or arm64, producing three static libraries ( libhfcommon.a, libhfuzz.a, libhfnetdriver.a) and a launcher executable for the device.

Steps:

Clone the honggfuzz source code and cross‑compile for the target architecture.

Copy the three static libraries into the AOSP source tree and add an Android.bp or Android.mk file to include them in the build.

Check the clang version used by AOSP (e.g.,

cat build/soong/cc/config/global.go | grep ClangDefaultVersion

) and replace any existing libclang_rt.fuzzer‑aarch64‑android.a with an empty file to avoid instrumentation conflicts.

After these steps, the AOSP build environment can instrument test cases that contain LLVMFuzzerTestOneInput() using the cc_fuzz (Android.bp) or BUILD_FUZZ_TEST (Android.mk) tags, linking against the three honggfuzz static libraries.

1.2 Running honggfuzz on Android

Execute the launcher on the device via adb shell with a command such as:

honggfuzz -z -i input -W result --crashdir crash -- ./fmq_fuzzer_honggfuzz

The launcher reports various metrics (iterations, mode, target, threads, speed, crashes, timeouts, corpus size, coverage, etc.) that help monitor the fuzzing progress.

2. honggfuzz Key Source Code Analysis

honggfuzz 2.6 is used for the analysis. The framework diagram (shown in the original article) highlights the modules involved in multi‑threaded fuzzing.

2.1 Multi‑Thread Startup

The launcher parses command‑line arguments into a honggfuzz_t structure and calls fuzz_threadsStart() to create a thread pool based on the specified thread count.

Each thread prepares execution arguments via subproc_prepareExecvArgs() and launches the target binary with execve() (see arch_launchChild).

The persistent mode runs the target’s main() repeatedly, invoking HonggfuzzRunFromFile() for each mutated input.

2.2 Cross‑Thread Coverage Sharing

honggfuzz supports several coverage collection methods; on Android only software instrumentation is feasible. Coverage data is stored in a global globalCovFeedback structure, allowing threads to share coverage information.

The instrumentation functions in instrument.c (part of libhfuzz.a) follow LLVM’s coverage API.

2.3 Mutation Strategies

Before each iteration, fuzz_fetchInput() selects an input corpus entry. In feedback‑driven mode, input_prepareDynamicInput() computes skip_factor and speed_factor to adjust mutation intensity.

honggfuzz implements about 20 mutation functions stored in the mangleFuncs array. Examples include:

mangle_Shrink : delete a random block of data.

mangle_Expand : insert a duplicated block (inflate) at a random offset; if printable is true, the inserted bytes are spaces.

mangle_Bit : flip a random bit in a random byte; printable mode maps the result to an ASCII printable character.

mangle_IncByte / mangle_DecByte : increment or decrement a random byte, with optional printable mapping.

mangle_NegByte : invert a random byte, optionally mapping to a printable character.

mangle_AddSub : add or subtract a random value to 1/2/4/8 bytes at a random offset.

mangle_MemSet / mangle_MemClr : overwrite or clear a random region with a value or spaces.

mangle_MemSwap : swap two random blocks of data.

mangle_Bytes : insert or overwrite 1–2 random bytes.

mangle_ASCIINum / mangle_ASCIINumChange : locate a decimal string and modify it (increment, double, random change, etc.).

mangle_Magic : insert special boundary values from mangleMagicVals.

mangle_StaticDict : insert data from a user‑provided dictionary file.

mangle_ConstFeedbackDict : use values collected by the constant‑feedback dictionary.

mangle_RandomBuf : replace a region with random data.

mangle_Splice : splice random data from an external file into the corpus.

The mutation rate can be tuned via the mutationsPerRun parameter (default 5). Each thread applies a random subset of the mutation functions, controlled by speed_factor.

3. Summary

honggfuzz leverages multi‑threading to fully utilize CPU resources and outperforms AFL and libFuzzer on the same platform. Its modular architecture allows easy customization of the fuzzing engine, coverage feedback, and mutation strategies, making it a powerful tool for security researchers seeking to discover vulnerabilities across multiple platforms.

Androidcoveragefuzz testinghonggfuzzmutation strategies
OPPO Amber Lab
Written by

OPPO Amber Lab

Centered on user data security and privacy, we conduct research and open our tech capabilities to developers, building an information‑security fortress for partners and users and safeguarding OPPO device security.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.