Der Fuzzer verhält sich als Client für den Remote-Dienst, indem er ihn über den generierten Stub importiert oder aufruft:
C++ API verwenden:
#include <fuzzbinder/libbinder_ndk_driver.h>
#include <fuzzer/FuzzedDataProvider.h>
#include <android-base/logging.h>
#include <android/binder_interface_utils.h>
using android::fuzzService;
using ndk::SharedRefBase;
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
auto binder = ndk::SharedRefBase::make<MyService>(...);
fuzzService(binder->asBinder().get(), FuzzedDataProvider(data, size));
return 0;
}
Rust API verwenden:
#![allow(missing_docs)]
#![no_main]
#[macro_use]
extern crate libfuzzer_sys;
use binder::{self, BinderFeatures, Interface};
use binder_random_parcel_rs::fuzz_service;
fuzz_target!(|data: &[u8]| {
let service = BnTestService::new_binder(MyService, BinderFeatures::default());
fuzz_service(&mut service.as_binder(), data);
});
Framework zum Fuzzing von AIDL-Diensten
Wie im Beispiel oben gezeigt, wird fuzzService im Fuzzer aufgerufen und nimmt einen IBinder (Dienst) und dataProvider als Eingabeparameter entgegen. Zuerst initialisiert sie mit dem Datenanbieter ein zufälliges Parcel-Objekt und ruft die Transaktionsmethode im Remote-Dienst mithilfe der Eingabeparzelle auf. Schließlich wird die Antwort in ein Antwortpaket hochgeladen.
Fuzzer erstellen und ausführen
Fuzzer werden standardmäßig mit Abdeckung erstellt.
Die folgenden Sanitizer werden empfohlen, um Speicherprobleme zu erkennen.
hwaddress
-Sanitizer werden nur auf arm
-Architekturen ausgeführt:
SANITIZE_HOST=address SANITIZE_TARGET=hwaddress
Wenn Sie libFuzzer
ausführen, kann in der Android.bp
-Datei ein Corpus (ein Verzeichnis) angegeben werden, den Sie an den Fuzzer übergeben können. Einige Fuzzer geben auch in ihrer Android.bp
-Datei einen dictionary:
an. Sie können diesen mit -dict path/to/dict
an libFuzzer übergeben. Weitere Optionen finden Sie in der offiziellen libFuzzer-Dokumentation.
Wenn Sie Fuzzer auf dem Gerät ausführen möchten, führen Sie adb sync data
und dann adb shell data/fuzz/arch/name/name
aus.
Führen Sie $ANDROID_HOST_OUT/fuzz/arch/name/name
aus, um Fuzzer auf dem Host auszuführen.
Fuzzer für neue oder bestehende Dienste empfehlen
Das Build-System prüft, ob jeder AOSP-Binder-Dienst einen Fuzzer-Eintrag in den Dienst-Fuzzer-Bindungen hat.
Beim Fuzzer-Bindungstest wird geprüft, ob jeder Dienst in service_contexts
einen Fuzzer hat. Wenn für einen neuen Dienst kein Fuzzer oder keine Ausnahme gefunden wird, liegt ein Buildfehler vor.
Ein automatischer C++-Dienst-Fuzzer kann durch Hinzufügen der folgenden Angaben geschrieben werden (Java- und Rust-Fuzzer werden noch nicht unterstützt):
- Ein
cc_fuzz
-Eintrag inAndroid.bp
zum Definieren des Fuzzer-Moduls. Dascc_default
-Modulservice_fuzzer_defaults
hat Abhängigkeiten, die fürfuzzService
erforderlich sind. - Dienstspezifische Abhängigkeiten sollten als Bibliothek oder als Quellen hinzugefügt werden.
- Eine Hauptdatei, die Ihren Dienst erstellt und
fuzzService
aufruft
Eine ausführliche Anleitung zur Verwendung von cc_fuzz
finden Sie in der Dokumentation Fuzzing mit libFuzzer. Aktualisieren Sie die Bindungen mit dem neuen Dienst und den neuen Fuzzernamen, um den Buildfehler zu beheben. Bei Java- oder Rust-Diensten kann die Fuzzerliste leer sein.