Der Fuzzer verhält sich wie ein Client für den Remote-Dienst, indem er über den generierten Stub importiert oder aufgerufen wird:
Mit der C++ API:
#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 für Fuzz-AIDL-Dienste
Wie im obigen Beispiel gezeigt, wird fuzzService im Fuzzer aufgerufen und akzeptiert einen IBinder (Service) und dataProvider als Eingabeparameter. Zuerst wird mit dem Datenanbieter ein zufälliges Parcel-Objekt initialisiert und die Transaktionsmethode im Remote-Dienst mithilfe der Eingabeparzelle aufgerufen. Anschließend wird die Antwort in ein Antwortpaket übertragen.
Fuzzer erstellen und ausführen
Fuzzer werden standardmäßig mit Abdeckung erstellt.
Die folgenden Desinfektionsmittel werden empfohlen, um Speicherprobleme zu erkennen.
hwaddress
-Sanitizers werden nur in der arm
-Architektur ausgeführt:
SANITIZE_HOST=address SANITIZE_TARGET=hwaddress
Bei der Ausführung mit libFuzzer
kann in der Datei Android.bp
ein Korpus angegeben werden, bei dem es sich um ein Verzeichnis handelt. Sie können dieses Verzeichnis dann an den Fuzzer übergeben. Einige Fuzzer geben auch eine dictionary:
in ihrer Android.bp
-Datei an, die Sie mit -dict path/to/dict
an libFuzzer übergeben können. Weitere Optionen finden Sie in der offiziellen libFuzzer-Dokumentation.
Wenn Sie Fuzzers 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 Fuzzers 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 Dienst-Fuzzer-Bindungen hat.
Der Fuzzer-Bindungstest prüft, ob jeder Dienst in service_contexts
einen Fuzzer hat. Wenn für einen neuen Dienst kein Fuzzer oder eine Ausnahme gefunden wird, liegt ein Build-Fehler vor.
Sie können einen automatischen C++-Service-Fuzzer schreiben, indem Sie Folgendes hinzufügen (Java- und Rost-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 zu Fuzzing mit libFuzzer. Aktualisieren Sie die Bindungen mit dem neuen Dienst- und Fuzzer-Namen, um Build-Fehler zu beheben. Bei Java- oder Rust-Diensten kann die Fuzzer-Liste leer sein.