Coverage-gesteuertes Fuzzing
Lassen Sie das reale Ziel unter Feedback ausführen, mit der vorgesehenen Oracle und einem reproduzierbaren Lebenszyklus. Ein laufender Fuzz-Binary oder ein wachsendes Korpus stellen keine nützliche Zielerreichung dar: „Der corpus count-Wert ist ein schlechter Indikator, um zu überprüfen, wie gut die Abdeckung ist“ (AFL++ Fuzzing in Depth §3.g).
Den tatsächlichen Lane auswählen
Lesen Sie den Ziel-Einstiegspunkt, den Build-Graphen, die aktivierten Funktionen, die Laufzeit/Architektur, den Decoder und die Eigenschaften. Identifizieren Sie, welche Zielmodule eine Instrumentierung erhalten und was sich unter dem Fuzz-Build ändert; ein nur treiber-instrumentierter Pfad oder eine Funktion, die nur in ihrem Wrapper aktiviert ist, kann die beabsichtigte Implementierung verfehlen. Die Feature-Optionen von cargo-fuzz „steuern die fuzz_targets-Crate“, bis sie weitergeleitet werden, und libFuzzer trennt die Instrumentierung (-fsanitize=fuzzer-no-link) vom Linken seiner main() (Rust Fuzz Book guide, Cargo features, LLVM libFuzzer, Fuzzer Usage).
Verwenden Sie den vorhandenen passenden Producer und Build-Besitzer. Wählen Sie nur die zutreffende Ausführungsreferenz aus:
| Ziel | Lesen Sie |
|---|---|
| Native Quelle/Binärdatei, AFL++ oder libFuzzer | Native Runner |
| Go oder Rust | Go und Rust |
| Python/native Erweiterungen oder JVM | Python und JVM |
| C++-Eigenschaftsdomänen mit FuzzTest | C++ FuzzTest |
| Node.js (CJS, ESM, TypeScript via Jest) | Node.js mit Jazzer.js |
Browser-Anwendungscode hat keinen prozessinternen coverage-gesteuerten Weg: Jazzer.js stuft „Andere Laufzeiten oder Browser-Support“ als außerhalb des Rahmens ein (Jazzer.js architecture, Constraints). Leiten Sie die UI-Erkundung des Browsers an die Fähigkeit weiter, die UI-Ereignissequenzen besitzt.
Überprüfen Sie die Voraussetzungen der ausgewählten Version und die installierte Hilfe, bevor Sie die Konfiguration ändern. Referenzen zeichnen einen datierten Quell-Snapshot auf, kein Versprechen, dass jede Version/Plattform dieselben Flags unterstützt. Führen Sie innerhalb der bestehenden Autorität des Benutzers aus; diese Fähigkeit autorisiert selbst keine Installationen, Zielbearbeitungen oder externen Ausgaben.
Einen begrenzten informativen Pilotlauf durchführen
Richten Sie den Entdeckungsmodus, die relevante Zielinstrumentierung, das Zustands-Reset und eine funktionierende Oracle ein, bevor Sie Worker hinzufügen. Go Seed-Wiedergabe, Jazzer-Regression, Jazzer.js Jest-Regression und der FuzzTest-Einheitsmodus unterscheiden sich von ihren Entdeckungsmodi: Einfaches go test führt Seeds aus „ähnlich wie ein Unit-Test“, „Jazzer arbeitet im Regressionsmodus, sofern der Fuzzing-Modus nicht explizit aktiviert ist“, Jazzer.js unter Jest standardmäßig im Modus "regression", und der FuzzTest-Einheitsmodus läuft „ohne Sanitizer- und Coverage-Instrumentierung“ (Go fuzzing, Running fuzz tests, Jazzer README, Regression mode, Jazzer.js fuzzing settings, mode, FuzzTest Bazel quickstart, Create and run a fuzz test).
Beobachten Sie Decoder-Zulassung, beabsichtigte Operation, erfolgreiche Effekte und Eigenschaftsbewertungen getrennt von der Engine-Abdeckung; Byte-Mutation eines komprimierten Formats kann dazu führen, dass „praktisch alle generierten Eingaben für uncompress ungültig sind“ (Google structure-aware fuzzing guide, Example: Compression). Diagnostizieren Sie zurückgewiesene Formate, versteckten Zustand oder unerfüllte Abhängigkeiten mit Reichweite, Reset und Feedback. Wählen Sie Wörterbuch-/Vergleichs-Feedback oder strukturelle Mutation gegen einen nachgewiesenen Blocker aus; jedes ändert einen anderen Teil der Suche (AFL++ CmpLog, Google structure-aware fuzzing guide).
Halten Sie die Steuerelemente für pro-Eingabe, Fuzz-Zeit, Wanduhrzeit, Worker/CPU und Speicher getrennt; beziehen Sie die Einrichtungs-/Wiedergabekosten in das autorisierte Budget ein. AFL++ -V ist „(nur Fuzz-Zeit!)“ und -E ist „eine ungefähre Anzahl von Gesamtausführungen“; keines ist die aggregierte Prozessor-CPU (AFL++ selected-ref CLI source, usage text). Go -timeout begrenzt die Fuzzing-Phase nicht (Go und Rust). Verwenden Sie separate eigene Ausgaben und begrenzte Bereinigung eigener Prozesse; libFuzzer sagt zu exakten Artefaktpfaden: „Verwenden Sie nicht denselben Pfad für mehrere parallele Prozesse“ (LLVM libFuzzer, Options). Beziehen Sie sich auf bugfinding-campaign für Allokationsentscheidungen.
Beweise interpretieren und aufbewahren
Bewahren Sie exakte Eingaben/typisierte Argumente, Build/Konfiguration/Instrumentierung, Anfangszustand oder -sequenz, Befehl/Grenzwerte, rohe Engine-Ausgabe, Ziel-/Eigenschaftszähler und ausgegebenes Wiedergabematerial auf. Zustand und Lebenszyklusunterschiede zwischen Aufrufen können die Ein-Datei-Reproduktion ungültig machen: Go erfordert, dass „der Zustand eines Fuzz-Ziels nicht über das Ende jedes Aufrufs hinaus bestehen bleiben sollte“, und Jazzer's Standard PER_TEST „bewahrt mit höherer Wahrscheinlichkeit unbeabsichtigt den Zustand zwischen Fuzz-Test-Ausführungen“ (Go fuzzing, Suggestions, Jazzer Lifecycle implementation).
Geben Sie zurück, was tatsächlich ausgeführt wurde, die beobachtete Eigenschaft, die Ressourcennutzung, Kandidaten und Auslassungen. Unterscheiden Sie Entdeckung von Regression, Abdeckung von semantischer Reichweite und Kandidatenfehler von Produktzuschreibung. Verwenden Sie corpus-evolution für kompatible Aufbewahrung/Austausch, failure-reduction für zeugenbewahrendes Schrumpfen und evidence-based-triage für Zuschreibung. Historische Ergebnisse der Seed-Auswahl hängen von ihrem Ziel/Planer ab; Rebert et al. fanden eine Hypothese „falsch unter dem optimalen Scheduling“ und testeten sie dennoch erneut unter Round-Robin. Machen Sie daraus keine universellen Durchsatz- oder Ertragsversprechen (Rebert et al., pp.864,871,873).
Lesen Sie für konkrete irreführende Läufe und Korrekturen häufige Fehler. Aus dieser Fähigkeit folgt kein zielspezifisches neues Framework.