Il fuzzer si comporta come un client per il servizio remoto importandolo/invocandolo tramite lo stub generato:
Utilizzando l'API C++:
#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;
}
Utilizzo dell'API Rust:
#![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 per fuzz servizi AIDL
Come mostrato nell'esempio precedente, fuzzService viene chiamato nel fuzzer e accetta un IBinder (Service) e un dataProvider come parametri di input. Innanzitutto inizializza un oggetto Parcel casuale utilizzando il fornitore di dati, chiama il metodo transact sul servizio remoto utilizzando il pacchetto di input e infine inserisce la risposta in un pacchetto di risposta.
Costruisci ed esegui fuzzer
I fuzzer sono creati con copertura per impostazione predefinita.
Si consigliano i seguenti disinfettanti per scoprire problemi di memoria. I disinfettanti hwaddress
funzionano solo sull'architettura arm
:
SANITIZE_HOST=address SANITIZE_TARGET=hwaddress
Quando si esegue con libFuzzer
, un corpus, ovvero una directory, può essere specificato nel file Android.bp
ed è possibile passare questa directory al fuzzer. Alcuni fuzzer specificano anche un dictionary:
nel loro file Android.bp
, e puoi passarlo a libFuzzer con -dict path/to/dict
. Per ulteriori opzioni, consultare la documentazione ufficiale di libFuzzer .
Per eseguire i fuzzer sul dispositivo, esegui adb sync data
e quindi adb shell data/fuzz/ arch / name / name
. Per eseguire i fuzzer sull'host, eseguire $ANDROID_HOST_OUT/ fuzz / arch / name / name
.
Raccomandare fuzzer per servizi nuovi/esistenti
Il sistema di compilazione controlla se ogni servizio di associazione AOSP dispone di una voce fuzzer nei collegamenti fuzzer del servizio . Il test di associazione Fuzzer verifica che ogni servizio in service_contexts
abbia un fuzzer. Se non viene trovato un fuzzer/un'eccezione per un nuovo servizio, si verifica un errore di compilazione.
È possibile scrivere un fuzzer automatico del servizio C++ aggiungendo quanto segue (i fuzzer Java e Rust non sono ancora supportati):
- Una voce
cc_fuzz
inAndroid.bp
per definire il modulo fuzzer. Il modulocc_default
service_fuzzer_defaults
ha dipendenze richieste perfuzzService
. - Le dipendenze specifiche del servizio dovrebbero essere aggiunte come libreria o come origini.
- Un file principale che costruisce il tuo servizio e chiama
fuzzService
Per istruzioni dettagliate sull'utilizzo cc_fuzz
, consultare la documentazione di Fuzzing con libFuzzer . Per risolvere l'errore di compilazione, aggiorna le associazioni con i nuovi nomi di servizio e fuzzer. Per i servizi Java/Rust, l'elenco fuzzer può essere vuoto.