Der Fuzzer verhält sich wie ein 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 verwendet einen IBinder (Service) und einen DataProvider als Eingabeparameter. Zuerst wird ein zufälliges Parcel-Objekt mit dem Datenanbieter initialisiert und die Methode „transact“ für den Remote-Dienst mit dem Eingabe-Parcel aufgerufen. Schließlich wird die Antwort in ein Antwort-Parcel abgerufen.
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 der arm-Architektur ausgeführt:
SANITIZE_HOST=address SANITIZE_TARGET=hwaddress
Bei der Ausführung mit libFuzzer kann ein Korpus, der ein Verzeichnis ist, in der Datei Android.bp angegeben werden. Sie können dieses Verzeichnis an den Fuzzer übergeben. Einige Fuzzer geben auch ein dictionary: in ihrer Android.bp-Datei an. Sie können dies 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 vorhandene Dienste empfehlen
Das Build-System prüft, ob jeder AOSP-Binder-Dienst einen Fuzzer-Eintrag in service fuzzer bindings hat.
Beim Fuzzer-Binding-Test 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 Build-Fehler vor.
Ein automatischer C++-Service-Fuzzer kann durch Hinzufügen des Folgenden geschrieben werden (Java- und Rust-Fuzzer werden noch nicht unterstützt):
- Ein
cc_fuzz-Eintrag inAndroid.bpzum Definieren des Fuzzer-Moduls. Das Modulcc_defaultservice_fuzzer_defaultshat Abhängigkeiten, die fürfuzzServiceerforderlich sind. - Dienstspezifische Abhängigkeiten sollten als Bibliothek oder als Quellen hinzugefügt werden.
- Eine Hauptdatei, die Ihren Dienst erstellt und
fuzzServiceaufruft
Eine ausführliche Anleitung zur Verwendung von cc_fuzz finden Sie in der Dokumentation Fuzzing with libFuzzer. Aktualisieren Sie die Bindungen mit den neuen Dienst- und Fuzzer-Namen, um den Build-Fehler zu beheben. Bei Java- oder Rust-Diensten kann die Fuzzer-Liste leer sein.